mirror of
https://github.com/SWG-Source/src.git
synced 2026-09-28 15:12:53 -04:00
Added TransferServer project and CTServiceGameAPI library
This commit is contained in:
@@ -6,3 +6,4 @@ add_subdirectory(LoginServer)
|
||||
add_subdirectory(LogServer)
|
||||
add_subdirectory(PlanetServer)
|
||||
add_subdirectory(TaskManager)
|
||||
add_subdirectory(TransferServer)
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
project(TransferServer)
|
||||
|
||||
add_subdirectory(src)
|
||||
@@ -0,0 +1,89 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
shared/CentralServerConnection.cpp
|
||||
shared/CentralServerConnection.h
|
||||
shared/ConfigTransferServer.cpp
|
||||
shared/ConfigTransferServer.h
|
||||
shared/ConsoleCommandParser.cpp
|
||||
shared/ConsoleCommandParser.h
|
||||
shared/ConsoleManager.cpp
|
||||
shared/ConsoleManager.h
|
||||
shared/CTSAPIClient.cpp
|
||||
shared/CTSAPIClient.h
|
||||
shared/FirstTransferServer.h
|
||||
shared/TransferServer.cpp
|
||||
shared/TransferServer.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
win32/WinMain.cpp
|
||||
)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
linux/main.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/shared
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCompression/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/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/sharedThread/include/public
|
||||
${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/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/unicode/include
|
||||
${SWG_EXTERNALS_SOURCE_DIR}/3rd/library/soePlatform/CTServiceGameAPI
|
||||
)
|
||||
|
||||
link_directories(${STLPORT_LIBDIR})
|
||||
|
||||
add_executable(TransferServer
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
|
||||
target_link_libraries(TransferServer
|
||||
sharedCommandParser
|
||||
sharedCompression
|
||||
sharedDebug
|
||||
sharedFile
|
||||
sharedFoundation
|
||||
sharedLog
|
||||
sharedMath
|
||||
sharedMemoryManager
|
||||
sharedMessageDispatch
|
||||
sharedNetwork
|
||||
sharedNetworkMessages
|
||||
sharedRandom
|
||||
sharedSynchronization
|
||||
sharedThread
|
||||
sharedUtility
|
||||
serverNetworkMessages
|
||||
serverUtility
|
||||
archive
|
||||
fileInterface
|
||||
localization
|
||||
localizationArchive
|
||||
unicode
|
||||
unicodeArchive
|
||||
udplibrary
|
||||
CTServiceGameAPI
|
||||
${ZLIB_LIBRARY}
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
target_link_libraries(TransferServer mswsock ws2_32)
|
||||
endif()
|
||||
@@ -0,0 +1,60 @@
|
||||
// main.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedNetwork/SetupSharedNetwork.h"
|
||||
#include "sharedNetwork/NetworkHandler.h"
|
||||
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
#include "TransferServer.h"
|
||||
#include "ConfigTransferServer.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(1024);
|
||||
|
||||
//-- setup foundation
|
||||
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
|
||||
|
||||
setupFoundationData.argc = argc;
|
||||
setupFoundationData.argv = argv;
|
||||
setupFoundationData.runInBackground = true;
|
||||
SetupSharedFoundation::install (setupFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
SetupSharedFile::install(false);
|
||||
SetupSharedNetworkMessages::install();
|
||||
|
||||
SetupSharedNetwork::SetupData networkSetupData;
|
||||
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
|
||||
SetupSharedNetwork::install(networkSetupData);
|
||||
NetworkHandler::install();
|
||||
|
||||
Os::setProgramName("TransferServer");
|
||||
ConfigTransferServer::install();
|
||||
|
||||
//-- run server
|
||||
SetupSharedFoundation::callbackWithExceptionHandling(TransferServer::run);
|
||||
|
||||
NetworkHandler::remove();
|
||||
SetupSharedFoundation::remove();
|
||||
SetupSharedThread::remove();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,336 @@
|
||||
// CTSAPIClient.h
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
#include "CentralServerConnection.h"
|
||||
#include "ConfigTransferServer.h"
|
||||
#include "CTSAPIClient.h"
|
||||
#include "CTCommon/CTServiceServer.h"
|
||||
#include <map>
|
||||
#include "sharedLog/Log.h"
|
||||
#include "TransferServer.h"
|
||||
#include "UnicodeUtils.h"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
class CentralServerConnection;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace CTSAPIClientNamespace
|
||||
{
|
||||
struct TransactionTrackData
|
||||
{
|
||||
const CentralServerConnection * m_sourceCentralServerConnection;
|
||||
const CentralServerConnection * m_destinationCentralServerConnection;
|
||||
unsigned int m_track;
|
||||
};
|
||||
|
||||
std::map<unsigned int, TransactionTrackData> s_activeTransfers;
|
||||
std::map<unsigned int, int> s_completedTransfers;
|
||||
}
|
||||
using namespace CTSAPIClientNamespace;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
CTSAPIClient::CTSAPIClient(const std::string & hostName, const std::string & game) :
|
||||
CTServiceAPI(hostName.c_str(), game.c_str())
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
CTSAPIClient::~CTSAPIClient()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onTest(const unsigned track, const int resultCode, const unsigned value, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onTest(%d, %d, %d, %p)", track, resultCode, value, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyTest(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyTest(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyMoveStatus(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyMoveStatus(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyValidateMove(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyValidateMove(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyMove(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyMove(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyTransferAccount(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyTransferAccount(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyCharacterList(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyCharacterList(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyServerList(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyServerList(%d, %d, %p)",track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onReplyDestinationServerList(const unsigned track, const int resultCode, void *user)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onReplyDestinationServerList(%d, %d, %p)", track, resultCode, user));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
void CTSAPIClient::onServerTest(const unsigned server_track, const char *game, const char *param)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onServerTest(%d, %s, %s)", server_track, game, param));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestMoveStatus(const unsigned server_track, const char *language, const unsigned transactionID)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestMoveStatus(%d, %s, %d)", server_track, language, transactionID));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestValidateMove(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *sourceServer, const CTService::CTUnicodeChar *destServer, const CTService::CTUnicodeChar *sourceCharacter, const CTService::CTUnicodeChar *destCharacter, const unsigned uid, const unsigned destuid, bool /*withItems*/, bool /*allowOverride*/)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestValidateMove(%d, %s, %s, %s, %s, %s, %d, %d", server_track, language, Unicode::wideToNarrow(sourceServer).c_str(), Unicode::wideToNarrow(destServer).c_str(), Unicode::wideToNarrow(sourceCharacter).c_str(), Unicode::wideToNarrow(destCharacter).c_str(), uid, destuid));
|
||||
TransferServer::requestMoveValidation(server_track, uid, destuid, Unicode::wideToNarrow(Unicode::String(sourceServer)), Unicode::wideToNarrow(Unicode::String(destServer)), Unicode::wideToNarrow(Unicode::String(sourceCharacter)), Unicode::wideToNarrow(Unicode::String(destCharacter)), std::string(language));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestMove(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *sourceServer, const CTService::CTUnicodeChar *destServer, const CTService::CTUnicodeChar *sourceCharacter, const CTService::CTUnicodeChar *destCharacter, const unsigned uid, const unsigned destuid, const unsigned transactionID, bool withItems, bool allowOverride)
|
||||
{
|
||||
std::map<unsigned int, TransactionTrackData>::const_iterator f = s_activeTransfers.find(uid);
|
||||
if(f == s_activeTransfers.end())
|
||||
{
|
||||
std::string isWithItems = "false";
|
||||
if(withItems)
|
||||
isWithItems = "true";
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestMove(%d, %s, %s, %s, %s, %s, %d, %d, %d, %s)", server_track, language, Unicode::wideToNarrow(sourceServer).c_str(), Unicode::wideToNarrow(destServer).c_str(), Unicode::wideToNarrow(sourceCharacter).c_str(), Unicode::wideToNarrow(destCharacter).c_str(), uid, destuid, transactionID, isWithItems.c_str()));
|
||||
TransferServer::requestMove(server_track, std::string(language), Unicode::wideToNarrow(Unicode::String(sourceServer)), Unicode::wideToNarrow(Unicode::String(destServer)), Unicode::wideToNarrow(Unicode::String(sourceCharacter)), Unicode::wideToNarrow(Unicode::String(destCharacter)), uid, destuid, transactionID, withItems, allowOverride);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CTSAPI", ("Received a transfer request for station ID %d, but a transfer for that id is already in progress", uid));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SOFTERROR);
|
||||
IGNORE_RETURN(replyMove(server_track, result, NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestTransferAccount(const unsigned server_track, const unsigned uid, const unsigned destuid, const unsigned transactionID)
|
||||
{
|
||||
std::map<unsigned int, TransactionTrackData>::const_iterator f = s_activeTransfers.find(uid);
|
||||
if(f == s_activeTransfers.end())
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestTransferAccount(%d, d, %d, %d)", server_track, uid, destuid, transactionID));
|
||||
TransferServer::requestTransferAccount(server_track, uid, destuid, transactionID);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CTSAPI", ("Received a transfer request for station ID %d, but a transfer for that id is already in progress", uid));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SOFTERROR);
|
||||
IGNORE_RETURN(replyTransferAccount(server_track, result, NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestCharacterList(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *server, const unsigned uid)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestCharacterList(%d, %s, %s, %d)", server_track, language, Unicode::wideToNarrow(server).c_str(), uid));
|
||||
TransferServer::requestCharacterList(server_track, uid, Unicode::wideToNarrow(Unicode::String(server)), std::string(language));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestServerList(const unsigned server_track, const char *language)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestServerList(%d, %s)", server_track, language));
|
||||
std::map<std::string, CentralServerConnection *> galaxies = CentralServerConnection::getGalaxies();
|
||||
std::vector<CTService::CTServiceServer> servers;
|
||||
std::vector<std::string>::const_iterator i;
|
||||
|
||||
for (i = ConfigTransferServer::getServersAllowedToUploadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToUploadCharacterData().end(); ++i)
|
||||
{
|
||||
std::map<std::string, CentralServerConnection *>::iterator f = galaxies.find(*i);
|
||||
if(f != galaxies.end())
|
||||
{
|
||||
servers.push_back(CTService::CTServiceServer(Unicode::narrowToWide(i->c_str()).c_str()));
|
||||
}
|
||||
}
|
||||
if(! servers.empty())
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_RESULT_SUCCESS);
|
||||
IGNORE_RETURN(replyServerList(server_track, result, servers.size(), &servers[0], NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_RESULT_FAILURE);
|
||||
IGNORE_RETURN(replyServerList(server_track, result, servers.size(), NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onRequestDestinationServerList(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *character, const CTService::CTUnicodeChar *server)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onRequestDestinationServerList(%d, %s, %s, %s)", server_track, language, Unicode::wideToNarrow(character).c_str(), Unicode::wideToNarrow(server).c_str()));
|
||||
std::map<std::string, CentralServerConnection *> galaxies = CentralServerConnection::getGalaxies();
|
||||
std::vector<CTService::CTServiceServer> servers;
|
||||
std::vector<std::string>::const_iterator i;
|
||||
|
||||
for (i = ConfigTransferServer::getServersAllowedToDownloadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToDownloadCharacterData().end(); ++i)
|
||||
{
|
||||
std::map<std::string, CentralServerConnection *>::iterator f = galaxies.find(*i);
|
||||
if(f != galaxies.end())
|
||||
{
|
||||
servers.push_back(CTService::CTServiceServer(Unicode::narrowToWide(i->c_str()).c_str()));
|
||||
}
|
||||
}
|
||||
if(! servers.empty())
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_RESULT_SUCCESS);
|
||||
IGNORE_RETURN(replyDestinationServerList(server_track, result, servers.size(), &servers[0], NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_RESULT_FAILURE);
|
||||
IGNORE_RETURN(replyDestinationServerList(server_track, result, servers.size(), NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::onConnect(const char *host, const short port, const short current, const short max)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onConnect(%s, %d, %d, %d)", host, port, current, max));
|
||||
REPORT_LOG(true, ("CTSAPIClient::onConnect(%s, %d, %d, %d)\n", host, port, current, max));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
|
||||
void CTSAPIClient::onDisconnect(const char *host, const short port, const short current, const short max)
|
||||
{
|
||||
LOG("CTSAPI", ("CTSAPIClient::onDisconnect(%s, %d, %d, %d)", host, port, current, max));
|
||||
REPORT_LOG(true, ("CTSAPIClient::onDisconnect(%s, %d, %d, %d)\n", host, port, current, max));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::moveStart(unsigned int stationId, unsigned int track, const CentralServerConnection * sourceCentralServerConnection, const CentralServerConnection * destinationCentralServerConnection)
|
||||
{
|
||||
// first check to see if this track has been completed
|
||||
std::map<unsigned int, int>::iterator f = s_completedTransfers.find(track);
|
||||
if(f != s_completedTransfers.end())
|
||||
{
|
||||
IGNORE_RETURN(replyMove(track, f->second, NULL, NULL));
|
||||
}
|
||||
else
|
||||
{
|
||||
TransactionTrackData trackData;
|
||||
trackData.m_destinationCentralServerConnection = destinationCentralServerConnection;
|
||||
trackData.m_sourceCentralServerConnection = sourceCentralServerConnection;
|
||||
trackData.m_track = track;
|
||||
IGNORE_RETURN(s_activeTransfers.insert(std::make_pair(stationId, trackData)));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CTSAPIClient::lostCentralServerConnection(const CentralServerConnection * centralServerConnection)
|
||||
{
|
||||
// send a failure response to the CTS backend for all id's with
|
||||
// a transaction in progress on the dead server
|
||||
std::map<unsigned int, TransactionTrackData>::iterator i;
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SERVER_IS_DOWN);
|
||||
for(i = s_activeTransfers.begin(); i != s_activeTransfers.end();)
|
||||
{
|
||||
if(i->second.m_sourceCentralServerConnection == centralServerConnection || i->second.m_destinationCentralServerConnection == centralServerConnection)
|
||||
{
|
||||
IGNORE_RETURN(replyMove(i->second.m_track, result, NULL, NULL));
|
||||
s_activeTransfers.erase(i++);
|
||||
}
|
||||
else
|
||||
{
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// NOT IMPLEMENTED IN SWG TRANSFER SERVICE
|
||||
void CTSAPIClient::moveComplete(unsigned int id, unsigned int track, int result) const
|
||||
{
|
||||
std::map<unsigned int, TransactionTrackData>::iterator f = s_activeTransfers.find(id);
|
||||
if(f != s_activeTransfers.end())
|
||||
{
|
||||
s_activeTransfers.erase(f);
|
||||
}
|
||||
if(track != 0)
|
||||
{
|
||||
s_completedTransfers.insert(std::make_pair(track, result));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// NOT IMPLEMENTED IN SWG TRANSFER SERVICE
|
||||
void CTSAPIClient::onReplyDelete(const unsigned int, const int, void *)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// NOT IMPLEMENTED IN SWG TRANSFER SERVICE
|
||||
void CTSAPIClient::onReplyRestore(const unsigned int, const int, void *)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// NOT IMPLEMENTED IN SWG TRANSFER SERVICE
|
||||
void CTSAPIClient::onRequestDelete(const unsigned int, const char *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const unsigned int, const unsigned int, const unsigned int, bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
// NOT IMPLEMENTED IN SWG TRANSFER SERVICE
|
||||
void CTSAPIClient::onRequestRestore(const unsigned int, const char *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const unsigned int, const unsigned int, const unsigned int, bool, bool)
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,65 @@
|
||||
// CTSAPIClient.h
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_CTSAPIClient_H
|
||||
#define _INCLUDED_CTSAPIClient_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "CTServiceAPI.h"
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class CTSAPIClient : public CTService::CTServiceAPI
|
||||
{
|
||||
public:
|
||||
CTSAPIClient(const std::string & hostName, const std::string & game);
|
||||
virtual ~CTSAPIClient();
|
||||
|
||||
virtual void onConnect(const char *host, const short port, const short current, const short max);
|
||||
virtual void onDisconnect(const char *host, const short port, const short current, const short max);
|
||||
|
||||
// ----- Normal Callbacks as a response to requests sent -----
|
||||
|
||||
virtual void onTest(const unsigned track, const int resultCode, const unsigned value, void *user);
|
||||
virtual void onReplyTest(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyMoveStatus(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyValidateMove(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyMove(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyTransferAccount(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyCharacterList(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyServerList(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyDestinationServerList(const unsigned track, const int resultCode, void *user);
|
||||
|
||||
// ----- Callbacks generated by the server directly -----
|
||||
|
||||
virtual void onServerTest(const unsigned server_track, const char *game, const char *param);
|
||||
virtual void onRequestMoveStatus(const unsigned server_track, const char *language, const unsigned transactionID);
|
||||
virtual void onRequestValidateMove(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *sourceServer, const CTService::CTUnicodeChar *destServer, const CTService::CTUnicodeChar *sourceCharacter,const CTService::CTUnicodeChar *destCharacter, const unsigned uid, const unsigned destuid, bool withItems, bool);
|
||||
virtual void onRequestMove(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *sourceServer, const CTService::CTUnicodeChar *destServer, const CTService::CTUnicodeChar *sourceCharacter, const CTService::CTUnicodeChar *destCharacter, const unsigned uid, const unsigned destuid, const unsigned transactionID, bool withItems, bool allowOverride);
|
||||
virtual void onRequestTransferAccount(const unsigned server_track, const unsigned uid, const unsigned destuid, const unsigned transactionID);
|
||||
virtual void onRequestCharacterList(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *server, const unsigned uid);
|
||||
virtual void onRequestServerList(const unsigned server_track, const char *language);
|
||||
virtual void onRequestDestinationServerList(const unsigned server_track, const char *language, const CTService::CTUnicodeChar *character, const CTService::CTUnicodeChar *server);
|
||||
void moveComplete(unsigned int id, unsigned int track, int result) const;
|
||||
void moveStart(unsigned int id, unsigned int track, const CentralServerConnection * sourceCentralServerConnection, const CentralServerConnection * destinationCentralServerConnection);
|
||||
void lostCentralServerConnection(const CentralServerConnection * centralServerConnection);
|
||||
|
||||
private:
|
||||
/* NOT IMPLEMENTED IN SWG TRANSFER SERVICE */
|
||||
void onReplyDelete(const unsigned int, const int, void *);
|
||||
void onReplyRestore(const unsigned int, const int, void *);
|
||||
void onRequestDelete(const unsigned int, const char *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const unsigned int, const unsigned int, const unsigned int, bool, bool);
|
||||
void onRequestRestore(const unsigned int, const char *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const CTService::CTUnicodeChar *, const unsigned int, const unsigned int, const unsigned int, bool, bool);
|
||||
|
||||
private:
|
||||
CTSAPIClient();
|
||||
CTSAPIClient(const CTSAPIClient &);
|
||||
CTSAPIClient & operator= (const CTSAPIClient &);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif//_INCLUDED_CTSAPIClient_H
|
||||
@@ -0,0 +1,410 @@
|
||||
// CentralServerConnection.cpp
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
#include "CentralServerConnection.h"
|
||||
#include "ConsoleManager.h"
|
||||
#include "TransferServer.h"
|
||||
#include "serverNetworkMessages/CharacterTransferStatusMessage.h"
|
||||
#include "serverNetworkMessages/DownloadCharacterMessage.h"
|
||||
#include "serverNetworkMessages/ToggleAvatarLoginStatus.h"
|
||||
#include "serverNetworkMessages/TransferAccountData.h"
|
||||
#include "serverNetworkMessages/TransferAccountDataArchive.h"
|
||||
#include "serverNetworkMessages/TransferCharacterData.h"
|
||||
#include "serverNetworkMessages/TransferCharacterDataArchive.h"
|
||||
#include "serverNetworkMessages/TransferReplyCharacterList.h"
|
||||
#include "serverNetworkMessages/TransferReplyMoveValidation.h"
|
||||
#include "serverNetworkMessages/UploadCharacterMessage.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedCommandParser/CommandParser.h"
|
||||
#include "sharedNetworkMessages/ConsoleChannelMessages.h"
|
||||
#include "sharedNetworkMessages/GameNetworkMessage.h"
|
||||
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace CentralServerConnectionNamespace
|
||||
{
|
||||
std::map<std::string, CentralServerConnection *> s_centralServerConnections;
|
||||
}
|
||||
|
||||
using namespace CentralServerConnectionNamespace;
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
CentralServerConnection::CentralServerConnection(UdpConnectionMT * u, TcpClient * t) :
|
||||
ServerConnection(u, t),
|
||||
m_galaxyName("")
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
CentralServerConnection::~CentralServerConnection()
|
||||
{
|
||||
std::map<std::string, CentralServerConnection *>::iterator f = s_centralServerConnections.find(m_galaxyName);
|
||||
if(f != s_centralServerConnections.end())
|
||||
{
|
||||
s_centralServerConnections.erase(f);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
CentralServerConnection * CentralServerConnection::getCentralServerConnectionForGalaxy(const std::string & galaxyName)
|
||||
{
|
||||
CentralServerConnection * result = 0;
|
||||
std::map<std::string, CentralServerConnection *>::iterator f = s_centralServerConnections.find(galaxyName);
|
||||
if(f != s_centralServerConnections.end())
|
||||
{
|
||||
result = f->second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const std::map<std::string, CentralServerConnection *> & CentralServerConnection::getGalaxies()
|
||||
{
|
||||
return s_centralServerConnections;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CentralServerConnection::onConnectionClosed()
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Connection with CentralServer running Galaxy %s has closed\n", m_galaxyName.c_str()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CentralServerConnection::onConnectionOpened()
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: A connection with a CentralServer has opened\n"));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CentralServerConnection::onReceive(const Archive::ByteStream & message)
|
||||
{
|
||||
Archive::ReadIterator ri = message.begin();
|
||||
const GameNetworkMessage msg(ri);
|
||||
ri = message.begin();
|
||||
if(msg.isType("CentralGalaxyName"))
|
||||
{
|
||||
|
||||
const GenericValueTypeMessage<std::string> cgn(ri);
|
||||
setGalaxyName(cgn.getValue());
|
||||
LOG("CustomerService", ("CharacterTransfer: Received CentralGalaxyName for %s", cgn.getValue().c_str()));
|
||||
}
|
||||
else if(msg.isType("UploadCharacterMessage"))
|
||||
{
|
||||
// receiving character data
|
||||
const UploadCharacterMessage ucm(ri);
|
||||
CharacterTransferData data;
|
||||
data.stationId = ucm.getStationId();
|
||||
data.fromGalaxy = m_galaxyName;
|
||||
data.packedData = ucm.getPackedCharacterData();
|
||||
bool result = TransferServer::uploadCharacterTransferData(data, ucm.getIsAdmin());
|
||||
if(result)
|
||||
{
|
||||
CharacterTransferStatusMessage uploadResult(ucm.getFromGameServerId(), ucm.getFromCharacterId(), "@base_player:upload_success");
|
||||
send(uploadResult, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterTransferStatusMessage uploadResult(ucm.getFromGameServerId(), ucm.getFromCharacterId(), "@base_player:upload_fail");
|
||||
send(uploadResult, true);
|
||||
}
|
||||
}
|
||||
else if(msg.isType("DownloadCharacterMessage"))
|
||||
{
|
||||
// retreive packed data from transfer server and
|
||||
// send it to the requesting central server
|
||||
const DownloadCharacterMessage dcm(ri);
|
||||
const CharacterTransferData * data = TransferServer::getCharacterTransferData(dcm.getStationId(), m_galaxyName, dcm.getIsAdmin());
|
||||
if(data)
|
||||
{
|
||||
const UploadCharacterMessage ucm(data->stationId, data->packedData, dcm.getGameServerId(), dcm.getToCharacterId(), true);
|
||||
send(ucm, true);
|
||||
LOG("CustomerService", ("CharacterTransfer: Character data for SUID %d downloaded\n", data->stationId));
|
||||
}
|
||||
else
|
||||
{
|
||||
CharacterTransferStatusMessage downloadResult(dcm.getGameServerId(), dcm.getToCharacterId(), "@base_player:download_fail");
|
||||
send(downloadResult, true);
|
||||
}
|
||||
|
||||
}
|
||||
else if(msg.isType("AuthorizeDownload"))
|
||||
{
|
||||
const GenericValueTypeMessage<unsigned int> auth(ri);
|
||||
TransferServer::authorizeDownload(auth.getValue());
|
||||
}
|
||||
else if(msg.isType("UnauthorizeDownload"))
|
||||
{
|
||||
const GenericValueTypeMessage<unsigned int> auth(ri);
|
||||
TransferServer::unauthorizeDownload(auth.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferReplyCharacterList"))
|
||||
{
|
||||
const TransferReplyCharacterList reply(ri);
|
||||
|
||||
// TESTING!
|
||||
LOG("CustomerService", ("CharacterTransfer: Received character list for station id %d\n", reply.getStationId()));
|
||||
const std::vector<AvatarRecord> & avatarList = reply.getAvatarList();
|
||||
std::vector<AvatarRecord>::const_iterator i;
|
||||
LOG("CustomerService", ("CharacterTransfer: Enumerating %d characters", avatarList.size()));
|
||||
for(i = avatarList.begin() ; i != avatarList.end(); ++i)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: m_name = \"%s\" m_networkId = %s\n", Unicode::wideToNarrow(i->m_name).c_str(), i->m_networkId.getValueString().c_str()));
|
||||
}
|
||||
|
||||
// TESTING END
|
||||
TransferServer::replyCharacterList(reply);
|
||||
}
|
||||
else if(msg.isType("TransferReplyMoveValidation"))
|
||||
{
|
||||
const TransferReplyMoveValidation reply(ri);
|
||||
if(reply.getResult() == TransferReplyMoveValidation::TRMVR_can_create_regular_character)
|
||||
{
|
||||
// save off the source character's template crc so it can be used in
|
||||
// subsequent TransferRequestMoveValidation queries, so the LoginServer
|
||||
// doesn't have to continually query the DB to fetch the same information
|
||||
// over and over again, because the character's template crc
|
||||
// (i.e. the character's species) should never, ever change
|
||||
TransferServer::cacheSourceCharacterTemplateCrc(reply.getSourceStationId(), reply.getSourceGalaxy(), reply.getSourceCharacter(), reply.getSourceCharacterTemplateId());
|
||||
|
||||
TransferCharacterData requestData(reply.getTransferRequestSource());
|
||||
requestData.setTrack(reply.getTrack());
|
||||
requestData.setCustomerLocalizedLanguage(reply.getCustomerLocalizedLanguage());
|
||||
requestData.setSourceGalaxy(reply.getSourceGalaxy());
|
||||
requestData.setDestinationGalaxy(reply.getDestinationGalaxy());
|
||||
requestData.setSourceCharacterName(reply.getSourceCharacter());
|
||||
requestData.setObjectTemplateCrc(reply.getSourceCharacterTemplateId());
|
||||
requestData.setDestinationCharacterName(reply.getDestinationCharacter());
|
||||
requestData.setSourceStationId(reply.getSourceStationId());
|
||||
requestData.setDestinationStationId(reply.getDestinationStationId());
|
||||
const GenericValueTypeMessage<TransferCharacterData> requestNameValidation("TransferRequestNameValidation", requestData);
|
||||
CentralServerConnection * destinationConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(reply.getDestinationGalaxy());
|
||||
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferReplyMoveValidation for %s on %s to %s on %s from CentralServer. Sending TransferRequestNameValidation to destination CentralServer.", reply.getSourceCharacter().c_str(), reply.getSourceGalaxy().c_str(), reply.getDestinationCharacter().c_str(), reply.getDestinationGalaxy().c_str()));
|
||||
|
||||
const GenericValueTypeMessage<std::pair<unsigned int, unsigned int> > kick("TransferRequestKickConnectedClients", std::make_pair(requestData.getSourceStationId(), requestData.getDestinationStationId()));
|
||||
if(destinationConnection)
|
||||
{
|
||||
destinationConnection->send(requestNameValidation, true);
|
||||
destinationConnection->send(kick, true);
|
||||
}
|
||||
|
||||
CentralServerConnection * sourceConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(reply.getSourceGalaxy());
|
||||
if(sourceConnection)
|
||||
{
|
||||
sourceConnection->send(kick, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: TransferReplyMoveValidation failed for %s on %s to %s on %s from CentralServer because the account cannot create a new character on the destination server", reply.getSourceCharacter().c_str(), reply.getSourceGalaxy().c_str(), reply.getDestinationCharacter().c_str(), reply.getDestinationGalaxy().c_str()));
|
||||
TransferServer::failedToValidateTransfer(reply);
|
||||
}
|
||||
}
|
||||
else if(msg.isType("TransferReplyNameValidation"))
|
||||
{
|
||||
const GenericValueTypeMessage<std::pair<std::string, TransferCharacterData> > replyNameValidation(ri);
|
||||
if(!replyNameValidation.getValue().second.getIsMoveRequest())
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Received replyNameValidation for move validation request. (%s) %s", replyNameValidation.getValue().first.c_str(), replyNameValidation.getValue().second.toString().c_str()));
|
||||
TransferServer::replyValidateMove(replyNameValidation.getValue().second);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(TransferServer::isRename(replyNameValidation.getValue().second))
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Received replyNameValidation for rename request, starting character rename protocol. (%s) %s", replyNameValidation.getValue().first.c_str(), replyNameValidation.getValue().second.toString().c_str()));
|
||||
const GenericValueTypeMessage<TransferCharacterData> renameCharacter("TransferRenameCharacter", replyNameValidation.getValue().second);
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(replyNameValidation.getValue().second.getSourceGalaxy());
|
||||
if(centralServerConnection)
|
||||
{
|
||||
centralServerConnection->send(renameCharacter, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
TransferServer::transferCreateCharacterFailed(replyNameValidation.getValue().second);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DEBUG_FATAL(true, ("Received TransferReplyNameValidation for a move request that is not a rename!"));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(msg.isType("TransferReplyCharacterDataFromLoginServer"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Got TransferReplyCharacterDataFromLoginServer, characterId=%s\n", reply.getValue().getCharacterId().getValueString().c_str()));
|
||||
|
||||
// is this a transfer or a rename?
|
||||
if(TransferServer::isRename(reply.getValue()))
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending TransferRequestNameValidation for character rename request: %s", reply.getValue().toString().c_str()));
|
||||
// send a name validation request
|
||||
const GenericValueTypeMessage<TransferCharacterData> requestNameValidation("TransferRequestNameValidation", reply.getValue());
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(reply.getValue().getSourceGalaxy());
|
||||
if(centralServerConnection)
|
||||
{
|
||||
centralServerConnection->send(requestNameValidation, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// this is a transfer
|
||||
TransferServer::getLoginLocationData(reply.getValue());
|
||||
}
|
||||
}
|
||||
else if(msg.isType("TransferReplyLoginLocationData"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Got TransferReplyLoginLocationData from CentralServer. TransferCharacterData=%s\n", reply.getValue().toString().c_str()));
|
||||
|
||||
// send character to ConnectionServer for login to a game server
|
||||
const GenericValueTypeMessage<TransferCharacterData> login("TransferLoginCharacterToSourceServer", reply.getValue());
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending TransferLoginCharacterToSourceServer to CentralServer : %s", login.getValue().toString().c_str()));
|
||||
send(login, true);
|
||||
}
|
||||
else if(msg.isType("TransferReceiveDataFromGameServer"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> transferReply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Got TransferReceiveDataFromGameServer: %s", transferReply.getValue().toString().c_str()));
|
||||
REPORT_LOG(true, ("Got TransferReceiveDataFromGameServer: %s\n", transferReply.getValue().toString().c_str()));
|
||||
|
||||
// find a central server connection for the target cluster
|
||||
CentralServerConnection * destinationCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(transferReply.getValue().getDestinationGalaxy());
|
||||
if(destinationCentralConnection)
|
||||
{
|
||||
// send character to ConnectionServer for creation on the destination server
|
||||
GenericValueTypeMessage<TransferCharacterData> login("TransferLoginCharacterToDestinationServer", transferReply.getValue());
|
||||
destinationCentralConnection->send(login, true);
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending TransferLoginCharacterToDestinationServer to CentralServer (%s) for (%s)", transferReply.getValue().getDestinationGalaxy().c_str(), login.getValue().toString().c_str()));
|
||||
}
|
||||
else
|
||||
{
|
||||
//@todo: report error to CTS API
|
||||
LOG("CustomerService", ("CharacterTransfer: Failed to get a CentralServer connection for %s", transferReply.getValue().getDestinationGalaxy().c_str()));
|
||||
TransferServer::transferCreateCharacterFailed(transferReply.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
else if(msg.isType("ApplyTransferDataSuccess"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> success(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferDataSuccess from target galaxy. %s", success.getValue().toString().c_str()));
|
||||
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(success.getValue().getSourceGalaxy());
|
||||
if(centralServerConnection)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending ToggleAvatarLoginStatus request to source central server"));
|
||||
const ToggleAvatarLoginStatus toggleLoginStatus(success.getValue().getSourceGalaxy(), success.getValue().getSourceStationId(), success.getValue().getCharacterId(), false);
|
||||
centralServerConnection->send(toggleLoginStatus, true);
|
||||
TransferServer::replyMoveSuccess(success.getValue());
|
||||
LOG("CustomerService", ("CharacterTransfer: TRANSFER SUCCESSFUL for transactionId=%u", success.getValue().getTransactionId()));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed on target galaxy : %s", success.getValue().toString().c_str()));
|
||||
TransferServer::transferCreateCharacterFailed(success.getValue());
|
||||
}
|
||||
|
||||
}
|
||||
else if(msg.isType("ApplyTransferDataFail"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> fail(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received ApplyTransferDataFail from target galaxy. %s", fail.getValue().toString().c_str()));
|
||||
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(fail.getValue().getDestinationGalaxy());
|
||||
if(centralServerConnection)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: failed to apply transfer data. Deleting character on destination server. %s", fail.getValue().toString().c_str()));
|
||||
const GenericValueTypeMessage<TransferCharacterData> deleteCharacter("DeleteFailedTransfer", fail.getValue());
|
||||
centralServerConnection->send(deleteCharacter, true);
|
||||
TransferServer::failedToApplyTransferData(fail.getValue());
|
||||
}
|
||||
}
|
||||
else if(msg.isType("TransferCreateCharacterFailed"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> fail(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferCreateCharacterFailed, sending response to CTS API. %s", fail.getValue().toString().c_str()));
|
||||
TransferServer::transferCreateCharacterFailed(fail.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferRenameCharacterReply"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferRenameCharacterReply from Central Server : %s", reply.getValue().toString().c_str()));
|
||||
if(reply.getValue().getIsValidName())
|
||||
{
|
||||
TransferServer::replyMoveSuccess(reply.getValue());
|
||||
}
|
||||
else
|
||||
{
|
||||
TransferServer::transferCreateCharacterFailed(reply.getValue());
|
||||
}
|
||||
}
|
||||
else if(msg.isType("TransferAccountReplySuccessTransferServer"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferAccountData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferAccountReplySuccessTransferServer from station Id %d to station Id %d", reply.getValue().getSourceStationId(), reply.getValue().getDestinationStationId()));
|
||||
TransferServer::replyTransferAccountSuccess(reply.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferAccountFailedToUpdateGameDatabase"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferAccountData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferAccountFailedToUpdateGameDatabase for transfer from station Id %d to station Id %d", reply.getValue().getSourceStationId(), reply.getValue().getDestinationStationId()));
|
||||
TransferServer::failedToTransferAccountNoCentralConnection(reply.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferAccountFailedDestinationNotEmpty"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferAccountData> reply(ri);
|
||||
LOG("CustomerService", ("CharacterTransfer: Received TransferAccountFailedDestinationNotEmpty for transfer from station Id %d to station Id %d", reply.getValue().getSourceStationId(), reply.getValue().getDestinationStationId()));
|
||||
TransferServer::failedToTransferAccountDestinationNotEmpty(reply.getValue());
|
||||
}
|
||||
else if(msg.isType("ReplyTransferDataFail"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> reply(ri);
|
||||
TransferServer::failedToRetrieveTransferData(reply.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferFailGameServerClosedConnectionWithConnectionServer"))
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> fail(ri);
|
||||
TransferServer::failedToTransferCharacterGameConnectionClosed(fail.getValue());
|
||||
}
|
||||
else if(msg.isType("TransferFailConnectionServerClosedConnectionWithCentralServer"))
|
||||
{
|
||||
const GenericValueTypeMessage<unsigned int> fail(ri);
|
||||
TransferServer::failedToTransferCharacterConnectionServerConnectionClosed(fail.getValue());
|
||||
}
|
||||
else if(msg.isType("ConGenericMessage"))
|
||||
{
|
||||
const ConGenericMessage cm(ri);
|
||||
std::string result;
|
||||
ConsoleManager::processString(cm.getMsg(), static_cast<const NetworkId::NetworkIdType>(cm.getMsgId()), result);
|
||||
const ConGenericMessage response(result, cm.getMsgId());
|
||||
send(response, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void CentralServerConnection::setGalaxyName(const std::string & galaxyName)
|
||||
{
|
||||
s_centralServerConnections[galaxyName] = this;
|
||||
m_galaxyName = galaxyName;
|
||||
REPORT_LOG("CentralServerConnection", ("Galaxy %s is handled by CentralServerConnection with %s:%d\n", m_galaxyName.c_str(), getRemoteAddress().c_str(), getRemotePort()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,42 @@
|
||||
// CentralServerConnection.h
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_CentralServerConnection_H
|
||||
#define _INCLUDED_CentralServerConnection_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "serverUtility/ServerConnection.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
class CentralServerConnection;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class CentralServerConnection : public ServerConnection
|
||||
{
|
||||
public:
|
||||
CentralServerConnection(UdpConnectionMT *, TcpClient * t);
|
||||
~CentralServerConnection();
|
||||
|
||||
virtual void onConnectionClosed ();
|
||||
virtual void onConnectionOpened ();
|
||||
virtual void onReceive (const Archive::ByteStream & message);
|
||||
|
||||
static CentralServerConnection * getCentralServerConnectionForGalaxy(const std::string & galaxyName);
|
||||
void setGalaxyName (const std::string & galaxyName);
|
||||
|
||||
static const std::map<std::string, CentralServerConnection *> & getGalaxies();
|
||||
|
||||
private:
|
||||
CentralServerConnection & operator = (const CentralServerConnection & rhs);
|
||||
CentralServerConnection(const CentralServerConnection & source);
|
||||
|
||||
std::string m_galaxyName;
|
||||
}; //lint !e1712 default constructor not defined for class 'CentralServerConnection'
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_CentralServerConnection_H
|
||||
@@ -0,0 +1,137 @@
|
||||
// ConfigTransferServer.cpp
|
||||
// Copyright 2000-01, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
#include "sharedFoundation/ConfigFile.h"
|
||||
#include "sharedNetwork/SetupSharedNetwork.h"
|
||||
#include "ConfigTransferServer.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConfigTransferServer::Data * ConfigTransferServer::data = 0;
|
||||
|
||||
#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("TransferServer", #a, b))
|
||||
#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("TransferServer", #a, b))
|
||||
#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("TransferServer", #a, b))
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace ConfigTransferServerNamespace
|
||||
{
|
||||
std::vector<std::string> s_serversAllowedToUploadCharacterData;
|
||||
std::vector<std::string> s_serversAllowedToDownloadCharacterData;
|
||||
}
|
||||
|
||||
using namespace ConfigTransferServerNamespace;
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const std::vector<std::string> & ConfigTransferServer::getServersAllowedToUploadCharacterData()
|
||||
{
|
||||
return s_serversAllowedToUploadCharacterData;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
const std::vector<std::string> & ConfigTransferServer::getServersAllowedToDownloadCharacterData()
|
||||
{
|
||||
return s_serversAllowedToDownloadCharacterData;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
void ConfigTransferServer::install(void)
|
||||
{
|
||||
SetupSharedNetwork::SetupData networkSetupData;
|
||||
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
|
||||
|
||||
data = new ConfigTransferServer::Data;
|
||||
|
||||
KEY_INT (centralServerServiceBindPort, 50005);
|
||||
KEY_STRING (centralServerServiceBindInterface, "");
|
||||
KEY_BOOL (allowSameServerTransfers, false);
|
||||
KEY_BOOL (allowAccountTransfers, true);
|
||||
KEY_STRING (apiServerHostAddress, "");
|
||||
KEY_BOOL (transferChatAvatar, false);
|
||||
|
||||
int index = 0;
|
||||
char const * result = 0;
|
||||
do
|
||||
{
|
||||
result = ConfigFile::getKeyString("TransferServer", "serverAllowedToUploadCharacterData", index++, 0);
|
||||
if (result != 0)
|
||||
{
|
||||
s_serversAllowedToUploadCharacterData.push_back(result);
|
||||
}
|
||||
}
|
||||
while (result);
|
||||
|
||||
index = 0;
|
||||
result = 0;
|
||||
do
|
||||
{
|
||||
result = ConfigFile::getKeyString("TransferServer", "serverAllowedToDownloadCharacterData", index++, 0);
|
||||
if (result != 0)
|
||||
{
|
||||
s_serversAllowedToDownloadCharacterData.push_back(result);
|
||||
}
|
||||
}
|
||||
while (result);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConfigTransferServer::remove(void)
|
||||
{
|
||||
delete data;
|
||||
data = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
unsigned short ConfigTransferServer::getCentralServerServiceBindPort()
|
||||
{
|
||||
return static_cast<unsigned short>(data->centralServerServiceBindPort);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const char * ConfigTransferServer::getCentralServerServiceBindInterface()
|
||||
{
|
||||
return data->centralServerServiceBindInterface;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool ConfigTransferServer::getAllowSameServerTransfers()
|
||||
{
|
||||
return data->allowSameServerTransfers;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool ConfigTransferServer::getAllowAccountTransfers()
|
||||
{
|
||||
return data->allowAccountTransfers;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const char * ConfigTransferServer::getApiServerHostAddress()
|
||||
{
|
||||
return data->apiServerHostAddress;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const bool ConfigTransferServer::getTransferChatAvatar()
|
||||
{
|
||||
return data->transferChatAvatar;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,48 @@
|
||||
// ConfigTransferServer.h
|
||||
// Copyright 2000-04, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _ConfigTransferServer_H
|
||||
#define _ConfigTransferServer_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class ConfigTransferServer
|
||||
{
|
||||
public:
|
||||
struct Data
|
||||
{
|
||||
int centralServerServiceBindPort;
|
||||
const char * consoleServiceBindInterface;
|
||||
const char * gameServiceBindInterface;
|
||||
const char * centralServerServiceBindInterface;
|
||||
bool allowSameServerTransfers;
|
||||
bool allowAccountTransfers;
|
||||
const char * apiServerHostAddress;
|
||||
bool transferChatAvatar;
|
||||
};
|
||||
|
||||
static uint16 getCentralServerServiceBindPort ();
|
||||
static const char * getCentralServerServiceBindInterface ();
|
||||
static bool getAllowSameServerTransfers ();
|
||||
static bool getAllowAccountTransfers ();
|
||||
|
||||
static void install ();
|
||||
static void remove ();
|
||||
|
||||
static const std::vector<std::string> & getServersAllowedToUploadCharacterData();
|
||||
static const std::vector<std::string> & getServersAllowedToDownloadCharacterData();
|
||||
static const char * getApiServerHostAddress();
|
||||
static const bool getTransferChatAvatar();
|
||||
private:
|
||||
static Data * data;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
#endif // _ConfigTransferServer_H
|
||||
@@ -0,0 +1,139 @@
|
||||
// ConsoleCommandParser.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "ConsoleCommandParser.h"
|
||||
#include "TransferServer.h"
|
||||
#include "UnicodeUtils.h"
|
||||
#include <vector>
|
||||
#include "Unicode.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace CommandNames
|
||||
{
|
||||
#define MAKE_COMMAND(a) const char * const a = #a
|
||||
#undef MAKE_COMMAND
|
||||
}
|
||||
|
||||
const CommandParser::CmdInfo cmds[] =
|
||||
{
|
||||
{"transfer", 4, "<requestMove> <station id> <character name> <source server> <destination server>", "Request a character transfer for <character name> from <source server> to <destination server>"},
|
||||
{"transfer", 2, "<requestAccountMove> <source station id> <destination station id>", "Request an account transfer from <source station id> to <destination station id>"},
|
||||
{"", 0, "", ""} // this must be last
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConsoleCommandParser::ConsoleCommandParser() :
|
||||
CommandParser ("", 0, "...", "console commands", this)
|
||||
{
|
||||
createDelegateCommands(cmds);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConsoleCommandParser::~ConsoleCommandParser()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool ConsoleCommandParser::performParsing(const NetworkId & track, const StringVector_t & argv, const String_t &, String_t & result, const CommandParser *)
|
||||
{
|
||||
bool successResult = false;
|
||||
|
||||
if(isCommand(argv[0], "transfer"))
|
||||
{
|
||||
if(isCommand(argv[1], "requestMove"))
|
||||
{
|
||||
if(argv.size() > 5)
|
||||
{
|
||||
std::string stationIdString = Unicode::wideToNarrow(argv[2]);
|
||||
std::string characterName = Unicode::wideToNarrow(argv[3]);
|
||||
std::string sourceServer = Unicode::wideToNarrow(argv[4]);
|
||||
std::string destinationServer = Unicode::wideToNarrow(argv[5]);
|
||||
|
||||
LOG("CustomerService", ("CharacterTransfer: received console request to transfer %s, belonging to %s from %s to %s", characterName.c_str(), stationIdString.c_str(), sourceServer.c_str(), destinationServer.c_str()));
|
||||
|
||||
result += Unicode::narrowToWide("Received request to move ");
|
||||
result += Unicode::narrowToWide(characterName);
|
||||
result += Unicode::narrowToWide(" owned by station ID ");
|
||||
result += Unicode::narrowToWide(stationIdString);
|
||||
result += Unicode::narrowToWide(" on cluster ");
|
||||
result += Unicode::narrowToWide(sourceServer);
|
||||
result += Unicode::narrowToWide(" to cluster ");
|
||||
result += Unicode::narrowToWide(destinationServer);
|
||||
|
||||
const unsigned int stationId = static_cast<const unsigned int>(atoi (stationIdString.c_str()));
|
||||
const unsigned int trackId = static_cast<const unsigned int>(track.getValue());
|
||||
|
||||
//todo : drive these through the command handler, just testing
|
||||
// basic functionality for now.
|
||||
const bool withItems = true;
|
||||
const bool allowOverride = true;
|
||||
|
||||
TransferServer::requestMove(trackId, "en", sourceServer, destinationServer, characterName, characterName, stationId, stationId, trackId, withItems, allowOverride);
|
||||
successResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string messageString = "not enough arguments to 'requestMove <station id> <character name> <source server> <destination server>'";
|
||||
StringVector_t::const_iterator i;
|
||||
|
||||
for(i = argv.begin(); i != argv.end(); ++i)
|
||||
{
|
||||
messageString = messageString + Unicode::wideToNarrow(*i) + " | ";
|
||||
}
|
||||
LOG("CustomerService", ("CharacterTransfer: %s", messageString.c_str()));
|
||||
result += Unicode::narrowToWide(messageString);
|
||||
}
|
||||
}
|
||||
else if (isCommand(argv[1], "requestAccountMove"))
|
||||
{
|
||||
if (argv.size() > 3)
|
||||
{
|
||||
std::string sourceStationIdString = Unicode::wideToNarrow(argv[2]);
|
||||
std::string destinationStationIdString = Unicode::wideToNarrow(argv[3]);
|
||||
|
||||
LOG("CustomerService", ("CharacterTransfer: received console request to transfer account from station ID %s to station ID %s", sourceStationIdString.c_str(), destinationStationIdString.c_str()));
|
||||
|
||||
result += Unicode::narrowToWide("Received request to move from station ID ");
|
||||
result += Unicode::narrowToWide(sourceStationIdString);
|
||||
result += Unicode::narrowToWide(" to station ID ");
|
||||
result += Unicode::narrowToWide(destinationStationIdString);
|
||||
result += Unicode::narrowToWide("\n");
|
||||
|
||||
const unsigned int sourceStationId = static_cast<const unsigned int>(atoi (sourceStationIdString.c_str()));
|
||||
const unsigned int destinationStationId = static_cast<const unsigned int>(atoi (destinationStationIdString.c_str()));
|
||||
const unsigned int trackId = static_cast<const unsigned int>(track.getValue());
|
||||
|
||||
TransferServer::requestTransferAccount(trackId, sourceStationId, destinationStationId, trackId);
|
||||
successResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string messageString = "not enough arguments to 'requestAccountMove <source station id> <destination station id>'";
|
||||
StringVector_t::const_iterator i;
|
||||
|
||||
for(i = argv.begin(); i != argv.end(); ++i)
|
||||
{
|
||||
messageString = messageString + Unicode::wideToNarrow(*i) + " | ";
|
||||
}
|
||||
LOG("CustomerService", ("CharacterTransfer: %s\n", messageString.c_str()));
|
||||
result += Unicode::narrowToWide(messageString);
|
||||
result += Unicode::narrowToWide("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return successResult;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,29 @@
|
||||
// ConsoleCommandParser.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_ConsoleCommandParser_H
|
||||
#define _INCLUDED_ConsoleCommandParser_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "sharedCommandParser/CommandParser.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class ConsoleCommandParser : public CommandParser
|
||||
{
|
||||
public:
|
||||
ConsoleCommandParser();
|
||||
~ConsoleCommandParser();
|
||||
virtual bool performParsing(const NetworkId & userId, const StringVector_t & argv,const String_t & originalCommand,String_t & result,const CommandParser * node);
|
||||
|
||||
private:
|
||||
ConsoleCommandParser & operator = (const ConsoleCommandParser & rhs);
|
||||
ConsoleCommandParser(const ConsoleCommandParser & source);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_ConsoleCommandParser_H
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
// ConsoleManager.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedFoundation/NetworkId.h"
|
||||
#include "ConsoleManager.h"
|
||||
#include "ConsoleCommandParser.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace ConsoleManagerNamespace
|
||||
{
|
||||
ConsoleCommandParser * s_consoleCommandParserRoot = NULL;
|
||||
}
|
||||
|
||||
using namespace ConsoleManagerNamespace;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConsoleManager::ConsoleManager()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
ConsoleManager::~ConsoleManager()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConsoleManager::install()
|
||||
{
|
||||
s_consoleCommandParserRoot = new ConsoleCommandParser;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConsoleManager::remove()
|
||||
{
|
||||
delete s_consoleCommandParserRoot;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void ConsoleManager::processString(const std::string & msg, const int track, std::string & result)
|
||||
{
|
||||
Unicode::String wideResult;
|
||||
IGNORE_RETURN(s_consoleCommandParserRoot->parse(NetworkId(static_cast<NetworkId::NetworkIdType>(track)), Unicode::narrowToWide(msg), wideResult));
|
||||
result = Unicode::wideToNarrow(wideResult);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// ConsoleManager.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_ConsoleManager_H
|
||||
#define _INCLUDED_ConsoleManager_H
|
||||
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class ConsoleManager
|
||||
{
|
||||
public:
|
||||
static void install();
|
||||
static void remove();
|
||||
static void processString(const std::string & msg, const int track, std::string & result);
|
||||
private:
|
||||
ConsoleManager & operator = (const ConsoleManager & rhs);
|
||||
ConsoleManager(const ConsoleManager & source);
|
||||
ConsoleManager();
|
||||
~ConsoleManager();
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_ConsoleManager_H
|
||||
@@ -0,0 +1,14 @@
|
||||
// FirstServerConsole.h
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_FirstServerConsole_H
|
||||
#define _INCLUDED_FirstServerConsole_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_FirstServerConsole_H
|
||||
@@ -0,0 +1,872 @@
|
||||
// TransferServer.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
#include "CentralServerConnection.h"
|
||||
#include "ConfigTransferServer.h"
|
||||
#include "ConsoleManager.h"
|
||||
#include "CTSAPIClient.h"
|
||||
#include "CTCommon/CTServiceCharacter.h"
|
||||
#include "serverNetworkMessages/TransferAccountData.h"
|
||||
#include "serverNetworkMessages/TransferAccountDataArchive.h"
|
||||
#include "serverNetworkMessages/TransferCharacterData.h"
|
||||
#include "serverNetworkMessages/TransferCharacterDataArchive.h"
|
||||
#include "serverNetworkMessages/TransferReplyCharacterList.h"
|
||||
#include "serverNetworkMessages/TransferReplyMoveValidation.h"
|
||||
#include "serverNetworkMessages/TransferRequestMoveValidation.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedLog/Log.h"
|
||||
#include "sharedLog/SetupSharedLog.h"
|
||||
#include "sharedMath/Vector.h"
|
||||
#include "sharedNetwork/Connection.h"
|
||||
#include "sharedNetwork/Service.h"
|
||||
#include "sharedNetwork/NetworkSetupData.h"
|
||||
#include "sharedNetworkMessages/GenericValueTypeMessage.h"
|
||||
#include "sharedUtility/DataTableManager.h"
|
||||
#include "TransferServer.h"
|
||||
#include "CentralServerConnection.h"
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <ostream>
|
||||
#include "Unicode.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
namespace TransferServerNamespace
|
||||
{
|
||||
Service * s_transferServerService;
|
||||
std::map<unsigned int, CharacterTransferData> s_transferData;
|
||||
std::set<std::string> s_serversAllowedToUpload;
|
||||
std::set<std::string> s_serversAllowedToDownload;
|
||||
std::set<unsigned int> s_authorizedDownloads;
|
||||
bool s_done = false;
|
||||
CTSAPIClient * s_apiClient = 0;
|
||||
|
||||
// as we receive the source character's template crc that comes back from the LoginServer
|
||||
// in the TransferReplyMoveValidation message, save it here, and send it back in subseqnent
|
||||
// TransferRequestMoveValidation messages as an optimization so the LoginServer doesn't have
|
||||
// to continually query the DB to fetch the same information over and over again, because
|
||||
// the character's template crc (i.e. the character's species) should never, ever change
|
||||
std::map<std::pair<unsigned int, std::pair<std::string, std::string> >, uint32> s_cacheSourceCharacterTemplateCrc;
|
||||
|
||||
void closePseudoClientConnection(const std::string & galaxyName, const unsigned int stationId)
|
||||
{
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(galaxyName);
|
||||
if(centralServerConnection)
|
||||
{
|
||||
GenericValueTypeMessage<unsigned int> closeRequest("TransferClosePseudoClientConnection", stationId);
|
||||
centralServerConnection->send(closeRequest, true);
|
||||
}
|
||||
}
|
||||
|
||||
void closePseudoClientConnections(const std::string & sourceGalaxyName, const unsigned int sourceStationId, const std::string & destinationGalaxyName, const unsigned int destinationStationId)
|
||||
{
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnection(sourceGalaxyName, sourceStationId);
|
||||
|
||||
unsigned int destId = destinationStationId;
|
||||
if(destId == 0)
|
||||
destId = sourceStationId;
|
||||
closePseudoClientConnection(destinationGalaxyName, destId);
|
||||
|
||||
}
|
||||
|
||||
std::string resultToString(CTService::CTMoveResult resultCode)
|
||||
{
|
||||
std::string resultString;
|
||||
|
||||
switch (resultCode)
|
||||
{
|
||||
case CTService::CT_GAMERESULT_SUCCESS:
|
||||
resultString = "CTService::CT_GAMERESULT_SUCCESS";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_SOFTERROR:
|
||||
resultString = "CTService::CT_GAMERESULT_SOFTERROR";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_HARDERROR:
|
||||
resultString = "CTService::CT_GAMERESULT_HARDERROR";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_INVALID_NAME:
|
||||
resultString = "CTService::CT_GAMERESULT_INVALID_NAME";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_NAME_ALREADY_TAKE:
|
||||
resultString = "CTService::CT_GAMERESULT_NAME_ALREADY_TAKE";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_HAS_CORPSE:
|
||||
resultString = "CTService::CT_GAMERESULT_NAME_HAS_CORPSE";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_SERVER_IS_DOWN:
|
||||
resultString = "CTService::CT_GAMERESULT_SERVER_IS_DOWN";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_MAX_CHAR_ON_DEST_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_MAX_CHAR_ON_DEST_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_TO_LEAVE_SRC_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_TO_LEAVE_SRC_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_ON_DEST_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_ON_DEST_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_SRC_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_SRC_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_TO_DEST_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_TO_DEST_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_THIS_SRC_SERVER_TO_THIS_DEST_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_THIS_SRC_SERVER_TO_THIS_DEST_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_TO_LEAVE_SRC_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_TO_LEAVE_SRC_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_ON_DEST_SERVER:
|
||||
resultString = "CTService::CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_ON_DEST_SERVER";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_SOFTERROR_FOR_LOCALIZED_TEXT:
|
||||
resultString = "CTService::CT_GAMERESULT_SOFTERROR_FOR_LOCALIZED_TEXT";
|
||||
break;
|
||||
case CTService::CT_GAMERESULT_HARDERROR_FOR_LOCALIZED_TEXT:
|
||||
resultString = "CTService::CT_GAMERESULT_HARDERROR_FOR_LOCALIZED_TEXT";
|
||||
break;
|
||||
default:
|
||||
{
|
||||
std::ostringstream buffer;
|
||||
buffer << "unknown code (" << resultCode << ")" << std::ends;
|
||||
resultString = buffer.str();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return resultString;
|
||||
}
|
||||
|
||||
void replyMove(const TransferCharacterData & reply, CTService::CTMoveResult resultCode)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
const std::string resultString = resultToString(resultCode);
|
||||
LOG("CustomerService", ("CharacterTransfer: transactionId=%u replyMove(%u, %s, NULL, NULL)", reply.getTransactionId(), reply.getTrack(), resultString.c_str()));
|
||||
const unsigned int result = static_cast<unsigned int>(resultCode);
|
||||
s_apiClient->moveComplete(reply.getSourceStationId(), reply.getTrack(), result);
|
||||
IGNORE_RETURN(s_apiClient->replyMove(reply.getTrack(), result, Unicode::narrowToWide(resultString).c_str(), NULL));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
using namespace TransferServerNamespace;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TransferServer::TransferServer()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
TransferServer::~TransferServer()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::authorizeDownload(unsigned int stationId)
|
||||
{
|
||||
IGNORE_RETURN(s_authorizedDownloads.insert(stationId));
|
||||
REPORT_LOG(true, ("Received download authorization for station id %d\n", stationId));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::unauthorizeDownload(unsigned int stationId)
|
||||
{
|
||||
std::set<unsigned int>::iterator f = s_authorizedDownloads.find(stationId);
|
||||
if(f != s_authorizedDownloads.end())
|
||||
{
|
||||
s_authorizedDownloads.erase(f);
|
||||
REPORT_LOG(true, ("Received request to remove download authorization for station id %d\n", stationId));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
const CharacterTransferData * TransferServer::getCharacterTransferData(unsigned int stationId, const std::string & fromGalaxy, bool administrativeRequest)
|
||||
{
|
||||
const CharacterTransferData * result = 0;
|
||||
|
||||
std::map<unsigned int, CharacterTransferData>::const_iterator f = s_transferData.find(stationId);
|
||||
if(f != s_transferData.end())
|
||||
result = &(*f).second;
|
||||
|
||||
if(result)
|
||||
{
|
||||
bool authorized = false;
|
||||
// was the request administratively initiated?
|
||||
if(administrativeRequest)
|
||||
{
|
||||
// admins always get what they want
|
||||
authorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// users, however, must live up to a higher standard
|
||||
// is the request coming from a server that is allowed
|
||||
// to download character data?
|
||||
std::set<std::string>::const_iterator g = s_serversAllowedToDownload.find(fromGalaxy);
|
||||
if(g != s_serversAllowedToDownload.end())
|
||||
{
|
||||
// the request is coming from a server that a user is allowed to download to
|
||||
if(ConfigTransferServer::getAllowSameServerTransfers())
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(fromGalaxy != result->fromGalaxy)
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// was this transfer pre-authorized administratively?
|
||||
std::set<unsigned int>::const_iterator a = s_authorizedDownloads.find(stationId);
|
||||
if(a != s_authorizedDownloads.end())
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// were all requirements met?
|
||||
if(! authorized)
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
REPORT_LOG(true, ("Download failed: Transfer data for SUID %d was not found.\n", stationId));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::requestCharacterList(unsigned int track, unsigned int stationId, const std::string & serverName, const std::string & customerLocalizedLanguage)
|
||||
{
|
||||
CentralServerConnection * centralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(serverName);
|
||||
if(centralConnection)
|
||||
{
|
||||
// this request is routed to the central server for the target
|
||||
// galaxy, which in turn queries a LoginServer for the character
|
||||
// list. The LoginServer returns the list, with the tracking
|
||||
// ID, to the CentralServer, and ultimately responds to this
|
||||
// transfer server with the listing.
|
||||
static const std::string emptyString("");
|
||||
TransferCharacterData characterData(TransferRequestMoveValidation::TRS_transfer_server);
|
||||
characterData.setCustomerLocalizedLanguage(customerLocalizedLanguage);
|
||||
characterData.setSourceGalaxy(serverName);
|
||||
characterData.setSourceStationId(stationId);
|
||||
characterData.setTrack(track);
|
||||
const GenericValueTypeMessage<TransferCharacterData> request("TransferRequestCharacterList", characterData);
|
||||
centralConnection->send(request, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// send failure to CTS API backend
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<int>(CTService::CT_RESULT_FAILURE);
|
||||
|
||||
IGNORE_RETURN(s_apiClient->replyCharacterList(track, result, 0, NULL, NULL));
|
||||
s_apiClient->moveComplete(stationId, track, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::getLoginLocationData(const TransferCharacterData & characterData)
|
||||
{
|
||||
CentralServerConnection * sourceCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(characterData.getSourceGalaxy());
|
||||
if(sourceCentralConnection)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending getLoginLocationData for %s", characterData.getSourceCharacterName().c_str()));
|
||||
const GenericValueTypeMessage<TransferCharacterData> getLoginLocation("TransferGetLoginLocationData", characterData);
|
||||
sourceCentralConnection->send(getLoginLocation, true);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::requestMove(unsigned int track, const std::string & customerLocalizedLanguage, const std::string & sourceGalaxy, const std::string & destinationGalaxy, const std::string & sourceCharacter, const std::string & destinationCharacter, unsigned int sourceStationId, unsigned int destinationStationId, unsigned int transactionId, const bool withItems, const bool allowOverride)
|
||||
{
|
||||
std::string withItemsString = "UNINITIALIZED";
|
||||
if(withItems)
|
||||
withItemsString = "true";
|
||||
else
|
||||
withItemsString = "false";
|
||||
|
||||
std::string allowOverrideString = "UNINITIALIZED";
|
||||
if(allowOverride)
|
||||
allowOverrideString = "true";
|
||||
else
|
||||
allowOverrideString = "false";
|
||||
|
||||
LOG("CustomerService", ("CharacterTransfer: TransferServer::requestMove(%d, %s, %s, %s, %s, %s, %d, %d, %d, %s, %s)", track, customerLocalizedLanguage.c_str(), sourceGalaxy.c_str(), destinationGalaxy.c_str(), sourceCharacter.c_str(), destinationCharacter.c_str(), sourceStationId, destinationStationId, transactionId, withItemsString.c_str(), allowOverrideString.c_str()));
|
||||
// this request is routed to the central server for the target
|
||||
// galaxy, which in turn queries a LoginServer for the character
|
||||
// list. The LoginServer populates the TransferCharacterData
|
||||
// with the source characterID. After the response is received
|
||||
// in CentralServerConnection.cpp, TransferServer::getLoginLocationData
|
||||
// is called.
|
||||
|
||||
// prequalification: if both Galaxies are available, send request, otherwise send failure
|
||||
CentralServerConnection * sourceCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(sourceGalaxy);
|
||||
CentralServerConnection * destinationCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(destinationGalaxy);
|
||||
|
||||
if(destinationStationId == 0)
|
||||
destinationStationId = sourceStationId;
|
||||
|
||||
std::string destinationCharacterName = destinationCharacter;
|
||||
if(destinationCharacter.empty())
|
||||
destinationCharacterName = sourceCharacter;
|
||||
|
||||
TransferCharacterData characterData(TransferRequestMoveValidation::TRS_transfer_server);
|
||||
characterData.setCustomerLocalizedLanguage(customerLocalizedLanguage);
|
||||
characterData.setSourceGalaxy(sourceGalaxy);
|
||||
characterData.setDestinationGalaxy(destinationGalaxy);
|
||||
characterData.setSourceCharacterName(sourceCharacter);
|
||||
characterData.setDestinationCharacterName(destinationCharacterName);
|
||||
characterData.setSourceStationId(sourceStationId);
|
||||
characterData.setDestinationStationId(destinationStationId);
|
||||
characterData.setTransactionId(transactionId);
|
||||
characterData.setIsMoveRequest(true);
|
||||
characterData.setWithItems(withItems);
|
||||
characterData.setAllowOverride(allowOverride);
|
||||
characterData.setTrack(track);
|
||||
|
||||
/*
|
||||
TransferCharacterData characterData(track, // track
|
||||
customerLocalizedLanguage, // customerLocalizedLanguage
|
||||
sourceGalaxy, // sourceGalaxy
|
||||
destinationGalaxy, // destinationGalaxy
|
||||
sourceCharacter, // sourceCharacterName
|
||||
destinationCharacterName, // destinationCharacterName
|
||||
sourceStationId, // sourceStationId
|
||||
destinationStationId, // destinationStationId
|
||||
transactionId, // transactionId
|
||||
NetworkId::cms_invalid, // characterId
|
||||
NetworkId::cms_invalid, // containerId
|
||||
std::string(""), // scene
|
||||
0, // clusterId
|
||||
Vector(), // starting coordinates
|
||||
std::string(""), // customization data
|
||||
std::vector<unsigned char>(), // script dictionary buffer
|
||||
std::string(""), // object template name
|
||||
1.0f, // scale factor
|
||||
std::string(""), // hair template name
|
||||
std::string(""), // hair appearance data
|
||||
std::string(""), // profession
|
||||
false, // is a jedi
|
||||
Unicode::String(), // Biography
|
||||
NetworkId::cms_invalid, // destination character id
|
||||
false, // is name validated?
|
||||
true, // is this a move request?
|
||||
withItems); // does the move include items?
|
||||
*/
|
||||
|
||||
if(sourceCentralConnection && destinationCentralConnection)
|
||||
{
|
||||
// transfer the character
|
||||
const GenericValueTypeMessage<TransferCharacterData> getCharacterData("TransferGetCharacterDataFromLoginServer", characterData);
|
||||
sourceCentralConnection->send(getCharacterData, true);
|
||||
s_apiClient->moveStart(sourceStationId, track, sourceCentralConnection, destinationCentralConnection);
|
||||
LOG("CustomerService", ("CharacterTransfer: sent TransferGetCharacterDataFromLoginServer message : %s\n", characterData.toString().c_str()));
|
||||
|
||||
const GenericValueTypeMessage<std::pair<unsigned int, unsigned int> > kick("TransferRequestKickConnectedClients", std::make_pair(sourceStationId, destinationStationId));
|
||||
sourceCentralConnection->send(kick, true);
|
||||
destinationCentralConnection->send(kick, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
replyMove(characterData, CTService::CT_GAMERESULT_SERVER_IS_DOWN);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::requestTransferAccount(unsigned int track, unsigned int sourceStationId, unsigned int destinationStationId, unsigned int transactionId)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: TransferServer::requestAccount(%d, %d, %d, %d)", track, sourceStationId, destinationStationId, transactionId));
|
||||
|
||||
if(!ConfigTransferServer::getAllowAccountTransfers())
|
||||
{
|
||||
LOG("CustomerService", ("Cannot transfer account, account transfers are not enabled\n"));
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
IGNORE_RETURN(s_apiClient->replyValidateMove(track, result, NULL, NULL, NULL));
|
||||
s_apiClient->moveComplete(sourceStationId, track, result);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// this request is routed to a login server
|
||||
// which in turn updates the DatabaseProcess in the CentralServer, and finally updates the ChatServer
|
||||
// prequalification: if a galaxy is available, send request, otherwise send failure
|
||||
std::map<std::string, CentralServerConnection *> galaxies = CentralServerConnection::getGalaxies();
|
||||
std::map<std::string, CentralServerConnection *>::iterator firstGalaxy = galaxies.begin();
|
||||
|
||||
if (firstGalaxy == galaxies.end())
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Account to account move request made, but no central server connections are available in transfer server source station id: %lu destination station id: %lu\n", sourceStationId, destinationStationId));
|
||||
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SERVER_IS_DOWN);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(track, result, NULL, NULL));
|
||||
s_apiClient->moveComplete(sourceStationId, track, result);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string galaxyName = firstGalaxy->first;
|
||||
CentralServerConnection * sourceCentralConnection = firstGalaxy->second;
|
||||
|
||||
if(destinationStationId == 0 || sourceStationId == 0)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Account move request made with a null destination station id: or source station id: %lu\n", sourceStationId));
|
||||
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(track, result, NULL, NULL));
|
||||
s_apiClient->moveComplete(sourceStationId, track, result);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
TransferAccountData transferData;
|
||||
transferData.setSourceStationId(sourceStationId);
|
||||
transferData.setDestinationStationId(destinationStationId);
|
||||
transferData.setTransactionId(transactionId);
|
||||
transferData.setStartGalaxy(galaxyName);
|
||||
transferData.setTrack(track);
|
||||
|
||||
// verify neither of the station ids are connected
|
||||
const GenericValueTypeMessage<std::pair<unsigned int, unsigned int> > kick("TransferRequestKickConnectedClients", std::make_pair(sourceStationId, destinationStationId));
|
||||
sourceCentralConnection->send(kick, true);
|
||||
|
||||
// start the transfer process
|
||||
const GenericValueTypeMessage<TransferAccountData> getAccountData("TransferAccountRequestLoginServer", transferData);
|
||||
sourceCentralConnection->send(getAccountData, true);
|
||||
|
||||
if (s_apiClient)
|
||||
s_apiClient->moveStart(sourceStationId, track, sourceCentralConnection, 0);
|
||||
|
||||
LOG("CustomerService", ("CharacterTransfer: sent TransferAccountRequestLoginServer message : %s\n", transferData.toString().c_str()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::requestMoveValidation(unsigned int track, unsigned int sourceStationId, unsigned int destinationStationId, const std::string & sourceGalaxy, const std::string & destinationGalaxy, const std::string & sourceCharacter, const std::string & destinationCharacter, const std::string & customerLocalizedLanguage)
|
||||
{
|
||||
// prequalification: if both Galaxies are available, send request, otherwise send failure
|
||||
const CentralServerConnection * sourceCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(sourceGalaxy);
|
||||
CentralServerConnection * destinationCentralConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(destinationGalaxy);
|
||||
|
||||
if(sourceStationId != destinationStationId && (!ConfigTransferServer::getAllowAccountTransfers()))
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
IGNORE_RETURN(s_apiClient->replyValidateMove(track, result, NULL, NULL, NULL));
|
||||
s_apiClient->moveComplete(sourceStationId, track, result);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(sourceCentralConnection && destinationCentralConnection)
|
||||
{
|
||||
// This is sent to the CentralServer on the destination galaxy
|
||||
// which then forwards it to an arbitrary LoginServer
|
||||
// the validation response is routed back to the TransferServer
|
||||
// and is handled in CentralServerConnection as a TransferReplyMoveValidation
|
||||
|
||||
// see if we already have the source character's template crc from a previous query
|
||||
// and if so, pass that along as an optimization so the LoginServer doesn't have
|
||||
// to continually query the DB to fetch the same information over and over again, because
|
||||
// the character's template crc (i.e. the character's species) should never, ever change
|
||||
std::map<std::pair<unsigned int, std::pair<std::string, std::string> >, uint32>::const_iterator const iterFind = s_cacheSourceCharacterTemplateCrc.find(std::make_pair(sourceStationId, std::make_pair(sourceGalaxy, sourceCharacter)));
|
||||
|
||||
const TransferRequestMoveValidation request(TransferRequestMoveValidation::TRS_transfer_server, track, sourceStationId, destinationStationId, sourceGalaxy, destinationGalaxy, sourceCharacter, NetworkId::cms_invalid, ((iterFind == s_cacheSourceCharacterTemplateCrc.end()) ? 0 : iterFind->second), destinationCharacter, customerLocalizedLanguage);
|
||||
|
||||
destinationCentralConnection->send(request, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SERVER_IS_DOWN);
|
||||
IGNORE_RETURN(s_apiClient->replyValidateMove(track, result, NULL, NULL, NULL));
|
||||
s_apiClient->moveComplete(sourceStationId, track, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::cacheSourceCharacterTemplateCrc(unsigned int stationId, const std::string & galaxy, const std::string & characterName, uint32 characterTemplateCrc)
|
||||
{
|
||||
s_cacheSourceCharacterTemplateCrc[std::make_pair(stationId, std::make_pair(galaxy, characterName))] = characterTemplateCrc;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::run()
|
||||
{
|
||||
SetupSharedLog::install("TransferServer");
|
||||
ConsoleManager::install();
|
||||
DataTableManager::install();
|
||||
|
||||
std::vector<std::string>::const_iterator i;
|
||||
|
||||
for (i = ConfigTransferServer::getServersAllowedToUploadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToUploadCharacterData().end(); ++i)
|
||||
{
|
||||
IGNORE_RETURN(s_serversAllowedToUpload.insert(*i));
|
||||
REPORT_LOG(true, ("%s allows players to upload character data\n", i->c_str()));
|
||||
}
|
||||
|
||||
for (i = ConfigTransferServer::getServersAllowedToDownloadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToDownloadCharacterData().end(); ++i)
|
||||
{
|
||||
IGNORE_RETURN(s_serversAllowedToDownload.insert(*i));
|
||||
REPORT_LOG(true, ("%s allows players to download character data without administrative intervention\n", i->c_str()));
|
||||
}
|
||||
|
||||
NetworkSetupData setup;
|
||||
setup.port = ConfigTransferServer::getCentralServerServiceBindPort();
|
||||
setup.bindInterface = ConfigTransferServer::getCentralServerServiceBindInterface();
|
||||
setup.maxConnections=500;
|
||||
|
||||
if(strlen(ConfigTransferServer::getApiServerHostAddress()))
|
||||
{
|
||||
s_apiClient = new CTSAPIClient(ConfigTransferServer::getApiServerHostAddress(), "SWG");
|
||||
REPORT_LOG(true, ("Attempting to connect to CTS Backend %s\n", ConfigTransferServer::getApiServerHostAddress()));
|
||||
LOG("CTSAPI", ("Attempting to connect to CTS Backend %s", ConfigTransferServer::getApiServerHostAddress()));
|
||||
}
|
||||
else
|
||||
{
|
||||
REPORT_LOG(true, ("Running without CTS backend connection because none is configured.\n"));
|
||||
LOG("CTSAPI", ("Running without CTS backend connection because none is configured."));
|
||||
}
|
||||
|
||||
s_transferServerService = new Service(ConnectionAllocator<CentralServerConnection>(), setup);
|
||||
while(! s_done)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
s_apiClient->process();
|
||||
}
|
||||
|
||||
NetworkHandler::update();
|
||||
NetworkHandler::dispatch();
|
||||
NetworkHandler::clearBytesThisFrame();
|
||||
Os::sleep(1);
|
||||
}
|
||||
delete s_apiClient;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::setDone(bool isDone)
|
||||
{
|
||||
s_done = isDone;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool TransferServer::uploadCharacterTransferData(const CharacterTransferData & data, bool administrative)
|
||||
{
|
||||
bool result = false;
|
||||
std::set<std::string>::const_iterator f = s_serversAllowedToUpload.find(data.fromGalaxy);
|
||||
|
||||
bool authorized = administrative;
|
||||
if(! authorized)
|
||||
{
|
||||
std::set<unsigned int>::const_iterator a = s_authorizedDownloads.find(data.stationId);
|
||||
if(a != s_authorizedDownloads.end())
|
||||
{
|
||||
authorized = true;
|
||||
}
|
||||
}
|
||||
|
||||
if(f != s_serversAllowedToUpload.end() || authorized)
|
||||
{
|
||||
s_transferData[data.stationId] = data;
|
||||
REPORT_LOG(true, ("%d bytes of data for SUID %d uploaded\n", data.packedData.length(), data.stationId));
|
||||
result = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
REPORT_LOG(true, ("An attempt to upload character data from %s was denied by the TransferServer configuration\n", data.fromGalaxy.c_str()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::replyCharacterList(const TransferReplyCharacterList & reply)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
std::vector<AvatarRecord>::const_iterator i;
|
||||
std::vector<CTService::CTServiceCharacter> chars;
|
||||
for(i = reply.getAvatarList().begin(); i != reply.getAvatarList().end(); ++i)
|
||||
{
|
||||
CTService::CTServiceCharacter character;
|
||||
character.SetCharacter(i->m_name.c_str());
|
||||
chars.push_back(character);
|
||||
LOG("CTSAPI", ("adding CTService::CTServiceCharacter(%s) to replyCharacterList", Unicode::wideToNarrow(i->m_name).c_str()));
|
||||
}
|
||||
|
||||
CTService::CTServiceCharacter * characters = 0;
|
||||
unsigned int result = static_cast<unsigned int>(CTService::CT_RESULT_SUCCESS);
|
||||
|
||||
if(! reply.getAvatarList().empty())
|
||||
{
|
||||
characters = &chars[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
result = static_cast<unsigned int>(CTService::CT_RESULT_FAILURE);
|
||||
s_apiClient->moveComplete(reply.getStationId(), reply.getTrack(), result);
|
||||
}
|
||||
LOG("CTSAPI", ("invoking CTServiceAPI::replyCharacterList(%d, %d, %d, characters, NULL)", reply.getTrack(), result, chars.size()));
|
||||
IGNORE_RETURN(s_apiClient->replyCharacterList(reply.getTrack(), result, reply.getAvatarList().size(), characters, NULL));
|
||||
}
|
||||
// else use another interface if available
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::replyValidateMove(const TransferCharacterData & reply)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Received replyValidateMove for %s", reply.toString().c_str()));
|
||||
|
||||
if(s_apiClient)
|
||||
{
|
||||
unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SUCCESS);
|
||||
if(! reply.getIsValidName())
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: replyValidateMove failed name validation for %s", reply.toString().c_str()));
|
||||
result = static_cast<unsigned int>(CTService::CT_GAMERESULT_NAME_ALREADY_TAKE);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: replyValidateMove passed name validation for %s", reply.toString().c_str()));
|
||||
}
|
||||
IGNORE_RETURN(s_apiClient->replyValidateMove(reply.getTrack(), result, NULL, NULL, NULL));
|
||||
s_apiClient->moveComplete(reply.getSourceStationId(), reply.getTrack(), result);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::replyMoveSuccess(const TransferCharacterData & reply)
|
||||
{
|
||||
// send RequestTransferAvatar to ChatServer via CentralServer
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(reply.getSourceGalaxy());
|
||||
if(centralServerConnection)
|
||||
{
|
||||
if(ConfigTransferServer::getTransferChatAvatar())
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> chatTransfer("RequestChatTransferAvatar", reply);
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending RequestChatTransferAvatar to Central Server %s. %s", chatTransfer.getValue().getSourceGalaxy().c_str(), chatTransfer.getValue().toString().c_str()));
|
||||
centralServerConnection->send(chatTransfer, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("Not transfering chat avatar. Chat transfers are currently disabled"));
|
||||
}
|
||||
}
|
||||
|
||||
replyMove(reply, CTService::CT_GAMERESULT_SUCCESS);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::replyTransferAccountSuccess(const TransferAccountData & reply)
|
||||
{
|
||||
// send RequestTransferAvatar to ChatServer via CentralServer for each of the cluster ids
|
||||
if(ConfigTransferServer::getTransferChatAvatar())
|
||||
{
|
||||
const std::vector<AvatarData> avatarData(reply.getSourceAvatarData());
|
||||
for (std::vector<AvatarData>::const_iterator i = avatarData.begin(); i != avatarData.end(); ++i)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Sending request to update chat server (cluster: %s) for account transfer from %lu to %lu\n", (i->first).c_str(), reply.getSourceStationId(), reply.getDestinationStationId()));
|
||||
|
||||
// need to make a small transferCharacterData object to send with the message
|
||||
TransferCharacterData chatRequest(TransferRequestMoveValidation::TRS_transfer_server);
|
||||
chatRequest.setSourceStationId(reply.getSourceStationId());
|
||||
chatRequest.setSourceGalaxy(i->first);
|
||||
chatRequest.setSourceCharacterName(i->second);
|
||||
chatRequest.setDestinationStationId(reply.getDestinationStationId());
|
||||
chatRequest.setDestinationGalaxy(i->first);
|
||||
chatRequest.setDestinationCharacterName(i->second);
|
||||
|
||||
CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(i->first);
|
||||
|
||||
if (centralServerConnection)
|
||||
{
|
||||
const GenericValueTypeMessage<TransferCharacterData> message("RequestChatTransferAvatar", chatRequest);
|
||||
centralServerConnection->send(message, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Could not transfer chat avatars for character %s on cluster %s from %lu to %lu: central connection does not exist in transferserver", i->second.c_str(), i->first.c_str(), reply.getSourceStationId(), reply.getDestinationStationId()));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
s_apiClient->moveComplete(reply.getSourceStationId(), reply.getTrack(), result);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(reply.getTrack(), result, NULL, NULL));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Not transfering any chat avatars. Chat transfers are currently disabled"));
|
||||
}
|
||||
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SUCCESS);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(reply.getTrack(), result, NULL, NULL));
|
||||
s_apiClient->moveComplete(reply.getSourceStationId(), reply.getTrack(), result);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::transferCreateCharacterFailed(const TransferCharacterData & failed)
|
||||
{
|
||||
replyMove(failed, CTService::CT_GAMERESULT_INVALID_NAME);
|
||||
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnections(failed.getSourceGalaxy(), failed.getSourceStationId(), failed.getDestinationGalaxy(), failed.getDestinationStationId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
bool TransferServer::isRename(const TransferCharacterData & request)
|
||||
{
|
||||
// IF:
|
||||
// the source and destination station ID are identcal (not a transfer to another account)
|
||||
// the source and destination galaxy are identicay (not a transfer to another server)
|
||||
// the destination name is not empty
|
||||
// the source and destination name are different
|
||||
// This is a character rename request
|
||||
return (request.getSourceStationId() == request.getDestinationStationId() && request.getSourceGalaxy() == request.getDestinationGalaxy() && !request.getDestinationCharacterName().empty() && request.getSourceCharacterName() != request.getDestinationCharacterName());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToRetrieveTransferData(const TransferCharacterData & failed)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: Failed to retrieve character data. Sending HARD ERROR to CTS API. %s", failed.toString().c_str()));
|
||||
replyMove(failed, CTService::CT_GAMERESULT_HARDERROR);
|
||||
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnections(failed.getSourceGalaxy(), failed.getSourceStationId(), failed.getDestinationGalaxy(), failed.getDestinationStationId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToApplyTransferData(const TransferCharacterData & failed)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: Failed to apply character data. Sending HARD ERROR to CTS API. %s", failed.toString().c_str()));
|
||||
|
||||
replyMove(failed, CTService::CT_GAMERESULT_HARDERROR);
|
||||
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnections(failed.getSourceGalaxy(), failed.getSourceStationId(), failed.getDestinationGalaxy(), failed.getDestinationStationId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToTransferAccountNoCentralConnection(const TransferAccountData & failed)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: Could not connect to central server to update game database. Sending HARD ERROR to CTS API. %s", failed.toString().c_str()));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
s_apiClient->moveComplete(failed.getSourceStationId(), failed.getTrack(), result);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(failed.getTrack(), result, NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToTransferAccountDestinationNotEmpty (const TransferAccountData & failed)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: Destination stationId has avatars. Sending HARD ERROR to CTS API. %s", failed.toString().c_str()));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_HARDERROR);
|
||||
s_apiClient->moveComplete(failed.getSourceStationId(), failed.getTrack(), result);
|
||||
IGNORE_RETURN(s_apiClient->replyTransferAccount(failed.getTrack(), result, NULL, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToTransferCharacterGameConnectionClosed(const TransferCharacterData & failed)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: GameServer connection closed while transfer was in progress. Sending SOFT ERROR to CTS API. %s", failed.toString().c_str()));
|
||||
|
||||
replyMove(failed, CTService::CT_GAMERESULT_SOFTERROR);
|
||||
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnections(failed.getSourceGalaxy(), failed.getSourceStationId(), failed.getDestinationGalaxy(), failed.getDestinationStationId());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToTransferCharacterConnectionServerConnectionClosed(unsigned int stationId)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
LOG("CustomerService", ("CharacterTransfer: Transfer failed: ConnectionServer connection closed with CentralServer while transfer was in progress for station id %d", stationId));
|
||||
const unsigned int result = static_cast<unsigned int>(CTService::CT_GAMERESULT_SOFTERROR);
|
||||
s_apiClient->moveComplete(stationId, 0, result);
|
||||
// tracking information is not availalable in this case, so an
|
||||
// API call can not be made. This is a SOFT error, however, and
|
||||
// the API will retry the transfer if there is a timeout.
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
void TransferServer::failedToValidateTransfer(const TransferReplyMoveValidation & reply)
|
||||
{
|
||||
if(s_apiClient)
|
||||
{
|
||||
const unsigned int result = ((reply.getResult() == TransferReplyMoveValidation::TRMVR_cannot_create_regular_character) ? static_cast<unsigned int>(CTService::CT_GAMERESULT_MAX_CHAR_ON_DEST_SERVER) : static_cast<unsigned int>(CTService::CT_GAMERESULT_SERVER_IS_DOWN));
|
||||
|
||||
IGNORE_RETURN(s_apiClient->replyValidateMove(reply.getTrack(), result, NULL, NULL, NULL));
|
||||
s_apiClient->moveComplete(reply.getSourceStationId(), reply.getTrack(), result);
|
||||
|
||||
// close pseudoclientconnections
|
||||
closePseudoClientConnections(reply.getSourceGalaxy(), reply.getSourceStationId(), reply.getDestinationGalaxy(), reply.getDestinationStationId());
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,71 @@
|
||||
// TransferServer.h
|
||||
// Copyright 2000-03, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
#ifndef _INCLUDED_TransferServer_H
|
||||
#define _INCLUDED_TransferServer_H
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "Archive/ByteStream.h"
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
struct CharacterTransferData
|
||||
{
|
||||
unsigned int stationId;
|
||||
std::string packedData;
|
||||
std::string fromGalaxy;
|
||||
};
|
||||
|
||||
class TransferAccountData;
|
||||
class TransferCharacterData;
|
||||
class TransferReplyCharacterList;
|
||||
class TransferReplyMoveValidation;
|
||||
class TransferReplyNameValidation;
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
class TransferServer
|
||||
{
|
||||
public:
|
||||
TransferServer();
|
||||
~TransferServer();
|
||||
|
||||
static void unauthorizeDownload (unsigned int stationId);
|
||||
static void authorizeDownload (unsigned int stationId);
|
||||
static const CharacterTransferData * getCharacterTransferData (unsigned int stationId, const std::string & fromGalaxy, bool administrativeRequest);
|
||||
static void run ();
|
||||
static void setDone (bool isDone);
|
||||
static bool uploadCharacterTransferData (const CharacterTransferData &, bool administrative);
|
||||
|
||||
static void requestCharacterList (unsigned int track, unsigned int stationId, const std::string & serverName, const std::string & customerLocalizedLanguage);
|
||||
static void requestMoveValidation (unsigned int track, unsigned int sourceStationId, unsigned int destinationStationId, const std::string & sourceGalaxy, const std::string & destinationGalaxy, const std::string & sourceCharacter, const std::string & destinationCharacter, const std::string & customerLocalizedLanguage);
|
||||
static void cacheSourceCharacterTemplateCrc(unsigned int stationId, const std::string & galaxy, const std::string & characterName, uint32 characterTemplateCrc);
|
||||
|
||||
static void requestMove (unsigned int track, const std::string & customerLocalizedLanguage, const std::string & sourceGalaxy, const std::string & destinationGalaxy, const std::string & sourceCharacter, const std::string & destinationCharacter, unsigned int sourceStationId, unsigned int destinationStationId, unsigned int transactionId, const bool withItems, const bool allowOverride);
|
||||
static void requestTransferAccount (unsigned int track, unsigned int sourceStationId, unsigned int destinationStationId, unsigned int transactionId);
|
||||
static void getLoginLocationData (const TransferCharacterData & characterData);
|
||||
static void replyCharacterList (const TransferReplyCharacterList & characterList);
|
||||
static void replyValidateMove (const TransferCharacterData &);
|
||||
static void replyMoveSuccess (const TransferCharacterData & reply);
|
||||
static void replyTransferAccountSuccess (const TransferAccountData & reply);
|
||||
static void transferCreateCharacterFailed(const TransferCharacterData & failed);
|
||||
static bool isRename (const TransferCharacterData & request);
|
||||
static void failedToRetrieveTransferData (const TransferCharacterData & failed);
|
||||
static void failedToApplyTransferData (const TransferCharacterData & failed);
|
||||
static void failedToTransferAccountNoCentralConnection (const TransferAccountData & failed);
|
||||
static void failedToTransferAccountDestinationNotEmpty (const TransferAccountData & failed);
|
||||
static void failedToTransferCharacterGameConnectionClosed (const TransferCharacterData & failed);
|
||||
static void failedToTransferCharacterConnectionServerConnectionClosed (const unsigned int stationId);
|
||||
static void failedToValidateTransfer (const TransferReplyMoveValidation & reply);
|
||||
|
||||
private:
|
||||
TransferServer & operator = (const TransferServer & rhs);
|
||||
TransferServer(const TransferServer & source);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#endif // _INCLUDED_TransferServer_H
|
||||
@@ -0,0 +1,60 @@
|
||||
// main.cpp
|
||||
// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved.
|
||||
// Author: Justin Randall
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
#include "FirstTransferServer.h"
|
||||
|
||||
#include "sharedFoundation/FirstSharedFoundation.h"
|
||||
#include "sharedCompression/SetupSharedCompression.h"
|
||||
#include "sharedDebug/SetupSharedDebug.h"
|
||||
#include "sharedFile/SetupSharedFile.h"
|
||||
#include "sharedFoundation/Os.h"
|
||||
#include "sharedFoundation/SetupSharedFoundation.h"
|
||||
#include "sharedNetwork/SetupSharedNetwork.h"
|
||||
#include "sharedNetwork/NetworkHandler.h"
|
||||
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
|
||||
#include "sharedThread/SetupSharedThread.h"
|
||||
#include "TransferServer.h"
|
||||
#include "ConfigTransferServer.h"
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
int main(int argc, char ** argv)
|
||||
{
|
||||
SetupSharedThread::install();
|
||||
SetupSharedDebug::install(1024);
|
||||
|
||||
//-- setup foundation
|
||||
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
|
||||
|
||||
setupFoundationData.argc = argc;
|
||||
setupFoundationData.argv = argv;
|
||||
setupFoundationData.createWindow = true;
|
||||
SetupSharedFoundation::install (setupFoundationData);
|
||||
|
||||
SetupSharedCompression::install();
|
||||
SetupSharedFile::install(false);
|
||||
SetupSharedNetworkMessages::install();
|
||||
|
||||
SetupSharedNetwork::SetupData networkSetupData;
|
||||
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
|
||||
SetupSharedNetwork::install(networkSetupData);
|
||||
NetworkHandler::install();
|
||||
|
||||
//Os::setProgramName("TransferServer");
|
||||
ConfigTransferServer::install();
|
||||
|
||||
//-- run server
|
||||
SetupSharedFoundation::callbackWithExceptionHandling(TransferServer::run);
|
||||
|
||||
NetworkHandler::remove();
|
||||
SetupSharedFoundation::remove();
|
||||
SetupSharedThread::remove();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
add_subdirectory(ChatAPI)
|
||||
add_subdirectory(CTServiceGameAPI)
|
||||
add_subdirectory(VChatAPI)
|
||||
|
||||
@@ -0,0 +1,283 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The author of this code is Justin Randall
|
||||
//
|
||||
// I have made modifications to the ByteStream
|
||||
// and AutoByteStream classes in order to make them suitable
|
||||
// for use in messaging systems which require objects that
|
||||
// are copyable and assignable. It is also desirable for
|
||||
// the ByteStream object to use a flexible allocator system
|
||||
// that may support multi-threaded programming models.
|
||||
|
||||
|
||||
#include "Archive.h"
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
CMutex ByteStreamMutex;
|
||||
#endif
|
||||
|
||||
#if defined (PASCAL_STRING)
|
||||
#pragma message ("--- Packing pascal style strings ---")
|
||||
void get(Base::ByteStream::ReadIterator& source, std::string& target)
|
||||
{
|
||||
unsigned int size = 0;
|
||||
Base::get (source, size);
|
||||
|
||||
const unsigned char *buf = source.getBuffer();
|
||||
|
||||
target.assign((const char *)buf, (const char *)(buf + size));
|
||||
|
||||
const unsigned int readSize = size * sizeof(char);
|
||||
source.advance(readSize);
|
||||
}
|
||||
|
||||
void put(ByteStream& target, const std::string& source)
|
||||
{
|
||||
const unsigned int size = source.size();
|
||||
put(target, size);
|
||||
target.put(source.data(), size * sizeof (char));
|
||||
}
|
||||
|
||||
#else
|
||||
#pragma message ("--- Packing c style strings ---")
|
||||
void get(ByteStream::ReadIterator & source, std::string & target)
|
||||
{
|
||||
target = reinterpret_cast<const char *>(source.getBuffer());
|
||||
source.advance(target.length() + 1);
|
||||
}
|
||||
|
||||
|
||||
void put(ByteStream & target, const std::string & source)
|
||||
{
|
||||
target.put(source.c_str(), source.size()+1);
|
||||
}
|
||||
#endif
|
||||
|
||||
ByteStream::ReadIterator::ReadIterator() :
|
||||
readPtr(0),
|
||||
stream(0)
|
||||
{
|
||||
}
|
||||
|
||||
ByteStream::ReadIterator::ReadIterator(const ReadIterator & source) :
|
||||
readPtr(source.readPtr),
|
||||
stream(source.stream)
|
||||
{
|
||||
}
|
||||
|
||||
ByteStream::ReadIterator::ReadIterator(const ByteStream & source) :
|
||||
readPtr(0),
|
||||
stream(&source)
|
||||
{
|
||||
}
|
||||
|
||||
ByteStream::ReadIterator::~ReadIterator()
|
||||
{
|
||||
stream = 0;
|
||||
}
|
||||
|
||||
ByteStream::ByteStream() :
|
||||
allocatedSize(0),
|
||||
beginReadIterator(),
|
||||
data(NULL),
|
||||
size(0),
|
||||
lastPutSize(0)
|
||||
{
|
||||
data = Data::getNewData();
|
||||
beginReadIterator = ReadIterator(*this);
|
||||
}
|
||||
|
||||
ByteStream::ByteStream(const unsigned char * const newBuffer, const unsigned int bufferSize) :
|
||||
allocatedSize(bufferSize),
|
||||
data(0),
|
||||
size(bufferSize),
|
||||
lastPutSize(0)
|
||||
{
|
||||
data = Data::getNewData();
|
||||
if(data->size < size)
|
||||
{
|
||||
delete[] data->buffer;
|
||||
data->buffer = new unsigned char[size];
|
||||
data->size = size;
|
||||
}
|
||||
memcpy(data->buffer, newBuffer, size);
|
||||
beginReadIterator = ReadIterator(*this);
|
||||
}
|
||||
|
||||
ByteStream::ByteStream(const ByteStream & source):
|
||||
allocatedSize(source.getSize()), // only allocate what is really there, be opportinistic when grow()'ing
|
||||
data(source.data),
|
||||
size(source.getSize()),
|
||||
lastPutSize(source.lastPutSize)
|
||||
{
|
||||
source.data->ref();
|
||||
beginReadIterator = ReadIterator(*this);
|
||||
}
|
||||
|
||||
ByteStream::ByteStream(ReadIterator & source) :
|
||||
allocatedSize(0),
|
||||
size(0),
|
||||
lastPutSize(0)
|
||||
{
|
||||
data = Data::getNewData();
|
||||
put(source.getBuffer(), source.getSize());
|
||||
source.advance(source.getSize());
|
||||
beginReadIterator = ReadIterator(*this);
|
||||
}
|
||||
|
||||
ByteStream::~ByteStream()
|
||||
{
|
||||
data->deref();
|
||||
allocatedSize = 0;
|
||||
data = 0; //lint !e672 (data deref insures the data is deleted if no one references it)
|
||||
size = 0;
|
||||
}
|
||||
|
||||
ByteStream & ByteStream::operator=(const ByteStream & rhs)
|
||||
{
|
||||
if(this != &rhs)
|
||||
{
|
||||
data->deref(); // deref local data
|
||||
rhs.data->ref();
|
||||
allocatedSize = rhs.allocatedSize;
|
||||
size = rhs.size;
|
||||
data = rhs.data; //lint !e672 (data is ref counted)
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void ByteStream::get(void * target, ReadIterator & readIterator, const unsigned long int targetSize) const
|
||||
{
|
||||
assert(readIterator.getReadPosition() + targetSize <= allocatedSize);
|
||||
memcpy(target, &data->buffer[readIterator.getReadPosition()], targetSize);
|
||||
}
|
||||
|
||||
void ByteStream::put(const void * const source, const unsigned int sourceSize)
|
||||
{
|
||||
if(data->getRef() > 1)
|
||||
{
|
||||
const unsigned char * const tmp = data->buffer;
|
||||
data->deref();
|
||||
data = Data::getNewData();
|
||||
if(data->size < sourceSize)
|
||||
{
|
||||
delete[] data->buffer;
|
||||
data->buffer = new unsigned char[size];
|
||||
data->size = size;
|
||||
}
|
||||
memcpy(data->buffer, tmp, size);
|
||||
allocatedSize = size;
|
||||
}
|
||||
growToAtLeast(size + sourceSize);
|
||||
memcpy(&data->buffer[size], source, sourceSize);
|
||||
size += sourceSize;
|
||||
if (sourceSize > 0)
|
||||
lastPutSize = sourceSize;
|
||||
}
|
||||
|
||||
bool ByteStream::overwriteEnd(const void * const source, const unsigned int sourceSize)
|
||||
{
|
||||
if(data->getRef() <= 1 &&
|
||||
lastPutSize == sourceSize &&
|
||||
sourceSize <= data->size)
|
||||
{
|
||||
memcpy(&data->buffer[size-sourceSize], source, sourceSize);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void ByteStream::reAllocate(const unsigned int newSize)
|
||||
{
|
||||
allocatedSize = newSize;
|
||||
if(data->size < allocatedSize)
|
||||
{
|
||||
unsigned char * tmp = new unsigned char[newSize];
|
||||
if(data->buffer != NULL)
|
||||
memcpy(tmp, data->buffer, size);
|
||||
delete[] data->buffer;
|
||||
data->buffer = tmp;
|
||||
data->size = newSize;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
AutoByteStream::AutoByteStream() :
|
||||
members()
|
||||
{
|
||||
}
|
||||
|
||||
AutoByteStream::~AutoByteStream()
|
||||
{
|
||||
}
|
||||
|
||||
void AutoByteStream::addVariable(AutoVariableBase & newVariable)
|
||||
{
|
||||
members.push_back(&newVariable);
|
||||
}
|
||||
|
||||
const unsigned int AutoByteStream::getItemCount() const
|
||||
{
|
||||
return members.size();
|
||||
}
|
||||
|
||||
void AutoByteStream::pack(ByteStream & target) const
|
||||
{
|
||||
std::vector<AutoVariableBase *>::const_iterator i;
|
||||
unsigned short packedSize=static_cast<unsigned short>(members.size());
|
||||
put(target,packedSize);
|
||||
for(i = members.begin(); i != members.end(); ++i)
|
||||
{
|
||||
(*i)->pack(target);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoByteStream::unpack(ByteStream::ReadIterator & source)
|
||||
{
|
||||
std::vector<AutoVariableBase *>::iterator i;
|
||||
unsigned short packedSize;
|
||||
get(source,packedSize);
|
||||
for(i = members.begin(); i != members.end(); ++i)
|
||||
{
|
||||
(*i)->unpack(source);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
AutoVariableBase::AutoVariableBase()
|
||||
{
|
||||
}
|
||||
|
||||
AutoVariableBase::~AutoVariableBase()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,746 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// The author of this code is Justin Randall
|
||||
//
|
||||
// I have made modifications to the ByteStream
|
||||
// and AutoByteStream classes in order to make them suitable
|
||||
// for use in messaging systems which require objects that
|
||||
// are copyable and assignable. It is also desirable for
|
||||
// the ByteStream object to use a flexible allocator system
|
||||
// that may support multi-threaded programming models.
|
||||
|
||||
|
||||
#ifndef BASE_ARCHIVE_H
|
||||
#define BASE_ARCHIVE_H
|
||||
|
||||
|
||||
#include <assert.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "Platform.h"
|
||||
|
||||
|
||||
//#if defined _MT || defined _REENTRANT
|
||||
//# define USE_ARCHIVE_MUTEX
|
||||
//# include "Mutex.h"
|
||||
//#endif
|
||||
|
||||
#ifdef WIN32
|
||||
# include "win32/Archive.h"
|
||||
#elif linux
|
||||
# include "linux/Archive.h"
|
||||
#elif sparc
|
||||
# include "solaris/Archive.h"
|
||||
#else
|
||||
#error /Base/Archive.h: Undefine platform type
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
const unsigned MAX_ARRAY_SIZE = 1024;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
extern CMutex ByteStreamMutex;
|
||||
#endif
|
||||
|
||||
class ByteStream
|
||||
{
|
||||
public:
|
||||
class ReadIterator
|
||||
{
|
||||
public:
|
||||
ReadIterator();
|
||||
ReadIterator(const ReadIterator & source);
|
||||
explicit ReadIterator(const ByteStream & source);
|
||||
~ReadIterator();
|
||||
|
||||
ReadIterator & operator = (const ReadIterator & source);
|
||||
void advance (const unsigned int distance);
|
||||
void get (void * target, const unsigned long int readSize);
|
||||
const unsigned int getSize () const;
|
||||
const unsigned char * const getBuffer () const;
|
||||
const unsigned int getReadPosition () const;
|
||||
|
||||
private:
|
||||
unsigned int readPtr;
|
||||
const ByteStream * stream;
|
||||
};
|
||||
|
||||
private:
|
||||
class Data
|
||||
{
|
||||
friend class ByteStream;
|
||||
friend class ReadIterator;
|
||||
public:
|
||||
~Data();
|
||||
|
||||
static Data * getNewData();
|
||||
|
||||
const int getRef () const;
|
||||
void deref ();
|
||||
void ref ();
|
||||
protected:
|
||||
unsigned char * buffer;
|
||||
unsigned long size;
|
||||
private:
|
||||
struct DataFreeList
|
||||
{
|
||||
~DataFreeList()
|
||||
{
|
||||
std::vector<ByteStream::Data *>::iterator i;
|
||||
for(i = freeList.begin(); i != freeList.end(); ++i)
|
||||
{
|
||||
delete (*i);
|
||||
}
|
||||
};
|
||||
std::vector<Data *> freeList;
|
||||
};
|
||||
Data();
|
||||
//explicit Data(unsigned char * buffer);
|
||||
static std::vector<Data *> & getDataFreeList();
|
||||
static void releaseOldData(Data * oldData);
|
||||
private:
|
||||
int refCount;
|
||||
};
|
||||
|
||||
friend class ReadIterator;
|
||||
public:
|
||||
ByteStream();
|
||||
ByteStream(const unsigned char * const buffer, const unsigned int bufferSize);
|
||||
ByteStream(const ByteStream & source);
|
||||
virtual ~ByteStream();
|
||||
|
||||
public:
|
||||
ByteStream(ReadIterator & source);
|
||||
ByteStream & operator = (const ByteStream & source);
|
||||
ByteStream & operator = (ReadIterator & source);
|
||||
const ReadIterator & begin() const;
|
||||
void clear();
|
||||
const unsigned char * const getBuffer() const;
|
||||
const unsigned int getSize() const;
|
||||
void put(const void * const source, const unsigned int sourceSize);
|
||||
bool overwriteEnd(const void * const source, const unsigned int sourceSize);
|
||||
|
||||
private:
|
||||
void get(void * target, ReadIterator & readIterator, const unsigned long int readSize) const;
|
||||
void growToAtLeast(const unsigned int targetSize);
|
||||
void reAllocate(const unsigned int newSize);
|
||||
|
||||
private:
|
||||
unsigned int allocatedSize;
|
||||
ReadIterator beginReadIterator;
|
||||
Data * data;
|
||||
unsigned int size;
|
||||
unsigned int lastPutSize;
|
||||
|
||||
};
|
||||
|
||||
inline ByteStream::Data::Data() :
|
||||
buffer(0),
|
||||
size(0),
|
||||
refCount(1)
|
||||
{
|
||||
}
|
||||
|
||||
inline ByteStream::Data::~Data()
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
refCount = 0;
|
||||
delete[] buffer;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ByteStream::Data::deref()
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
refCount--;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
|
||||
if(refCount < 1)
|
||||
releaseOldData(this);
|
||||
}
|
||||
|
||||
inline std::vector<ByteStream::Data *> & ByteStream::Data::getDataFreeList()
|
||||
{
|
||||
static DataFreeList freeList;
|
||||
return freeList.freeList;
|
||||
}
|
||||
|
||||
inline ByteStream::Data * ByteStream::Data::getNewData()
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
Data * result = 0;
|
||||
if(getDataFreeList().empty())
|
||||
{
|
||||
result = new Data;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = getDataFreeList().back();
|
||||
getDataFreeList().pop_back();
|
||||
}
|
||||
result->refCount = 1;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
inline const int ByteStream::Data::getRef() const
|
||||
{
|
||||
return refCount;
|
||||
}
|
||||
|
||||
inline void ByteStream::Data::ref()
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
refCount++;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void ByteStream::Data::releaseOldData(ByteStream::Data * oldData)
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
getDataFreeList().push_back(oldData);
|
||||
oldData->refCount = 0;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline ByteStream::ReadIterator & ByteStream::ReadIterator::operator = (const ByteStream::ReadIterator & rhs)
|
||||
{
|
||||
if(&rhs != this)
|
||||
{
|
||||
readPtr = rhs.readPtr;
|
||||
stream = rhs.stream;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline void ByteStream::ReadIterator::get(void * target, const unsigned long int readSize)
|
||||
{
|
||||
assert(stream);
|
||||
stream->get(target, *this, readSize);
|
||||
readPtr += readSize;
|
||||
}
|
||||
|
||||
inline const unsigned int ByteStream::ReadIterator::getSize() const
|
||||
{
|
||||
assert(stream);
|
||||
return stream->getSize() - readPtr;
|
||||
}
|
||||
|
||||
inline const ByteStream::ReadIterator & ByteStream::begin() const
|
||||
{
|
||||
return beginReadIterator;
|
||||
}
|
||||
|
||||
inline void ByteStream::ReadIterator::advance(const unsigned int distance)
|
||||
{
|
||||
readPtr += distance;
|
||||
}
|
||||
|
||||
inline const unsigned int ByteStream::ReadIterator::getReadPosition() const
|
||||
{
|
||||
return readPtr;
|
||||
}
|
||||
|
||||
inline const unsigned char * const ByteStream::ReadIterator::getBuffer() const
|
||||
{
|
||||
if(stream)
|
||||
return &stream->data->buffer[readPtr];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void ByteStream::clear()
|
||||
{
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Lock();
|
||||
#endif
|
||||
|
||||
size = 0;
|
||||
|
||||
#if defined(USE_ARCHIVE_MUTEX)
|
||||
ByteStreamMutex.Unlock();
|
||||
#endif
|
||||
}
|
||||
|
||||
inline const unsigned char * const ByteStream::getBuffer() const
|
||||
{
|
||||
return data->buffer;
|
||||
}
|
||||
|
||||
inline const unsigned int ByteStream::getSize() const
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
inline void ByteStream::growToAtLeast(const unsigned int targetSize)
|
||||
{
|
||||
if(allocatedSize < targetSize)
|
||||
{
|
||||
reAllocate(allocatedSize + allocatedSize + targetSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class AutoVariableBase
|
||||
{
|
||||
public:
|
||||
AutoVariableBase();
|
||||
virtual ~AutoVariableBase();
|
||||
|
||||
virtual void pack(ByteStream & target) const = 0;
|
||||
virtual void unpack(ByteStream::ReadIterator & source) = 0;
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class AutoByteStream
|
||||
{
|
||||
public:
|
||||
AutoByteStream();
|
||||
virtual ~AutoByteStream();
|
||||
void addVariable(AutoVariableBase & newVariable);
|
||||
virtual const unsigned int getItemCount() const;
|
||||
virtual void pack(ByteStream & target) const;
|
||||
virtual void unpack(ByteStream::ReadIterator & source);
|
||||
protected:
|
||||
std::vector<AutoVariableBase *> members;
|
||||
private:
|
||||
AutoByteStream(const AutoByteStream & source);
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
class AutoVariable : public AutoVariableBase
|
||||
{
|
||||
public:
|
||||
AutoVariable();
|
||||
explicit AutoVariable(const ValueType & source);
|
||||
virtual ~AutoVariable();
|
||||
|
||||
const ValueType & get() const;
|
||||
virtual void pack(ByteStream & target) const;
|
||||
void set(const ValueType & rhs);
|
||||
virtual void unpack(ByteStream::ReadIterator & source);
|
||||
|
||||
private:
|
||||
ValueType value;
|
||||
};
|
||||
|
||||
template<class ValueType>
|
||||
AutoVariable<ValueType>::AutoVariable() :
|
||||
AutoVariableBase(),
|
||||
value()
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
AutoVariable<ValueType>::AutoVariable(const ValueType & source) :
|
||||
AutoVariableBase(),
|
||||
value(source)
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
AutoVariable<ValueType>::~AutoVariable()
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
const ValueType & AutoVariable<ValueType>::get() const
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
void AutoVariable<ValueType>::pack(ByteStream & target) const
|
||||
{
|
||||
Base::put(target, value);
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
void AutoVariable<ValueType>::set(const ValueType & rhs)
|
||||
{
|
||||
value = rhs;
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
void AutoVariable<ValueType>::unpack(ByteStream::ReadIterator & source)
|
||||
{
|
||||
Base::get(source, value);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
template<class ValueType>
|
||||
class AutoArray : public AutoVariableBase
|
||||
{
|
||||
public:
|
||||
AutoArray();
|
||||
AutoArray(const AutoArray & source);
|
||||
~AutoArray();
|
||||
|
||||
const std::vector<ValueType> & get() const;
|
||||
void set(const std::vector<ValueType> & source);
|
||||
|
||||
virtual void pack(ByteStream & target) const;
|
||||
virtual void unpack(ByteStream::ReadIterator & source);
|
||||
|
||||
private:
|
||||
std::vector<ValueType> array;
|
||||
};
|
||||
|
||||
template<class ValueType>
|
||||
inline AutoArray<ValueType>::AutoArray()
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline AutoArray<ValueType>::AutoArray(const AutoArray & source) :
|
||||
array(source.array)
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline AutoArray<ValueType>::~AutoArray()
|
||||
{
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline const std::vector<ValueType> & AutoArray<ValueType>::get() const
|
||||
{
|
||||
return array;
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline void AutoArray<ValueType>::set(const std::vector<ValueType> & source)
|
||||
{
|
||||
array = source;
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline void AutoArray<ValueType>::pack(ByteStream & target) const
|
||||
{
|
||||
unsigned int arraySize = array.size();
|
||||
Base::put(target, arraySize);
|
||||
|
||||
typename std::vector<ValueType>::const_iterator i;
|
||||
for(i = array.begin(); i != array.end(); ++i)
|
||||
{
|
||||
ValueType v = (*i);
|
||||
Base::put(target, v);
|
||||
}
|
||||
}
|
||||
|
||||
template<class ValueType>
|
||||
inline void AutoArray<ValueType>::unpack(ByteStream::ReadIterator & source)
|
||||
{
|
||||
unsigned int arraySize;
|
||||
Base::get(source, arraySize);
|
||||
ValueType v;
|
||||
|
||||
if (arraySize > MAX_ARRAY_SIZE)
|
||||
arraySize = 0;
|
||||
|
||||
for(unsigned int i = 0; i < arraySize; ++i)
|
||||
{
|
||||
Base::get(source, v);
|
||||
array.push_back(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, ByteStream & target)
|
||||
{
|
||||
target.put(source.getBuffer(), source.getSize());
|
||||
source.advance(source.getSize());
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, double & target)
|
||||
{
|
||||
source.get(&target, 8);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, float & target)
|
||||
{
|
||||
source.get(&target, 4);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, uint64 & target)
|
||||
{
|
||||
source.get(&target, 8);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, int64 & target)
|
||||
{
|
||||
source.get(&target, 8);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, uint32 & target)
|
||||
{
|
||||
source.get(&target, 4);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, int32 & target)
|
||||
{
|
||||
source.get(&target, 4);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, uint16 & target)
|
||||
{
|
||||
source.get(&target, 2);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, int16 & target)
|
||||
{
|
||||
source.get(&target, 2);
|
||||
target = byteSwap(target);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, uint8 & target)
|
||||
{
|
||||
source.get(&target, 1);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, int8 & target)
|
||||
{
|
||||
source.get(&target, 1);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, unsigned char * const target, const unsigned int targetSize)
|
||||
{
|
||||
source.get(target, targetSize);
|
||||
}
|
||||
|
||||
inline void get(ByteStream::ReadIterator & source, bool & target)
|
||||
{
|
||||
source.get(&target, 1);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline void put(ByteStream & target, ByteStream::ReadIterator & source)
|
||||
{
|
||||
target.put(source.getBuffer(), source.getSize());
|
||||
source.advance(source.getSize());
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const double value)
|
||||
{
|
||||
double temp = byteSwap(value);
|
||||
target.put(&temp, 8);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const float value)
|
||||
{
|
||||
float temp = byteSwap(value);
|
||||
target.put(&temp, 4);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const uint64 value)
|
||||
{
|
||||
uint64 temp = byteSwap(value);
|
||||
target.put(&temp, 8);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const int64 value)
|
||||
{
|
||||
int64 temp = byteSwap(value);
|
||||
target.put(&temp, 8);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const uint32 value)
|
||||
{
|
||||
uint32 temp = byteSwap(value);
|
||||
target.put(&temp, 4);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const int32 value)
|
||||
{
|
||||
int32 temp = byteSwap(value);
|
||||
target.put(&temp, 4);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const uint16 value)
|
||||
{
|
||||
uint16 temp = byteSwap(value);
|
||||
target.put(&temp, 2);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const int16 value)
|
||||
{
|
||||
int16 temp = byteSwap(value);
|
||||
target.put(&temp, 2);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const uint8 value)
|
||||
{
|
||||
target.put(&value, 1);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const int8 value)
|
||||
{
|
||||
target.put(&value, 1);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const bool & source)
|
||||
{
|
||||
target.put(&source, 1);
|
||||
}
|
||||
|
||||
|
||||
inline void put(ByteStream & target, const unsigned char * const source, const unsigned int sourceSize)
|
||||
{
|
||||
target.put(source, sourceSize);
|
||||
}
|
||||
|
||||
inline void put(ByteStream & target, const ByteStream & source)
|
||||
{
|
||||
target.put(source.begin().getBuffer(), source.begin().getSize());
|
||||
}
|
||||
|
||||
void get(ByteStream::ReadIterator & source, std::string & target);
|
||||
void put(ByteStream & target, const std::string & source);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const double value)
|
||||
{
|
||||
double temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 8);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const float value)
|
||||
{
|
||||
float temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 4);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const uint64 value)
|
||||
{
|
||||
uint64 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 8);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const int64 value)
|
||||
{
|
||||
int64 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 8);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const uint32 value)
|
||||
{
|
||||
uint32 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 4);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const int32 value)
|
||||
{
|
||||
int32 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 4);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const uint16 value)
|
||||
{
|
||||
uint16 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 2);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const int16 value)
|
||||
{
|
||||
int16 temp = byteSwap(value);
|
||||
return target.overwriteEnd(&temp, 2);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const uint8 value)
|
||||
{
|
||||
return target.overwriteEnd(&value, 1);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const int8 value)
|
||||
{
|
||||
return target.overwriteEnd(&value, 1);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const bool & source)
|
||||
{
|
||||
return target.overwriteEnd(&source, 1);
|
||||
}
|
||||
|
||||
inline bool overwriteEnd(ByteStream & target, const unsigned char * const source, const unsigned int sourceSize)
|
||||
{
|
||||
return target.overwriteEnd(source, sourceSize);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,105 @@
|
||||
#ifndef BASE_PLATFORM_H
|
||||
#define BASE_PLATFORM_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#ifdef WIN32
|
||||
#include "win32/Platform.h"
|
||||
#elif linux
|
||||
#include "linux/Platform.h"
|
||||
#elif sparc
|
||||
#include "solaris/Platform.h"
|
||||
#else
|
||||
#error /Base/Platform.h: Undefine platform type
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
template <class T> inline T rotlFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return (T)((x<<y) | (x>>(sizeof(T)*8-y)));
|
||||
}
|
||||
|
||||
template <class T> inline T rotrFixed(T x, unsigned int y)
|
||||
{
|
||||
assert(y < sizeof(T)*8);
|
||||
return (x>>y) | (x<<(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
template <class T> inline T rotlMod(T x, unsigned int y)
|
||||
{
|
||||
y %= sizeof(T)*8;
|
||||
return (x<<y) | (x>>(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
template <class T> inline T rotrMod(T x, unsigned int y)
|
||||
{
|
||||
y %= sizeof(T)*8;
|
||||
return (x>>y) | (x<<(sizeof(T)*8-y));
|
||||
}
|
||||
|
||||
inline uint16 byteReverse16(void * data)
|
||||
{
|
||||
uint16 value = *static_cast<uint16 *>(data);
|
||||
return *static_cast<uint16 *>(data) = rotlFixed(value, 8U);
|
||||
// return rotlFixed(value, 8U);
|
||||
}
|
||||
|
||||
inline uint32 byteReverse32(void * data)
|
||||
{
|
||||
uint32 value = *static_cast<uint32 *>(data);
|
||||
return *static_cast<uint32 *>(data) = (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
|
||||
// return (rotrFixed(value, 8U) & 0xff00ff00) | (rotlFixed(value, 8U) & 0x00ff00ff);
|
||||
}
|
||||
inline uint64 byteReverse64(void * data)
|
||||
{
|
||||
uint64 value = *static_cast<uint64 *>(data);
|
||||
return *static_cast<uint64 *>(data) = (
|
||||
uint64((rotrFixed(uint32(value), 8U) & 0xff00ff00) | (rotlFixed(uint32(value), 8U) & 0x00ff00ff)) << 32) |
|
||||
(rotrFixed(uint32(value>>32), 8U) & 0xff00ff00) | (rotlFixed(uint32(value>>32), 8U) & 0x00ff00ff);
|
||||
// return (uint64(byteReverse(uint32(value))) << 32) | byteReverse(uint32(value>>32));
|
||||
}
|
||||
|
||||
inline uint32 strlen(const unsigned short * string)
|
||||
{
|
||||
if (string == 0)
|
||||
return 0;
|
||||
|
||||
uint32 length=0;
|
||||
while (*(string+length++) != 0);
|
||||
|
||||
return length-1;
|
||||
}
|
||||
|
||||
inline double getTimerLatency(Base::uint64 startTime, Base::uint64 finishTime=0)
|
||||
{
|
||||
Base::int64 requestAge;
|
||||
Base::int64 freq = Base::getTimerFrequency();
|
||||
Base::uint64 finish = (finishTime ? finishTime : Base::getTimer());
|
||||
if (finish < startTime)
|
||||
requestAge = (0 - 1) - startTime - finish;
|
||||
else
|
||||
requestAge = finish - startTime;
|
||||
return (double)requestAge/freq;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif // BASE_PLATFORM_H
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
#ifndef BASE_TYPES_H
|
||||
#define BASE_TYPES_H
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
#include "win32/Types.h"
|
||||
|
||||
#elif linux
|
||||
|
||||
#include "linux/Types.h"
|
||||
|
||||
#elif sparc
|
||||
|
||||
#include "solaris/Types.h"
|
||||
|
||||
#else
|
||||
|
||||
#error /Base/Types.h: Undefine platform type
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#ifndef BASE_LINUX_ARCHIVE_H
|
||||
#define BASE_LINUX_ARCHIVE_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
#ifdef PACK_BIG_ENDIAN
|
||||
|
||||
inline double byteSwap(double value) { byteReverse(&value); return value; }
|
||||
inline float byteSwap(float value) { byteReverse(&value); return value; }
|
||||
inline uint64 byteSwap(uint64 value) { byteReverse(&value); return value; }
|
||||
inline int64 byteSwap(int64 value) { byteReverse(&value); return value; }
|
||||
inline uint32 byteSwap(uint32 value) { byteReverse(&value); return value; }
|
||||
inline int32 byteSwap(int32 value) { byteReverse(&value); return value; }
|
||||
inline uint16 byteSwap(uint16 value) { byteReverse(&value); return value; }
|
||||
inline int16 byteSwap(int16 value) { byteReverse(&value); return value; }
|
||||
|
||||
#else
|
||||
|
||||
inline double byteSwap(double value) { return value; }
|
||||
inline float byteSwap(float value) { return value; }
|
||||
inline uint64 byteSwap(uint64 value) { return value; }
|
||||
inline int64 byteSwap(int64 value) { return value; }
|
||||
inline uint32 byteSwap(uint32 value) { return value; }
|
||||
inline int32 byteSwap(int32 value) { return value; }
|
||||
inline uint16 byteSwap(uint16 value) { return value; }
|
||||
inline int16 byteSwap(int16 value) { return value; }
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,55 @@
|
||||
////////////////////////////////////////
|
||||
// Platform.cpp
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Implementation of the global functionality declaired in Platform.h.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#include <ctype.h>
|
||||
#include "Platform.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
// Implementation of microsoft strlwr extension
|
||||
// This non-ANSI function is not supported under UNIX
|
||||
void _strlwr(char * s)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
*s = tolower(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
// Implementation of microsoft strlwr extension
|
||||
// This non-ANSI function is not supported under UNIX
|
||||
void _strupr(char * s)
|
||||
{
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CTimer::CTimer() :
|
||||
mTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
////////////////////////////////////////
|
||||
// Platform.h
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Include relevent system headers that are platform specific.
|
||||
// 2. Declair global platform specific functionality.
|
||||
// 3. Include primative type definitions
|
||||
//
|
||||
// Global Functions:
|
||||
// getTimer() : Return the current high resolution clock count.
|
||||
// getTimerFrequency() : Return the frequency of the high resolution clock.
|
||||
// sleep() : Voluntarily relinquish timeslice of the calling thread for a
|
||||
// specified number of milliseconds.
|
||||
// strlwr() : Alters the contents of a string, making it all lower-case.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#ifndef BASE_LINUX_PLATFORM_H
|
||||
#define BASE_LINUX_PLATFORM_H
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/errno.h>
|
||||
#include <pthread.h>
|
||||
#include <resolv.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
uint64 getTimer(void);
|
||||
uint64 getTimerFrequency(void);
|
||||
void sleep(uint32 ms);
|
||||
|
||||
inline uint64 getTimer(void)
|
||||
{
|
||||
uint64 t;
|
||||
struct timeval tv;
|
||||
|
||||
gettimeofday(&tv, 0);
|
||||
t = tv.tv_sec;
|
||||
t = t * 1000000;
|
||||
t += tv.tv_usec;
|
||||
return t;
|
||||
}
|
||||
|
||||
inline uint64 getTimerFrequency(void)
|
||||
{
|
||||
uint64 f = 1000000;
|
||||
return f;
|
||||
}
|
||||
|
||||
inline void sleep(uint32 ms)
|
||||
{
|
||||
usleep(static_cast<unsigned long>(ms * 1000));
|
||||
}
|
||||
|
||||
void _strlwr(char * s);
|
||||
void _strupr(char * s);
|
||||
|
||||
|
||||
class CTimer
|
||||
{
|
||||
public:
|
||||
CTimer();
|
||||
|
||||
void Set(uint32 seconds);
|
||||
void Signal();
|
||||
bool Expired();
|
||||
|
||||
private:
|
||||
uint32 mTimer;
|
||||
};
|
||||
|
||||
inline void CTimer::Set(uint32 interval)
|
||||
{
|
||||
mTimer = (uint32)time(0) + interval;
|
||||
}
|
||||
|
||||
inline void CTimer::Signal()
|
||||
{
|
||||
mTimer = 0;
|
||||
}
|
||||
|
||||
inline bool CTimer::Expired()
|
||||
{
|
||||
return (mTimer <= (uint32)time(0));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif // BASE_LINUX_PLATFORM_H
|
||||
@@ -0,0 +1,42 @@
|
||||
////////////////////////////////////////
|
||||
// Types.h
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Define integer types that are unambiguous with respect to size
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#ifndef BASE_LINUX_TYPES_H
|
||||
#define BASE_LINUX_TYPES_H
|
||||
|
||||
#include <sys/bitypes.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
namespace Base
|
||||
{
|
||||
#define INT32_MAX 0x7FFFFFFF
|
||||
#define INT32_MIN 0x80000000
|
||||
#define UINT32_MAX 0xFFFFFFFF
|
||||
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef signed short int16;
|
||||
typedef unsigned short uint16;
|
||||
|
||||
typedef int32_t int32;
|
||||
typedef u_int32_t uint32;
|
||||
typedef int64_t int64;
|
||||
typedef u_int64_t uint64;
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif // BASE_LINUX_TYPES_H
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#ifndef BASE_WIN32_ARCHIVE_H
|
||||
#define BASE_WIN32_ARCHIVE_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
#ifdef PACK_BIG_ENDIAN
|
||||
|
||||
inline double byteSwap(double value) { byteReverse64(&value); return value; }
|
||||
inline float byteSwap(float value) { byteReverse32(&value); return value; }
|
||||
inline uint64 byteSwap(uint64 value) { byteReverse64(&value); return value; }
|
||||
inline int64 byteSwap(int64 value) { byteReverse64(&value); return value; }
|
||||
inline uint32 byteSwap(uint32 value) { byteReverse32(&value); return value; }
|
||||
inline int32 byteSwap(int32 value) { byteReverse32(&value); return value; }
|
||||
inline uint16 byteSwap(uint16 value) { byteReverse16(&value); return value; }
|
||||
inline int16 byteSwap(int16 value) { byteReverse16(&value); return value; }
|
||||
|
||||
#else
|
||||
|
||||
inline double byteSwap(double value) { return value; }
|
||||
inline float byteSwap(float value) { return value; }
|
||||
inline uint64 byteSwap(uint64 value) { return value; }
|
||||
inline int64 byteSwap(int64 value) { return value; }
|
||||
inline uint32 byteSwap(uint32 value) { return value; }
|
||||
inline int32 byteSwap(int32 value) { return value; }
|
||||
inline uint16 byteSwap(uint16 value) { return value; }
|
||||
inline int16 byteSwap(int16 value) { return value; }
|
||||
|
||||
#endif
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,31 @@
|
||||
////////////////////////////////////////
|
||||
// Platform.cpp
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Implementation of the global functionality declaired in Platform.h.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#include "Platform.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
|
||||
CTimer::CTimer() :
|
||||
mTimer(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,98 @@
|
||||
////////////////////////////////////////
|
||||
// Platform.h
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Include relevent system headers that are platform specific.
|
||||
// 2. Declair global platform specific functionality.
|
||||
// 3. Include primative type definitions
|
||||
//
|
||||
// Global Functions:
|
||||
// getTimer() : Return the current high resolution clock count.
|
||||
// getTimerFrequency() : Return the frequency of the high resolution clock.
|
||||
// sleep() : Voluntarily relinquish timeslice of the calling thread for a
|
||||
// specified number of milliseconds.
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#ifndef BASE_WIN32_PLATFORM_H
|
||||
#define BASE_WIN32_PLATFORM_H
|
||||
|
||||
#include <memory.h>
|
||||
#include <winsock2.h>
|
||||
#include <time.h>
|
||||
#include <io.h>
|
||||
#include <fcntl.h>
|
||||
#include <direct.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "Types.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
uint64 getTimer(void);
|
||||
uint64 getTimerFrequency(void);
|
||||
|
||||
inline uint64 getTimer(void)
|
||||
{
|
||||
uint64 result;
|
||||
if (!QueryPerformanceCounter(reinterpret_cast<LARGE_INTEGER *>(&result)))
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline uint64 getTimerFrequency(void)
|
||||
{
|
||||
uint64 result;
|
||||
if (!QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER *>(&result)))
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void sleep(uint32 ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
||||
|
||||
class CTimer
|
||||
{
|
||||
public:
|
||||
CTimer();
|
||||
|
||||
void Set(uint32 seconds);
|
||||
void Signal();
|
||||
bool Expired();
|
||||
|
||||
private:
|
||||
uint32 mTimer;
|
||||
};
|
||||
|
||||
inline void CTimer::Set(uint32 interval)
|
||||
{
|
||||
mTimer = (uint32)time(0) + interval;
|
||||
}
|
||||
|
||||
inline void CTimer::Signal()
|
||||
{
|
||||
mTimer = 0;
|
||||
}
|
||||
|
||||
inline bool CTimer::Expired()
|
||||
{
|
||||
return (mTimer <= (uint32)time(0));
|
||||
}
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif BASE_WIN32_PLATFORM_H
|
||||
@@ -0,0 +1,42 @@
|
||||
////////////////////////////////////////
|
||||
// Types.h
|
||||
//
|
||||
// Purpose:
|
||||
// 1. Define integer types that are unambiguous with respect to size
|
||||
//
|
||||
// Revisions:
|
||||
// 07/10/2001 Created
|
||||
//
|
||||
|
||||
#ifndef BASE_WIN32_TYPES_H
|
||||
#define BASE_WIN32_TYPES_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
namespace Base
|
||||
{
|
||||
|
||||
#define INT32_MAX 0x7FFFFFFF
|
||||
#define INT32_MIN 0x80000000
|
||||
#define UINT32_MAX 0xFFFFFFFF
|
||||
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef short int16;
|
||||
typedef unsigned short uint16;
|
||||
|
||||
typedef int int32;
|
||||
typedef unsigned uint32;
|
||||
typedef __int64 int64;
|
||||
typedef unsigned __int64 uint64;
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // BASE_WIN32_TYPES_H
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
|
||||
set(SHARED_SOURCES
|
||||
CTServiceAPI.cpp
|
||||
CTServiceAPI.h
|
||||
CTServiceAPICore.cpp
|
||||
CTServiceAPICore.h
|
||||
Request.cpp
|
||||
Request.h
|
||||
Response.cpp
|
||||
Response.h
|
||||
|
||||
Base/Archive.cpp
|
||||
|
||||
CTCommon/CTEnum.h
|
||||
CTCommon/CTServiceCharacter.cpp
|
||||
CTCommon/CTServiceCharacter.h
|
||||
CTCommon/CTServiceCustomer.h
|
||||
CTCommon/CTServiceDBOrder.h
|
||||
CTCommon/CTServiceDBTransaction.h
|
||||
CTCommon/CTServiceObjects.h
|
||||
CTCommon/CTServiceServer.cpp
|
||||
CTCommon/CTServiceServer.h
|
||||
CTCommon/CTServiceWebAPITransaction.h
|
||||
CTCommon/RequestStrings.h
|
||||
|
||||
CTGenericAPI/GenericApiCore.cpp
|
||||
CTGenericAPI/GenericApiCore.h
|
||||
CTGenericAPI/GenericConnection.cpp
|
||||
CTGenericAPI/GenericConnection.h
|
||||
CTGenericAPI/GenericMessage.cpp
|
||||
CTGenericAPI/GenericMessage.h
|
||||
|
||||
TcpLibrary/Clock.cpp
|
||||
TcpLibrary/Clock.h
|
||||
TcpLibrary/IPAddress.cpp
|
||||
TcpLibrary/IPAddress.h
|
||||
TcpLibrary/TcpBlockAllocator.cpp
|
||||
TcpLibrary/TcpBlockAllocator.h
|
||||
TcpLibrary/TcpConnection.cpp
|
||||
TcpLibrary/TcpConnection.h
|
||||
TcpLibrary/TcpHandlers.h
|
||||
TcpLibrary/TcpManager.cpp
|
||||
TcpLibrary/TcpManager.h
|
||||
|
||||
Unicode/FirstUnicode.cpp
|
||||
Unicode/FirstUnicode.h
|
||||
Unicode/Unicode.cpp
|
||||
Unicode/Unicode.h
|
||||
Unicode/UnicodeBlocks.cpp
|
||||
Unicode/UnicodeBlocks.h
|
||||
Unicode/UnicodeCharacterData.cpp
|
||||
Unicode/UnicodeCharacterData.h
|
||||
Unicode/UnicodeCharacterDataMap.cpp
|
||||
Unicode/UnicodeCharacterDataMap.h
|
||||
Unicode/UnicodeUtils.cpp
|
||||
Unicode/UnicodeUtils.h
|
||||
)
|
||||
|
||||
if(WIN32)
|
||||
set(PLATFORM_SOURCES
|
||||
Base/win32/Platform.cpp
|
||||
)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Base/win32)
|
||||
else()
|
||||
set(PLATFORM_SOURCES
|
||||
Base/linux/Platform.cpp
|
||||
)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Base/linux)
|
||||
endif()
|
||||
|
||||
add_definitions(-DNAMESPACE=CTService -DUSE_TCP_LIBRARY)
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
add_library(CTServiceGameAPI
|
||||
${SHARED_SOURCES}
|
||||
${PLATFORM_SOURCES}
|
||||
)
|
||||
@@ -0,0 +1,434 @@
|
||||
#ifndef CTENUM_H
|
||||
#define CTENUM_H
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
enum InternalErrorCodes
|
||||
{
|
||||
CONFIG_PARAMS_MISSING=-1,
|
||||
FAIL_LOAD_CONFIG_FILE=-2
|
||||
};
|
||||
|
||||
enum ServerStatus
|
||||
{
|
||||
SERVER_READY = 0,
|
||||
SERVER_SHUTTING_DOWN,
|
||||
SERVER_DOWN
|
||||
};
|
||||
|
||||
enum LOG_TYPES
|
||||
{
|
||||
LOG_ERROR=1,
|
||||
LOG_REQUEST,
|
||||
LOG_CONNECTION,
|
||||
LOG_GENERAL,
|
||||
LOG_STATS
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Add New API requests Here
|
||||
//-----------------------------------------
|
||||
enum RequestTypes
|
||||
{
|
||||
// ----- Store/Web API begins at 1 -----
|
||||
//CTWEB_REQUEST_TEST = 1,
|
||||
CTWEB_REQUEST_GET_GAMES = 2,
|
||||
CTWEB_REQUEST_GET_SUBSCRIPTIONS = 3,
|
||||
CTWEB_REQUEST_GET_CHARACTERS = 4,
|
||||
CTWEB_REQUEST_GET_SOURCE_SERVERS = 5,
|
||||
CTWEB_REQUEST_GET_DEST_SERVERS = 6,
|
||||
CTWEB_REQUEST_VALIDATE_TRANSACTION = 7,
|
||||
CTWEB_REQUEST_VALIDATE_ORDER = 8,
|
||||
CTWEB_REQUEST_SUBMIT_ORDER = 9,
|
||||
CTWEB_REQUEST_GET_ORDER_STATUS = 10,
|
||||
CTWEB_REQUEST_GET_ORDERS_BY_STATION_ID = 11,
|
||||
CTWEB_REQUEST_GET_TRANSACTIONS_BY_ORDER_ID = 12,
|
||||
CTWEB_REQUEST_CSR_MOVE = 13,
|
||||
CTWEB_REQUEST_CSR_DELETE = 14,
|
||||
CTWEB_REQUEST_CSR_RESTORE = 15,
|
||||
CTWEB_REQUEST_CSR_TRANSFER_ACCOUNT = 16,
|
||||
|
||||
// ----- Game API begins at 1000 -----
|
||||
// first requests sent from API to server
|
||||
//CTGAME_REQUEST_TEST = 1000,
|
||||
CTGAME_REQUEST_CONNECT = 1001,
|
||||
CTGAME_REPLY_TEST,
|
||||
CTGAME_REPLY_MOVESTATUS,
|
||||
CTGAME_REPLY_VALIDATEMOVE,
|
||||
CTGAME_REPLY_MOVE,
|
||||
CTGAME_REPLY_CHARACTERLIST,
|
||||
CTGAME_REPLY_SERVERLIST,
|
||||
CTGAME_REPLY_DESTSERVERLIST,
|
||||
CTGAME_REPLY_DELETE,
|
||||
CTGAME_REPLY_RESTORE,
|
||||
CTGAME_REPLY_TRANSFER_ACCOUNT,
|
||||
// then requests send from server to API
|
||||
CTGAME_SERVER_TEST = 1100,
|
||||
CTGAME_SERVER_MOVESTATUS,
|
||||
CTGAME_SERVER_VALIDATEMOVE,
|
||||
CTGAME_SERVER_MOVE,
|
||||
CTGAME_SERVER_CHARACTERLIST,
|
||||
CTGAME_SERVER_SERVERLIST,
|
||||
CTGAME_SERVER_DESTSERVERLIST,
|
||||
CTGAME_SERVER_DELETE,
|
||||
CTGAME_SERVER_RESTORE,
|
||||
CTGAME_SERVER_TRANSFER_ACCOUNT,
|
||||
|
||||
// ----- Login API begins at 2000 -----
|
||||
CTLOGIN_REQUEST_GET_ACCOUNT_STATUS = 2000,
|
||||
CTLOGIN_REQUEST_GET_ACCOUNT_SUBSCRIPTIONS,
|
||||
CTLOGIN_REQUEST_GET_MEMBER_INFO,
|
||||
|
||||
// ----- Ecomm API begins at 3000 -----
|
||||
CTECOMM_REQUEST_VALIDATE_CARD = 3000,
|
||||
CTECOMM_REQUEST_GET_PRODUCT,
|
||||
CTECOMM_REQUEST_GET_PRODUCT_LIST,
|
||||
CTECOMM_REQUEST_CALUCULATE_ORDER_AMOUNT,
|
||||
CTECOMM_REQUEST_GET_PRODUCTS_BY_GAME_AND_TYPE,
|
||||
CTECOMM_REQUEST_PREAUTH_ORDER,
|
||||
CTECOMM_REQUEST_DEPOSIT_CREDIT_CARD
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Add result codes for both API's Here
|
||||
//-----------------------------------------
|
||||
enum CTResultCodes
|
||||
{
|
||||
CT_RESULT_SUCCESS = 0, // general hardware/system type messages
|
||||
CT_RESULT_TIMEOUT,
|
||||
CT_RESULT_FAILURE,
|
||||
CT_RESULT_1OR_MORE_TRANSACTIONS_FAILED,
|
||||
CT_RESULT_NO_TRANS_IN_ORDER,
|
||||
CT_RESULT_ORDER_FOR_DIFFERENT_GAMES,//5
|
||||
CT_RESULT_ORDER_FOR_DIFFERENT_USERS,
|
||||
CT_RESULT_MULTI_TRANS_FOR_CHARACTER,
|
||||
CT_RESULT_DEST_STATIONNAME_PASSWORD_INVALID,
|
||||
CT_RESULT_SOURCE_STATION_ACCOUNT_NOT_ACTIVE,
|
||||
CT_RESULT_DEST_STATION_ACCOUNT_NOT_ACTIVE,//10
|
||||
CT_RESULT_INVALID_UID,
|
||||
CT_RESULT_SOURCE_UID_INVALID,
|
||||
CT_RESULT_ALL_REQUIRED_TRANSACTION_INFO_NOT_PROVIDED,
|
||||
CT_RESULT_NOT_SAME_FIRST_NAME_ON_STATION_ACCOUNTS,
|
||||
CT_RESULT_NOT_SAME_LAST_NAME_ON_STATION_ACCOUNTS,//15
|
||||
CT_RESULT_NOT_SAME_EMAIL_ON_STATION_ACCOUNTS,
|
||||
CT_RESULT_TRANSFER_TO_SAME_ACCOUNT,
|
||||
CT_RESULT_WEB_INFO_DOES_NOT_MATCH_STATION_INFO,
|
||||
CT_RESULT_SOURCE_SUBSCRIPTION_STATUS_NOT_ALLOWED,
|
||||
CT_RESULT_DEST_SUBSCRIPTION_STATUS_NOT_ALLOWED,//20
|
||||
CT_RESULT_BAD_CC_INFO,
|
||||
CT_RESULT_ZIP_FAILED_AVS,
|
||||
CT_RESULT_HARD_DECLINE_ECOMM,
|
||||
CT_RESULT_SOFT_DECLINE_ECOMM,
|
||||
CT_RESULT_OTHER_ECOMM_ERROR,//25
|
||||
CT_RESULT_INVALID_STOREFRONT,
|
||||
CT_RESULT_ILLEGAL_TRANSACTION_REQUESTED_FOR_GAME,
|
||||
CT_RESULT_ILLEGAL_GAME_CODE,
|
||||
CT_RESULT_UPDATE_ORDER_PRICE_FAILED,
|
||||
CT_RESULT_UPDATE_ORDER_PRICE_FAILED_TWICE,//30
|
||||
CT_RESULT_HARD_DECLINE_GAME,
|
||||
CT_RESULT_SOFT_DECLINE_GAME,
|
||||
CT_RESULT_TRANSACTION_DOES_NOT_DO_ANYTHING,
|
||||
// ADDITIONS HERE SHOULD BE ADDED TO REQUESTSTRINGS.H AS WELL
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Add localized messages here
|
||||
//-----------------------------------------
|
||||
enum CTLocalizedMessages
|
||||
{
|
||||
CT_MESSAGE_SOURCE_SUBSCRIPTION_STATUS_NOT_ALLOWED = 1,
|
||||
CT_MESSAGE_DEST_SUBSCRIPTION_STATUS_NOT_ALLOWED,
|
||||
CT_MESSAGE_TIMEOUT,
|
||||
CT_MESSAGE_FAILURE,
|
||||
CT_MESSAGE_SOURCE_STATION_ACCOUNT_NOT_ACTIVE,//5
|
||||
CT_MESSAGE_SOURCE_UID_INVALID,
|
||||
CT_MESSAGE_TRANSFER_TO_SAME_ACCOUNT,
|
||||
CT_MESSAGE_NOT_SAME_FIRST_NAME_ON_STATION_ACCOUNTS,
|
||||
CT_MESSAGE_NOT_SAME_LAST_NAME_ON_STATION_ACCOUNTS,
|
||||
CT_MESSAGE_NOT_SAME_EMAIL_ON_STATION_ACCOUNTS,//10
|
||||
CT_MESSAGE_INVALID_UID,
|
||||
CT_MESSAGE_DEST_STATION_ACCOUNT_NOT_ACTIVE,
|
||||
CT_MESSAGE_DEST_STATIONNAME_PASSWORD_INVALID,
|
||||
CT_MESSAGE_ALL_REQUIRED_TRANSACTION_INFO_NOT_PROVIDED,
|
||||
CT_MESSAGE_ILLEGAL_TRANSACTION_REQUESTED_FOR_GAME,//15
|
||||
CT_MESSAGE_ILLEGAL_GAME_CODE,
|
||||
// ADDITIONS HERE SHOULD BE ADDED TO REQUESTSTRINGS.H AS WELL
|
||||
};
|
||||
//-----------------------------------------
|
||||
// Add resource manager codes Here
|
||||
//-----------------------------------------
|
||||
enum ServiceTypes
|
||||
{
|
||||
SERVICE_DATABASE=0,
|
||||
SERVICE_GAMEAPI,
|
||||
SERVICE_LOGIN_SERVER,
|
||||
SERVICE_ECOMM_SERVER,
|
||||
SERVICE_TRANSACTION
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Add resource request ID's Here
|
||||
//-----------------------------------------
|
||||
enum ResourceRequestTypes
|
||||
{
|
||||
CTGAMEAPI_RESOURCE_TEST=1,
|
||||
CTGAMEAPI_RESOURCE_MOVESTATUS,
|
||||
CTGAMEAPI_RESOURCE_VALIDATEMOVE,
|
||||
CTGAMEAPI_RESOURCE_MOVE,
|
||||
CTGAMEAPI_RESOURCE_CHARACTERLIST,//5
|
||||
CTGAMEAPI_RESOURCE_SERVERLIST,
|
||||
CTGAMEAPI_RESOURCE_DESTSERVERLIST,
|
||||
CTGAMEAPI_RESOURCE_DELETE,
|
||||
CTGAMEAPI_RESOURCE_RESTORE,
|
||||
CTGAMEAPI_RESOURCE_TRANSFER_ACCOUNT,
|
||||
|
||||
|
||||
LOGIN_SERVER_REQUEST_VALIDATE_STATION_ACCOUNT=101,
|
||||
LOGIN_SERVER_REQUEST_VALIDATE_STATION_ACCOUNT_WITH_ID,
|
||||
LOGIN_SERVER_REQUEST_GET_ACCOUNT_SUBSCRIPTIONS,
|
||||
LOGIN_SERVER_REQUEST_VALIDATE_TRANSFER_OWNERSHIP,
|
||||
|
||||
|
||||
ECOMM_VALIDATE_CARD=201,
|
||||
ECOMM_GET_PRODUCT,
|
||||
ECOMM_GET_PRODUCT_LIST,
|
||||
ECOMM_CALCULATE_ORDER_AMOUNTS,
|
||||
ECOMM_GET_PRODUCTS_BY_GAME_AND_TYPE,//205
|
||||
ECOMM_PREAUTH_ORDER,
|
||||
ECOMM_DEPOSIT_CREDIT_CARD,
|
||||
|
||||
// DB Requests
|
||||
DB_REQUEST_GET_GAMES=301,
|
||||
DB_REQUEST_GET_GAME,
|
||||
DB_REQUEST_SUBMIT_ORDER,
|
||||
DB_REQUEST_CREATE_TRANSACTION,
|
||||
DB_REQUEST_FINISH_TRANSACTION,//305
|
||||
DB_REQUEST_GET_OLDEST_TRANSACTION,
|
||||
DB_REQUEST_GET_ORDER_BY_ORDER_ID,
|
||||
DB_REQUEST_GET_ORDER_STATUS,
|
||||
DB_REQUEST_GET_TRANSACTION,
|
||||
DB_REQUEST_GET_TRANSACTIONS_BY_SERVER,//310
|
||||
DB_REQUEST_GET_TRANSACTIONS_FOR_ORDER,
|
||||
DB_REQUEST_GET_ORDERS_BY_STATION_ID,
|
||||
DB_REQUEST_SET_TRANSACTION_WAITING,
|
||||
DB_REQUEST_UPDATE_ORDER_PRICE,
|
||||
DB_REQUEST_UPDATE_ORDER_STATUS,//315
|
||||
DB_REQUEST_UPDATE_TRANSACTION_STATUS,
|
||||
DB_REQUEST_GET_ALL_LOCALIZED_MESSAGES,
|
||||
DB_REQUEST_GET_LOCALIZED_MESSAGE_LANGUAGES,
|
||||
DB_REQUEST_CREATE_LOCALIZED_MESSAGE,
|
||||
DB_REQUEST_MODIFY_LOCALIZED_MESSAGE_TEXT,//320
|
||||
DB_REQUEST_MODIFY_GAME,
|
||||
DB_REQUEST_ADD_GAME,
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Status codes used by onGetOrderStatus for webAPI
|
||||
//-----------------------------------------
|
||||
enum CTOrderStatus
|
||||
{
|
||||
CT_ORDER_STATUS_UNKNOWN = 0, // A problem occured retrieving the status of an order
|
||||
CT_ORDER_STATUS_NEW, // Just created in DB
|
||||
CT_ORDER_STATUS_PENDING, // Pre-Auth of Credit Card OK. Waiting for TransactionManager to process.
|
||||
CT_ORDER_STATUS_PREAUTH_FAILED, // Pre-Auth of Credit Card Failed
|
||||
CT_ORDER_STATUS_ABOUT_TO_DEPOSIT, // All game transactions are complete, fixing to deposit credit card
|
||||
CT_ORDER_STATUS_FINISHED,//5 // Deposit successful. Order is complete. (some transaction may not have been processed by game, deposit amount was adjusted in this case
|
||||
CT_ORDER_STATUS_BILLING_FAILED, // Deposit failed, CS Alerted
|
||||
CT_ORDER_STATUS_ORDER_ID_NOT_FOUND_IN_DB, // DB Call was successful, but the order does not exist
|
||||
CSR_NEW,
|
||||
CSR_HARD_FAIL,
|
||||
CSR_SOFT_FAIL,//10
|
||||
CSR_SPECIFIC_HARD_FAIL,
|
||||
CSR_FINISHED,
|
||||
CSR_SOFT_GAME_FAIL,
|
||||
CSR_FAILED_GAME
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
// Status codes used by replyMoveStatus in game API
|
||||
//-----------------------------------------
|
||||
enum CTMoveStatus
|
||||
{
|
||||
CT_STATUS_COMPLETE = 0, // operation completed by game server
|
||||
CT_STATUS_INPROGRESS, // operation still in progress
|
||||
CT_STATUS_UNKNOWN, // transaction ID unrecognised by game server
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
// Result codes used by replyMove, replyDelete, replyRestore, and replyTransferAccount in game API
|
||||
//-----------------------------------------
|
||||
enum CTMoveResult
|
||||
{
|
||||
CT_GAMERESULT_SUCCESS = 0, // operation completed ok
|
||||
CT_GAMERESULT_SOFTERROR, // operation cannot be completed at this time, a "temporary" fail
|
||||
CT_GAMERESULT_HARDERROR, // operation failed and cannot succeed even if retried
|
||||
// any values below this are game-specific HARDERRORS. Use these to help provide feedback to the customers and CSR's
|
||||
CT_GAMERESULT_INVALID_NAME = 1000,
|
||||
CT_GAMERESULT_NAME_ALREADY_TAKE,
|
||||
CT_GAMERESULT_HAS_CORPSE,
|
||||
CT_GAMERESULT_SERVER_IS_DOWN,
|
||||
CT_GAMERESULT_MAX_CHAR_ON_DEST_SERVER,
|
||||
CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_TO_LEAVE_SRC_SERVER,//1005
|
||||
CT_GAMERESULT_CHAR_HAS_ITEM_NOT_ALLOWED_ON_DEST_SERVER,
|
||||
CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_SRC_SERVER,
|
||||
CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_TO_DEST_SERVER,
|
||||
CT_GAMERESULT_CHAR_NOT_ALLOWED_TO_MOVE_FROM_THIS_SRC_SERVER_TO_THIS_DEST_SERVER,
|
||||
CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_TO_LEAVE_SRC_SERVER,//1010 this type of character is not allowed to leave source server(faction, race, class, etc)
|
||||
CT_GAMERESULT_CHAR_TYPE_NOT_ALLOWED_ON_DEST_SERVER, // this type of character is not allowed on dest server(faction, race, class, etc)
|
||||
CT_GAMERESULT_SOFTERROR_FOR_LOCALIZED_TEXT, // ctserver will convert CT_GAMERESULT_SOFTERROR to this for getting localized text
|
||||
CT_GAMERESULT_HARDERROR_FOR_LOCALIZED_TEXT, // ctserver will convert CT_GAMERESULT_HARDERROR to this for getting localized text
|
||||
};
|
||||
enum CTLocalizedEmailMessages
|
||||
{
|
||||
// 2000 - 2999 CUSTOMER EMAIL SUBJECT
|
||||
CT_EMAIL_ORDER_COMP_SUCCESS = 2001, // NO PROBLEMS AT ALL IN THE ORDER, ALL TRANSACTIONS SUCCESSFUL
|
||||
CT_EMAIL_ORDER_COMP = 2002, // ORDER WAS BILLED FOR A CORRECTED AMOUNT (NOT ALL TRANSACTIONS WERE SUCCESFUL)
|
||||
CT_EMAIL_ORDER_PROCESSING = 2003, // ORDER PASSED VALIDATION AND GOT WRITTEN TO DB, PREAUTH DONE, TRANSACTION MANAGER HAS NOT BEGUN TO PROCESS IT YET
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED = 2004, // A FAIL OCCURED THAT WILL NOT ALLOW THE ORDER TO BE PROCESSED. ALTHOUGH A PREAUTH WAS DONE, NO TRANSACTIONS WERE COMPLETED, AND DEPOSIT WAS NOT CALLED
|
||||
CT_EMAIL_ORDER_PROBLEM = 2005, // AT LEAST ONE TRANSACTION WAS COMPLETED, ORDER WAS NOT BILLED. CSR INTERVENTION A MUST AT THIS POINT
|
||||
|
||||
// 3000 - 3999 CUSTOMER EMAIL CONTENT (ENGLISH)
|
||||
CT_EMAIL_PRE_NAME_GREETING = 3001, //ALL EMAILS (ex. Dear)
|
||||
// AUTO EMAIL ONCE ORDER HAS BEEN WRITTEN TO DB AND BEFORE TRANSACTION MANAGER STARTS
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_1 = 3002,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_2 = 3003,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_3 = 3004,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_4 = 3005,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_5 = 3006,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_6 = 3007,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_7 = 3008,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_8 = 3009,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_LINE_9 = 3010,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_1 = 3011,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_2 = 3012,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_3 = 3013,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_4 = 3014,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_5 = 3015,
|
||||
CT_EMAIL_ORDER_BEING_PROCESSED_CLOSING_LINE_6 = 3016,
|
||||
|
||||
// EMAIL SENT TO CUSTOMER AFTER ALL TRANSACTIONS ARE SUCCESSFUL AND BILLING IS SUCCESFUL
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_1 = 3102,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_2 = 3103,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_3 = 3104,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_4 = 3105,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_5 = 3106,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_6 = 3107,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_7 = 3108,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_8 = 3109,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_LINE_9 = 3110,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_1 = 3111,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_2 = 3112,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_3 = 3113,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_4 = 3114,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_5 = 3115,
|
||||
CT_EMAIL_ORDER_COMPLETE_SUCCESS_CLOSING_LINE_6 = 3116,
|
||||
|
||||
// EMAIL SENT TO CUSTOMER AFTER ALL TRANSACTIONS ARE COMPLETE
|
||||
// (SOME TRANSACTION MAY NOT HAVE BEEN SUCCESFUL, BUT THE CUSTOMER WAS BILLED ONLY FOR THE SUCCESSFUL ONES) AND BILLING IS SUCCESFUL
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_1 = 3202,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_2 = 3203,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_3 = 3204,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_4 = 3205,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_5 = 3206,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_6 = 3207,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_7 = 3208,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_8 = 3209,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_LINE_9 = 3210,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_1 = 3211,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_2 = 3212,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_3 = 3213,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_4 = 3214,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_5 = 3215,
|
||||
CT_EMAIL_ORDER_PARTIAL_SUCCESS_CLOSING_LINE_6 = 3216,
|
||||
|
||||
// EMAIL SENT TO CUSTOMER IF AN ERROR OCCURED THAT PREVENTS ANY TRANSACTION BEING PROCESS. NO BILLING IS DONE.
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_1 = 3302,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_2 = 3303,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_3 = 3304,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_4 = 3305,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_5 = 3306,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_6 = 3307,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_7 = 3308,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_8 = 3309,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_LINE_9 = 3310,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_1 = 3311,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_2 = 3312,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_3 = 3313,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_4 = 3314,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_5 = 3315,
|
||||
CT_EMAIL_ORDER_NOT_PROCESSED_CLOSING_LINE_6 = 3316,
|
||||
|
||||
// EMAIL SENT TO CUSTOMER AFTER 1 TO ALL TRANSACTIONS ARE COMPLETE
|
||||
// BUT BILLING WAS NOT SUCCESSFUL
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_1 = 3402,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_2 = 3403,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_3 = 3404,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_4 = 3405,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_5 = 3406,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_6 = 3407,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_7 = 3408,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_8 = 3409,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_LINE_9 = 3410,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_1 = 3411,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_2 = 3412,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_3 = 3413,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_4 = 3414,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_5 = 3415,
|
||||
CT_EMAIL_ORDER_FAILED_TO_BILL_CLOSING_LINE_6 = 3416,
|
||||
|
||||
// INDIVIDUAL LINES IN THE CUSTOMER EMAIL THAT WILL BE APPENDED WITH INFORMATION
|
||||
// example: "YOUR ORDER TRACKING NUMBER IS:"
|
||||
CT_EMAIL_ORDER_DETAIL_FOR_ORDER_TEXT = 3500,
|
||||
CT_EMAIL_SWG_GAME_NAME_TEXT = 3501,
|
||||
CT_EMAIL_EQ_GAME_NAME_TEXT = 3502,
|
||||
CT_EMAIL_PS_GAME_NAME_TEXT = 3503,
|
||||
CT_EMAIL_EQ2_GAME_NAME_TEXT = 3504,
|
||||
CT_EMAIL_CHARACTER_TEXT = 3505,
|
||||
CT_EMAIL_SERVER_NAME_TEXT = 3506,
|
||||
CT_EMAIL_NAME_CHANGED_TO_TEXT = 3507,
|
||||
CT_EMAIL_MOVED_TO_SERVER_NAME_TEXT = 3508,
|
||||
CT_EMAIL_TRANSFERED_TO_STATION_ACCOUNT_TEXT = 3509,
|
||||
CT_EMAIL_WITH_ITEMS_TEXT = 3510,
|
||||
CT_EMAIL_WITHOUT_ITEMS_TEXT = 3511,
|
||||
CT_EMAIL_TRANSACTIONS_REQUESTED_TEXT = 3512,
|
||||
CT_EMAIL_TOTAL_RENAMES_TEXT = 3513,
|
||||
CT_EMAIL_TOTAL_SERVER_TO_SERVER_MOVES_WITH_ITMES_TEXT = 3514,
|
||||
CT_EMAIL_TOTAL_SERVER_TO_SERVER_MOVES_WITHOUT_ITMES_TEXT = 3515,
|
||||
CT_EMAIL_TOTAL_ACCOUNT_TO_ACCOUNT_TRANSFERS_WITH_ITEMS_TEXT = 3516,
|
||||
CT_EMAIL_TOTAL_ACCOUNT_TO_ACCOUNT_TRANSFERS_WITHOUT_ITEMS_TEXT = 3517,
|
||||
CT_EMAIL_SUBTOTAL_FOR_ALL_TRANSACTIONS_BILLED_TEXT = 3518,
|
||||
CT_EMAIL_TAX_FOR_ALL_TRANSACTIONS_BILLED_TEXT = 3519,
|
||||
CT_EMAIL_VAT_TAX_FOR_ALL_TRANSACTIONS_BILLED_TEXT = 3520,
|
||||
CT_EMAIL_DISCOUNTS_FOR_ALL_TRANSACTIONS_BILLED_TEXT = 3521,
|
||||
CT_EMAIL_TOTAL_AMOUNT_BILLED_TEXT = 3522,
|
||||
CT_EMAIL_FAILED_TO_MOVE_TO_SERVER_TEXT = 3523,
|
||||
CT_EMAIL_FAILED_TO_RENAME_CHARACTER_TEXT = 3524,
|
||||
CT_EMAIL_FAILED_TO_TRANSFER_CHARACTER_TO_STATION_ACCOUNT_TEXT = 3525,
|
||||
CT_EMAIL_REASON_TEXT = 3526,
|
||||
CT_EMAIL_TRANSACTIONS_BILLED_TEXT = 3527,
|
||||
CT_EMAIL_YOUR_ORDER_TRACKING_NUMBER_TEXT = 3528,
|
||||
CT_EMAIL_OVERRIDE_TRUE_TEXT = 3529,
|
||||
CT_EMAIL_OVERRIDE_FALSE_TEXT = 3530,
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
/*
|
||||
enum StationAccountStatus
|
||||
{
|
||||
ACCOUNT_STATUS_NULL, // Invalid account status
|
||||
ACCOUNT_STATUS_ACTIVE,
|
||||
ACCOUNT_STATUS_CLOSED,
|
||||
// Add new account status codes here
|
||||
ACCOUNT_STATUS_END
|
||||
};
|
||||
*/
|
||||
}; // namespace
|
||||
|
||||
#endif
|
||||
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
#include "CTServiceCharacter.h"
|
||||
#include <Base/Archive.h>
|
||||
#include <Unicode/UnicodeUtils.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
using namespace Plat_Unicode;
|
||||
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceCharacter & target)
|
||||
{
|
||||
bool value;
|
||||
Plat_Unicode::String temp;
|
||||
|
||||
get(source, temp);
|
||||
target.SetCharacter(temp.c_str());
|
||||
|
||||
get(source, value);
|
||||
target.SetCanRename(value);
|
||||
get(source, value);
|
||||
target.SetCanMove(value);
|
||||
get(source, value);
|
||||
target.SetCanTransfer(value);
|
||||
|
||||
get(source, temp);
|
||||
target.SetRenameReason(temp.c_str());
|
||||
get(source, temp);
|
||||
target.SetMoveReason(temp.c_str());
|
||||
get(source, temp);
|
||||
target.SetTransferReason(temp.c_str());
|
||||
|
||||
// printf("\nCTServiceCharacter::get() -> [%s] [%d,%d,%d] [%s] [%s] [%s]",
|
||||
// wideToNarrow(target.GetCharacter()).c_str(), target.GetCanRename(), target.GetCanMove(),
|
||||
// target.GetCanTransfer(), wideToNarrow(target.GetRenameReason()).c_str(),
|
||||
// wideToNarrow(target.GetMoveReason()).c_str(), wideToNarrow(target.GetTransferReason()).c_str()); //debug
|
||||
}
|
||||
|
||||
void put(ByteStream & target, CTService::CTServiceCharacter & source)
|
||||
{
|
||||
Plat_Unicode::String temp;
|
||||
|
||||
temp = source.GetCharacter();
|
||||
put(target, temp);
|
||||
|
||||
put(target, source.GetCanRename());
|
||||
put(target, source.GetCanMove());
|
||||
put(target, source.GetCanTransfer());
|
||||
|
||||
temp = source.GetRenameReason();
|
||||
put(target, temp);
|
||||
temp = source.GetMoveReason();
|
||||
put(target, temp);
|
||||
temp = source.GetTransferReason();
|
||||
put(target, temp);
|
||||
|
||||
// printf("\nCTServiceCharacter::put() -> [%s] [%d,%d,%d] [%s] [%s] [%s]",
|
||||
// wideToNarrow(source.GetCharacter()).c_str(), source.GetCanRename(), source.GetCanMove(),
|
||||
// source.GetCanTransfer(), wideToNarrow(source.GetRenameReason()).c_str(),
|
||||
// wideToNarrow(source.GetMoveReason()).c_str(), wideToNarrow(source.GetTransferReason()).c_str()); //debug
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
}; // namespace
|
||||
#endif
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
#ifndef CTSERVICECHARACTER_H
|
||||
#define CTSERVICECHARACTER_H
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
//--------------------------------------------------------
|
||||
class CTServiceCharacter
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
typedef unsigned short uchar_t;
|
||||
inline void copy_wide_string(uchar_t * target, const uchar_t * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
public:
|
||||
enum { CHARACTER_SIZE=64, CHARACTER_BUFFER, REASON_SIZE=4096, REASON_BUFFER };
|
||||
|
||||
CTServiceCharacter() : mCharacter(), mCanRename(true), mCanMove(true), mCanTransfer(true), mRenameReason(), mMoveReason(), mTransferReason()
|
||||
{ mCharacter[0] = 0;
|
||||
mRenameReason[0] = 0;
|
||||
mMoveReason[0] = 0;
|
||||
mTransferReason[0]= 0; }
|
||||
|
||||
CTServiceCharacter(const unsigned short *ch) : mCharacter(), mCanRename(true), mCanMove(true), mCanTransfer(true), mRenameReason(), mMoveReason(), mTransferReason()
|
||||
{ copy_wide_string(mCharacter, ch, CHARACTER_BUFFER);
|
||||
mRenameReason[0] = 0;
|
||||
mMoveReason[0] = 0;
|
||||
mTransferReason[0]= 0; }
|
||||
|
||||
void SetCharacter(const uchar_t * value) { copy_wide_string(mCharacter, value, CHARACTER_BUFFER); }
|
||||
const uchar_t * GetCharacter() const { return mCharacter; }
|
||||
|
||||
void SetCanRename(const bool value) { mCanRename = value; }
|
||||
const bool GetCanRename() const { return mCanRename; }
|
||||
void SetCanMove(const bool value) { mCanMove = value; }
|
||||
const bool GetCanMove() const { return mCanMove; }
|
||||
void SetCanTransfer(const bool value) { mCanTransfer = value; }
|
||||
const bool GetCanTransfer() const { return mCanTransfer; }
|
||||
|
||||
void SetRenameReason(const uchar_t * value) { copy_wide_string(mRenameReason, value, REASON_BUFFER); }
|
||||
const uchar_t * GetRenameReason() const { return mRenameReason; }
|
||||
void SetMoveReason(const uchar_t * value) { copy_wide_string(mMoveReason, value, REASON_BUFFER); }
|
||||
const uchar_t * GetMoveReason() const { return mMoveReason; }
|
||||
void SetTransferReason(const uchar_t * value) { copy_wide_string(mTransferReason, value, REASON_BUFFER); }
|
||||
const uchar_t * GetTransferReason() const { return mTransferReason; }
|
||||
|
||||
private:
|
||||
uchar_t mCharacter[CHARACTER_BUFFER];
|
||||
bool mCanRename;
|
||||
bool mCanMove;
|
||||
bool mCanTransfer;
|
||||
uchar_t mRenameReason[REASON_BUFFER];
|
||||
uchar_t mMoveReason[REASON_BUFFER];
|
||||
uchar_t mTransferReason[REASON_BUFFER];
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //CTSERVICECHARACTER_H
|
||||
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
#ifndef CTSERVICECUSTOMER_H
|
||||
#define CTSERVICECUSTOMER_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
//--------------------------------------------------------
|
||||
class CTServiceCustomer
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
inline void copy_wide_string(unsigned short * target, const unsigned short * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
public:
|
||||
enum { SHORT_NAME_SIZE=64, SHORT_NAME_BUFFER,
|
||||
PHONE_SIZE=32, PHONE_BUFFER,
|
||||
EMAIL_SIZE=128, EMAIL_BUFFER,
|
||||
CARD_NAME_SIZE=255, CARD_NAME_BUFFER,
|
||||
CARD_ADDRESS1_SIZE=255, CARD_ADDRESS1_BUFFER,
|
||||
CARD_ADDRESS2_SIZE=255, CARD_ADDRESS2_BUFFER,
|
||||
CARD_CITY_SIZE=255, CARD_CITY_BUFFER,
|
||||
CARD_STATE_SIZE=255, CARD_STATE_BUFFER,
|
||||
CARD_ZIP_SIZE=255, CARD_ZIP_BUFFER,
|
||||
CARD_COUNTRY_SIZE=2, CARD_COUNTRY_BUFFER,
|
||||
CARD_NUMBER_SIZE=255, CARD_NUMBER_BUFFER,
|
||||
CARD_EXPIRATION_MONTH_SIZE=2,CARD_EXPIRATION_MONTH_BUFFER,
|
||||
CARD_EXPIRATION_YEAR_SIZE=4,CARD_EXPIRATION_YEAR_BUFFER };
|
||||
CTServiceCustomer() : mFirstName(), mLastName(), mPhone(), mEmail(), mStationID(0), mCardName(), mCardAddress1(), mCardAddress2(), mCardCity(), mCardState(), mCardZip(), mCountry(), mCardNumber(), mCardExpirationMonth(), mCardExpirationYear()
|
||||
{ mFirstName[0] = 0;
|
||||
mLastName[0] = 0;
|
||||
mPhone[0] = 0;
|
||||
mEmail[0] = 0;
|
||||
mCardName[0] = 0;
|
||||
mCardAddress1[0] = 0;
|
||||
mCardAddress2[0] = 0;
|
||||
mCardCity[0] = 0;
|
||||
mCardState[0] = 0;
|
||||
mCardZip[0] = 0;
|
||||
mCountry[0] = 0;
|
||||
mCardNumber[0] = 0;
|
||||
mCardExpirationMonth[0]= 0;
|
||||
mCardExpirationYear[0]= 0; }
|
||||
|
||||
|
||||
void SetFirstName(const unsigned short * value) { copy_wide_string(mFirstName, value, SHORT_NAME_BUFFER); }
|
||||
unsigned short *GetFirstName() { return mFirstName; }
|
||||
|
||||
void SetLastName(const unsigned short * value) { copy_wide_string(mLastName, value, SHORT_NAME_BUFFER); }
|
||||
unsigned short *GetLastName() { return mLastName; }
|
||||
|
||||
void SetPhone(const unsigned short * value) { copy_wide_string(mPhone, value, PHONE_BUFFER); }
|
||||
unsigned short *GetPhone() { return mPhone; }
|
||||
|
||||
void SetEmail(const unsigned short * value) { copy_wide_string(mEmail, value, EMAIL_BUFFER); }
|
||||
unsigned short *GetEmail() { return mEmail; }
|
||||
|
||||
void SetStationID(const unsigned value) { mStationID = value; }
|
||||
unsigned GetStationID() { return mStationID; }
|
||||
|
||||
void SetCardName(const unsigned short * value) { copy_wide_string(mCardName, value, CARD_NAME_BUFFER); }
|
||||
unsigned short *GetCardName() { return mCardName; }
|
||||
|
||||
void SetCardAddress1(const unsigned short * value) { copy_wide_string(mCardAddress1, value, CARD_ADDRESS1_BUFFER); }
|
||||
unsigned short *GetCardAddress1() { return mCardAddress1; }
|
||||
|
||||
void SetCardAddress2(const unsigned short * value) { copy_wide_string(mCardAddress2, value, CARD_ADDRESS2_BUFFER); }
|
||||
unsigned short *GetCardAddress2() { return mCardAddress2; }
|
||||
|
||||
void SetCardCity(const unsigned short * value) { copy_wide_string(mCardCity, value, CARD_CITY_BUFFER); }
|
||||
unsigned short *GetCardCity() { return mCardCity; }
|
||||
|
||||
void SetCardState(const unsigned short * value) { copy_wide_string(mCardState, value, CARD_STATE_BUFFER); }
|
||||
unsigned short *GetCardState() { return mCardState; }
|
||||
|
||||
void SetCardZip(const unsigned short * value) { copy_wide_string(mCardZip, value, CARD_ZIP_BUFFER); }
|
||||
unsigned short *GetCardZip() { return mCardZip; }
|
||||
|
||||
void SetCountry(const unsigned short * value) { copy_wide_string(mCountry, value, CARD_COUNTRY_BUFFER); }
|
||||
unsigned short *GetCountry() { return mCountry; }
|
||||
|
||||
void SetCardNumber(const unsigned short * value) { copy_wide_string(mCardNumber, value, CARD_NUMBER_BUFFER); }
|
||||
unsigned short *GetCardNumber() { return mCardNumber; }
|
||||
|
||||
void SetCardExpirationMonth(const unsigned short * value){ copy_wide_string(mCardExpirationMonth, value, CARD_EXPIRATION_MONTH_BUFFER); }
|
||||
unsigned short *GetCardExpirationMonth() { return mCardExpirationMonth; }
|
||||
|
||||
void SetCardExpirationYear(const unsigned short * value) { copy_wide_string(mCardExpirationYear, value, CARD_EXPIRATION_YEAR_BUFFER); }
|
||||
unsigned short *GetCardExpirationYear() { return mCardExpirationYear; }
|
||||
|
||||
|
||||
private:
|
||||
unsigned short mFirstName[SHORT_NAME_BUFFER];
|
||||
unsigned short mLastName[SHORT_NAME_BUFFER];
|
||||
unsigned short mPhone[PHONE_BUFFER];
|
||||
unsigned short mEmail[EMAIL_BUFFER];
|
||||
unsigned mStationID;
|
||||
unsigned short mCardName[CARD_NAME_BUFFER];
|
||||
unsigned short mCardAddress1[CARD_ADDRESS1_BUFFER];
|
||||
unsigned short mCardAddress2[CARD_ADDRESS2_BUFFER];
|
||||
unsigned short mCardCity[CARD_CITY_BUFFER];
|
||||
unsigned short mCardState[CARD_STATE_BUFFER];
|
||||
unsigned short mCardZip[CARD_ZIP_BUFFER];
|
||||
unsigned short mCountry[CARD_COUNTRY_BUFFER];
|
||||
unsigned short mCardNumber[CARD_NUMBER_BUFFER];
|
||||
unsigned short mCardExpirationMonth[CARD_EXPIRATION_MONTH_BUFFER];
|
||||
unsigned short mCardExpirationYear[CARD_EXPIRATION_YEAR_BUFFER];
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif
|
||||
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
#ifndef CTSERVICEDBORDER_H
|
||||
#define CTSERVICEDBORDER_H
|
||||
|
||||
#include <string.h>
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
//--------------------------------------------------------
|
||||
|
||||
// This object is used to pass back an order to the webAPI.
|
||||
//this objects intended use is for CSR functionality, see also DBOrder.h(server only, not in webapi)
|
||||
//--------------------------------------------------------
|
||||
class CTServiceDBOrder
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
inline void copy_wide_string(unsigned short * target, const unsigned short * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
enum { LANGUAGE_SIZE=2, LANGUAGE_BUFFER,
|
||||
DATE_SIZE=20, DATE_BUFFER,
|
||||
ECOMM_ORDER_ID_SIZE=16, ECOMM_ORDER_ID_BUFFER,
|
||||
ORDER_STATUS_SIZE=16, ORDER_STATUS_BUFFER,
|
||||
CUSTOMER_NAME_SIZE=64, CUSTOMER_NAME_BUFFER,
|
||||
CUSTOMER_PHONE_SIZE=32, CUSTOMER_PHONE_BUFFER,
|
||||
CUSTOMER_EMAIL_SIZE=128, CUSTOMER_EMAIL_BUFFER,
|
||||
CARD_INFO_SIZE=255, CARD_INFO_BUFFER,
|
||||
COUNTRY_SIZE=2, COUNTRY_BUFFER,
|
||||
CARD_EXP_MONTH_SIZE=2, CARD_EXP_MONTH_BUFFER,
|
||||
CARD_EXP_YEAR_SIZE=4, CARD_EXP_YEAR_BUFFER,
|
||||
GAME_CODE_SIZE=25, GAME_CODE_BUFFER };
|
||||
CTServiceDBOrder() : mOrderID(0), mEcommOrderID(), mOrderStatus(), mLanguage(), mGameCode(),
|
||||
mStationID(0), mCustomerFirstName(), mCustomerLastName(), mCustomerPhone(),
|
||||
mCustomerEmail(), mCardName(), mCardAddress1(), mCardAddress2(), mCardCity(),
|
||||
mCardState(), mCardZip(), mCountry(), mCreationDate(), mModifyDate(), mCompletionDate(),
|
||||
mTransactionCount(0), mSuccessfulTransactions(0), mFailedTransactions(0)
|
||||
{
|
||||
mEcommOrderID[0] = 0;
|
||||
mOrderStatus[0] = 0;
|
||||
mLanguage[0] = 0;
|
||||
mGameCode[0] = 0;
|
||||
mCustomerFirstName[0] = 0;
|
||||
mCustomerLastName[0] = 0;
|
||||
mCustomerPhone[0] = 0;
|
||||
mCustomerEmail[0] = 0;
|
||||
mCardName[0] = 0;
|
||||
mCardAddress1[0] = 0;
|
||||
mCardAddress2[0] = 0;
|
||||
mCardCity[0] = 0;
|
||||
mCardState[0] = 0;
|
||||
mCardZip[0] = 0;
|
||||
mCountry[0] = 0;
|
||||
}
|
||||
|
||||
// unsigned
|
||||
void SetOrderID(const unsigned value) { mOrderID = value; }
|
||||
unsigned GetOrderID() { return mOrderID; }
|
||||
|
||||
void SetStationID(const unsigned value) { mStationID = value; }
|
||||
unsigned GetStationID() { return mStationID; }
|
||||
|
||||
void SetTransactionCount(const unsigned value) { mTransactionCount = value; }
|
||||
unsigned GetTransactionCount() { return mTransactionCount; }
|
||||
|
||||
void SetSuccessfulTransactions(const unsigned value) { mSuccessfulTransactions = value; }
|
||||
unsigned GetSuccessfulTransactions() { return mSuccessfulTransactions; }
|
||||
|
||||
void SetFailedTransactions(const unsigned value) { mFailedTransactions = value; }
|
||||
unsigned GetFailedTransactions() { return mFailedTransactions; }
|
||||
|
||||
// char
|
||||
void SetCreationDate(const char * value) { if (value) strncpy(mCreationDate, value, DATE_BUFFER); else mCreationDate[0] = 0; }
|
||||
const char * GetCreationDate() { return mCreationDate; }
|
||||
|
||||
void SetModifyDate(const char * value) { if (value) strncpy(mModifyDate, value, DATE_BUFFER); else mModifyDate[0] = 0; }
|
||||
const char * GetModifyDate() { return mModifyDate; }
|
||||
|
||||
void SetCompletionDate(const char * value) { if (value) strncpy(mCompletionDate, value, DATE_BUFFER); else mCompletionDate[0] = 0; }
|
||||
const char * GetCompletionDate() { return mCompletionDate; }
|
||||
|
||||
void SetEcommOrderID(const char * value) { if (value) strncpy(mEcommOrderID, value, ECOMM_ORDER_ID_BUFFER); else mEcommOrderID[0] = 0; }
|
||||
const char * GetEcommOrderID() { return mEcommOrderID; }
|
||||
|
||||
void SetOrderStatus(const char * value) { if (value) strncpy(mOrderStatus, value, ORDER_STATUS_BUFFER); else mOrderStatus[0] = 0; }
|
||||
const char * GetOrderStatus() { return mOrderStatus; }
|
||||
|
||||
void SetLanguage(const char * value) { if (value) strncpy(mLanguage, value, LANGUAGE_BUFFER); else mLanguage[0] = 0; }
|
||||
const char * GetLanguage() { return mLanguage; }
|
||||
|
||||
void SetGameCode(const char * value) { if (value) strncpy(mGameCode, value, GAME_CODE_BUFFER); else mGameCode[0] = 0; }
|
||||
const char * GetGameCode() { return mGameCode; }
|
||||
|
||||
// unsigned short
|
||||
void SetCustomerFirstName(const unsigned short * value) { copy_wide_string(mCustomerFirstName, value, CUSTOMER_NAME_BUFFER); }
|
||||
unsigned short *GetCustomerFirstName() { return mCustomerFirstName; }
|
||||
|
||||
void SetCustomerLastName(const unsigned short * value) { copy_wide_string(mCustomerLastName, value, CUSTOMER_NAME_BUFFER); }
|
||||
unsigned short *GetCustomerLastName() { return mCustomerLastName; }
|
||||
|
||||
void SetCustomerPhone(const unsigned short * value) { copy_wide_string(mCustomerPhone, value, CUSTOMER_PHONE_BUFFER); }
|
||||
unsigned short *GetCustomerPhone() { return mCustomerPhone; }
|
||||
|
||||
void SetCustomerEmail(const unsigned short * value) { copy_wide_string(mCustomerEmail, value, CUSTOMER_EMAIL_BUFFER); }
|
||||
unsigned short *GetCustomerEmail() { return mCustomerEmail; }
|
||||
|
||||
void SetCardName(const unsigned short * value) { copy_wide_string(mCardName, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardName() { return mCardName; }
|
||||
|
||||
void SetCardAddress1(const unsigned short * value) { copy_wide_string(mCardAddress1, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardAddress1() { return mCardAddress1; }
|
||||
|
||||
void SetCardAddress2(const unsigned short * value) { copy_wide_string(mCardAddress2, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardAddress2() { return mCardAddress2; }
|
||||
|
||||
void SetCardCity(const unsigned short * value) { copy_wide_string(mCardCity, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardCity() { return mCardCity; }
|
||||
|
||||
void SetCardState(const unsigned short * value) { copy_wide_string(mCardState, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardState() { return mCardState; }
|
||||
|
||||
void SetCardZip(const unsigned short * value) { copy_wide_string(mCardZip, value, CARD_INFO_BUFFER); }
|
||||
unsigned short *GetCardZip() { return mCardZip; }
|
||||
|
||||
void SetCountry(const unsigned short * value) { copy_wide_string(mCountry, value, COUNTRY_BUFFER); }
|
||||
unsigned short *GetCountry() { return mCountry; }
|
||||
|
||||
private:
|
||||
unsigned mOrderID;
|
||||
char mEcommOrderID[ECOMM_ORDER_ID_BUFFER];
|
||||
char mOrderStatus[ORDER_STATUS_BUFFER];
|
||||
char mLanguage[LANGUAGE_BUFFER];
|
||||
char mGameCode[GAME_CODE_BUFFER];
|
||||
unsigned mStationID;
|
||||
unsigned short mCustomerFirstName[CUSTOMER_NAME_BUFFER];
|
||||
unsigned short mCustomerLastName[CUSTOMER_NAME_BUFFER];
|
||||
unsigned short mCustomerPhone[CUSTOMER_PHONE_BUFFER];
|
||||
unsigned short mCustomerEmail[CUSTOMER_EMAIL_BUFFER];
|
||||
unsigned short mCardName[CARD_INFO_BUFFER];
|
||||
unsigned short mCardAddress1[CARD_INFO_BUFFER];
|
||||
unsigned short mCardAddress2[CARD_INFO_BUFFER];
|
||||
unsigned short mCardCity[CARD_INFO_BUFFER];
|
||||
unsigned short mCardState[CARD_INFO_BUFFER];
|
||||
unsigned short mCardZip[CARD_INFO_BUFFER];
|
||||
unsigned short mCountry[COUNTRY_BUFFER];
|
||||
char mCreationDate[DATE_BUFFER];
|
||||
char mModifyDate[DATE_BUFFER];
|
||||
char mCompletionDate[DATE_BUFFER];
|
||||
unsigned mTransactionCount;
|
||||
unsigned mSuccessfulTransactions;
|
||||
unsigned mFailedTransactions;
|
||||
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //CTSERVICEDBORDER_H
|
||||
+160
@@ -0,0 +1,160 @@
|
||||
#ifndef CTSERVICEDBTRANSACTION_H
|
||||
#define CTSERVICEDBTRANSACTION_H
|
||||
|
||||
#include <string.h>
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
//--------------------------------------------------------
|
||||
// This object is used to pass back a transaction to the webAPI.
|
||||
//this objects intended use is for CSR functionality, see also DBTransaction.h(server only, not in webapi) and CTServiceWebAPITransaction.h(server and webapi, in common folder)
|
||||
//--------------------------------------------------------
|
||||
class CTServiceTransaction
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
inline void copy_wide_string(unsigned short * target, const unsigned short * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
|
||||
public:
|
||||
enum { LANGUAGE_SIZE=2, LANGUAGE_BUFFER,
|
||||
DATE_SIZE=20, DATE_BUFFER,
|
||||
GAME_CODE_SIZE=25, GAME_CODE_BUFFER,
|
||||
NAME_SIZE=64, NAME_BUFFER,
|
||||
TRANSACTIONS_STATUS_SIZE=64, TRANSACTIONS_STATUS_BUFFER };
|
||||
|
||||
CTServiceTransaction() : mTransactionID(0), mOrderID(0), mTransactionStatus(), mGameResultID(0),
|
||||
mSuggestedName(), mGameCode(), mSourceServer(), mDestServer(),
|
||||
mSourceCharacter(), mDestCharacter(), mSourceUID(0), mDestStationName(),
|
||||
mDestUID(0), mWithItems(0), mOverride(0), mLanguage(), mTransferServerHost(),
|
||||
mTransferServerPort(), mRetryCounter(0), mTimeoutDate(), mCreationDate(),
|
||||
mModifyDate(), mCompletionDate()
|
||||
{
|
||||
mTransactionStatus[0] = 0;
|
||||
mSuggestedName[0] = 0;
|
||||
mGameCode[0] = 0;
|
||||
mSourceServer[0] = 0;
|
||||
mDestServer[0] = 0;
|
||||
mSourceCharacter[0] = 0;
|
||||
mDestCharacter[0] = 0;
|
||||
mDestStationName[0] = 0;
|
||||
mLanguage[0] = 0;
|
||||
mTransferServerHost[0] = 0;
|
||||
mTransferServerPort[0] = 0;
|
||||
}
|
||||
|
||||
// unsigned
|
||||
|
||||
void SetTransactionID(const unsigned value) { mTransactionID = value; }
|
||||
unsigned GetTransactionID() { return mTransactionID; }
|
||||
|
||||
void SetOrderID(const unsigned value) { mOrderID = value; }
|
||||
unsigned GetOrderID() { return mOrderID; }
|
||||
|
||||
void SetGameResultID(const unsigned value) { mGameResultID = value; }
|
||||
unsigned GetGameResultID() { return mGameResultID; }
|
||||
|
||||
void SetSourceUID(const unsigned value) { mSourceUID = value; }
|
||||
unsigned GetSourceUID() { return mSourceUID; }
|
||||
|
||||
void SetDestUID(const unsigned value) { mDestUID = value; }
|
||||
unsigned GetDestUID() { return mDestUID; }
|
||||
|
||||
void SetWithItems(const unsigned value) { mWithItems = value; }
|
||||
unsigned GetWithItems() { return mWithItems; }
|
||||
|
||||
void SetOverride(const unsigned value) { mOverride = value; }
|
||||
unsigned GetOverride() { return mOverride; }
|
||||
|
||||
void SetRetryCounter(const unsigned value) { mRetryCounter = value; }
|
||||
unsigned GetRetryCounter() { return mRetryCounter; }
|
||||
|
||||
// char
|
||||
|
||||
void SetTimeoutDate(const char * value) { if (value) strncpy(mTimeoutDate, value, DATE_BUFFER); else mTimeoutDate[0] = 0; }
|
||||
const char * GetTimeoutDate() { return mTimeoutDate; }
|
||||
|
||||
void SetCreationDate(const char * value) { if (value) strncpy(mCreationDate, value, DATE_BUFFER); else mCreationDate[0] = 0; }
|
||||
const char * GetCreationDate() { return mCreationDate; }
|
||||
|
||||
void SetModifyDate(const char * value) { if (value) strncpy(mModifyDate, value, DATE_BUFFER); else mModifyDate[0] = 0; }
|
||||
const char * GetModifyDate() { return mModifyDate; }
|
||||
|
||||
void SetCompletionDate(const char * value) { if (value) strncpy(mCompletionDate, value, DATE_BUFFER); else mCompletionDate[0] = 0; }
|
||||
const char * GetCompletionDate() { return mCompletionDate; }
|
||||
|
||||
void SetTransactionStatus(const char * value) { if (value) strncpy(mTransactionStatus, value, TRANSACTIONS_STATUS_BUFFER); else mTransactionStatus[0] = 0; }
|
||||
const char * GetTransactionStatus() { return mTransactionStatus; }
|
||||
|
||||
void SetGameCode(const char * value) { if (value) strncpy(mGameCode, value, GAME_CODE_BUFFER); else mGameCode[0] = 0; }
|
||||
const char * GetGameCode() { return mGameCode; }
|
||||
|
||||
void SetLanguage(const char * value) { if (value) strncpy(mLanguage, value, LANGUAGE_BUFFER); else mLanguage[0] = 0; }
|
||||
const char * GetLanguage() { return mLanguage; }
|
||||
|
||||
void SetTransferServerHost(const char * value) { if (value) strncpy(mTransferServerHost, value, NAME_BUFFER); else mTransferServerHost[0] = 0; }
|
||||
const char * GetTransferServerHost() { return mTransferServerHost; }
|
||||
|
||||
void SetTransferServerPort(const char * value) { if (value) strncpy(mTransferServerPort, value, NAME_BUFFER); else mTransferServerPort[0] = 0; }
|
||||
const char * GetTransferServerPort() { return mTransferServerPort; }
|
||||
|
||||
// unsigned short
|
||||
|
||||
void SetSuggestedName(const unsigned short * value) { copy_wide_string(mSuggestedName, value, NAME_BUFFER); }
|
||||
unsigned short *GetSuggestedName() { return mSuggestedName; }
|
||||
|
||||
void SetSourceServer(const unsigned short * value) { copy_wide_string(mSourceServer, value, NAME_BUFFER); }
|
||||
unsigned short *GetSourceServer() { return mSourceServer; }
|
||||
|
||||
void SetDestServer(const unsigned short * value) { copy_wide_string(mDestServer, value, NAME_BUFFER); }
|
||||
unsigned short *GetDestServer() { return mDestServer; }
|
||||
|
||||
void SetSourceCharacter(const unsigned short * value) { copy_wide_string(mSourceCharacter, value, NAME_BUFFER); }
|
||||
unsigned short *GetSourceCharacter() { return mSourceCharacter; }
|
||||
|
||||
void SetDestCharacter(const unsigned short * value) { copy_wide_string(mDestCharacter, value, NAME_BUFFER); }
|
||||
unsigned short *GetDestCharacter() { return mDestCharacter; }
|
||||
|
||||
void SetDestStationName(const unsigned short * value) { copy_wide_string(mDestStationName, value, NAME_BUFFER); }
|
||||
unsigned short *GetDestStationName() { return mDestStationName; }
|
||||
|
||||
|
||||
private:
|
||||
unsigned mTransactionID;
|
||||
unsigned mOrderID;
|
||||
char mTransactionStatus[TRANSACTIONS_STATUS_BUFFER];
|
||||
unsigned mGameResultID;
|
||||
unsigned short mSuggestedName[NAME_BUFFER];
|
||||
char mGameCode[GAME_CODE_BUFFER];
|
||||
unsigned short mSourceServer[NAME_BUFFER];
|
||||
unsigned short mDestServer[NAME_BUFFER];
|
||||
unsigned short mSourceCharacter[NAME_BUFFER];
|
||||
unsigned short mDestCharacter[NAME_BUFFER];
|
||||
unsigned mSourceUID;
|
||||
unsigned short mDestStationName[NAME_BUFFER];
|
||||
unsigned mDestUID;
|
||||
unsigned mWithItems;
|
||||
unsigned mOverride;
|
||||
char mLanguage[LANGUAGE_BUFFER];
|
||||
char mTransferServerHost[NAME_BUFFER];
|
||||
char mTransferServerPort[NAME_BUFFER];
|
||||
unsigned mRetryCounter;
|
||||
char mTimeoutDate[DATE_BUFFER];
|
||||
char mCreationDate[DATE_BUFFER];
|
||||
char mModifyDate[DATE_BUFFER];
|
||||
char mCompletionDate[DATE_BUFFER];
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //CTSERVICEDBTRANSACTION_H
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
#if !defined (CTSERVICEOBJECTS_H_)
|
||||
#define CTSERVICEOBJECTS_H_
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include <Base/Archive.h>
|
||||
#include "CTServiceCharacter.h"
|
||||
#include "CTServiceServer.h"
|
||||
#include "CTServiceWebAPITransaction.h"
|
||||
#include "CTServiceCustomer.h"
|
||||
#include "CTServiceDBOrder.h"
|
||||
#include "CTServiceDBTransaction.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Base
|
||||
{
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceCharacter & target);
|
||||
void put(ByteStream & target, CTService::CTServiceCharacter & source);
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceServer & target);
|
||||
void put(ByteStream & target, CTService::CTServiceServer & source);
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceWebAPITransaction & target);
|
||||
void put(ByteStream & target, CTService::CTServiceWebAPITransaction & source);
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceCustomer & target);
|
||||
void put(ByteStream & target, CTService::CTServiceCustomer & source);
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceDBOrder & target);
|
||||
void put(ByteStream & target, CTService::CTServiceDBOrder & source);
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceTransaction & target);
|
||||
void put(ByteStream & target, CTService::CTServiceTransaction & source);
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
}; // namespace
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#include "CTServiceServer.h"
|
||||
#include <Base/Archive.h>
|
||||
#include <Unicode/UnicodeUtils.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Base
|
||||
{
|
||||
|
||||
using namespace Plat_Unicode;
|
||||
|
||||
void get(ByteStream::ReadIterator & source, CTService::CTServiceServer & target)
|
||||
{
|
||||
bool value;
|
||||
Plat_Unicode::String temp;
|
||||
|
||||
get(source, temp);
|
||||
target.SetServer(temp.c_str());
|
||||
|
||||
get(source, value);
|
||||
target.SetCanRename(value);
|
||||
get(source, value);
|
||||
target.SetCanMove(value);
|
||||
get(source, value);
|
||||
target.SetCanTransfer(value);
|
||||
|
||||
get(source, temp);
|
||||
target.SetRenameReason(temp.c_str());
|
||||
get(source, temp);
|
||||
target.SetMoveReason(temp.c_str());
|
||||
get(source, temp);
|
||||
target.SetTransferReason(temp.c_str());
|
||||
|
||||
// printf("\nCTServiceServer::get() -> [%s] [%d,%d,%d] [%s] [%s] [%s]",
|
||||
// wideToNarrow(target.GetServer()).c_str(), target.GetCanRename(), target.GetCanMove(),
|
||||
// target.GetCanTransfer(), wideToNarrow(target.GetRenameReason()).c_str(),
|
||||
// wideToNarrow(target.GetMoveReason()).c_str(), wideToNarrow(target.GetTransferReason()).c_str()); //debug
|
||||
}
|
||||
|
||||
void put(ByteStream & target, CTService::CTServiceServer & source)
|
||||
{
|
||||
Plat_Unicode::String temp;
|
||||
|
||||
temp = source.GetServer();
|
||||
put(target, temp);
|
||||
|
||||
put(target, source.GetCanRename());
|
||||
put(target, source.GetCanMove());
|
||||
put(target, source.GetCanTransfer());
|
||||
|
||||
temp = source.GetRenameReason();
|
||||
put(target, temp);
|
||||
temp = source.GetMoveReason();
|
||||
put(target, temp);
|
||||
temp = source.GetTransferReason();
|
||||
put(target, temp);
|
||||
|
||||
// printf("\nCTServiceServer::put() -> [%s] [%d,%d,%d] [%s] [%s] [%s]",
|
||||
// wideToNarrow(source.GetServer()).c_str(), source.GetCanRename(), source.GetCanMove(),
|
||||
// source.GetCanTransfer(), wideToNarrow(source.GetRenameReason()).c_str(),
|
||||
// wideToNarrow(source.GetMoveReason()).c_str(), wideToNarrow(source.GetTransferReason()).c_str()); //debug
|
||||
}
|
||||
|
||||
}
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
}; // namespace
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef CTSERVICESERVER_H
|
||||
#define CTSERVICESERVER_H
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
//--------------------------------------------------------
|
||||
class CTServiceServer
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
inline void copy_wide_string(unsigned short * target, const unsigned short * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
public:
|
||||
enum { SERVER_SIZE=64, SERVER_BUFFER, REASON_SIZE=4096, REASON_BUFFER };
|
||||
|
||||
CTServiceServer() : mServer(), mCanRename(true), mCanMove(true), mCanTransfer(true), mRenameReason(), mMoveReason(), mTransferReason()
|
||||
{ mServer[0] = 0;
|
||||
mRenameReason[0] = 0;
|
||||
mMoveReason[0] = 0;
|
||||
mTransferReason[0]= 0; }
|
||||
|
||||
CTServiceServer(const unsigned short *server) : mServer(), mCanRename(true), mCanMove(true), mCanTransfer(true), mRenameReason(), mMoveReason(), mTransferReason()
|
||||
{ copy_wide_string(mServer, server, SERVER_BUFFER);
|
||||
mRenameReason[0] = 0;
|
||||
mMoveReason[0] = 0;
|
||||
mTransferReason[0]= 0; }
|
||||
|
||||
void SetServer(const unsigned short * value) { copy_wide_string(mServer, value, SERVER_BUFFER); }
|
||||
unsigned short *GetServer() { return mServer; }
|
||||
|
||||
void SetCanRename(const bool value) { mCanRename = value; }
|
||||
const bool GetCanRename() const { return mCanRename; }
|
||||
void SetCanMove(const bool value) { mCanMove = value; }
|
||||
const bool GetCanMove() const { return mCanMove; }
|
||||
void SetCanTransfer(const bool value) { mCanTransfer = value; }
|
||||
const bool GetCanTransfer() const { return mCanTransfer; }
|
||||
|
||||
void SetRenameReason(const unsigned short * value) { copy_wide_string(mRenameReason, value, REASON_BUFFER); }
|
||||
const unsigned short * GetRenameReason() const { return mRenameReason; }
|
||||
void SetMoveReason(const unsigned short * value) { copy_wide_string(mMoveReason, value, REASON_BUFFER); }
|
||||
const unsigned short * GetMoveReason() const { return mMoveReason; }
|
||||
void SetTransferReason(const unsigned short * value) { copy_wide_string(mTransferReason, value, REASON_BUFFER); }
|
||||
const unsigned short * GetTransferReason() const { return mTransferReason; }
|
||||
|
||||
private:
|
||||
unsigned short mServer[SERVER_BUFFER];
|
||||
bool mCanRename;
|
||||
bool mCanMove;
|
||||
bool mCanTransfer;
|
||||
unsigned short mRenameReason[REASON_BUFFER];
|
||||
unsigned short mMoveReason[REASON_BUFFER];
|
||||
unsigned short mTransferReason[REASON_BUFFER];
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //CTSERVICESERVER_H
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
#ifndef CTSERVICEWEBAPITRANSACTION_H
|
||||
#define CTSERVICEWEBAPITRANSACTION_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
//--------------------------------------------------------
|
||||
// this object is used by the webapi to send in a transaction to the CTServer.
|
||||
// see also DBTransaction.h(server only, not in webapi) and CTServicDBTransaction.h(server and webapi, in common folder)
|
||||
//--------------------------------------------------------
|
||||
class CTServiceWebAPITransaction
|
||||
//--------------------------------------------------------
|
||||
{
|
||||
inline void copy_wide_string(unsigned short * target, const unsigned short * source, int length)
|
||||
{
|
||||
if (!target)
|
||||
return;
|
||||
if (!source)
|
||||
{
|
||||
target[0] = 0;
|
||||
return;
|
||||
}
|
||||
int offset = 0;
|
||||
while (offset < length && (target[offset++] = source[offset]));
|
||||
target[length-1] = 0;
|
||||
}
|
||||
typedef unsigned short uchar_t;
|
||||
|
||||
public:
|
||||
enum { CHARACTER_SIZE=64, CHARACTER_BUFFER,
|
||||
GAMECODE_SIZE=25, GAMECODE_BUFFER,
|
||||
SERVER_SIZE=64, SERVER_BUFFER,
|
||||
REASON_SIZE=4096, REASON_BUFFER,
|
||||
STATION_NAME_SIZE=30, STATION_NAME_BUFFER,
|
||||
STATION_PASSWORD_SIZE=30, STATION_PASSWORD_BUFFER };
|
||||
CTServiceWebAPITransaction() : mGameCode(), mSourceServerName(), mDestServerName(), mSourceCharacterName(), mDestCharacterName(), mSourceUID(0), mDestStationName(), mDestStationPassword(), mWithItems(), mOverride()
|
||||
{ mGameCode[0] = 0;
|
||||
mSourceServerName[0] = 0;
|
||||
mDestServerName[0] = 0;
|
||||
mSourceCharacterName[0] = 0;
|
||||
mDestCharacterName[0] = 0;
|
||||
mDestStationName[0] = 0;
|
||||
mDestStationPassword[0]= 0;
|
||||
mWithItems = false;
|
||||
mOverride = false; }
|
||||
void SetGameCode(const char * value) { if (value) strncpy(mGameCode, value, GAMECODE_BUFFER); else mGameCode[0] = 0; }
|
||||
// void SetGameCode(const char * value) { strncpy(mGameCode, value, GAMECODE_BUFFER); }
|
||||
const char * GetGameCode() const { return mGameCode; }
|
||||
|
||||
void SetSourceServerName(const unsigned short * value) { copy_wide_string(mSourceServerName, value, SERVER_BUFFER); }
|
||||
const uchar_t * GetSourceServerName() const { return mSourceServerName; }
|
||||
|
||||
void SetDestServerName(const unsigned short * value) { copy_wide_string(mDestServerName, value, SERVER_BUFFER); }
|
||||
const uchar_t * GetDestServerName() const { return mDestServerName; }
|
||||
|
||||
void SetSourceCharacterName(const unsigned short * value){ copy_wide_string(mSourceCharacterName, value, CHARACTER_BUFFER); }
|
||||
const uchar_t * GetSourceCharacterName() const { return mSourceCharacterName; }
|
||||
|
||||
void SetDestCharacterName(const unsigned short * value) { copy_wide_string(mDestCharacterName, value, CHARACTER_BUFFER); }
|
||||
const uchar_t * GetDestCharacterName() const { return mDestCharacterName; }
|
||||
|
||||
void SetSourceUID(const unsigned value) { mSourceUID = value; }
|
||||
unsigned GetSourceUID() { return mSourceUID; }
|
||||
|
||||
void SetDestStationName(const unsigned short * value) { copy_wide_string(mDestStationName, value, STATION_NAME_BUFFER); }
|
||||
const uchar_t * GetDestStationName() const { return mDestStationName; }
|
||||
|
||||
void SetDestStationPassword(const unsigned short * value){ copy_wide_string(mDestStationPassword, value, STATION_PASSWORD_BUFFER); }
|
||||
const uchar_t * GetDestStationPassword() const { return mDestStationPassword; }
|
||||
|
||||
void SetWithItems(const bool value) { mWithItems = value; }
|
||||
bool GetWithItems() { return mWithItems; }
|
||||
|
||||
void SetOverride(const bool value) { mOverride = value; }
|
||||
bool GetOverride() { return mOverride; }
|
||||
|
||||
|
||||
private:
|
||||
char mGameCode[GAMECODE_BUFFER];
|
||||
uchar_t mSourceServerName[SERVER_BUFFER];
|
||||
uchar_t mDestServerName[SERVER_BUFFER];
|
||||
uchar_t mSourceCharacterName[CHARACTER_BUFFER];
|
||||
uchar_t mDestCharacterName[CHARACTER_BUFFER];
|
||||
unsigned mSourceUID;
|
||||
uchar_t mDestStationName[STATION_NAME_BUFFER];
|
||||
uchar_t mDestStationPassword[STATION_PASSWORD_BUFFER];
|
||||
bool mWithItems;
|
||||
bool mOverride;
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
#ifndef REQUESTSTRINGS_H
|
||||
#define REQUESTSTRINGS_H
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include "CTEnum.h"
|
||||
#include <map>
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
static const char * _gamecodeName[] =
|
||||
{
|
||||
"",
|
||||
"SP",
|
||||
"EQ",
|
||||
"EQ2",
|
||||
"SWG",
|
||||
"PS",
|
||||
"EQOA-beta",
|
||||
"EQOA",
|
||||
"EQIM",
|
||||
"EQM"
|
||||
};
|
||||
|
||||
|
||||
#define key_text std::pair<unsigned,const char *>
|
||||
|
||||
// ----- REQUEST NAMES -----
|
||||
|
||||
static const unsigned _RequestCount = 46;
|
||||
|
||||
static const key_text _requestString[_RequestCount] =
|
||||
{
|
||||
// key_text(CTWEB_REQUEST_TEST, "WEB_REQUEST_TEST"),
|
||||
key_text(CTWEB_REQUEST_GET_GAMES, "WEB_REQUEST_GET_GAMES"),
|
||||
key_text(CTWEB_REQUEST_GET_SUBSCRIPTIONS, "WEB_REQUEST_GET_SUBSCRIPTIONS"),
|
||||
key_text(CTWEB_REQUEST_GET_CHARACTERS, "WEB_REQUEST_GET_CHARACTERS"),
|
||||
key_text(CTWEB_REQUEST_GET_SOURCE_SERVERS, "WEB_REQUEST_GET_SOURCE_SERVERS"),
|
||||
key_text(CTWEB_REQUEST_GET_DEST_SERVERS, "WEB_REQUEST_GET_DEST_SERVERS"),
|
||||
key_text(CTWEB_REQUEST_VALIDATE_TRANSACTION,"WEB_REQUEST_VALIDATE_TRANSACTION"),
|
||||
key_text(CTWEB_REQUEST_VALIDATE_ORDER, "WEB_REQUEST_VALIDATE_ORDER"),
|
||||
key_text(CTWEB_REQUEST_SUBMIT_ORDER, "WEB_REQUEST_SUBMIT_ORDER"),
|
||||
key_text(CTWEB_REQUEST_GET_ORDER_STATUS, "WEB_REQUEST_GET_ORDER_STATUS"),
|
||||
key_text(CTWEB_REQUEST_GET_ORDERS_BY_STATION_ID, "WEB_REQUEST_GET_ORDERS_BY_STATION_ID"),
|
||||
key_text(CTWEB_REQUEST_GET_TRANSACTIONS_BY_ORDER_ID, "WEB_REQUEST_GET_TRANSACTIONS_BY_ORDER_ID"),
|
||||
key_text(CTWEB_REQUEST_CSR_MOVE, "WEB_REQUEST_CSR_MOVE"),
|
||||
key_text(CTWEB_REQUEST_CSR_DELETE, "WEB_REQUEST_CSR_DELETE"),
|
||||
key_text(CTWEB_REQUEST_CSR_RESTORE, "WEB_REQUEST_CSR_RESTORE"),
|
||||
key_text(CTWEB_REQUEST_CSR_TRANSFER_ACCOUNT, "WEB_REQUEST_CSR_TRANSFER_ACCOUNT"),
|
||||
|
||||
// key_text(CTGAME_REQUEST_TEST, "GAME_REQUEST_TEST"),
|
||||
key_text(CTGAME_REQUEST_CONNECT, "GAME_REQUEST_CONNECT"),
|
||||
key_text(CTGAME_REPLY_TEST, "GAME_REPLY_TEST"),
|
||||
key_text(CTGAME_SERVER_TEST, "GAME_SERVER_TEST"),
|
||||
key_text(CTGAME_SERVER_MOVESTATUS, "GAME_SERVER_MOVESTATUS"),
|
||||
key_text(CTGAME_REPLY_MOVESTATUS, "GAME_REPLY_MOVESTATUS"),
|
||||
key_text(CTGAME_SERVER_VALIDATEMOVE, "GAME_SERVER_VALIDATEMOVE"),
|
||||
key_text(CTGAME_REPLY_VALIDATEMOVE, "GAME_REPLY_VALIDATEMOVE"),
|
||||
key_text(CTGAME_SERVER_MOVE, "GAME_SERVER_MOVE"),
|
||||
key_text(CTGAME_REPLY_MOVE, "GAME_REPLY_MOVE"),
|
||||
key_text(CTGAME_SERVER_DELETE, "GAME_SERVER_DELETE"),
|
||||
key_text(CTGAME_REPLY_DELETE, "GAME_REPLY_DELETE"),
|
||||
key_text(CTGAME_SERVER_RESTORE, "GAME_SERVER_RESTORE"),
|
||||
key_text(CTGAME_REPLY_RESTORE, "GAME_REPLY_RESTORE"),
|
||||
key_text(CTGAME_SERVER_TRANSFER_ACCOUNT, "GAME_SERVER_TRANSFER_ACCOUNT"),
|
||||
key_text(CTGAME_REPLY_TRANSFER_ACCOUNT, "GAME_REPLY_TRANSFER_ACCOUNT"),
|
||||
key_text(CTGAME_SERVER_CHARACTERLIST, "GAME_SERVER_CHARACTERLIST"),
|
||||
key_text(CTGAME_REPLY_CHARACTERLIST, "GAME_REPLY_CHARACTERLIST"),
|
||||
key_text(CTGAME_SERVER_SERVERLIST, "GAME_SERVER_SERVERLIST"),
|
||||
key_text(CTGAME_REPLY_SERVERLIST, "GAME_REPLY_SERVERLIST"),
|
||||
key_text(CTGAME_SERVER_DESTSERVERLIST, "GAME_SERVER_DESTSERVERLIST"),
|
||||
key_text(CTGAME_REPLY_DESTSERVERLIST, "GAME_REPLY_DESTSERVERLIST"),
|
||||
|
||||
key_text(CTLOGIN_REQUEST_GET_ACCOUNT_STATUS, "LOGIN_REQUEST_GET_ACCOUNT_STATUS"),
|
||||
key_text(CTLOGIN_REQUEST_GET_ACCOUNT_SUBSCRIPTIONS, "LOGIN_REQUEST_GET_ACCOUNT_SUBSCRIPTIONS"),
|
||||
key_text(CTLOGIN_REQUEST_GET_MEMBER_INFO, "LOGIN_REQUEST_GET_MEMBER_INFO"),
|
||||
|
||||
key_text(CTECOMM_REQUEST_VALIDATE_CARD, "ECOMM_REQUEST_VALIDATE_CARD"),
|
||||
key_text(CTECOMM_REQUEST_GET_PRODUCT, "ECOMM_REQUEST_GET_PRODUCT"),
|
||||
key_text(CTECOMM_REQUEST_GET_PRODUCT_LIST, "ECOMM_REQUEST_GET_PRODUCT_LIST"),
|
||||
key_text(CTECOMM_REQUEST_CALUCULATE_ORDER_AMOUNT, "ECOMM_REQUEST_CALUCULATE_ORDER_AMOUNT"),
|
||||
key_text(CTECOMM_REQUEST_GET_PRODUCTS_BY_GAME_AND_TYPE, "ECOMM_REQUEST_GET_PRODUCTS_BY_GAME_AND_TYPE"),
|
||||
key_text(CTECOMM_REQUEST_PREAUTH_ORDER, "ECOMM_REQUEST_PREAUTH_ORDER"),
|
||||
key_text(CTECOMM_REQUEST_DEPOSIT_CREDIT_CARD, "ECOMM_REQUEST_DEPOSIT_CREDIT_CARD"),
|
||||
|
||||
};
|
||||
static std::map<unsigned,const char *> RequestString((const std::map<unsigned,const char *>::value_type *)&_requestString[0],(const std::map<unsigned,const char *>::value_type *)&_requestString[_RequestCount]);
|
||||
|
||||
|
||||
// ----- RESULT CODE NAMES -----
|
||||
|
||||
static const unsigned _ResultCount = 33;
|
||||
static const key_text _resultString[_ResultCount] =
|
||||
{
|
||||
key_text(CT_RESULT_SUCCESS, "SUCCESS"),
|
||||
key_text(CT_RESULT_TIMEOUT, "TIMEOUT"),
|
||||
key_text(CT_RESULT_FAILURE, "FAILURE"),
|
||||
key_text(CT_RESULT_NO_TRANS_IN_ORDER, "NO TRANSACTIONS IN ORDER"),
|
||||
key_text(CT_RESULT_ORDER_FOR_DIFFERENT_GAMES, "NOT ALL TRANSACTIONS IN ORDER HAVE SAME GAMECODE"),
|
||||
key_text(CT_RESULT_ORDER_FOR_DIFFERENT_USERS, "NOT ALL TRANSACTIONS IN ORDER ARE FOR SAME SOURCE UID"),
|
||||
key_text(CT_RESULT_MULTI_TRANS_FOR_CHARACTER, "MULTIPLE TRANSACTIONS EXIST FOR SAME CHARACTER IN A SINGLE ORDER"),
|
||||
key_text(CT_RESULT_1OR_MORE_TRANSACTIONS_FAILED, "ONE OR MORE TRANSACTIONS IN ORDER FAILED"),
|
||||
key_text(CT_RESULT_DEST_STATIONNAME_PASSWORD_INVALID, "INVALID DEST STATIONNAME/PASSWORD COMBO"),
|
||||
key_text(CT_RESULT_SOURCE_STATION_ACCOUNT_NOT_ACTIVE, "SOURCE STATION ACCOUNT NOT ACTIVE"),
|
||||
key_text(CT_RESULT_DEST_STATION_ACCOUNT_NOT_ACTIVE, "DEST STATION ACCOUNT NOT ACTIVE"),
|
||||
key_text(CT_RESULT_SOURCE_UID_INVALID, "SOURCE UID INVALID"),
|
||||
key_text(CT_RESULT_INVALID_UID, "INVALID UID (Source or Dest)"),
|
||||
key_text(CT_RESULT_NOT_SAME_FIRST_NAME_ON_STATION_ACCOUNTS, "SAME FIRST NAME NOT ON BOTH STATION ACCOUNTS"),
|
||||
key_text(CT_RESULT_NOT_SAME_LAST_NAME_ON_STATION_ACCOUNTS, "SAME LAST NAME NOT ON BOTH STATION ACCOUNTS"),
|
||||
key_text(CT_RESULT_NOT_SAME_EMAIL_ON_STATION_ACCOUNTS, "SAME EMAIL NAME NOT ON BOTH STATION ACCOUNTS"),
|
||||
key_text(CT_RESULT_TRANSFER_TO_SAME_ACCOUNT, "ATTEMPT TO TRANSFER TO SAME STATION ACCOUNT"),
|
||||
key_text(CT_RESULT_ALL_REQUIRED_TRANSACTION_INFO_NOT_PROVIDED,"REQUIRED TRANSACTION INFORMATION PASSED IN IS MISSING"),
|
||||
key_text(CT_RESULT_WEB_INFO_DOES_NOT_MATCH_STATION_INFO, "INFORMATION PROVIDED DOES NOT MATCH STATION ACCOUNT INFO"),
|
||||
key_text(CT_RESULT_SOURCE_SUBSCRIPTION_STATUS_NOT_ALLOWED, "CURRENT SOURCE SUBSCRIPTION STATUS IS INVALID FOR THIS TRANSACTION"),
|
||||
key_text(CT_RESULT_DEST_SUBSCRIPTION_STATUS_NOT_ALLOWED, "CURRENT DEST SUBSCRIPTION STATUS IS INVALID FOR THIS TRANSACTION"),
|
||||
key_text(CT_RESULT_BAD_CC_INFO, "ECOMM RETURNED FAIL ON CUSTOMER/CC INFO"),
|
||||
key_text(CT_RESULT_ZIP_FAILED_AVS, "ECOMM RETURNED ZIP_FAILED_AVS"),
|
||||
key_text(CT_RESULT_HARD_DECLINE_ECOMM, "ECOMM RETURNED HARD DECLINE"),
|
||||
key_text(CT_RESULT_HARD_DECLINE_GAME, "GAME RETURNED HARD DECLINE"),
|
||||
key_text(CT_RESULT_SOFT_DECLINE_ECOMM, "ECOMM RETURNED SOFT DECLINE"),
|
||||
key_text(CT_RESULT_SOFT_DECLINE_GAME, "GAME RETURNED SOFT DECLINE"),
|
||||
key_text(CT_RESULT_OTHER_ECOMM_ERROR, "ECOMM RETURNED OTHER ERROR"),
|
||||
key_text(CT_RESULT_INVALID_STOREFRONT, "ECOMM RETURNED INVALID STOREFRONT"),
|
||||
key_text(CT_RESULT_ILLEGAL_TRANSACTION_REQUESTED_FOR_GAME, "TRANSACTION REQUESTED ACTION NOT SUPPORTED BY GAME"),
|
||||
key_text(CT_RESULT_ILLEGAL_GAME_CODE, "ILLEGAL GAME CODE"),
|
||||
key_text(CT_RESULT_UPDATE_ORDER_PRICE_FAILED_TWICE, "FAILED TO UPDATE ORDER PRICE AND STATUS IN DB, ORDER NOT BEING PROCESS"),
|
||||
key_text(CT_RESULT_TRANSACTION_DOES_NOT_DO_ANYTHING, "TRANSACTION DOES NOT DO ANYTHING"),
|
||||
|
||||
|
||||
|
||||
// REMEMBER TO INCREMENT THE _ResultCount ABOVE
|
||||
};
|
||||
|
||||
static std::map<unsigned,const char *> ResultString((const std::map<unsigned,const char *>::value_type *)&_resultString[0],(const std::map<unsigned,const char *>::value_type *)&_resultString[_ResultCount]);
|
||||
|
||||
static const unsigned _ResourceCount = 10;
|
||||
static const key_text _ResourceString[_ResourceCount] =
|
||||
{
|
||||
key_text(CTGAMEAPI_RESOURCE_TEST, "GAME_RESOURCE_TEST"),
|
||||
key_text(CTGAMEAPI_RESOURCE_MOVESTATUS, "GAME_RESOURCE_MOVESTATUS"),
|
||||
key_text(CTGAMEAPI_RESOURCE_VALIDATEMOVE, "GAME_RESOURCE_VALIDATEMOVE"),
|
||||
key_text(CTGAMEAPI_RESOURCE_MOVE, "GAME_RESOURCE_MOVE"),
|
||||
key_text(CTGAMEAPI_RESOURCE_CHARACTERLIST, "GAME_RESOURCE_CHARACTERLIST"),
|
||||
key_text(CTGAMEAPI_RESOURCE_SERVERLIST, "GAME_RESOURCE_SERVERLIST"),
|
||||
key_text(CTGAMEAPI_RESOURCE_DESTSERVERLIST, "GAME_RESOURCE_DESTSERVERLIST"),
|
||||
key_text(CTGAMEAPI_RESOURCE_DELETE, "GAME_RESOURCE_DELETE"),
|
||||
key_text(CTGAMEAPI_RESOURCE_RESTORE, "GAME_RESOURCE_RESTORE"),
|
||||
key_text(CTGAMEAPI_RESOURCE_TRANSFER_ACCOUNT, "GAME_RESOURCE_TRANSFER_ACCOUNT"),
|
||||
};
|
||||
static std::map<unsigned,const char *> ResourceString((const std::map<unsigned,const char *>::value_type *)&_ResourceString[0],(const std::map<unsigned,const char *>::value_type *)&_ResourceString[_ResourceCount]);
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
#include "GenericApiCore.h"
|
||||
#include "GenericConnection.h"
|
||||
#include "GenericMessage.h"
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
using namespace std;
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
//----------------------------------------
|
||||
ServerTrackObject::ServerTrackObject(unsigned mapped_track, unsigned real_track, GenericConnection *con)
|
||||
: m_mappedTrack(mapped_track), m_realTrack(real_track), m_connection(con)
|
||||
//----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
GenericAPICore::GenericAPICore(const char *host,
|
||||
short port,
|
||||
unsigned reqTimeout,
|
||||
unsigned reconnectTimeout,
|
||||
unsigned noDataTimeoutSecs,
|
||||
unsigned noAckTimeoutSecs,
|
||||
unsigned incomingBufSizeInKB,
|
||||
unsigned outgoingBufSizeInKB,
|
||||
unsigned keepAlive,
|
||||
unsigned maxRecvMessageSizeInKB)
|
||||
: m_currTrack(0),
|
||||
m_reconnectTimeout(0),
|
||||
m_outCount(0),
|
||||
m_pendingCount(0),
|
||||
m_requestTimeout(reqTimeout),
|
||||
m_currentConnections(0), m_maxConnections(0),
|
||||
m_suspended(false),
|
||||
m_nextConnectionIndex(0)
|
||||
//----------------------------------------
|
||||
{
|
||||
GenericConnection *con = new GenericConnection(host, port, this, reconnectTimeout, noDataTimeoutSecs, noAckTimeoutSecs, incomingBufSizeInKB, outgoingBufSizeInKB, keepAlive, maxRecvMessageSizeInKB);
|
||||
m_serverConnections.push_back(con);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
GenericAPICore::GenericAPICore(const char *game, const char *hosts[],
|
||||
const short port[],
|
||||
unsigned arraySize,
|
||||
unsigned reqTimeout,
|
||||
unsigned reconnectTimeout,
|
||||
unsigned noDataTimeoutSecs,
|
||||
unsigned noAckTimeoutSecs,
|
||||
unsigned incomingBufSizeInKB,
|
||||
unsigned outgoingBufSizeInKB,
|
||||
unsigned keepAlive,
|
||||
unsigned maxRecvMessageSizeInKB)
|
||||
: m_currTrack(0),
|
||||
m_reconnectTimeout(0),
|
||||
m_outCount(0),
|
||||
m_pendingCount(0),
|
||||
m_requestTimeout(reqTimeout),
|
||||
m_currentConnections(0), m_maxConnections(0),
|
||||
m_suspended(false),
|
||||
m_nextConnectionIndex(0),
|
||||
m_game(game)
|
||||
//----------------------------------------
|
||||
{
|
||||
for (unsigned i=0; i<arraySize; i++)
|
||||
{
|
||||
GenericConnection *con = new GenericConnection(hosts[i], port[i], this, reconnectTimeout, noDataTimeoutSecs, noAckTimeoutSecs, incomingBufSizeInKB, outgoingBufSizeInKB, keepAlive, maxRecvMessageSizeInKB);
|
||||
m_serverConnections.push_back(con);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
GenericAPICore::~GenericAPICore()
|
||||
//----------------------------------------
|
||||
{
|
||||
for (std::vector<GenericConnection *>::iterator conIter = m_serverConnections.begin(); conIter != m_serverConnections.end(); conIter++)
|
||||
{
|
||||
GenericConnection *con = *conIter;
|
||||
delete con;
|
||||
}
|
||||
m_serverConnections.clear();
|
||||
|
||||
for(map<unsigned, GenericResponse *>::iterator iter = m_pending.begin(); iter != m_pending.end(); ++iter)
|
||||
{
|
||||
delete (*iter).second;
|
||||
}
|
||||
|
||||
m_pending.empty();
|
||||
|
||||
while(m_outCount > 0)
|
||||
{
|
||||
delete m_outboundQueue.front().second;
|
||||
delete m_outboundQueue.front().first;
|
||||
m_outboundQueue.pop();
|
||||
--m_outCount;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
unsigned GenericAPICore::submitRequest(GenericRequest *req, GenericResponse *res)
|
||||
//----------------------------------------
|
||||
{
|
||||
++m_outCount;
|
||||
if(m_currTrack == 0)
|
||||
{
|
||||
m_currTrack++;
|
||||
}
|
||||
req->setTrack(m_currTrack);
|
||||
res->setTrack(m_currTrack);
|
||||
time_t timeout = time(NULL) + m_requestTimeout;
|
||||
|
||||
req->setTimeout(timeout);
|
||||
res->setTimeout(timeout);
|
||||
|
||||
m_outboundQueue.push(pair<GenericRequest *, GenericResponse *>(req, res));
|
||||
return(m_currTrack++);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void GenericAPICore::process()
|
||||
//----------------------------------------
|
||||
{
|
||||
GenericRequest *req;
|
||||
GenericResponse *res;
|
||||
|
||||
if (!m_suspended)
|
||||
{
|
||||
// Process timeout on pending requests
|
||||
while((m_outCount > 0) && ((req = m_outboundQueue.front().first)->getTimeout() <= time(NULL)))
|
||||
{
|
||||
--m_outCount;
|
||||
res = m_outboundQueue.front().second;
|
||||
m_outboundQueue.pop();
|
||||
|
||||
responseCallback(res);
|
||||
delete res;
|
||||
delete req;
|
||||
}
|
||||
|
||||
// Process timeout on pending responses
|
||||
while((m_pendingCount > 0) && ((res = (*m_pending.begin()).second)->getTimeout() <= time(NULL)))
|
||||
{
|
||||
--m_pendingCount;
|
||||
m_pending.erase(m_pending.begin());
|
||||
responseCallback(res);
|
||||
delete res;
|
||||
}
|
||||
|
||||
while(m_outCount > 0)
|
||||
{
|
||||
pair<GenericRequest *, GenericResponse *> out_pair = m_outboundQueue.front();
|
||||
req = out_pair.first;
|
||||
res = out_pair.second;
|
||||
GenericConnection *con = NULL;
|
||||
if (req->getMappedServerTrack() == 0) // request has no originating "owner" server
|
||||
{
|
||||
con = getNextActiveConnection(); // it does not matter which server we send this to
|
||||
}
|
||||
else
|
||||
{
|
||||
ServerTrackObject *stobj = findServer(req->getMappedServerTrack());
|
||||
if (stobj)
|
||||
{
|
||||
con = stobj->getConnection(); // the server connection to respond to
|
||||
req->setServerTrack(stobj->getRealServerTrack()); // map server track back to REAL server track
|
||||
//printf("\nUnmapping %d to %d", stobj->getMappedServerTrack(), req->getMappedServerTrack()); //debug
|
||||
delete stobj;
|
||||
}
|
||||
}
|
||||
|
||||
if (con != NULL)
|
||||
{
|
||||
Base::ByteStream msg;
|
||||
req->pack(msg);
|
||||
con->Send(msg);
|
||||
m_pending.insert(pair<unsigned, GenericResponse *>(res->getTrack(), res));
|
||||
--m_outCount;
|
||||
++m_pendingCount;
|
||||
m_outboundQueue.pop();
|
||||
delete req;
|
||||
}
|
||||
else
|
||||
{
|
||||
//no active connections
|
||||
break; //from while loop
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<GenericConnection *>::iterator conIter = m_serverConnections.begin(); conIter != m_serverConnections.end(); conIter++)
|
||||
{
|
||||
GenericConnection *con = *conIter;
|
||||
con->process();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//----------------------------------------
|
||||
GenericConnection *GenericAPICore::getNextActiveConnection()
|
||||
//----------------------------------------
|
||||
{
|
||||
unsigned startIndex = m_nextConnectionIndex;
|
||||
unsigned maxIndex = m_serverConnections.size() - 1;
|
||||
|
||||
GenericConnection *con = NULL;
|
||||
|
||||
//loop until we find an active connection, or until we get back
|
||||
// to where we started
|
||||
do
|
||||
{
|
||||
if (m_serverConnections[m_nextConnectionIndex]->isConnected())
|
||||
{
|
||||
con = m_serverConnections[m_nextConnectionIndex];
|
||||
if (m_nextConnectionIndex == maxIndex)
|
||||
m_nextConnectionIndex = 0;
|
||||
else
|
||||
m_nextConnectionIndex++;
|
||||
|
||||
}
|
||||
else if (++m_nextConnectionIndex > maxIndex)
|
||||
{
|
||||
//went past end of vector, start back at 0
|
||||
m_nextConnectionIndex = 0;
|
||||
}
|
||||
}while (con == NULL && m_nextConnectionIndex != startIndex);
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void GenericAPICore::countOpenConnections()
|
||||
//----------------------------------------
|
||||
{
|
||||
m_currentConnections = 0;
|
||||
m_maxConnections = m_serverConnections.size();
|
||||
|
||||
for (std::vector<GenericConnection *>::iterator conIter = m_serverConnections.begin(); conIter != m_serverConnections.end(); conIter++)
|
||||
{
|
||||
GenericConnection *con = *conIter;
|
||||
if (con->isConnected())
|
||||
++m_currentConnections;
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
ServerTrackObject *GenericAPICore::findServer(unsigned server_track)
|
||||
//----------------------------------------
|
||||
{
|
||||
std::map<unsigned, ServerTrackObject *>::iterator iter = m_serverTracks.find(server_track);
|
||||
if (iter == m_serverTracks.end())
|
||||
return NULL;
|
||||
ServerTrackObject *stobj = (*iter).second;
|
||||
m_serverTracks.erase(server_track);
|
||||
return stobj;
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
+121
@@ -0,0 +1,121 @@
|
||||
#if !defined (GENERICAPICORE_H_)
|
||||
#define GENERICAPICORE_H_
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
#pragma warning (disable: 4786)
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <time.h>
|
||||
#include <Base/Archive.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class GenericRequest;
|
||||
class GenericResponse;
|
||||
class GenericConnection;
|
||||
|
||||
//----------------------------------------------
|
||||
class ServerTrackObject
|
||||
//----------------------------------------------
|
||||
{
|
||||
public:
|
||||
ServerTrackObject(unsigned mapped_track, unsigned real_track, GenericConnection *con);
|
||||
~ServerTrackObject() { }
|
||||
|
||||
inline GenericConnection *getConnection() { return m_connection; }
|
||||
inline unsigned getRealServerTrack() { return m_realTrack; }
|
||||
inline unsigned getMappedServerTrack() { return m_mappedTrack; }
|
||||
|
||||
private:
|
||||
unsigned m_mappedTrack;
|
||||
unsigned m_realTrack;
|
||||
GenericConnection *m_connection;
|
||||
};
|
||||
|
||||
//----------------------------------------------
|
||||
class GenericAPICore
|
||||
//----------------------------------------------
|
||||
{
|
||||
public:
|
||||
friend class GenericConnection;
|
||||
|
||||
GenericAPICore::GenericAPICore(const char *host,
|
||||
short port,
|
||||
unsigned reqTimeout,
|
||||
unsigned reconnectTimeout,
|
||||
unsigned noDataTimeoutSecs = 5,
|
||||
unsigned noAckTimeoutSecs = 5,
|
||||
unsigned incomingBufSizeInKB = 32,
|
||||
unsigned outgoingBufSizeInKB = 32,
|
||||
unsigned keepAlive = 1,
|
||||
unsigned maxRecvMessageSizeInKB = 0);
|
||||
|
||||
/**
|
||||
* NOTE: arraySize must be actual size of host and port arrays.
|
||||
* ALSO: cannot specify a 0 array size.
|
||||
*/
|
||||
GenericAPICore(const char *game, const char *hosts[],
|
||||
const short port[],
|
||||
unsigned arraySize,
|
||||
unsigned reqTimeout,
|
||||
unsigned reconnectTimeout,
|
||||
unsigned noDataTimeoutSecs = 5,
|
||||
unsigned noAckTimeoutSecs = 5,
|
||||
unsigned incomingBufSizeInKB = 32,
|
||||
unsigned outgoingBufSizeInKB = 32,
|
||||
unsigned keepAlive = 1,
|
||||
unsigned maxRecvMessageSizeInKB = 0);
|
||||
|
||||
virtual ~GenericAPICore();
|
||||
|
||||
void process();
|
||||
virtual void responseCallback(short type, Base::ByteStream::ReadIterator &iter, GenericConnection *con) = 0;
|
||||
virtual void responseCallback(GenericResponse *R) = 0;
|
||||
|
||||
virtual void OnDisconnect(GenericConnection *con) = 0;
|
||||
virtual void OnConnect(GenericConnection *con) = 0;
|
||||
|
||||
void countOpenConnections();
|
||||
ServerTrackObject *findServer(unsigned server_track);
|
||||
|
||||
|
||||
void suspendProcessing() { m_suspended = true; }
|
||||
void resumeProcessing() { m_suspended = false; }
|
||||
unsigned submitRequest(GenericRequest *req, GenericResponse *res);
|
||||
GenericConnection *getNextActiveConnection();
|
||||
std::string &getGameCode() { return m_game; }
|
||||
|
||||
protected:
|
||||
std::vector<GenericConnection *> m_serverConnections;
|
||||
std::map<unsigned, GenericResponse *> m_pending;
|
||||
std::queue<std::pair<GenericRequest *, GenericResponse *> > m_outboundQueue;
|
||||
unsigned m_currTrack;
|
||||
time_t m_reconnectTimeout;
|
||||
unsigned m_outCount;
|
||||
unsigned m_pendingCount;
|
||||
unsigned m_requestTimeout;
|
||||
unsigned m_currentConnections; // number currently connected
|
||||
unsigned m_maxConnections; // number that should be connected
|
||||
std::map<unsigned, ServerTrackObject *> m_serverTracks;
|
||||
|
||||
private:
|
||||
bool m_suspended;
|
||||
unsigned m_nextConnectionIndex;
|
||||
std::string m_game;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
+209
@@ -0,0 +1,209 @@
|
||||
#include "GenericApiCore.h"
|
||||
#include "GenericConnection.h"
|
||||
#include "GenericMessage.h"
|
||||
#include "CTCommon/CTEnum.h"
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
using namespace Base;
|
||||
|
||||
GenericConnection::GenericConnection(const char *host, short port, GenericAPICore *apiCore, unsigned reconnectTimeout, unsigned noDataTimeoutSecs, unsigned noAckTimeoutSecs, unsigned incomingBufSizeInKB, unsigned outgoingBufSizeInKB, unsigned keepAlive, unsigned maxRecvMessageSizeInKB)
|
||||
: m_bConnected(CON_NONE),
|
||||
m_apiCore(apiCore),
|
||||
m_con(NULL),
|
||||
m_host(host),
|
||||
m_port(port),
|
||||
m_lastTrack(123455), //random choice != 1
|
||||
m_conState(CON_DISCONNECT),
|
||||
m_reconnectTimeout(reconnectTimeout)
|
||||
{
|
||||
TcpManager::TcpParams params;
|
||||
|
||||
params.incomingBufferSize = incomingBufSizeInKB * 1024;
|
||||
params.outgoingBufferSize = outgoingBufSizeInKB * 1024;
|
||||
params.maxConnections = 1;
|
||||
params.port = 0;
|
||||
params.maxRecvMessageSize = maxRecvMessageSizeInKB*1024;
|
||||
params.keepAliveDelay = keepAlive * 1000;
|
||||
params.noDataTimeout = noDataTimeoutSecs * 1000;
|
||||
//params.oldestUnacknowledgedTimeout = noAckTimeoutSecs * 1000;
|
||||
|
||||
m_manager = new TcpManager(params);
|
||||
}
|
||||
|
||||
GenericConnection::~GenericConnection()
|
||||
{
|
||||
if(m_con)
|
||||
{
|
||||
m_con->SetHandler(NULL);
|
||||
m_con->Disconnect();//don't worry about onterminated being called, we've set it's handler to null, so it wont
|
||||
m_con->Release();
|
||||
}
|
||||
|
||||
m_manager->Release();
|
||||
}
|
||||
|
||||
void GenericConnection::disconnect()
|
||||
{
|
||||
if (m_con)
|
||||
{
|
||||
m_con->Disconnect();
|
||||
//no need to release, since callback to onTerminated releases it, and callback is allways made m_con->Release();
|
||||
m_con = NULL;
|
||||
}
|
||||
m_conState = CON_DISCONNECT;
|
||||
m_bConnected = CON_NONE;
|
||||
}
|
||||
|
||||
void GenericConnection::OnTerminated(TcpConnection *con)
|
||||
{
|
||||
// m_apiCore->OnDisconnect(m_host.c_str(), m_port);
|
||||
m_apiCore->OnDisconnect(this);
|
||||
if(m_con)
|
||||
{
|
||||
m_con->Release();
|
||||
m_con = NULL;
|
||||
}
|
||||
m_conState = CON_DISCONNECT;
|
||||
m_bConnected = CON_NONE;
|
||||
}
|
||||
|
||||
void GenericConnection::OnRoutePacket(TcpConnection *con, const unsigned char *data, int dataLen)
|
||||
{
|
||||
short type;
|
||||
unsigned track;
|
||||
|
||||
ByteStream msg(data, dataLen);
|
||||
ByteStream::ReadIterator iter = msg.begin();
|
||||
|
||||
get(iter, type);
|
||||
get(iter, track);
|
||||
GenericResponse *res = NULL;
|
||||
|
||||
// the following if block is a temporary fix that prevents
|
||||
// a crash with a game team in which they occasionally find
|
||||
// themselves receiving a dupe track in consecutive calls to
|
||||
// OnRoutePacket (which then leads to a callback being called
|
||||
// twice and data being invalid on the second call -> crash!).
|
||||
if (track != 0 &&
|
||||
track == m_lastTrack)
|
||||
{
|
||||
printf("!!! ERROR !!! Got a duplicate track ID %u\n", track);
|
||||
return;
|
||||
}
|
||||
m_lastTrack = track;
|
||||
|
||||
// end temporary fix.
|
||||
|
||||
if(track == 0) // notification message from the server, not as a response to a request from this API
|
||||
{
|
||||
if (type == CTService::CTGAME_REQUEST_CONNECT)
|
||||
{ // this is a special case, for when we have identified our game code to server
|
||||
m_bConnected = CON_IDENTIFIED;
|
||||
m_apiCore->OnConnect(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_apiCore->responseCallback(type, iter, this);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
map<unsigned, GenericResponse *>::iterator mapIter = m_apiCore->m_pending.find(track);
|
||||
|
||||
if(mapIter != m_apiCore->m_pending.end())
|
||||
{
|
||||
res = (*mapIter).second;
|
||||
iter = msg.begin();
|
||||
res->unpack(iter);
|
||||
m_apiCore->responseCallback(res);
|
||||
m_apiCore->m_pendingCount--;
|
||||
m_apiCore->m_pending.erase(mapIter);
|
||||
delete res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GenericConnection::process()
|
||||
{
|
||||
switch(m_conState)
|
||||
{
|
||||
case CON_DISCONNECT:
|
||||
// create connection object, attempting to connect and
|
||||
// checking for connection in next state, CON_NEGOTIATE
|
||||
m_con = m_manager->EstablishConnection(m_host.c_str(), m_port);
|
||||
if(m_con)
|
||||
{
|
||||
m_con->SetHandler(this);
|
||||
m_conState = CON_NEGOTIATE;
|
||||
m_conTimeout = time(NULL) + m_reconnectTimeout;
|
||||
}
|
||||
break;
|
||||
case CON_NEGOTIATE:
|
||||
// check for connection
|
||||
|
||||
if(m_con->GetStatus() == TcpConnection::StatusConnected)
|
||||
{
|
||||
// we're connected
|
||||
m_conState = CON_CONNECT;
|
||||
m_bConnected = CON_CONNECTED;
|
||||
// instead of calling OnConnect() right now, we are going to submit a connection packet
|
||||
// identifying us
|
||||
// m_apiCore->OnConnect(this);
|
||||
Base::ByteStream msg;
|
||||
put(msg, (short)CTService::CTGAME_REQUEST_CONNECT);
|
||||
put(msg, (unsigned)0); // track
|
||||
put(msg, (unsigned)API_VERSION_CODE);
|
||||
put(msg, m_apiCore->getGameCode());
|
||||
Send(msg);
|
||||
}
|
||||
else if(time(NULL) > m_conTimeout)
|
||||
{
|
||||
// we did not connect
|
||||
m_con->Disconnect();
|
||||
//no need to release, since callback to onTerminated releases it, and callback is allways made m_con->Release();
|
||||
m_con = NULL;
|
||||
m_conState = CON_DISCONNECT;
|
||||
m_bConnected = CON_NONE;
|
||||
}
|
||||
break;
|
||||
case CON_CONNECT:
|
||||
// do nothing
|
||||
break;
|
||||
default:
|
||||
// this should not occur, but we revert to CON_DISCONNECT if it does
|
||||
m_conState = CON_DISCONNECT;
|
||||
m_bConnected = CON_NONE;
|
||||
if (m_con)
|
||||
{
|
||||
m_con->Disconnect();
|
||||
//no need to release, since callback to onTerminated releases it, and callback is allways made m_con->Release();
|
||||
m_con = NULL;
|
||||
}
|
||||
}
|
||||
m_manager->GiveTime();
|
||||
}
|
||||
|
||||
void GenericConnection::Send(Base::ByteStream &msg)
|
||||
{
|
||||
if(m_con && m_con->GetStatus() == TcpConnection::StatusConnected)
|
||||
{
|
||||
m_con->Send((const char *)msg.getBuffer(), msg.getSize());
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
+81
@@ -0,0 +1,81 @@
|
||||
#if !defined (GENERICCONNECTION_H_)
|
||||
#define GENERICCONNECTION_H_
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
#include <Base/Archive.h>
|
||||
#include <TcpLibrary/TcpManager.h>
|
||||
#include <TcpLibrary/TcpConnection.h>
|
||||
#include <TcpLibrary/TcpHandlers.h>
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
static const unsigned API_VERSION_CODE = 1;
|
||||
|
||||
enum eConState
|
||||
{
|
||||
CON_DISCONNECT,
|
||||
CON_NEGOTIATE,
|
||||
CON_CONNECT
|
||||
};
|
||||
enum eConnectStatus
|
||||
{
|
||||
CON_NONE,
|
||||
CON_CONNECTED,
|
||||
CON_IDENTIFIED
|
||||
};
|
||||
|
||||
class GenericConnection : public TcpConnectionHandler
|
||||
{
|
||||
public:
|
||||
GenericConnection(const char *host,
|
||||
short port,
|
||||
GenericAPICore *apiCore,
|
||||
unsigned reconnectTimeout,
|
||||
unsigned noDataTimeoutSecs = 5,
|
||||
unsigned noAckTimeoutSecs = 5,
|
||||
unsigned incomingBufSizeInKB = 32,
|
||||
unsigned outgoingBufSizeInKB = 32,
|
||||
unsigned keepAlive = 1,
|
||||
unsigned maxRecvMessageSizeInKB = 0);
|
||||
|
||||
virtual ~GenericConnection();
|
||||
|
||||
virtual void OnRoutePacket(TcpConnection *con, const unsigned char *data, int dataLen);
|
||||
virtual void OnTerminated(TcpConnection *con);
|
||||
void Send(Base::ByteStream &msg);
|
||||
inline const char *getHost() const { return m_host.c_str(); }
|
||||
inline const short getPort() const { return m_port; }
|
||||
|
||||
inline eConnectStatus isConnected() { return m_bConnected; }
|
||||
void disconnect();
|
||||
void process();
|
||||
|
||||
private:
|
||||
eConnectStatus m_bConnected;
|
||||
GenericAPICore *m_apiCore;
|
||||
TcpManager *m_manager;
|
||||
TcpConnection *m_con;
|
||||
std::string m_host;
|
||||
short m_port;
|
||||
unsigned m_lastTrack;
|
||||
eConState m_conState;
|
||||
time_t m_conTimeout;
|
||||
unsigned m_reconnectTimeout;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#include "GenericMessage.h"
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
|
||||
#endif
|
||||
|
||||
using namespace Base;
|
||||
|
||||
//-------------------------------------------
|
||||
GenericRequest::GenericRequest(short type, unsigned server_track)
|
||||
: m_type(type), m_server_track(server_track)
|
||||
//-------------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
GenericResponse::GenericResponse(short type, unsigned result, void *user)
|
||||
: m_type(type), m_result(result), m_user(user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void GenericResponse::unpack(ByteStream::ReadIterator &iter)
|
||||
//-----------------------------------------
|
||||
{
|
||||
get(iter, m_type);
|
||||
get(iter, m_track);
|
||||
get(iter, m_result);
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
#if !defined (GENERICMESSAGE_H_)
|
||||
#define GENERICMESSAGE_H_
|
||||
|
||||
//----------------------------------------
|
||||
//
|
||||
// WARNING: These files are NOT standard generic API files
|
||||
// They have been modified for this project.
|
||||
// Do NOT replace them with generic API files
|
||||
//
|
||||
//----------------------------------------
|
||||
|
||||
#include <time.h>
|
||||
#include <Base/Archive.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
//-------------------------------------------
|
||||
class GenericRequest
|
||||
//-------------------------------------------
|
||||
{
|
||||
public:
|
||||
GenericRequest(short type, unsigned server_track = 0);
|
||||
virtual ~GenericRequest() {};
|
||||
|
||||
virtual void pack(Base::ByteStream &msg) = 0;
|
||||
short getType() const { return m_type; }
|
||||
void setTimeout(time_t t) { m_timeout = t; }
|
||||
time_t getTimeout() { return m_timeout; }
|
||||
void setTrack(unsigned t) { m_track = t; }
|
||||
unsigned getTrack() const { return m_track; }
|
||||
inline const unsigned getMappedServerTrack() const { return m_server_track; }
|
||||
inline void setServerTrack(unsigned track) { m_server_track = track; }
|
||||
|
||||
protected:
|
||||
short m_type;
|
||||
unsigned m_track;
|
||||
time_t m_timeout;
|
||||
unsigned m_server_track;
|
||||
};
|
||||
|
||||
// Basic response message from server. In the case that this response to a request
|
||||
// submitted from this API, the response would have been generated at request submission
|
||||
// time, and the timeout value filled in appropriatly
|
||||
//-------------------------------------------
|
||||
class GenericResponse
|
||||
//-------------------------------------------
|
||||
{
|
||||
public:
|
||||
GenericResponse(short type, unsigned result, void *user);
|
||||
virtual ~GenericResponse() {};
|
||||
virtual void unpack(Base::ByteStream::ReadIterator &iter);
|
||||
|
||||
short getType() const { return m_type; }
|
||||
void setTimeout(time_t t) { m_timeout = t; }
|
||||
time_t getTimeout() { return m_timeout; }
|
||||
void setTrack(unsigned t) { m_track = t; }
|
||||
unsigned getTrack() const { return m_track; }
|
||||
unsigned getResult() const { return m_result; }
|
||||
void setResult(unsigned res) { m_result = res; }
|
||||
void * getUser() const { return m_user; }
|
||||
protected:
|
||||
short m_type;
|
||||
unsigned m_track;
|
||||
unsigned m_result;
|
||||
void *m_user;
|
||||
time_t m_timeout;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif
|
||||
@@ -0,0 +1,187 @@
|
||||
#pragma warning (disable : 4786)
|
||||
//test
|
||||
#include <string.h>
|
||||
#include "CTServiceAPI.h"
|
||||
#include "CTServiceAPICore.h"
|
||||
#include "Request.h"
|
||||
#include "Response.h"
|
||||
|
||||
const unsigned short EMPTY_STRING[1] = { 0 };
|
||||
const char * DEFAULT_GAMECODE = "ZZZ";
|
||||
const char * DEFAULT_HOST = "ctservice.station.sony.com";
|
||||
const unsigned short DEFAULT_PORT = 2000;
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
using namespace Base;
|
||||
|
||||
//-----------------------------------------------
|
||||
CTServiceAPI::CTServiceAPI(const char *hostName, const char *game)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
std::vector<const char *> hostArray;
|
||||
std::vector<short> portArray;
|
||||
char hostConfig[4096];
|
||||
if (hostName == NULL)
|
||||
hostName = DEFAULT_HOST;
|
||||
if (!game)
|
||||
game = DEFAULT_GAMECODE;
|
||||
strncpy(hostConfig, hostName, 4096); hostConfig[4095] = 0;
|
||||
if (char * ptr = strtok(hostConfig, " "))
|
||||
{
|
||||
do
|
||||
{
|
||||
char * host = ptr;
|
||||
char * portStr = strchr(host, ':');
|
||||
unsigned short port = DEFAULT_PORT;
|
||||
if (portStr)
|
||||
{
|
||||
*portStr++ = 0;
|
||||
port = atoi(portStr);
|
||||
}
|
||||
|
||||
if (::strlen(host) && port)
|
||||
{
|
||||
hostArray.push_back(host);
|
||||
portArray.push_back(port);
|
||||
}
|
||||
}
|
||||
while ((ptr = strtok(NULL, " ")) != NULL);
|
||||
}
|
||||
if (hostArray.empty())
|
||||
{
|
||||
hostArray.push_back(DEFAULT_HOST);
|
||||
portArray.push_back(DEFAULT_PORT);
|
||||
}
|
||||
m_apiCore = new CTServiceAPICore(&hostArray[0], &portArray[0], hostArray.size(), this, game);
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
CTServiceAPI::~CTServiceAPI()
|
||||
//-----------------------------------------------
|
||||
{
|
||||
delete m_apiCore;
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------
|
||||
void CTServiceAPI::process()
|
||||
//-----------------------------------------------
|
||||
{
|
||||
m_apiCore->process();
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
//
|
||||
// Add requests and replies here
|
||||
//
|
||||
//-----------------------------------------------
|
||||
/*
|
||||
//----------- TEST CODE ONLY ------------
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::requestTest(const char *astring, const unsigned anint, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
std::string s_astring = astring;
|
||||
ReqTest *req = new ReqTest(s_astring, anint);
|
||||
return (m_apiCore->submitRequest(req, new ResTest(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyTest(const unsigned server_track, const unsigned value, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
ReqReplyTest *req = new ReqReplyTest(server_track, value);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyTest(user)));
|
||||
}
|
||||
//----------- TEST CODE ONLY ------------
|
||||
*/
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyMoveStatus(const unsigned server_track, const unsigned status, const unsigned result, const CTUnicodeChar *reason, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
ReqReplyMoveStatus *req = new ReqReplyMoveStatus(server_track, status, result, reason);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyMoveStatus(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyValidateMove(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, const CTUnicodeChar *suggestedName, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
if (!suggestedName)
|
||||
suggestedName = EMPTY_STRING;
|
||||
ReqReplyValidateMove *req = new ReqReplyValidateMove(server_track, result, reason, suggestedName);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyValidateMove(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyMove(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
ReqReplyMove *req = new ReqReplyMove(server_track, result, reason);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyMove(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyDelete(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
ReqReplyDelete *req = new ReqReplyDelete(server_track, result, reason);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyDelete(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyRestore(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
ReqReplyRestore *req = new ReqReplyRestore(server_track, result, reason);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyRestore(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyTransferAccount(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
if (!reason)
|
||||
reason = EMPTY_STRING;
|
||||
ReqReplyTransferAccount *req = new ReqReplyTransferAccount(server_track, result, reason);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyTransferAccount(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyCharacterList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceCharacter *characters, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
ReqReplyCharacterList *req = new ReqReplyCharacterList(server_track, result, count, characters);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyCharacterList(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyServerList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
ReqReplyServerList *req = new ReqReplyServerList(server_track, result, count, servers);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyServerList(user)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------
|
||||
unsigned CTServiceAPI::replyDestinationServerList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers, void *user)
|
||||
//-----------------------------------------------
|
||||
{
|
||||
ReqReplyDestinationServerList *req = new ReqReplyDestinationServerList(server_track, result, count, servers);
|
||||
return (m_apiCore->submitRequest(req, new ResReplyDestinationServerList(user)));
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
@@ -0,0 +1,112 @@
|
||||
#ifndef CTSERVICEAPI_H
|
||||
#define CTSERVICEAPI_H
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include "CTCommon/CTServiceCharacter.h"
|
||||
#include "CTCommon/CTServiceServer.h"
|
||||
#include "CTCommon/CTEnum.h"
|
||||
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
class CTServiceAPICore;
|
||||
|
||||
typedef unsigned short CTUnicodeChar;
|
||||
|
||||
//--------------------------------------
|
||||
class CTServiceAPI
|
||||
//--------------------------------------
|
||||
{
|
||||
public:
|
||||
CTServiceAPI(const char *hostName, const char *game); // hostName: "addr1:port1 addr2:port2"
|
||||
virtual ~CTServiceAPI();
|
||||
|
||||
virtual void onConnect(const char *host, const short port, const short current, const short max) = 0;
|
||||
virtual void onDisconnect(const char *host, const short port, const short current, const short max) = 0;
|
||||
void process();
|
||||
|
||||
// ----- Requests generated by API -----
|
||||
|
||||
// unsigned requestTest(const char *astring, const unsigned anint, void *user);
|
||||
// unsigned replyTest(const unsigned server_track, const unsigned value, void *user);
|
||||
unsigned replyMoveStatus(const unsigned server_track, const unsigned status, const unsigned result, const CTUnicodeChar *reason, void *user);
|
||||
unsigned replyValidateMove(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, const CTUnicodeChar *suggestedName, void *user);
|
||||
unsigned replyMove(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user);
|
||||
unsigned replyCharacterList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceCharacter *characters, void *user);
|
||||
unsigned replyServerList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers, void *user);
|
||||
unsigned replyDestinationServerList(const unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers, void *user);
|
||||
unsigned replyDelete(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user);
|
||||
unsigned replyRestore(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user);
|
||||
unsigned replyTransferAccount(const unsigned server_track, const unsigned result, const CTUnicodeChar *reason, void *user);
|
||||
|
||||
// ----- Normal Callbacks as a response to requests sent -----
|
||||
|
||||
// virtual void onTest(const unsigned track, const int resultCode, const unsigned value, void *user) = 0;
|
||||
// virtual void onReplyTest(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyMoveStatus(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyValidateMove(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyMove(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyDelete(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyRestore(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyTransferAccount(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyCharacterList(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyServerList(const unsigned track, const int resultCode, void *user) = 0;
|
||||
virtual void onReplyDestinationServerList(const unsigned track, const int resultCode, void *user) = 0;
|
||||
|
||||
// ----- Callbacks generated by the server directly -----
|
||||
|
||||
virtual void onServerTest(const unsigned server_track, const char *game, const char *param) = 0;
|
||||
virtual void onRequestMoveStatus(const unsigned server_track, const char *language,
|
||||
const unsigned transactionID) = 0;
|
||||
virtual void onRequestValidateMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, bool withItems, bool override) = 0;
|
||||
virtual void onRequestMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID,
|
||||
bool withItems,
|
||||
bool override) = 0;
|
||||
virtual void onRequestDelete(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID,
|
||||
bool withItems,
|
||||
bool override) = 0;
|
||||
virtual void onRequestRestore(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID,
|
||||
bool withItems,
|
||||
bool override) = 0;
|
||||
virtual void onRequestTransferAccount(const unsigned server_track,
|
||||
const unsigned uid,
|
||||
const unsigned destuid,
|
||||
const unsigned transactionID) = 0;
|
||||
virtual void onRequestCharacterList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *server, const unsigned uid) = 0;
|
||||
virtual void onRequestServerList(const unsigned server_track, const char *language) = 0;
|
||||
virtual void onRequestDestinationServerList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *character, const CTUnicodeChar *server) = 0;
|
||||
|
||||
private:
|
||||
CTServiceAPICore *m_apiCore;
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //CTSERVICEAPI_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
#include "CTServiceAPICore.h"
|
||||
#include "CTServiceAPI.h"
|
||||
#include "Response.h"
|
||||
#include <Unicode/UnicodeUtils.h>
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
using namespace Base;
|
||||
using namespace Plat_Unicode;
|
||||
|
||||
//----------------------------------------
|
||||
CTServiceAPICore::CTServiceAPICore(const char *host[], const short port[], int count, CTServiceAPI *api, const char *game)
|
||||
: GenericAPICore(game, host, port, count, 45, 5, 0, 90, 32, 32),
|
||||
m_api(api), m_mappedServerTrack(1000)
|
||||
//----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
CTServiceAPICore::~CTServiceAPICore()
|
||||
//----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void CTServiceAPICore::OnConnect(GenericConnection *con)
|
||||
//----------------------------------------
|
||||
{
|
||||
countOpenConnections();
|
||||
m_api->onConnect(con->getHost(), con->getPort(), m_currentConnections, m_maxConnections);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void CTServiceAPICore::OnDisconnect(GenericConnection *con)
|
||||
//----------------------------------------
|
||||
{
|
||||
countOpenConnections();
|
||||
m_api->onDisconnect(con->getHost(), con->getPort(), m_currentConnections, m_maxConnections);
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void CTServiceAPICore::responseCallback(short type, Base::ByteStream::ReadIterator &iter, GenericConnection *con)
|
||||
// Received a request/notification from the server
|
||||
//----------------------------------------
|
||||
{
|
||||
unsigned real_server_track;
|
||||
get(iter, real_server_track);
|
||||
ServerTrackObject *stobj = new ServerTrackObject(++m_mappedServerTrack, real_server_track, con);
|
||||
m_serverTracks.insert(std::pair<unsigned, ServerTrackObject *>(m_mappedServerTrack, stobj));
|
||||
//printf("\nMapping %d to %d", real_server_track, m_mappedServerTrack); //debug
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case CTGAME_SERVER_TEST:
|
||||
{
|
||||
std::string game, param;
|
||||
get(iter, game);
|
||||
get(iter, param);
|
||||
m_api->onServerTest(m_mappedServerTrack, game.c_str(), param.c_str());
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_MOVESTATUS:
|
||||
{
|
||||
std::string lang;
|
||||
unsigned transactionID;
|
||||
get(iter, lang);
|
||||
get(iter, transactionID);
|
||||
m_api->onRequestMoveStatus(m_mappedServerTrack, lang.c_str(), transactionID);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_VALIDATEMOVE:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String sourceServer, destServer, sourceCharacter, destCharacter;
|
||||
unsigned UID, destUID;
|
||||
bool withItems;
|
||||
bool override;
|
||||
get(iter, lang);
|
||||
get(iter, sourceServer);
|
||||
get(iter, destServer);
|
||||
get(iter, sourceCharacter);
|
||||
get(iter, destCharacter);
|
||||
get(iter, UID);
|
||||
get(iter, destUID);
|
||||
get(iter, withItems);
|
||||
get(iter, override);
|
||||
m_api->onRequestValidateMove(m_mappedServerTrack, lang.c_str(), sourceServer.c_str(), destServer.c_str(),
|
||||
sourceCharacter.c_str(), destCharacter.c_str(), UID, destUID, withItems, override);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_MOVE:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String sourceServer, destServer, sourceCharacter, destCharacter;
|
||||
unsigned UID, destUID, transactionID;
|
||||
bool withItems;
|
||||
bool override;
|
||||
get(iter, lang);
|
||||
get(iter, sourceServer);
|
||||
get(iter, destServer);
|
||||
get(iter, sourceCharacter);
|
||||
get(iter, destCharacter);
|
||||
get(iter, UID);
|
||||
get(iter, destUID);
|
||||
get(iter, transactionID);
|
||||
get(iter, withItems);
|
||||
get(iter, override);
|
||||
m_api->onRequestMove(m_mappedServerTrack, lang.c_str(), sourceServer.c_str(), destServer.c_str(),
|
||||
sourceCharacter.c_str(), destCharacter.c_str(), UID, destUID, transactionID, withItems, override);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_DELETE:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String sourceServer, destServer, sourceCharacter, destCharacter;
|
||||
unsigned UID, destUID, transactionID;
|
||||
bool withItems;
|
||||
bool override;
|
||||
get(iter, lang);
|
||||
get(iter, sourceServer);
|
||||
get(iter, destServer);
|
||||
get(iter, sourceCharacter);
|
||||
get(iter, destCharacter);
|
||||
get(iter, UID);
|
||||
get(iter, destUID);
|
||||
get(iter, transactionID);
|
||||
get(iter, withItems);
|
||||
get(iter, override);
|
||||
m_api->onRequestDelete(m_mappedServerTrack, lang.c_str(), sourceServer.c_str(), destServer.c_str(),
|
||||
sourceCharacter.c_str(), destCharacter.c_str(), UID, destUID, transactionID, withItems, override);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_RESTORE:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String sourceServer, destServer, sourceCharacter, destCharacter;
|
||||
unsigned UID, destUID, transactionID;
|
||||
bool withItems;
|
||||
bool override;
|
||||
get(iter, lang);
|
||||
get(iter, sourceServer);
|
||||
get(iter, destServer);
|
||||
get(iter, sourceCharacter);
|
||||
get(iter, destCharacter);
|
||||
get(iter, UID);
|
||||
get(iter, destUID);
|
||||
get(iter, transactionID);
|
||||
get(iter, withItems);
|
||||
get(iter, override);
|
||||
m_api->onRequestRestore(m_mappedServerTrack, lang.c_str(), sourceServer.c_str(), destServer.c_str(),
|
||||
sourceCharacter.c_str(), destCharacter.c_str(), UID, destUID, transactionID, withItems, override);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_TRANSFER_ACCOUNT:
|
||||
{
|
||||
unsigned UID, destUID, transactionID;
|
||||
get(iter, UID);
|
||||
get(iter, destUID);
|
||||
get(iter, transactionID);
|
||||
m_api->onRequestTransferAccount(m_mappedServerTrack, UID, destUID, transactionID);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_CHARACTERLIST:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String server;
|
||||
unsigned uid;
|
||||
get(iter, lang);
|
||||
get(iter, server);
|
||||
get(iter, uid);
|
||||
m_api->onRequestCharacterList(m_mappedServerTrack, lang.c_str(), server.c_str(), uid);
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_SERVERLIST:
|
||||
{
|
||||
std::string lang;
|
||||
get(iter, lang);
|
||||
m_api->onRequestServerList(m_mappedServerTrack, lang.c_str());
|
||||
break;
|
||||
}
|
||||
case CTGAME_SERVER_DESTSERVERLIST:
|
||||
{
|
||||
std::string lang;
|
||||
Plat_Unicode::String character, server;
|
||||
get(iter, lang);
|
||||
get(iter, character);
|
||||
get(iter, server);
|
||||
m_api->onRequestDestinationServerList(m_mappedServerTrack, lang.c_str(), character.c_str(), server.c_str());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------
|
||||
void CTServiceAPICore::responseCallback(GenericResponse *res)
|
||||
//----------------------------------------
|
||||
{
|
||||
switch(res->getType())
|
||||
{
|
||||
/*case CTGAME_REQUEST_TEST:
|
||||
m_api->onTest(((ResTest *)res)->getTrack(), ((ResTest *)res)->getResult(),
|
||||
((ResTest *)res)->getValue(), ((ResTest *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_TEST:
|
||||
m_api->onReplyTest(((ResTest *)res)->getTrack(), ((ResTest *)res)->getResult(),
|
||||
((ResTest *)res)->getUser());
|
||||
break;*/
|
||||
case CTGAME_REPLY_MOVESTATUS:
|
||||
m_api->onReplyMoveStatus(((ResReplyMoveStatus *)res)->getTrack(),
|
||||
((ResReplyMoveStatus *)res)->getResult(),
|
||||
((ResReplyMoveStatus *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_VALIDATEMOVE:
|
||||
m_api->onReplyValidateMove(((ResReplyValidateMove *)res)->getTrack(),
|
||||
((ResReplyValidateMove *)res)->getResult(),
|
||||
((ResReplyValidateMove *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_MOVE:
|
||||
m_api->onReplyMove(((ResReplyMove *)res)->getTrack(),
|
||||
((ResReplyMove *)res)->getResult(),
|
||||
((ResReplyMove *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_DELETE:
|
||||
m_api->onReplyDelete(((ResReplyDelete *)res)->getTrack(),
|
||||
((ResReplyDelete *)res)->getResult(),
|
||||
((ResReplyDelete *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_RESTORE:
|
||||
m_api->onReplyRestore(((ResReplyRestore *)res)->getTrack(),
|
||||
((ResReplyRestore *)res)->getResult(),
|
||||
((ResReplyRestore *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_TRANSFER_ACCOUNT:
|
||||
m_api->onReplyTransferAccount(((ResReplyTransferAccount *)res)->getTrack(),
|
||||
((ResReplyTransferAccount *)res)->getResult(),
|
||||
((ResReplyTransferAccount *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_CHARACTERLIST:
|
||||
m_api->onReplyCharacterList(((ResReplyCharacterList *)res)->getTrack(),
|
||||
((ResReplyCharacterList *)res)->getResult(),
|
||||
((ResReplyCharacterList *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_SERVERLIST:
|
||||
m_api->onReplyServerList(((ResReplyServerList *)res)->getTrack(),
|
||||
((ResReplyServerList *)res)->getResult(),
|
||||
((ResReplyServerList *)res)->getUser());
|
||||
break;
|
||||
case CTGAME_REPLY_DESTSERVERLIST:
|
||||
m_api->onReplyDestinationServerList(((ResReplyDestinationServerList *)res)->getTrack(),
|
||||
((ResReplyDestinationServerList *)res)->getResult(),
|
||||
((ResReplyDestinationServerList *)res)->getUser());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
@@ -0,0 +1,39 @@
|
||||
#ifndef APICORE_H
|
||||
#define APICORE_H
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include "CTGenericAPI/GenericApiCore.h"
|
||||
#include "CTGenericAPI/GenericConnection.h"
|
||||
#include <Base/Archive.h>
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
class CTServiceAPI;
|
||||
|
||||
//---------------------------------------------------
|
||||
class CTServiceAPICore : public GenericAPICore
|
||||
//---------------------------------------------------
|
||||
{
|
||||
public:
|
||||
CTServiceAPICore(const char *hostName[], const short port[], int count, CTServiceAPI *api, const char *game);
|
||||
virtual ~CTServiceAPICore();
|
||||
|
||||
void OnConnect(GenericConnection *con);
|
||||
void OnDisconnect(GenericConnection *con);
|
||||
void responseCallback(GenericResponse *res);
|
||||
void responseCallback(short type, Base::ByteStream::ReadIterator &iter, GenericConnection *con);
|
||||
|
||||
|
||||
private:
|
||||
CTServiceAPI *m_api;
|
||||
unsigned m_mappedServerTrack;
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //APICORE_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
#include "Request.h"
|
||||
#include "CTCommon/CTServiceObjects.h"
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
using namespace Base;
|
||||
using namespace Plat_Unicode;
|
||||
|
||||
/*
|
||||
//----------- TEST CODE ONLY ------------
|
||||
//-----------------------------------------
|
||||
ReqTest::ReqTest(std::string &astring, unsigned anint)
|
||||
: GenericRequest(CTGAME_REQUEST_TEST),
|
||||
m_astring(astring), m_anint(anint)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqTest::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_astring);
|
||||
put(msg, m_anint);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyTest::ReqReplyTest(unsigned server_track, unsigned value)
|
||||
: GenericRequest(CTGAME_REPLY_TEST, server_track),
|
||||
m_value(value)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyTest::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_value);
|
||||
}
|
||||
//----------- TEST CODE ONLY ------------
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyMoveStatus::ReqReplyMoveStatus(unsigned server_track, const unsigned status, const unsigned result, const CTUnicodeChar *reason)
|
||||
: GenericRequest(CTGAME_REPLY_MOVESTATUS, server_track),
|
||||
m_status(status), m_result(result), m_reason(reason)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyMoveStatus::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_status);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyValidateMove::ReqReplyValidateMove(unsigned server_track, const unsigned result, const CTUnicodeChar *reason, const CTUnicodeChar *suggestedName)
|
||||
: GenericRequest(CTGAME_REPLY_VALIDATEMOVE, server_track),
|
||||
m_result(result), m_reason(reason), m_suggestedName(suggestedName)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyValidateMove::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
put(msg, m_suggestedName);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyMove::ReqReplyMove(unsigned server_track, const unsigned result, const CTUnicodeChar *reason)
|
||||
: GenericRequest(CTGAME_REPLY_MOVE, server_track),
|
||||
m_result(result), m_reason(reason)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyMove::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyDelete::ReqReplyDelete(unsigned server_track, const unsigned result, const CTUnicodeChar *reason)
|
||||
: GenericRequest(CTGAME_REPLY_DELETE, server_track),
|
||||
m_result(result), m_reason(reason)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyDelete::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyRestore::ReqReplyRestore(unsigned server_track, const unsigned result, const CTUnicodeChar *reason)
|
||||
: GenericRequest(CTGAME_REPLY_RESTORE, server_track),
|
||||
m_result(result), m_reason(reason)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyRestore::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyTransferAccount::ReqReplyTransferAccount(unsigned server_track, const unsigned result, const CTUnicodeChar *reason)
|
||||
: GenericRequest(CTGAME_REPLY_TRANSFER_ACCOUNT, server_track),
|
||||
m_result(result), m_reason(reason)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyTransferAccount::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_reason);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyCharacterList::ReqReplyCharacterList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceCharacter *characters)
|
||||
: GenericRequest(CTGAME_REPLY_CHARACTERLIST, server_track),
|
||||
m_result(result), m_count(count)
|
||||
//-----------------------------------------
|
||||
{
|
||||
for (unsigned i=0; i < count; i++)
|
||||
{
|
||||
m_characterArray.push_back(characters[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyCharacterList::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_count);
|
||||
for (unsigned i=0; i < m_count; i++)
|
||||
put(msg, m_characterArray[i]);
|
||||
printf("\nReqReplyCharacterList::pack: m_track(%d) m_server_track(%d)\n", m_track, m_server_track);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyServerList::ReqReplyServerList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers)
|
||||
: GenericRequest(CTGAME_REPLY_SERVERLIST, server_track),
|
||||
m_result(result), m_count(count)
|
||||
//-----------------------------------------
|
||||
{
|
||||
for (unsigned i=0; i < count; i++)
|
||||
{
|
||||
m_serverArray.push_back(servers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyServerList::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_count);
|
||||
for (unsigned i=0; i < m_count; i++)
|
||||
put(msg, m_serverArray[i]);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ReqReplyDestinationServerList::ReqReplyDestinationServerList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers)
|
||||
: GenericRequest(CTGAME_REPLY_DESTSERVERLIST, server_track),
|
||||
m_result(result), m_count(count)
|
||||
//-----------------------------------------
|
||||
{
|
||||
for (unsigned i=0; i < count; i++)
|
||||
{
|
||||
m_serverArray.push_back(servers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ReqReplyDestinationServerList::pack(Base::ByteStream &msg)
|
||||
//-----------------------------------------
|
||||
{
|
||||
put(msg, m_type);
|
||||
put(msg, m_track);
|
||||
put(msg, m_server_track);
|
||||
put(msg, m_result);
|
||||
put(msg, m_count);
|
||||
for (unsigned i=0; i < m_count; i++)
|
||||
put(msg, m_serverArray[i]);
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
@@ -0,0 +1,193 @@
|
||||
#if !defined (REQUEST_H_)
|
||||
#define REQUEST_H_
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include "CTGenericAPI/GenericMessage.h"
|
||||
#include <Base/Archive.h>
|
||||
#include <Unicode/UnicodeUtils.h>
|
||||
#include "CTServiceAPI.h"
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
/*
|
||||
//----------- TEST CODE ONLY ------------
|
||||
//-----------------------------------------
|
||||
class ReqTest : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqTest(std::string &astring, unsigned anint);
|
||||
virtual ~ReqTest() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
std::string m_astring;
|
||||
unsigned m_anint;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyTest : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyTest(unsigned server_track, unsigned value);
|
||||
virtual ~ReqReplyTest() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_value;
|
||||
};
|
||||
//----------- TEST CODE ONLY ------------
|
||||
*/
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyMoveStatus : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyMoveStatus(unsigned server_track, const unsigned status, const unsigned result, const CTUnicodeChar *reason);
|
||||
virtual ~ReqReplyMoveStatus() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_status;
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyValidateMove : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyValidateMove(unsigned server_track, const unsigned result, const CTUnicodeChar *reason, const CTUnicodeChar *suggestedName);
|
||||
virtual ~ReqReplyValidateMove() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
Plat_Unicode::String m_suggestedName;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyMove : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyMove(unsigned server_track, const unsigned result, const CTUnicodeChar *reason);
|
||||
virtual ~ReqReplyMove() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyDelete : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyDelete(unsigned server_track, const unsigned result, const CTUnicodeChar *reason);
|
||||
virtual ~ReqReplyDelete() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyRestore : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyRestore(unsigned server_track, const unsigned result, const CTUnicodeChar *reason);
|
||||
virtual ~ReqReplyRestore() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyTransferAccount : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyTransferAccount(unsigned server_track, const unsigned result, const CTUnicodeChar *reason);
|
||||
virtual ~ReqReplyTransferAccount() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
Plat_Unicode::String m_reason;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyCharacterList : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyCharacterList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceCharacter *characters);
|
||||
virtual ~ReqReplyCharacterList() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
unsigned m_count;
|
||||
std::vector<CTServiceCharacter> m_characterArray;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyServerList : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyServerList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers);
|
||||
virtual ~ReqReplyServerList() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
unsigned m_count;
|
||||
std::vector<CTServiceServer> m_serverArray;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ReqReplyDestinationServerList : public GenericRequest
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ReqReplyDestinationServerList(unsigned server_track, const unsigned result, const unsigned count, const CTServiceServer *servers);
|
||||
virtual ~ReqReplyDestinationServerList() {};
|
||||
|
||||
void pack(Base::ByteStream &msg);
|
||||
|
||||
private:
|
||||
unsigned m_result;
|
||||
unsigned m_count;
|
||||
std::vector<CTServiceServer> m_serverArray;
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
#include "Response.h"
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
using namespace Base;
|
||||
|
||||
/*
|
||||
//----------- TEST CODE ONLY ------------
|
||||
//-----------------------------------------
|
||||
ResTest::ResTest(void *user)
|
||||
: GenericResponse(CTGAME_REQUEST_TEST, CT_RESULT_TIMEOUT, user),
|
||||
m_value(0)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
void ResTest::unpack(ByteStream::ReadIterator &iter)
|
||||
//-----------------------------------------
|
||||
{
|
||||
get(iter, m_type);
|
||||
get(iter, m_track);
|
||||
get(iter, m_result);
|
||||
get(iter, m_value);
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyTest::ResReplyTest(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_TEST, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
//----------- TEST CODE ONLY ------------
|
||||
*/
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyMoveStatus::ResReplyMoveStatus(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_MOVESTATUS, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyValidateMove::ResReplyValidateMove(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_VALIDATEMOVE, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyMove::ResReplyMove(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_MOVE, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyDelete::ResReplyDelete(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_DELETE, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyRestore::ResReplyRestore(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_RESTORE, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyTransferAccount::ResReplyTransferAccount(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_TRANSFER_ACCOUNT, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyCharacterList::ResReplyCharacterList(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_CHARACTERLIST, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyServerList::ResReplyServerList(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_SERVERLIST, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------
|
||||
ResReplyDestinationServerList::ResReplyDestinationServerList(void *user)
|
||||
: GenericResponse(CTGAME_REPLY_DESTSERVERLIST, CT_RESULT_TIMEOUT, user)
|
||||
//-----------------------------------------
|
||||
{
|
||||
}
|
||||
|
||||
}; // namespace
|
||||
@@ -0,0 +1,150 @@
|
||||
#if !defined (RESPONSE_H_)
|
||||
#define RESPONSE_H_
|
||||
|
||||
#pragma warning (disable : 4786)
|
||||
|
||||
#include "CTGenericAPI/GenericMessage.h"
|
||||
#include <Base/Archive.h>
|
||||
#include "CTCommon/RequestStrings.h"
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
|
||||
|
||||
//----------- TEST CODE ONLY ------------
|
||||
//-----------------------------------------
|
||||
class ResTest : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResTest(void *user);
|
||||
virtual ~ResTest() {}
|
||||
|
||||
void unpack(Base::ByteStream::ReadIterator &iter);
|
||||
|
||||
inline unsigned getValue() { return m_value; }
|
||||
|
||||
private:
|
||||
unsigned m_value;
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyTest : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyTest(void *user);
|
||||
virtual ~ResReplyTest() {}
|
||||
|
||||
private:
|
||||
};
|
||||
//----------- TEST CODE ONLY ------------
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyMoveStatus : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyMoveStatus(void *user);
|
||||
virtual ~ResReplyMoveStatus() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyValidateMove : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyValidateMove(void *user);
|
||||
virtual ~ResReplyValidateMove() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyMove : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyMove(void *user);
|
||||
virtual ~ResReplyMove() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyDelete : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyDelete(void *user);
|
||||
virtual ~ResReplyDelete() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyRestore : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyRestore(void *user);
|
||||
virtual ~ResReplyRestore() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyTransferAccount : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyTransferAccount(void *user);
|
||||
virtual ~ResReplyTransferAccount() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyCharacterList : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyCharacterList(void *user);
|
||||
virtual ~ResReplyCharacterList() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyServerList : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyServerList(void *user);
|
||||
virtual ~ResReplyServerList() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------
|
||||
class ResReplyDestinationServerList : public GenericResponse
|
||||
//-----------------------------------------
|
||||
{
|
||||
public:
|
||||
ResReplyDestinationServerList(void *user);
|
||||
virtual ~ResReplyDestinationServerList() {}
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
}; // namespace
|
||||
|
||||
#endif //RESPONSE_H_
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
#include "Clock.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#else //WIN32
|
||||
#include <sys/stat.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
Clock::Clock()
|
||||
: m_lastStart(0),
|
||||
m_totalRunTime(0)
|
||||
{
|
||||
}
|
||||
|
||||
ClockStamp Clock::getCurTime()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
static int sClockHigh = 0;
|
||||
static ClockStamp sClockLast = 0;
|
||||
|
||||
int high = sClockHigh;
|
||||
DWORD low = GetTickCount();
|
||||
ClockStamp holdLast = sClockLast; // this should be interlocked too
|
||||
ClockStamp ret = ((ClockStamp)high << 32) | low;
|
||||
|
||||
// crazy trick to allow threading to work, by putting in a 1000 second fudge factor, we effective say
|
||||
// that it is ok to time-slice us at a bad point and we will still handle it, provided that our thread
|
||||
// gets processing time again within 1000 seconds
|
||||
if (ret < holdLast - 1000000)
|
||||
{
|
||||
sClockHigh = high + 1;
|
||||
ret = ((ClockStamp)high << 32) | low;
|
||||
}
|
||||
|
||||
sClockLast = ret; // this really should be interlocked to be totally safe since it is a 64 bit value, but I don't see a way to do that and am not sure it would mess up anything but the one call anyways
|
||||
|
||||
return ret;
|
||||
#else
|
||||
struct timeval tv;
|
||||
int err;
|
||||
err = gettimeofday(&tv, NULL);
|
||||
return (static_cast<ClockStamp>(tv.tv_sec) * 1000 + static_cast<ClockStamp>(tv.tv_usec / 1000));
|
||||
#endif
|
||||
}
|
||||
|
||||
ClockStamp Clock::getElapsedSinceLastStart()
|
||||
{
|
||||
if (m_lastStart == 0)
|
||||
{
|
||||
//hasn't been started
|
||||
return 0;
|
||||
}
|
||||
|
||||
ClockStamp elapsed = getCurTime() - m_lastStart;
|
||||
|
||||
if (elapsed > 2000000000) // only time differences up to 23 days can be measured with this function
|
||||
elapsed = 2000000000;
|
||||
|
||||
return elapsed;
|
||||
}
|
||||
|
||||
void Clock::start()
|
||||
{
|
||||
if (m_lastStart != 0)
|
||||
{
|
||||
//already started
|
||||
return;
|
||||
}
|
||||
|
||||
//set last start to curtime
|
||||
m_lastStart = getCurTime();
|
||||
}
|
||||
|
||||
void Clock::stop()
|
||||
{
|
||||
if (m_lastStart == 0)
|
||||
{
|
||||
//need to start before stoping
|
||||
return;
|
||||
}
|
||||
|
||||
m_totalRunTime += (unsigned)getElapsedSinceLastStart(); //rlsmith - explicit cast to prevent compiler warning
|
||||
m_lastStart = 0;
|
||||
}
|
||||
|
||||
|
||||
bool Clock::isDone(unsigned runTime)
|
||||
{
|
||||
if (m_lastStart == 0)
|
||||
{
|
||||
//never started, so say no
|
||||
return false;
|
||||
}
|
||||
|
||||
ClockStamp totalElapsed = getElapsedSinceLastStart() + m_totalRunTime;
|
||||
|
||||
return (totalElapsed >= runTime);
|
||||
}
|
||||
|
||||
void Clock::reset()
|
||||
{
|
||||
m_lastStart = 0;
|
||||
m_totalRunTime = 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,71 @@
|
||||
#ifndef CLOCK_H
|
||||
#define CLOCK_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
typedef __int64 ClockStamp;
|
||||
#else
|
||||
typedef long long ClockStamp;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief A Clock can be used as a millisecond timer.
|
||||
*/
|
||||
class Clock
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Creates a clock, must still be started with Clock::start method.
|
||||
*
|
||||
* Once created, a clock can be started, and stoped as often as possible.
|
||||
*/
|
||||
Clock();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Starts the timer running.
|
||||
*/
|
||||
void start();
|
||||
|
||||
/**
|
||||
* @brief Stops the timer from running (note: can still be started again later).
|
||||
*/
|
||||
void stop();
|
||||
|
||||
/**
|
||||
* @brief Tells you if the timer has been in the started state for longer than runTime.
|
||||
*
|
||||
* @param runTime The amount of time to test if this timer has ran longer than.
|
||||
*
|
||||
* @return 'true' if timer has ran for longer than or equal to runTime, false otherwise.
|
||||
*/
|
||||
bool isDone(unsigned runTime);
|
||||
|
||||
/**
|
||||
* @brief Resets this clock (as if it were never started).
|
||||
*/
|
||||
void reset();
|
||||
|
||||
private:
|
||||
ClockStamp m_lastStart;
|
||||
unsigned m_totalRunTime;
|
||||
|
||||
ClockStamp getCurTime();
|
||||
ClockStamp getElapsedSinceLastStart();
|
||||
};
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif //CLOCK_H
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
#include "IPAddress.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <winsock.h>
|
||||
typedef int socklen_t;
|
||||
#else // for non-windows platforms (linux)
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/socket.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
IPAddress::IPAddress(unsigned int ip)
|
||||
: m_IP(ip)
|
||||
{
|
||||
}
|
||||
|
||||
char *IPAddress::GetAddress(char *buffer) const
|
||||
{
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_addr.s_addr = m_IP;
|
||||
strcpy(buffer, inet_ntoa(addr.sin_addr));
|
||||
return(buffer);
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,51 @@
|
||||
#ifndef TCPIPADDRESS_H
|
||||
#define TCPIPADDRESS_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Container object for IP Address.
|
||||
*/
|
||||
class IPAddress
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief Constructor, sets the ip address if specified.
|
||||
*/
|
||||
IPAddress(unsigned int ip = 0);
|
||||
|
||||
/**
|
||||
* @brief Sets the ip address.
|
||||
*/
|
||||
void SetAddress(unsigned int ip){ m_IP = ip; }
|
||||
|
||||
/**
|
||||
* @brief Returns the unsigned int representation of this address.
|
||||
*/
|
||||
unsigned int GetAddress() const { return m_IP; }
|
||||
|
||||
/**
|
||||
* @brief Used to retreive the the dot-notation represenatatiion of this address.
|
||||
*
|
||||
* @param buffer A pointer to the buffer to place the ip address into.
|
||||
* Must be at least 17 characters long, will be null terminated.
|
||||
*
|
||||
* @return A pointer to the buffer the address was placed into.
|
||||
*/
|
||||
char *GetAddress(char *buffer) const;
|
||||
|
||||
private:
|
||||
unsigned int m_IP;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //TCPIPADDRESS_H
|
||||
|
||||
|
||||
+94
@@ -0,0 +1,94 @@
|
||||
#include "TcpBlockAllocator.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
TcpBlockAllocator::TcpBlockAllocator(const unsigned initSize, const unsigned initCount)
|
||||
: m_freeHead(NULL), m_blockCount(initCount), m_blockSize(initSize), m_numAvailBlocks(0)
|
||||
{
|
||||
realloc();
|
||||
}
|
||||
|
||||
TcpBlockAllocator::~TcpBlockAllocator()
|
||||
{
|
||||
while(m_freeHead)
|
||||
{
|
||||
data_block *tmp = m_freeHead;
|
||||
m_freeHead = m_freeHead->m_next;
|
||||
delete[] tmp->m_data;
|
||||
delete tmp;m_numAvailBlocks--;
|
||||
}
|
||||
}
|
||||
|
||||
data_block *TcpBlockAllocator::getBlock()
|
||||
{
|
||||
data_block *tmp;
|
||||
|
||||
if(!m_freeHead)
|
||||
{
|
||||
realloc();
|
||||
}
|
||||
|
||||
tmp = m_freeHead;
|
||||
m_freeHead = m_freeHead->m_next;
|
||||
tmp->m_next = NULL;
|
||||
m_numAvailBlocks--;
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
void TcpBlockAllocator::returnBlock(data_block *b)
|
||||
{
|
||||
b->m_usedSize = 0;
|
||||
b->m_sentSize = 0;
|
||||
|
||||
if (m_numAvailBlocks >= m_blockCount)
|
||||
{
|
||||
delete[] b->m_data;
|
||||
delete b;
|
||||
return;
|
||||
}
|
||||
|
||||
b->m_next = m_freeHead;
|
||||
m_freeHead = b; m_numAvailBlocks++;
|
||||
}
|
||||
|
||||
void TcpBlockAllocator::realloc()
|
||||
{
|
||||
data_block *tmp = NULL, *cursor = NULL;
|
||||
|
||||
tmp = new data_block; m_numAvailBlocks++;
|
||||
cursor = tmp;
|
||||
memset(cursor, 0, sizeof(data_block));
|
||||
cursor->m_data = new char[m_blockSize];
|
||||
cursor->m_totalSize = m_blockSize;
|
||||
|
||||
for(unsigned i = 1; i < m_blockCount; i++)
|
||||
{
|
||||
cursor->m_next = new data_block; m_numAvailBlocks++;
|
||||
cursor = cursor->m_next;
|
||||
memset(cursor, 0, sizeof(data_block));
|
||||
cursor->m_data = new char[m_blockSize];
|
||||
cursor->m_totalSize = m_blockSize;
|
||||
}
|
||||
|
||||
if(m_freeHead)
|
||||
{
|
||||
cursor->m_next = m_freeHead;
|
||||
m_freeHead = tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_freeHead = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
#ifndef TCPBLOCKALLOCATOR_H
|
||||
#define TCPBLOCKALLOCATOR_H
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
struct data_block
|
||||
{
|
||||
unsigned m_usedSize;
|
||||
unsigned m_sentSize;
|
||||
unsigned m_totalSize;
|
||||
char *m_data;
|
||||
data_block *m_next;
|
||||
};
|
||||
|
||||
class TcpBlockAllocator
|
||||
{
|
||||
public:
|
||||
TcpBlockAllocator(const unsigned initSize, const unsigned initCount);
|
||||
~TcpBlockAllocator();
|
||||
data_block *getBlock();
|
||||
void returnBlock(data_block *);
|
||||
|
||||
private:
|
||||
void realloc();
|
||||
data_block *m_freeHead;
|
||||
unsigned m_blockCount;
|
||||
unsigned m_blockSize;
|
||||
unsigned m_numAvailBlocks;
|
||||
};
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif //TCPBLOCKALLOCATOR_H
|
||||
|
||||
|
||||
|
||||
|
||||
+784
@@ -0,0 +1,784 @@
|
||||
#include "TcpConnection.h"
|
||||
#include "TcpManager.h"
|
||||
#include "Clock.h"
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
//used when want to open new connection with this socket
|
||||
TcpConnection::TcpConnection(TcpManager *tcpManager, TcpBlockAllocator *sendAlloc, TcpManager::TcpParams ¶ms, const IPAddress &destIP, short destPort, unsigned timeout)
|
||||
: m_nextConnection(NULL),
|
||||
m_prevConnection(NULL),
|
||||
m_socket(INVALID_SOCKET),
|
||||
m_nextKeepAliveConnection(NULL),
|
||||
m_prevKeepAliveConnection(NULL),
|
||||
m_aliveListId(tcpManager->m_aliveList.m_listID),
|
||||
m_nextRecvDataConnection(NULL),
|
||||
m_prevRecvDataConnection(NULL),
|
||||
m_recvDataListId(tcpManager->m_dataList.m_listID),
|
||||
m_manager(tcpManager),
|
||||
m_status(StatusNegotiating),
|
||||
m_handler(NULL),
|
||||
m_destIP(destIP),
|
||||
m_destPort(destPort),
|
||||
m_refCount(0),
|
||||
m_sendAllocator(sendAlloc),
|
||||
m_head(NULL),
|
||||
m_tail(NULL),
|
||||
m_bytesRead(0),
|
||||
m_bytesNeeded(0),
|
||||
m_params(params),
|
||||
m_recvBuff(NULL),
|
||||
m_connectTimeout(timeout),
|
||||
m_connectTimer(),
|
||||
m_wasConRemovedFromMgr(false)
|
||||
{
|
||||
//start connection timer
|
||||
m_connectTimer.start();
|
||||
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
if (m_params.maxRecvMessageSize != 0)
|
||||
{
|
||||
m_recvBuff = new char[m_params.maxRecvMessageSize];
|
||||
}
|
||||
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
|
||||
setOptions();
|
||||
|
||||
|
||||
m_addr.sin_family = AF_INET;
|
||||
m_addr.sin_port = htons(m_destPort);
|
||||
m_addr.sin_addr.s_addr = m_destIP.GetAddress();
|
||||
|
||||
int err = connect(m_socket, (sockaddr *)&m_addr, sizeof(m_addr));
|
||||
|
||||
if(err == SOCKET_ERROR)
|
||||
{
|
||||
#ifdef WIN32
|
||||
int sockerr = WSAGetLastError();
|
||||
if(sockerr != WSAEWOULDBLOCK)
|
||||
{
|
||||
//a real error
|
||||
m_status = StatusDisconnected;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = StatusNegotiating;
|
||||
}
|
||||
|
||||
#else // UNIX
|
||||
|
||||
if (errno != EINPROGRESS)
|
||||
{
|
||||
m_status = StatusDisconnected;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = StatusNegotiating;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
//we are connected, wow
|
||||
m_status = StatusConnected;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//used when server mode creates new connection object representing a connect request
|
||||
TcpConnection::TcpConnection(TcpManager *tcpManager, TcpBlockAllocator *sendAlloc, TcpManager::TcpParams ¶ms, SOCKET socket, const IPAddress &destIP, short destPort)
|
||||
: m_nextConnection(NULL),
|
||||
m_prevConnection(NULL),
|
||||
m_socket(socket),
|
||||
m_nextKeepAliveConnection(NULL),
|
||||
m_prevKeepAliveConnection(NULL),
|
||||
m_aliveListId(tcpManager->m_aliveList.m_listID),
|
||||
m_nextRecvDataConnection(NULL),
|
||||
m_prevRecvDataConnection(NULL),
|
||||
m_recvDataListId(tcpManager->m_dataList.m_listID),
|
||||
m_manager(tcpManager),
|
||||
m_status(StatusConnected),
|
||||
m_handler(NULL),
|
||||
m_destIP(destIP),
|
||||
m_destPort(destPort),
|
||||
m_refCount(0),
|
||||
m_sendAllocator(sendAlloc),
|
||||
m_head(NULL),
|
||||
m_tail(NULL),
|
||||
m_bytesRead(0),
|
||||
m_bytesNeeded(0),
|
||||
m_params(params),
|
||||
m_recvBuff(NULL),
|
||||
m_connectTimeout(0),
|
||||
m_connectTimer(),
|
||||
m_wasConRemovedFromMgr(false)
|
||||
{
|
||||
memset(&m_addr, 0, sizeof(m_addr));
|
||||
if (m_params.maxRecvMessageSize != 0)
|
||||
{
|
||||
m_recvBuff = new char[m_params.maxRecvMessageSize];
|
||||
}
|
||||
|
||||
|
||||
setOptions();
|
||||
}
|
||||
|
||||
void TcpConnection::setOptions()
|
||||
{
|
||||
if (m_socket != INVALID_SOCKET)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
unsigned long isNonBlocking = 1;
|
||||
int outBufSize = m_params.outgoingBufferSize;
|
||||
int inBufSize = m_params.incomingBufferSize;
|
||||
int keepAlive = 1;
|
||||
int reuseAddr = 1;
|
||||
struct linger ld;
|
||||
ld.l_onoff = 0;
|
||||
ld.l_linger = 0;
|
||||
|
||||
if (ioctlsocket(m_socket, FIONBIO, &isNonBlocking) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (char *)&outBufSize, sizeof(outBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&inBufSize, sizeof(inBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepAlive, sizeof(keepAlive)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseAddr, sizeof(reuseAddr)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_LINGER, (char *)&ld, sizeof(ld)) != 0 )
|
||||
{
|
||||
//bummer, but no need to crash now.... ?
|
||||
}
|
||||
|
||||
#else // linux is to remain the default compile mode
|
||||
unsigned long isNonBlocking = 1;
|
||||
unsigned long keepAlive = 1;
|
||||
unsigned long outBufSize = m_params.outgoingBufferSize;
|
||||
unsigned long inBufSize = m_params.incomingBufferSize;
|
||||
unsigned long reuseAddr = 1;
|
||||
struct linger ld;
|
||||
ld.l_onoff = 0;
|
||||
ld.l_linger = 0;
|
||||
|
||||
if (ioctl(m_socket, FIONBIO, &isNonBlocking) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, &outBufSize, sizeof(outBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, &inBufSize, sizeof(inBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &ld, sizeof(ld)) != 0)
|
||||
{
|
||||
//bummer, but no need to crash now.... ?
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int TcpConnection::finishConnect()
|
||||
{
|
||||
AddRef();
|
||||
int returnVal = 0;
|
||||
/**< returns < 0 if fatal error and connect will not work, =0 if need more time, >0 if connect completed */
|
||||
switch (m_status)
|
||||
{
|
||||
case StatusDisconnected:
|
||||
{
|
||||
//something went wrong
|
||||
Disconnect(false);
|
||||
returnVal = -1;
|
||||
}
|
||||
break;
|
||||
case StatusNegotiating:
|
||||
{
|
||||
#ifdef WIN32
|
||||
//try to finish connection
|
||||
fd_set wrSet;
|
||||
FD_ZERO(&wrSet);
|
||||
|
||||
FD_SET(m_socket, &wrSet);
|
||||
|
||||
timeval t;
|
||||
t.tv_sec = 0;
|
||||
t.tv_usec = 0;
|
||||
|
||||
int err = select(m_socket + 1, NULL, &wrSet, NULL, &t);
|
||||
|
||||
if (err == 0)
|
||||
{
|
||||
//needs more time
|
||||
returnVal = 0;
|
||||
}
|
||||
else if (err == SOCKET_ERROR)
|
||||
{
|
||||
//huhoh, let's hope it needs more time
|
||||
int sockerr = WSAGetLastError();
|
||||
if (sockerr == WSAEINPROGRESS
|
||||
|| sockerr == WSAEWOULDBLOCK
|
||||
|| sockerr == WSAEALREADY
|
||||
|| sockerr == WSAEINVAL)
|
||||
{
|
||||
//yep
|
||||
returnVal = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
Disconnect(false);
|
||||
returnVal = -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//check if write bit set for socket
|
||||
if (FD_ISSET(m_socket, &wrSet))
|
||||
{
|
||||
//connection complete
|
||||
m_status = StatusConnected;
|
||||
returnVal = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//give it more time??
|
||||
returnVal = 0;
|
||||
}
|
||||
}
|
||||
|
||||
#else // not WIN32
|
||||
int err = connect(m_socket, (sockaddr *)&m_addr, sizeof(m_addr));
|
||||
|
||||
if(err == SOCKET_ERROR)
|
||||
{
|
||||
if (errno != EINPROGRESS && errno != EALREADY)
|
||||
{
|
||||
Disconnect(false);
|
||||
returnVal = -1;//failure
|
||||
}
|
||||
else
|
||||
{
|
||||
returnVal = 0;//need to wait
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_status = StatusConnected;
|
||||
returnVal = 1;//connect success
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
case StatusConnected:
|
||||
{
|
||||
//wierd, shouldn't be trying to do this here
|
||||
Disconnect(true);
|
||||
returnVal = -1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (returnVal == 0 && m_connectTimeout != 0 && m_connectTimer.isDone(m_connectTimeout))
|
||||
{
|
||||
Disconnect(false);
|
||||
returnVal = -1;
|
||||
}
|
||||
else if (returnVal ==1/* && m_connectTimeout != 0*/)
|
||||
{
|
||||
//need to give, onConnect callback
|
||||
if (m_manager->m_handler)
|
||||
m_manager->m_handler->OnConnectRequest(this);
|
||||
}
|
||||
|
||||
Release();
|
||||
return returnVal;
|
||||
|
||||
}
|
||||
|
||||
|
||||
TcpConnection::~TcpConnection()
|
||||
{
|
||||
if (m_recvBuff != NULL)
|
||||
{
|
||||
delete [] m_recvBuff;
|
||||
}
|
||||
|
||||
while(m_head != NULL)
|
||||
{
|
||||
data_block *tmp = m_head;
|
||||
m_head = m_head->m_next;
|
||||
m_sendAllocator->returnBlock(tmp);
|
||||
}
|
||||
|
||||
//TODO: need to notify app if are currently connected
|
||||
}
|
||||
|
||||
void TcpConnection::Send(const char *data, unsigned int dataLen)
|
||||
{
|
||||
//add msg to buf
|
||||
int totalLen = dataLen + sizeof(int);
|
||||
|
||||
if(m_status == StatusDisconnected)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_params.keepAliveDelay > 0 && m_aliveListId == m_manager->m_aliveList.m_listID)
|
||||
{
|
||||
m_aliveListId = m_manager->m_keepAliveList.m_listID;
|
||||
|
||||
if (m_prevKeepAliveConnection != NULL)
|
||||
m_prevKeepAliveConnection->m_nextKeepAliveConnection = m_nextKeepAliveConnection;
|
||||
if (m_nextKeepAliveConnection != NULL)
|
||||
m_nextKeepAliveConnection->m_prevKeepAliveConnection = m_prevKeepAliveConnection;
|
||||
if (m_manager->m_keepAliveList.m_beginList == this)
|
||||
m_manager->m_keepAliveList.m_beginList = m_nextKeepAliveConnection;
|
||||
|
||||
m_nextKeepAliveConnection = m_manager->m_aliveList.m_beginList;
|
||||
m_prevKeepAliveConnection = NULL;
|
||||
if (m_manager->m_aliveList.m_beginList != NULL)
|
||||
m_manager->m_aliveList.m_beginList->m_prevKeepAliveConnection = this;
|
||||
m_manager->m_aliveList.m_beginList = this;
|
||||
}
|
||||
|
||||
|
||||
data_block *work = NULL;
|
||||
|
||||
// this connection has no send buffer. Get a block
|
||||
if(!m_tail)
|
||||
{
|
||||
m_head = m_sendAllocator->getBlock();
|
||||
m_tail = m_head;
|
||||
}
|
||||
work = m_tail;
|
||||
|
||||
//send message len first
|
||||
unsigned nLen = htonl(totalLen);
|
||||
unsigned lenLength = sizeof(int);
|
||||
unsigned lenIndex = 0;
|
||||
while(lenIndex < lenLength)
|
||||
{
|
||||
if ((lenLength - lenIndex) <= (work->m_totalSize - work->m_usedSize))
|
||||
{
|
||||
//size will fit in this block
|
||||
memcpy(work->m_data + work->m_usedSize, (char *)(&nLen) + lenIndex, lenLength - lenIndex);
|
||||
work->m_usedSize += (lenLength - lenIndex);
|
||||
lenIndex += (lenLength - lenIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
//size will not fit in this block
|
||||
memcpy(work->m_data + work->m_usedSize, (char *)(&nLen) + lenIndex, work->m_totalSize - work->m_usedSize);
|
||||
lenIndex += work->m_totalSize - work->m_usedSize;
|
||||
work->m_usedSize += work->m_totalSize - work->m_usedSize;
|
||||
work->m_next = m_sendAllocator->getBlock();
|
||||
work = work->m_next;
|
||||
m_tail = work;
|
||||
}
|
||||
}
|
||||
|
||||
//now send message payload
|
||||
unsigned messageIndex = 0;
|
||||
while(messageIndex < dataLen)
|
||||
{
|
||||
if((dataLen - messageIndex) <= (work->m_totalSize - work->m_usedSize))
|
||||
{
|
||||
// data will fit in this block
|
||||
memcpy(work->m_data + work->m_usedSize, data + messageIndex, (dataLen - messageIndex));
|
||||
work->m_usedSize += (dataLen - messageIndex);
|
||||
messageIndex += (dataLen - messageIndex);
|
||||
}
|
||||
else
|
||||
{
|
||||
// data will not fit in this block. Fill this block and get another block
|
||||
memcpy(work->m_data + work->m_usedSize, data + messageIndex, work->m_totalSize - work->m_usedSize);
|
||||
messageIndex += work->m_totalSize - work->m_usedSize;
|
||||
work->m_usedSize += work->m_totalSize - work->m_usedSize;
|
||||
work->m_next = m_sendAllocator->getBlock();
|
||||
work = work->m_next;
|
||||
m_tail = work;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
void TcpConnection::Disconnect(bool notifyApplication)
|
||||
{
|
||||
AddRef();
|
||||
m_status = StatusDisconnected;
|
||||
if (!m_wasConRemovedFromMgr)
|
||||
{
|
||||
m_manager->removeConnection(this);
|
||||
m_wasConRemovedFromMgr = true;
|
||||
}
|
||||
|
||||
|
||||
if(m_socket != INVALID_SOCKET)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(m_socket);
|
||||
#else
|
||||
close(m_socket);
|
||||
#endif
|
||||
m_socket = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
|
||||
if (notifyApplication && m_handler)
|
||||
m_handler->OnTerminated(this);
|
||||
|
||||
Release();
|
||||
}
|
||||
|
||||
|
||||
void TcpConnection::AddRef()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
|
||||
void TcpConnection::Release()
|
||||
{
|
||||
if (--m_refCount == 0)
|
||||
{
|
||||
//make sure manager knows I'm gone
|
||||
if (m_status != StatusDisconnected)
|
||||
Disconnect(false);
|
||||
delete this;
|
||||
}
|
||||
}
|
||||
|
||||
int TcpConnection::processIncoming()
|
||||
{
|
||||
/**< returns < 0 if fatal error and socket has been closed,
|
||||
=0 if read anything (full or partial message),
|
||||
>0 if nothing to read now, or would block so shouldn't try again immediately. */
|
||||
|
||||
if (m_status != StatusConnected)
|
||||
{
|
||||
//wait until connect succeeds
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (m_params.noDataTimeout > 0 && m_recvDataListId == m_manager->m_dataList.m_listID)
|
||||
{
|
||||
m_recvDataListId = m_manager->m_noDataList.m_listID;
|
||||
|
||||
if (m_prevRecvDataConnection != NULL)
|
||||
m_prevRecvDataConnection->m_nextRecvDataConnection = m_nextRecvDataConnection;
|
||||
if (m_nextRecvDataConnection != NULL)
|
||||
m_nextRecvDataConnection->m_prevRecvDataConnection = m_prevRecvDataConnection;
|
||||
if (m_manager->m_noDataList.m_beginList == this)
|
||||
m_manager->m_noDataList.m_beginList = m_nextRecvDataConnection;
|
||||
|
||||
m_nextRecvDataConnection = m_manager->m_dataList.m_beginList;
|
||||
m_prevRecvDataConnection = NULL;
|
||||
if (m_manager->m_dataList.m_beginList != NULL)
|
||||
m_manager->m_dataList.m_beginList->m_prevRecvDataConnection = this;
|
||||
m_manager->m_dataList.m_beginList = this;
|
||||
}
|
||||
|
||||
|
||||
int newMsg = 0;
|
||||
|
||||
|
||||
if (m_bytesRead < sizeof(int))
|
||||
{
|
||||
//new msg
|
||||
newMsg = 1;
|
||||
//printf("socket: %d\n", m_socket);
|
||||
int ret = recv(m_socket, ((char *)(&m_bytesNeeded) + m_bytesRead),
|
||||
4 - m_bytesRead, 0);
|
||||
//fprintf(stderr, "READ: %d\n", ret);
|
||||
if (ret == 0)
|
||||
{
|
||||
//We did a select, so there should be data. Socket was closed.
|
||||
Disconnect();
|
||||
return -1;
|
||||
}
|
||||
else if (ret == -1)
|
||||
{
|
||||
if (translateRecvSocketEror())
|
||||
{
|
||||
//fatal error
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//need to wait
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bytesRead += ret;
|
||||
if (m_bytesRead < 4)
|
||||
{
|
||||
return 1;//need to wait
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
m_bytesNeeded = ntohl(m_bytesNeeded);
|
||||
|
||||
//printf("m_bytesNeeded = %i\n", m_bytesNeeded);
|
||||
if (m_bytesNeeded == sizeof(int))
|
||||
{
|
||||
//keepalive, ignore
|
||||
m_bytesRead = 0;
|
||||
m_bytesNeeded = 0;
|
||||
return 0;
|
||||
}
|
||||
else if (m_bytesNeeded < sizeof(int))
|
||||
{
|
||||
//major protocol violation
|
||||
Disconnect();
|
||||
return -1;
|
||||
}
|
||||
else if (m_params.maxRecvMessageSize == 0)
|
||||
{
|
||||
if (m_recvBuff!=NULL)
|
||||
delete [] m_recvBuff;
|
||||
m_recvBuff = new char[m_bytesNeeded-4];
|
||||
}
|
||||
else if (m_params.maxRecvMessageSize != 0 && (m_bytesNeeded-4) > m_params.maxRecvMessageSize)
|
||||
{
|
||||
//error, maxRecvMeessageSize exceeded, Disconnect
|
||||
Disconnect();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int msgBytesRead = m_bytesRead - 4;
|
||||
int msgBytesNeeded = m_bytesNeeded - 4;
|
||||
|
||||
int ret = recv(m_socket, (char *)(m_recvBuff + msgBytesRead),
|
||||
msgBytesNeeded - msgBytesRead, 0);
|
||||
if (ret == 0 && !newMsg)
|
||||
{
|
||||
//We did a select, so there should be data. Socket was closed.
|
||||
Disconnect();
|
||||
return -1;
|
||||
}
|
||||
if (ret == -1)
|
||||
{
|
||||
if (translateRecvSocketEror())
|
||||
{
|
||||
//fatal error
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
//need to wait
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
{
|
||||
m_bytesRead += ret;
|
||||
}
|
||||
|
||||
if (m_bytesRead == m_bytesNeeded)
|
||||
{
|
||||
m_bytesRead = 0;
|
||||
m_bytesNeeded = 0;
|
||||
if (m_handler)
|
||||
{
|
||||
AddRef();//could get deleted during this callback
|
||||
m_handler->OnRoutePacket(this, (unsigned char *)m_recvBuff, msgBytesNeeded);
|
||||
|
||||
if (m_status == StatusDisconnected)
|
||||
{
|
||||
Release();
|
||||
return -1;
|
||||
}
|
||||
Release();
|
||||
}
|
||||
|
||||
//entire message received
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 1;//couldn't get entire msg
|
||||
}
|
||||
}
|
||||
|
||||
int TcpConnection::processOutgoing()
|
||||
{
|
||||
/**< returns < 0 if fatal error and socket has been closed,
|
||||
=0 if sent data, call again immediately if want to,
|
||||
>0 may have sent data, but calling again would do no good because there is either no more data to send, or would block. */
|
||||
if (m_status != StatusConnected)
|
||||
{
|
||||
//wait until connect succeeds
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int sendError = 1;
|
||||
|
||||
// If m_head is not null, then this connection has something to send
|
||||
|
||||
|
||||
if(m_head)
|
||||
{
|
||||
|
||||
|
||||
int amt = ::send(m_socket, m_head->m_data + m_head->m_sentSize, m_head->m_usedSize - m_head->m_sentSize, 0);
|
||||
if(amt < 0)
|
||||
{
|
||||
#ifdef WIN32
|
||||
switch(WSAGetLastError())
|
||||
{
|
||||
case WSAEWOULDBLOCK:
|
||||
case WSAEINTR:
|
||||
case WSAEINPROGRESS:
|
||||
case WSAEALREADY:
|
||||
case WSA_IO_PENDING:
|
||||
case WSA_NOT_ENOUGH_MEMORY:
|
||||
case WSATRY_AGAIN:
|
||||
//try again
|
||||
sendError = 1;
|
||||
break;
|
||||
default:
|
||||
//assume broken, Disconnect
|
||||
Disconnect();
|
||||
sendError = -1;
|
||||
break;
|
||||
}
|
||||
#else //not WIN32
|
||||
|
||||
// error condition, EAGAIN is recoverable, otherwise raise an error condition. Break from loop
|
||||
switch(errno)
|
||||
{
|
||||
case EAGAIN:
|
||||
//try again
|
||||
sendError = 1;
|
||||
break;
|
||||
default:
|
||||
//assume broken, Disconnect
|
||||
Disconnect();
|
||||
sendError = -1;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if(static_cast<unsigned>(amt) < (m_head->m_usedSize - m_head->m_sentSize))
|
||||
{
|
||||
// partial send: trying to do anything more now would be a waste of time. Break from loop
|
||||
m_head->m_sentSize += amt;
|
||||
sendError = 1;
|
||||
}
|
||||
else if(amt == 0)
|
||||
{
|
||||
Disconnect();
|
||||
sendError = -1;
|
||||
// client closed connection
|
||||
}
|
||||
else
|
||||
{
|
||||
// everything was sent from this block. Return it to the pool, advance m_head. Attempt to continue
|
||||
// sending
|
||||
data_block *tmp = m_head;
|
||||
if(m_tail == m_head)
|
||||
{
|
||||
m_tail = m_tail->m_next;
|
||||
m_head = m_head->m_next;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_head = m_head->m_next;
|
||||
}
|
||||
m_sendAllocator->returnBlock(tmp);
|
||||
|
||||
sendError = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return sendError;
|
||||
}
|
||||
|
||||
|
||||
bool TcpConnection::translateRecvSocketEror()
|
||||
{
|
||||
/**< returns false if fatal error and socket has been closed,
|
||||
true if should try again. */
|
||||
bool fatalError=false;
|
||||
#ifdef WIN32
|
||||
|
||||
switch(WSAGetLastError())
|
||||
{
|
||||
case WSAENOBUFS:
|
||||
case WSAEINPROGRESS:
|
||||
case WSAEINTR:
|
||||
case WSAEWOULDBLOCK:
|
||||
case WSABASEERR:
|
||||
fatalError=false;
|
||||
break;
|
||||
|
||||
case WSANOTINITIALISED:
|
||||
case WSAENETDOWN:
|
||||
case WSAEFAULT:
|
||||
case WSAENOTCONN:
|
||||
case WSAENETRESET:
|
||||
case WSAENOTSOCK:
|
||||
case WSAEOPNOTSUPP:
|
||||
case WSAESHUTDOWN:
|
||||
case WSAEMSGSIZE:
|
||||
case WSAEINVAL:
|
||||
case WSAECONNABORTED:
|
||||
case WSAETIMEDOUT:
|
||||
case WSAECONNRESET:
|
||||
default:
|
||||
//fatal
|
||||
fatalError=true;
|
||||
Disconnect();
|
||||
break;
|
||||
}
|
||||
|
||||
#else //not WIN32
|
||||
|
||||
switch(errno)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
case EINTR:
|
||||
case ETIMEDOUT:
|
||||
case ENOBUFS:
|
||||
//try later
|
||||
fatalError=false;
|
||||
break;
|
||||
|
||||
case EBADF:
|
||||
case ECONNRESET:
|
||||
case EFAULT:
|
||||
case EINVAL:
|
||||
case ENOTCONN:
|
||||
case ENOTSOCK:
|
||||
case EOPNOTSUPP:
|
||||
case EPIPE:
|
||||
case EIO:
|
||||
case ENOMEM:
|
||||
case ENOSR:
|
||||
default:
|
||||
//fatal
|
||||
fatalError=true;
|
||||
Disconnect();
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
return fatalError;
|
||||
}
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
#ifndef TCPCONNECTION_H
|
||||
#define TCPCONNECTION_H
|
||||
|
||||
|
||||
#include "TcpHandlers.h"
|
||||
#include "TcpManager.h"
|
||||
#include "IPAddress.h"
|
||||
#include "TcpBlockAllocator.h"
|
||||
#include "Clock.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
typedef int socklen_t;
|
||||
#else // for non-windows platforms (linux)
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Manages a single connection.
|
||||
*/
|
||||
class TcpConnection
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* @brief The connection status.
|
||||
*/
|
||||
enum Status {
|
||||
StatusNegotiating, /**< Currently attempting to connect. */
|
||||
StatusConnected, /**< Currently connected. */
|
||||
StatusDisconnected /**< Currently disconnected. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Sets the handler object which will receive callback methods.
|
||||
*
|
||||
* To have the TcpConnection call your object directly when packets are received, and when the
|
||||
* connection is disconnected, you simply need to derive your class
|
||||
* (multiply if necessary) from TcpConnectionHandler, then you can use
|
||||
* this method to set the object the TcpConnection will call as appropriate.
|
||||
* default = NULL (no callbacks made)
|
||||
*
|
||||
* @param handler The object which will be called for notifications.
|
||||
*/
|
||||
void SetHandler(TcpConnectionHandler *handler){ m_handler = handler; }
|
||||
|
||||
/**
|
||||
* @brief Returns the handler associated with this object.
|
||||
*/
|
||||
TcpConnectionHandler *GetHandler(){ return m_handler; }
|
||||
|
||||
/**
|
||||
* @brief Returns the current status of this connection.
|
||||
*/
|
||||
Status GetStatus(){ return m_status; }
|
||||
|
||||
/**
|
||||
* @brief Queues a message to be sent on this connection.
|
||||
*/
|
||||
void Send(const char *data, unsigned dataLen);
|
||||
|
||||
/**
|
||||
* @brief Disconnects and recycles the socket.
|
||||
*
|
||||
* @param notifyApplication primarily used internally, but when set to 'true', it will cause the application
|
||||
* to be called back via the onTerminated handler due to this call (the callback will not occur if the connection was
|
||||
* already disconnected)
|
||||
*/
|
||||
void Disconnect(bool notifyApplication=true);
|
||||
|
||||
/**
|
||||
* @brief Returns the ip on the other side of this connection.
|
||||
*/
|
||||
IPAddress GetDestinationIp(){ return m_destIP; }
|
||||
|
||||
/**
|
||||
* @brief Returns the port on the other side of this conection.
|
||||
*/
|
||||
short GetDestinationPort(){ return m_destPort; }
|
||||
|
||||
/**
|
||||
* @brief Standard AddRef/Release scheme
|
||||
*/
|
||||
void AddRef();
|
||||
|
||||
/**
|
||||
* @brief Standard AddRef/Release scheme
|
||||
*/
|
||||
void Release();
|
||||
|
||||
bool wasRemovedFromMgr() { return m_wasConRemovedFromMgr; }
|
||||
void setRemovedFromMgr() { m_wasConRemovedFromMgr = true; }
|
||||
|
||||
protected:
|
||||
friend class TcpManager;
|
||||
TcpConnection(TcpManager *tcpManager, TcpBlockAllocator *sendAlloc, TcpManager::TcpParams ¶ms, const IPAddress &destIP, short destPort, unsigned timeout);
|
||||
int finishConnect();/**< returns < 0 if fatal error and connect will not work, =0 if need more time, >0 if connect completed */
|
||||
TcpConnection(TcpManager *tcpManager, TcpBlockAllocator *sendAlloc, TcpManager::TcpParams ¶ms, SOCKET socket, const IPAddress &destIP, short destPort);
|
||||
TcpConnection *m_nextConnection; /**< Double linked list imp. */
|
||||
TcpConnection *m_prevConnection; /**< Double linked list imp. */
|
||||
SOCKET m_socket;
|
||||
int processOutgoing();/**< returns < 0 if fatal error and socket has been closed, =0 if sent data, call again immediately if want to, >0 may have sent data, but calling again would do no good because there is either no more data to send, or would block. */
|
||||
int processIncoming();/**< returns < 0 if fatal error and socket has been closed, =0 if read anything (full or partial message), >0 if nothing to read now, or would block so shouldn't try again immediately. */
|
||||
|
||||
|
||||
TcpConnection *m_nextKeepAliveConnection; /**< Double linked list imp. */
|
||||
TcpConnection *m_prevKeepAliveConnection; /**< Double linked list imp. */
|
||||
int m_aliveListId;
|
||||
|
||||
TcpConnection *m_nextRecvDataConnection;
|
||||
TcpConnection *m_prevRecvDataConnection;
|
||||
int m_recvDataListId;
|
||||
|
||||
private:
|
||||
~TcpConnection();
|
||||
void setOptions();
|
||||
TcpManager *m_manager;
|
||||
bool translateRecvSocketEror();
|
||||
Status m_status;
|
||||
TcpConnectionHandler *m_handler;
|
||||
IPAddress m_destIP;
|
||||
short m_destPort;
|
||||
unsigned m_refCount;
|
||||
TcpBlockAllocator *m_sendAllocator;
|
||||
data_block *m_head;
|
||||
data_block *m_tail;
|
||||
unsigned m_bytesRead;
|
||||
unsigned m_bytesNeeded;
|
||||
TcpManager::TcpParams m_params;
|
||||
char *m_recvBuff;
|
||||
sockaddr_in m_addr;
|
||||
unsigned m_connectTimeout;
|
||||
Clock m_connectTimer;
|
||||
|
||||
bool m_wasConRemovedFromMgr;
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //TCPCONNECTION_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
#ifndef TCPHANDLERS_H
|
||||
#define TCPHANDLERS_H
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class TcpConnection;
|
||||
|
||||
/**
|
||||
* @brief Interface used by TcpManager class for notification to application of connection state/etc.
|
||||
*
|
||||
* Note: these callbacks will only be made when during a call to TcpManager::giveTime.
|
||||
*/
|
||||
class TcpManagerHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Callback made when a new connection has been established by the manager.
|
||||
*/
|
||||
virtual void OnConnectRequest(TcpConnection *con)=0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Interface used by TcpConnection class for notification to application of connection state/etc.
|
||||
*
|
||||
* Note: these callbacks will only be made when during a call to TcpManager::giveTime.
|
||||
*/
|
||||
class TcpConnectionHandler
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Callback made when a new message has been received on the specified connection.
|
||||
*/
|
||||
virtual void OnRoutePacket(TcpConnection *con, const unsigned char *data, int dataLen)=0;
|
||||
|
||||
/**
|
||||
* @brief Callback made when the specified connection has closed, or been closed.
|
||||
*/
|
||||
virtual void OnTerminated(TcpConnection *con)=0;
|
||||
};
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
#endif //TCPHANDLERS_H
|
||||
|
||||
@@ -0,0 +1,734 @@
|
||||
#include "TcpManager.h"
|
||||
#include <assert.h>
|
||||
#include "IPAddress.h"
|
||||
#include "TcpConnection.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
TcpManager::TcpParams::TcpParams()
|
||||
: port(0),
|
||||
maxConnections(10),
|
||||
incomingBufferSize(64*1024),
|
||||
outgoingBufferSize(64*1024),
|
||||
allocatorBlockSize(8*1024),
|
||||
allocatorBlockCount(16),
|
||||
maxRecvMessageSize(0),
|
||||
keepAliveDelay(0),
|
||||
noDataTimeout(0)
|
||||
{
|
||||
memset(bindAddress, 0, sizeof(bindAddress));
|
||||
}
|
||||
|
||||
TcpManager::TcpParams::TcpParams(const TcpParams &cpy)
|
||||
: port(cpy.port),
|
||||
maxConnections(cpy.maxConnections),
|
||||
incomingBufferSize(cpy.incomingBufferSize),
|
||||
outgoingBufferSize(cpy.outgoingBufferSize),
|
||||
allocatorBlockSize(cpy.allocatorBlockSize),
|
||||
allocatorBlockCount(cpy.allocatorBlockCount),
|
||||
maxRecvMessageSize(cpy.maxRecvMessageSize),
|
||||
keepAliveDelay(cpy.keepAliveDelay),
|
||||
noDataTimeout(cpy.noDataTimeout)
|
||||
{
|
||||
}
|
||||
|
||||
TcpManager::TcpManager(const TcpParams ¶ms)
|
||||
: m_handler(NULL),
|
||||
m_keepAliveList(NULL, 1),
|
||||
m_aliveList(NULL, 2),
|
||||
m_noDataList(NULL, 1),
|
||||
m_dataList(NULL, 2),
|
||||
m_params(params),
|
||||
m_refCount(1),
|
||||
m_connectionList(NULL),
|
||||
m_connectionListCount(0),
|
||||
m_socket(INVALID_SOCKET),
|
||||
m_boundAsServer(false),
|
||||
m_allocator(params.allocatorBlockSize, params.allocatorBlockCount),
|
||||
m_keepAliveTimer(),
|
||||
m_noDataTimer()
|
||||
{
|
||||
if (params.keepAliveDelay > 0)
|
||||
m_keepAliveTimer.start();
|
||||
|
||||
if (params.noDataTimeout > 0)
|
||||
m_noDataTimer.start();
|
||||
|
||||
#if defined(WIN32)
|
||||
WSADATA wsaData;
|
||||
WSAStartup(MAKEWORD(1,1), &wsaData);
|
||||
|
||||
FD_ZERO(&m_permfds);//select only used on win32
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
TcpManager::~TcpManager()
|
||||
{
|
||||
#if defined(WIN32)
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
if (m_boundAsServer)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
closesocket(m_socket);
|
||||
#else
|
||||
close(m_socket);
|
||||
#endif
|
||||
}
|
||||
while (m_connectionList != NULL)
|
||||
{
|
||||
TcpConnection *con = m_connectionList;
|
||||
m_connectionList = m_connectionList->m_nextConnection;
|
||||
con->Release();
|
||||
m_connectionListCount--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool TcpManager::BindAsServer()
|
||||
{
|
||||
|
||||
m_socket = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
if (m_socket != INVALID_SOCKET)
|
||||
{
|
||||
#if defined(WIN32)
|
||||
FD_SET(m_socket, &m_permfds);//the socket this server is listening on
|
||||
|
||||
unsigned long isNonBlocking = 1;
|
||||
int outBufSize = m_params.outgoingBufferSize;
|
||||
int inBufSize = m_params.incomingBufferSize;
|
||||
int keepAlive = 1;
|
||||
int reuseAddr = 1;
|
||||
struct linger ld;
|
||||
ld.l_onoff = 0;
|
||||
ld.l_linger = 0;
|
||||
|
||||
if (ioctlsocket(m_socket, FIONBIO, &isNonBlocking) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, (char *)&outBufSize, sizeof(outBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, (char *)&inBufSize, sizeof(inBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, (char *)&keepAlive, sizeof(keepAlive)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&reuseAddr, sizeof(reuseAddr)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_LINGER, (char *)&ld, sizeof(ld)) != 0 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#else // linux is to remain the default compile mode
|
||||
unsigned long isNonBlocking = 1;
|
||||
unsigned long keepAlive = 1;
|
||||
unsigned long outBufSize = m_params.outgoingBufferSize;
|
||||
unsigned long inBufSize = m_params.incomingBufferSize;
|
||||
unsigned long reuseAddr = 1;
|
||||
struct linger ld;
|
||||
ld.l_onoff = 0;
|
||||
ld.l_linger = 0;
|
||||
|
||||
if (ioctl(m_socket, FIONBIO, &isNonBlocking) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_SNDBUF, &outBufSize, sizeof(outBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_RCVBUF, &inBufSize, sizeof(inBufSize)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_KEEPALIVE, &keepAlive, sizeof(keepAlive)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_REUSEADDR, &reuseAddr, sizeof(reuseAddr)) != 0
|
||||
|| setsockopt(m_socket, SOL_SOCKET, SO_LINGER, &ld, sizeof(ld)) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
struct sockaddr_in addr_loc;
|
||||
addr_loc.sin_family = AF_INET;
|
||||
addr_loc.sin_port = htons(m_params.port);
|
||||
addr_loc.sin_addr.s_addr = htonl(INADDR_ANY);
|
||||
if (m_params.bindAddress[0] != 0)
|
||||
{
|
||||
unsigned long address = inet_addr(m_params.bindAddress);
|
||||
if (address == INADDR_NONE)
|
||||
{
|
||||
struct hostent * lphp;
|
||||
lphp = gethostbyname(m_params.bindAddress);
|
||||
if (lphp != NULL)
|
||||
addr_loc.sin_addr.s_addr = ((struct in_addr *)(lphp->h_addr))->s_addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
addr_loc.sin_addr.s_addr = address;
|
||||
}
|
||||
}
|
||||
|
||||
if (bind(m_socket, (struct sockaddr *)&addr_loc, sizeof(addr_loc)) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (listen(m_socket, 1000) != 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
m_boundAsServer = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
TcpConnection *TcpManager::acceptClient()
|
||||
{
|
||||
TcpConnection *newConn = NULL;
|
||||
|
||||
if (m_boundAsServer && m_connectionListCount < m_params.maxConnections)
|
||||
{
|
||||
|
||||
sockaddr_in addr;
|
||||
int addrLength = sizeof(addr);
|
||||
SOCKET sock = ::accept(m_socket, (sockaddr *) &addr, (socklen_t *) &addrLength);
|
||||
|
||||
|
||||
if (sock != INVALID_SOCKET)
|
||||
{
|
||||
newConn = new TcpConnection(this, &m_allocator, m_params, sock, IPAddress(addr.sin_addr.s_addr), ntohs(addr.sin_port));
|
||||
addNewConnection(newConn);
|
||||
if (m_handler != NULL)
|
||||
{
|
||||
m_handler->OnConnectRequest(newConn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newConn;
|
||||
}
|
||||
|
||||
void TcpManager::SetHandler(TcpManagerHandler *handler)
|
||||
{
|
||||
m_handler = handler;
|
||||
}
|
||||
|
||||
SOCKET TcpManager::getMaxFD()
|
||||
{
|
||||
#ifdef WIN32
|
||||
return 0;//this param is not used on win32 for select, only on unix
|
||||
#else
|
||||
SOCKET maxfd = 0;
|
||||
|
||||
if (m_boundAsServer)
|
||||
maxfd = m_socket+1;
|
||||
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_connectionList ; con != NULL ; con = next)
|
||||
{
|
||||
next = con->m_nextConnection;
|
||||
if (con->GetStatus() != TcpConnection::StatusDisconnected && con->m_socket > maxfd)
|
||||
{
|
||||
maxfd = con->m_socket + 1;
|
||||
}
|
||||
}
|
||||
return maxfd;
|
||||
#endif
|
||||
}
|
||||
|
||||
TcpConnection *TcpManager::getConnection(SOCKET fd)
|
||||
{
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_connectionList ; con != NULL ; con = next)
|
||||
{
|
||||
next = con->m_nextConnection;
|
||||
if (con->m_socket == fd)
|
||||
{
|
||||
return con;
|
||||
}
|
||||
}
|
||||
//if get here ,couldn't find it
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool TcpManager::GiveTime(unsigned maxTimeAcceptingConnections,unsigned maxSendTimePerConnection, unsigned maxRecvTimePerConnection)
|
||||
{
|
||||
bool processedIncoming = false;
|
||||
|
||||
if (maxTimeAcceptingConnections == 0 && maxSendTimePerConnection==0 && maxRecvTimePerConnection==0)
|
||||
{
|
||||
//they don't want to do anything now
|
||||
return processedIncoming;
|
||||
}
|
||||
|
||||
AddRef(); //keep a reference to ourself in case we callback to the application and the application releases us.
|
||||
|
||||
|
||||
|
||||
//first process outgoing on each connection, and finish establishing connections, if params say to
|
||||
if (m_connectionListCount != 0 && maxSendTimePerConnection != 0)
|
||||
{
|
||||
|
||||
// Send output from last heartbeat
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_connectionList ; con != NULL ; con = next)
|
||||
{
|
||||
con->AddRef();
|
||||
if (next) next->Release();
|
||||
next = con->m_nextConnection;
|
||||
if (next) next->AddRef();
|
||||
if(con->GetStatus() == TcpConnection::StatusConnected)
|
||||
{
|
||||
Clock timer;
|
||||
timer.start();
|
||||
while(!timer.isDone(maxSendTimePerConnection))
|
||||
{
|
||||
int err = con->processOutgoing();
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
//couldn't finish processing last request, don't try more
|
||||
break;
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
con->Release();
|
||||
}
|
||||
else if (con->GetStatus() == TcpConnection::StatusNegotiating)
|
||||
{
|
||||
if (con->finishConnect() < 0)
|
||||
{
|
||||
con->Release();
|
||||
continue;
|
||||
}
|
||||
con->Release();
|
||||
}
|
||||
else //inactive client in client list????
|
||||
{
|
||||
removeConnection(con);
|
||||
con->Release();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//process incoming messages (including connect requests)
|
||||
if ((
|
||||
m_boundAsServer //if in server mode and want to spend time accepting clients
|
||||
&& maxTimeAcceptingConnections != 0
|
||||
)
|
||||
||
|
||||
(
|
||||
m_connectionListCount != 0 //if there are connections and want to spend time receiving on them
|
||||
&& maxRecvTimePerConnection != 0
|
||||
)
|
||||
)
|
||||
{
|
||||
#ifdef WIN32
|
||||
SOCKET maxfd = getMaxFD(); //re-calc maxfd every time select on WIN32
|
||||
|
||||
//select on all fd's
|
||||
struct timeval timeout;
|
||||
|
||||
fd_set tmpfds;
|
||||
tmpfds = m_permfds;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 0;
|
||||
int cnt = select(maxfd, &tmpfds, NULL, NULL, &timeout); // blocks for timeout
|
||||
|
||||
|
||||
if (cnt > 0)
|
||||
{
|
||||
if (m_boundAsServer && maxTimeAcceptingConnections != 0)
|
||||
{//activity on our socket means connect requests
|
||||
|
||||
//see if are new incoming clients
|
||||
if (FD_ISSET(m_socket, &tmpfds))
|
||||
{
|
||||
//yep
|
||||
Clock timer;
|
||||
timer.start();
|
||||
while (acceptClient() && !timer.isDone(maxTimeAcceptingConnections))
|
||||
{
|
||||
//loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//process incoming client messages
|
||||
if (maxRecvTimePerConnection != 0)
|
||||
{
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_connectionList ; con != NULL ; con = next)
|
||||
{
|
||||
con->AddRef();
|
||||
if (next) next->Release();
|
||||
next = con->m_nextConnection;
|
||||
if (next) next->AddRef();
|
||||
|
||||
SOCKET fd = con->m_socket;
|
||||
if (fd == INVALID_SOCKET)
|
||||
{
|
||||
//invalid socket in list?, check if is connecting, otherwise, Disconnect and discard
|
||||
if (con->GetStatus() != TcpConnection::StatusNegotiating)
|
||||
{
|
||||
removeConnection(con);
|
||||
con->Release();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (FD_ISSET(fd, &tmpfds))
|
||||
{
|
||||
Clock timer;
|
||||
timer.start();
|
||||
while(!timer.isDone(maxRecvTimePerConnection) && con->GetStatus() == TcpConnection::StatusConnected)
|
||||
{
|
||||
int err = con->processIncoming();
|
||||
if (err >= 0)
|
||||
{
|
||||
processedIncoming = true;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
//couldn't finish processing last request, don't try more
|
||||
break;
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}//while(!timer...)
|
||||
}//if (FD_ISSET...)
|
||||
con->Release();
|
||||
}//for (...)
|
||||
} //maxRecvTimePerConnection != 0
|
||||
}//cnt > 0
|
||||
#else //on UNIX use poll
|
||||
|
||||
int numfds = m_connectionListCount;
|
||||
int idx = 0;
|
||||
if (m_boundAsServer)
|
||||
{
|
||||
numfds++;
|
||||
idx++;
|
||||
}
|
||||
|
||||
struct pollfd pollfds[numfds];
|
||||
|
||||
if (m_boundAsServer)
|
||||
{
|
||||
pollfds[0].fd = m_socket;
|
||||
pollfds[0].events |= POLLIN;
|
||||
}
|
||||
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_connectionList ; con != NULL ; con = next, idx++)
|
||||
{
|
||||
next = con->m_nextConnection;
|
||||
pollfds[idx].fd = con->m_socket;
|
||||
pollfds[idx].events |= POLLIN;
|
||||
pollfds[idx].events |= POLLHUP;
|
||||
}
|
||||
|
||||
|
||||
int cnt = poll(pollfds, numfds, 1);
|
||||
|
||||
if(cnt == SOCKET_ERROR)
|
||||
{
|
||||
//poll not working?
|
||||
//TODO: need to notify client somehow, don't think we can assume a fatal error here
|
||||
}
|
||||
else if (cnt > 0)
|
||||
{
|
||||
for (idx = 0; idx < numfds; idx++)
|
||||
{
|
||||
//find corresponding TcpConnection
|
||||
//TODO: optimize, seriously, this is takes linear time, every time
|
||||
TcpConnection *con = getConnection(pollfds[idx].fd);
|
||||
|
||||
if (pollfds[idx].revents & POLLIN)
|
||||
{
|
||||
if (m_boundAsServer && maxTimeAcceptingConnections != 0 && pollfds[idx].fd == m_socket)
|
||||
{
|
||||
//new incoming clients
|
||||
Clock timer;
|
||||
timer.start();
|
||||
while (acceptClient() && !timer.isDone(maxTimeAcceptingConnections))
|
||||
{
|
||||
//loop
|
||||
}
|
||||
|
||||
continue;//don't try to readmsgs from listening fd
|
||||
}
|
||||
|
||||
//process regular msg(s)
|
||||
if (con == NULL)
|
||||
{
|
||||
close(pollfds[idx].fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
Clock timer;
|
||||
timer.start();
|
||||
con->AddRef();//so it can't get deleted while we are checking it's status
|
||||
while(!timer.isDone(maxRecvTimePerConnection) && con->GetStatus() == TcpConnection::StatusConnected)
|
||||
{
|
||||
int err = con->processIncoming();
|
||||
if (err >= 0)
|
||||
{
|
||||
processedIncoming = true;
|
||||
}
|
||||
|
||||
if (err > 0)
|
||||
{
|
||||
//couldn't finish processing last request, don't try more
|
||||
break;
|
||||
}
|
||||
else if (err < 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
}//while(!timer....)
|
||||
con->Release();
|
||||
}//if(pollfds[...
|
||||
else if (pollfds[idx].revents & POLLHUP)
|
||||
{
|
||||
if (con == NULL)
|
||||
{
|
||||
close(pollfds[idx].fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
//Disconnect client
|
||||
con->Disconnect();
|
||||
}
|
||||
}//for (idx=0....
|
||||
}//else if (cnt > 0)
|
||||
|
||||
#endif
|
||||
}//wanted to process incoming messages or connect requests
|
||||
|
||||
//now process any keepalives, if time to do that
|
||||
if (m_params.keepAliveDelay > 0 && m_keepAliveTimer.isDone(m_params.keepAliveDelay))
|
||||
{
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_keepAliveList.m_beginList ; con != NULL ; con = next)
|
||||
{
|
||||
con->AddRef();
|
||||
if (next) next->Release();
|
||||
next = con->m_nextKeepAliveConnection;
|
||||
if (next) next->AddRef();
|
||||
|
||||
con->Send(NULL, 0); //note: this request will move the connection from the keepAliveList to the aliveList
|
||||
con->Release();
|
||||
}
|
||||
|
||||
//now move the complete alive list over to the keepalive list to reset those timers
|
||||
m_keepAliveList.m_beginList = m_aliveList.m_beginList;
|
||||
m_aliveList.m_beginList = NULL;
|
||||
|
||||
//switch id's for those connections that were in the alive list last go - around
|
||||
int tmpID = m_aliveList.m_listID;
|
||||
m_aliveList.m_listID = m_keepAliveList.m_listID;
|
||||
m_keepAliveList.m_listID = tmpID;
|
||||
|
||||
m_keepAliveTimer.reset();
|
||||
m_keepAliveTimer.start();
|
||||
}
|
||||
|
||||
//now process any noDataCons, if time to do that
|
||||
if (m_params.noDataTimeout > 0 && m_noDataTimer.isDone(m_params.noDataTimeout))
|
||||
{
|
||||
TcpConnection *next = NULL;
|
||||
for (TcpConnection *con = m_noDataList.m_beginList ; con != NULL ; con = next)
|
||||
{
|
||||
con->AddRef();
|
||||
if (next) next->Release();
|
||||
next = con->m_nextRecvDataConnection;
|
||||
if (next) next->AddRef();
|
||||
|
||||
//time to disconnect this guy
|
||||
con->Disconnect();
|
||||
con->Release();
|
||||
}
|
||||
|
||||
//now move the complete data list over to the nodata list to reset those timers
|
||||
m_noDataList.m_beginList = m_dataList.m_beginList;
|
||||
m_dataList.m_beginList = NULL;
|
||||
|
||||
//switch id's for those connections that were in the data list last go - around
|
||||
int tmpID = m_dataList.m_listID;
|
||||
m_dataList.m_listID = m_noDataList.m_listID;
|
||||
m_noDataList.m_listID = tmpID;
|
||||
|
||||
m_noDataTimer.reset();
|
||||
m_noDataTimer.start();
|
||||
}
|
||||
|
||||
Release();
|
||||
|
||||
return processedIncoming;
|
||||
}
|
||||
|
||||
TcpConnection *TcpManager::EstablishConnection(const char *serverAddress, unsigned short serverPort, unsigned timeout)
|
||||
{
|
||||
if (m_boundAsServer)
|
||||
{
|
||||
//can't open outgoing connections when in server mode
|
||||
// use a different TcpManager to do that
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (m_connectionListCount >= m_params.maxConnections)
|
||||
return(NULL);
|
||||
|
||||
// get server address
|
||||
unsigned long address = inet_addr(serverAddress);
|
||||
if (address == INADDR_NONE)
|
||||
{
|
||||
struct hostent * lphp;
|
||||
lphp = gethostbyname(serverAddress);
|
||||
if (lphp == NULL)
|
||||
return(NULL);
|
||||
address = ((struct in_addr *)(lphp->h_addr))->s_addr;
|
||||
}
|
||||
IPAddress destIP(address);
|
||||
|
||||
TcpConnection *con = new TcpConnection(this, &m_allocator, m_params, destIP, serverPort, timeout);
|
||||
con->AddRef();//for the client - to conform to UdpLibrary method
|
||||
addNewConnection(con);
|
||||
|
||||
return con;
|
||||
}
|
||||
|
||||
void TcpManager::addNewConnection(TcpConnection *con)
|
||||
{
|
||||
con->AddRef();
|
||||
#ifdef WIN32 //uses select
|
||||
if (con->m_socket != INVALID_SOCKET)
|
||||
FD_SET(con->m_socket, &m_permfds);
|
||||
#endif
|
||||
con->m_nextConnection = m_connectionList;
|
||||
con->m_prevConnection = NULL;
|
||||
if (m_connectionList != NULL)
|
||||
m_connectionList->m_prevConnection = con;
|
||||
m_connectionList = con;
|
||||
m_connectionListCount++;
|
||||
|
||||
con->m_nextKeepAliveConnection = m_aliveList.m_beginList;
|
||||
con->m_prevKeepAliveConnection = NULL;
|
||||
if (m_aliveList.m_beginList != NULL)
|
||||
m_aliveList.m_beginList->m_prevKeepAliveConnection = con;
|
||||
m_aliveList.m_beginList = con;
|
||||
con->m_aliveListId = m_keepAliveList.m_listID;//start it out thinking it's already in the alive list, since it is
|
||||
|
||||
con->m_nextRecvDataConnection = m_dataList.m_beginList;
|
||||
con->m_prevRecvDataConnection = NULL;
|
||||
if (m_dataList.m_beginList != NULL)
|
||||
m_dataList.m_beginList->m_prevRecvDataConnection = con;
|
||||
m_dataList.m_beginList = con;
|
||||
con->m_recvDataListId = m_noDataList.m_listID;//start it out thinking it's already in the data list, since it is
|
||||
}
|
||||
|
||||
void TcpManager::removeConnection(TcpConnection *con)
|
||||
{
|
||||
if (!con->wasRemovedFromMgr())
|
||||
{
|
||||
con->setRemovedFromMgr();
|
||||
m_connectionListCount--;
|
||||
#ifdef WIN32 //select only used on win32
|
||||
if (con->m_socket != INVALID_SOCKET)
|
||||
{
|
||||
FD_CLR(con->m_socket, &m_permfds);
|
||||
}
|
||||
#endif
|
||||
if (con->m_prevConnection != NULL)
|
||||
con->m_prevConnection->m_nextConnection = con->m_nextConnection;
|
||||
if (con->m_nextConnection != NULL)
|
||||
con->m_nextConnection->m_prevConnection = con->m_prevConnection;
|
||||
if (m_connectionList == con)
|
||||
m_connectionList = con->m_nextConnection;
|
||||
con->m_nextConnection = NULL;
|
||||
con->m_prevConnection = NULL;
|
||||
|
||||
if (con->m_prevKeepAliveConnection != NULL)
|
||||
con->m_prevKeepAliveConnection->m_nextKeepAliveConnection = con->m_nextKeepAliveConnection;
|
||||
if (con->m_nextKeepAliveConnection != NULL)
|
||||
con->m_nextKeepAliveConnection->m_prevKeepAliveConnection = con->m_prevKeepAliveConnection;
|
||||
|
||||
if (m_aliveList.m_beginList == con)
|
||||
m_aliveList.m_beginList = con->m_nextKeepAliveConnection;
|
||||
else if (m_keepAliveList.m_beginList == con)
|
||||
m_keepAliveList.m_beginList = con->m_nextKeepAliveConnection;
|
||||
con->m_nextKeepAliveConnection = NULL;
|
||||
con->m_prevKeepAliveConnection = NULL;
|
||||
|
||||
|
||||
|
||||
if (con->m_prevRecvDataConnection != NULL)
|
||||
con->m_prevRecvDataConnection->m_nextRecvDataConnection = con->m_nextRecvDataConnection;
|
||||
if (con->m_nextRecvDataConnection != NULL)
|
||||
con->m_nextRecvDataConnection->m_prevRecvDataConnection = con->m_prevRecvDataConnection;
|
||||
|
||||
if (m_dataList.m_beginList == con)
|
||||
m_dataList.m_beginList = con->m_nextRecvDataConnection;
|
||||
else if (m_noDataList.m_beginList == con)
|
||||
m_noDataList.m_beginList = con->m_nextRecvDataConnection;
|
||||
con->m_nextRecvDataConnection = NULL;
|
||||
con->m_prevRecvDataConnection = NULL;
|
||||
|
||||
|
||||
|
||||
con->Release();
|
||||
}
|
||||
}
|
||||
|
||||
void TcpManager::AddRef()
|
||||
{
|
||||
m_refCount++;
|
||||
}
|
||||
|
||||
void TcpManager::Release()
|
||||
{
|
||||
if (--m_refCount == 0)
|
||||
delete this;
|
||||
}
|
||||
|
||||
IPAddress TcpManager::GetLocalIp() const
|
||||
{
|
||||
struct sockaddr_in addr_self;
|
||||
memset(&addr_self, 0, sizeof(addr_self));
|
||||
socklen_t len = sizeof(addr_self);
|
||||
getsockname(m_socket, (struct sockaddr *)&addr_self, &len);
|
||||
return(IPAddress(addr_self.sin_addr.s_addr));
|
||||
|
||||
}
|
||||
|
||||
unsigned int TcpManager::GetLocalPort() const
|
||||
{
|
||||
struct sockaddr_in addr_self;
|
||||
memset(&addr_self, 0, sizeof(addr_self));
|
||||
socklen_t len = sizeof(addr_self);
|
||||
getsockname(m_socket, (struct sockaddr *)&addr_self, &len);
|
||||
return(ntohs(addr_self.sin_port));
|
||||
}
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
#ifndef TCPMANAGER_H
|
||||
#define TCPMANAGER_H
|
||||
|
||||
#include "TcpHandlers.h"
|
||||
|
||||
#include "TcpBlockAllocator.h"
|
||||
#include "IPAddress.h"
|
||||
#include "Clock.h"
|
||||
|
||||
#if defined(WIN32)
|
||||
#include <winsock2.h>
|
||||
typedef int socklen_t;
|
||||
#else // for non-windows platforms (linux)
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
const int INVALID_SOCKET = 0xFFFFFFFF;
|
||||
const int SOCKET_ERROR = 0xFFFFFFFF;
|
||||
typedef int SOCKET;
|
||||
#endif
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
class TcpConnection;
|
||||
|
||||
struct ConnectionList
|
||||
{
|
||||
ConnectionList(TcpConnection *con, int id) : m_beginList(con), m_listID(id) {}
|
||||
|
||||
TcpConnection *m_beginList;
|
||||
int m_listID;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief The purpose of the TcpManager is to manage a set of connections that are coming in on a particular port.
|
||||
*
|
||||
*/
|
||||
class TcpManager
|
||||
{
|
||||
public:
|
||||
|
||||
/** @brief Parameters for the TcpManager. */
|
||||
struct TcpParams
|
||||
{
|
||||
/** @brief Simple constructor sets default values for members. */
|
||||
TcpParams();
|
||||
|
||||
/** @brief Simple copy constructor. */
|
||||
TcpParams(const TcpParams &cpy);
|
||||
|
||||
/**
|
||||
* @brief Connection port number.
|
||||
*
|
||||
* this is the port number that this manager will use for all incoming and outgoing data. On the client side
|
||||
* this is typically set to 0, which causes the manager object to randomly pick an available port. On the server
|
||||
* side, this port should be set to a specific value as it will represent the port number that clients will use
|
||||
* to connect to the server (ie. the listening port). It's generally a good idea to give the user on the client
|
||||
* side the option of fixing this port number at a specific value as well as it is often necessary for them to
|
||||
* do so in order to navigate company firewalls which may have specific port numbers open to them for this purpose.
|
||||
* default = 0
|
||||
*/
|
||||
unsigned short port;
|
||||
|
||||
/**
|
||||
* @ brief Server bind ip.
|
||||
*
|
||||
*/
|
||||
char bindAddress[64];
|
||||
|
||||
|
||||
/**
|
||||
* @brief Maximum number of connections that can be established by this manager.
|
||||
*
|
||||
* this is the maximum number of connections that can be established by this manager, any incoming/outgoing connections
|
||||
* over this limit will be refused. On the client side, this typically only needs to be set to 1, though there
|
||||
* is little harm in setting this number larger.
|
||||
* default = 10
|
||||
*/
|
||||
unsigned maxConnections;
|
||||
|
||||
/**
|
||||
* @brief The size of the incoming socket buffer.
|
||||
*
|
||||
* The client will want to set this fairly small (32k or so), but the server
|
||||
* will want to set this fairly large (512k)
|
||||
* default = 64k
|
||||
*/
|
||||
unsigned incomingBufferSize;
|
||||
|
||||
/**
|
||||
* @brief The size of the outgoing socket buffer.
|
||||
*
|
||||
* The client will want to set this fairly small (32k or so), but the server
|
||||
* will want to set this fairly large (512k)
|
||||
* default = 64k
|
||||
*/
|
||||
unsigned outgoingBufferSize;
|
||||
|
||||
/**
|
||||
* @brief The block size of a single outgoing buffer memory allocator block.
|
||||
*
|
||||
* This param should allways be set at least as high as the maximum message size you
|
||||
* expect to send (performance will suffer otherwise).
|
||||
* default = 8K
|
||||
*/
|
||||
unsigned allocatorBlockSize;
|
||||
|
||||
/**
|
||||
* @brief The number of block memory allocator 'blocks' created at a time.
|
||||
*
|
||||
* This is the number of blocks created for the buffer allocator for each
|
||||
* TcpConnection opened by this manager. Since the block size should be
|
||||
* the max size of an outgoing message, the recommended setting is: greater
|
||||
* than the number of concurrent connections you expect to normally have open.
|
||||
* default = 1024
|
||||
*/
|
||||
unsigned allocatorBlockCount;
|
||||
|
||||
/**
|
||||
* @brief The maximum size that a recvd message is allowed to be.
|
||||
*
|
||||
* Really only here for protection, not required. If you set this, you can safeguard
|
||||
* your client/server from receiving stray oversized messages. If a message on the socket
|
||||
* specifies it's length at larger than this value, then the message is not read, and the connection
|
||||
* is terminated. If the value is set to 0, then there is no max message size checking
|
||||
* on incoming messages (this will also cary a performance hit, since every new message
|
||||
* recieved will have to have a new buffer created if you don't specify a value here). Be careful
|
||||
* not to set this too small, if you have messages that could exceed the value you set here
|
||||
* they will be discarded, and the connection will be terminated without warning.
|
||||
* default = 0
|
||||
*/
|
||||
unsigned maxRecvMessageSize;
|
||||
|
||||
unsigned keepAliveDelay;
|
||||
|
||||
unsigned noDataTimeout;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*/
|
||||
TcpManager(const TcpParams ¶ms);
|
||||
|
||||
/**
|
||||
* @brief Use to specify a handler object to receive callbacks.
|
||||
*
|
||||
* To have the TcpManager call your object directly when connection requests come in, you
|
||||
* simply need to derive your class (multiply if necessary) from TcpManagerHandler, then you can use
|
||||
* this method to set the object the TcpManager will call as appropriate. The TcpConnection object
|
||||
* also has a handler mechanism that replaces the other callback functions below, see TcpConnection::SetHandler
|
||||
* default = NULL (no callbacks made)
|
||||
*
|
||||
* @param handler The object which will be called for manager related notifications.
|
||||
*/
|
||||
void SetHandler(TcpManagerHandler *handler);
|
||||
|
||||
/**
|
||||
* @brief This function MUST be called on a regular basis in order to give the manager object time to service the socket and give time to various connection objects that may need processing time, etc.
|
||||
*
|
||||
* @param maxTimeAcceptingConnections The max amount of time in milliseconds to spend accepting new client connections.
|
||||
* This parameter is only used if this manager has been bound as a server (bindAsServer).
|
||||
* If you set this param to 0, it will not attempt to accept any new connections.
|
||||
*
|
||||
* @param giveConnectionsTime
|
||||
* True if every connection opened on this manager is given time in this call, false if
|
||||
* no connections are given time.
|
||||
*
|
||||
* @param maxSendTimePerConnection Max amount of time in milliseconds to spend on each client processing outgoing messages.
|
||||
* A max of the specified amount of time will be spent on each and every individual connection. If you set
|
||||
* this parametrer to 0, it will not process any outgoing messages on any clients. Note also that when attempting
|
||||
* to establish new connections (via the EstablishConnection method), this parameter must be > 0 in order to
|
||||
* complete the connection process for any connections that were still negotiating.
|
||||
*
|
||||
* @param maxRecvTimePerConnection Max amount of time in milliseconds to spend on each client processing incoming messages.
|
||||
* A max of the specified amount of time will be spent on each and every individual connection. If you set
|
||||
* this param to 0, it will not process any incoming messages on any clients.
|
||||
* This is a good way to give the manager processing time for outgoing packets in situations
|
||||
* where the application does not want to have to worry about processing incoming packets.
|
||||
*
|
||||
* @return true if any incoming packets were processed during this time slice, otherwise returns false
|
||||
*/
|
||||
bool GiveTime(unsigned maxTimeAcceptingConnections = 5, unsigned maxSendTimePerConnection = 5, unsigned maxRecvTimePerConnection = 5);
|
||||
|
||||
/**
|
||||
* @brief Used to establish a connection to a server that is listening at the specified address and port.
|
||||
*
|
||||
* The serverAddress will do a DNS lookup as appropriate. This call will block long enough to resolve
|
||||
* the DNS lookup, but then will return a TcpConnection object that will be in a StatusNegotiating
|
||||
* state until the connection is actually established. The application must give the manager
|
||||
* object time after calling EstablishConnection or else the negotiation process to establish the
|
||||
* connection will never have time to actually occur. Typically the client establishing the connection
|
||||
* will call EstablishConnection, then sit in a loop calling TcpManager::GiveTime and checking to see
|
||||
* if the status of the returned TcpConnection object is changed from StatusNegotiating. This allows
|
||||
* the application to look for the ESC key or timeout an attempted connection.
|
||||
*
|
||||
* @param serverAddress The address of the server to open a connection to.
|
||||
*
|
||||
* @param serverPort The port of the server to open a connection to.
|
||||
*
|
||||
* @param timeout How long to attempt connecting to the server (in milliseconds).
|
||||
* Setting the timeout value to something greater than 0 will cause the TcpConnection object to change
|
||||
* from a StatusNegotiating state to a StatusDisconnected state after the timeout has expired. It will also cause
|
||||
* the connect-complete callback to be called if the connection is succesfull.
|
||||
*
|
||||
* @return A pointer to a TcpConnection object.
|
||||
* NULL if the manager object has exceeded its maximum number of connections
|
||||
* or if the serverAddress cannot be resolved to an IP address.
|
||||
*/
|
||||
TcpConnection *EstablishConnection(const char *serverAddress, unsigned short serverPort, unsigned timeout = 0);
|
||||
|
||||
/**
|
||||
* @brief Binds this manager as a server which will listen for and accept incoming connections.
|
||||
*
|
||||
* @return 'true' if manager is able to bind succesfully, false otherwise.
|
||||
*/
|
||||
bool BindAsServer();
|
||||
|
||||
/**
|
||||
* @brief Standard AddRef/Release scheme
|
||||
*/
|
||||
void AddRef();
|
||||
|
||||
/**
|
||||
* @brief Standard AddRef/Release scheme
|
||||
*/
|
||||
void Release();
|
||||
|
||||
/**
|
||||
* @brief Returns the ip address of this machine. If the machine is multi-homed, this value may be blank.
|
||||
*/
|
||||
IPAddress GetLocalIp() const;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns the port the manager is actually using. This value will be the same as is specified in
|
||||
* Params::port (or if Params::port was set to 0, this will be the dynamically assigned port number)
|
||||
*/
|
||||
unsigned int GetLocalPort() const;
|
||||
|
||||
protected:
|
||||
friend class TcpConnection;
|
||||
void removeConnection(TcpConnection *con);
|
||||
TcpManagerHandler *m_handler;
|
||||
|
||||
ConnectionList m_keepAliveList;
|
||||
ConnectionList m_aliveList;
|
||||
|
||||
ConnectionList m_noDataList;
|
||||
ConnectionList m_dataList;
|
||||
|
||||
private:
|
||||
~TcpManager();
|
||||
TcpParams m_params;
|
||||
int m_refCount;
|
||||
TcpConnection *m_connectionList;
|
||||
unsigned m_connectionListCount;
|
||||
#ifdef WIN32
|
||||
fd_set m_permfds; /**< Used for select on WIN32 if we are in server mode. Keeps track of all clients connected to us. */
|
||||
#endif //WIN32
|
||||
SOCKET m_socket;
|
||||
bool m_boundAsServer;
|
||||
TcpBlockAllocator m_allocator;
|
||||
Clock m_keepAliveTimer;
|
||||
Clock m_noDataTimer;
|
||||
|
||||
void addNewConnection(TcpConnection *con);
|
||||
SOCKET getMaxFD();
|
||||
TcpConnection *getConnection(SOCKET fd);
|
||||
TcpConnection *acceptClient();
|
||||
};
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif //TCPMANAGER_H
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,535 @@
|
||||
#include "Client.h"
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
using namespace CTService;
|
||||
using namespace Plat_Unicode;
|
||||
|
||||
extern unsigned openRequests;
|
||||
extern std::map<unsigned, unsigned> m_tests;
|
||||
|
||||
//-------------------------------------------
|
||||
Client::Client(const char *hostName, const char *game)
|
||||
: CTServiceAPI(hostName, game), m_connected(false)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\nClient::Client()");
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
Client::~Client()
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\nClient::~Client()");
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onConnect(const char *host, short port, short current, short max)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\nConnect to %s:%d (%d of %d)", host, port, current, max);
|
||||
m_connected = true;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onDisconnect(const char *host, short port, short current, short max)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\nDisconnect from %s:%d (%d of %d)", host, port, current, max);
|
||||
m_connected = false;
|
||||
}
|
||||
/*
|
||||
//-------------------------------------------
|
||||
void Client::onTest(const unsigned track, const int resultCode, const unsigned value, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onTest] track(%d) resultCode(%s) value(%d)", track, ResultString[resultCode], value);
|
||||
openRequests--;
|
||||
}
|
||||
*/
|
||||
//-------------------------------------------
|
||||
void Client::onServerTest(unsigned server_track, const char *game, const char *param)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onServerTest] server_track(%d), game(%s) param(%s)", server_track, game, param);
|
||||
#if TEST_MULTIPLE_SERVERS == 1
|
||||
m_tests.insert(std::pair<unsigned, unsigned>(server_track, (unsigned)(time(0) + 3))); // 35 for fail
|
||||
printf("\nQueuing send for server track = %d", server_track);
|
||||
//replyTest(server_track, server_track * 100, "Test");
|
||||
//openRequests++;
|
||||
#endif
|
||||
}
|
||||
/*
|
||||
//-------------------------------------------
|
||||
void Client::onReplyTest(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyTest] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
*/
|
||||
//-------------------------------------------
|
||||
void Client::onRequestMoveStatus(unsigned server_track, const char *language, const unsigned transactionID)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onRequestMoveStatus] server_track(%d), language(%s), transID(%d)", server_track, language, transactionID);
|
||||
unsigned gameStatus = CT_STATUS_UNKNOWN;
|
||||
unsigned ctStatus = CT_RESULT_TIMEOUT;
|
||||
Plat_Unicode::String reason = narrowToWide("Reason String Text");
|
||||
|
||||
if (transactionID == 7000)
|
||||
{
|
||||
gameStatus = CT_STATUS_COMPLETE;
|
||||
ctStatus = CT_RESULT_SUCCESS;
|
||||
}
|
||||
else if (transactionID == 6000)
|
||||
{
|
||||
gameStatus = CT_STATUS_UNKNOWN;
|
||||
ctStatus = CT_RESULT_SUCCESS;
|
||||
}
|
||||
else if (transactionID == 5000)
|
||||
{
|
||||
gameStatus = CT_STATUS_INPROGRESS;
|
||||
ctStatus = CT_RESULT_SUCCESS;
|
||||
}
|
||||
replyMoveStatus(server_track, CT_STATUS_UNKNOWN, CT_RESULT_SUCCESS, reason.c_str(),(void *)"test");
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyMoveStatus(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyMoveStatus] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestValidateMove(unsigned server_track, const char *language, const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer, const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, bool withItems, bool override)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String sServer = sourceServer;
|
||||
Plat_Unicode::String dServer = destServer;
|
||||
Plat_Unicode::String sCharacter = sourceCharacter;
|
||||
Plat_Unicode::String dCharacter = destCharacter;
|
||||
printf("\n[onRequestValidateMove] server_track(%d), language(%s), sourceServer(%s), destServer(%s), sourceChar(%s), destChar(%s), uid(%d), destuid(%d), withItems(%d), override(%d)",
|
||||
server_track, language, wideToNarrow(sServer).c_str(), wideToNarrow(dServer).c_str(),
|
||||
wideToNarrow(sCharacter).c_str(), wideToNarrow(dCharacter).c_str(), uid, destuid, withItems, override);
|
||||
|
||||
Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
Plat_Unicode::String reason2 = narrowToWide("SUCCESS");
|
||||
Plat_Unicode::String reason3 = narrowToWide("Name Taken");
|
||||
Plat_Unicode::String reason4 = narrowToWide("Game Server down for routine maitenence");
|
||||
Plat_Unicode::String suggestedName = narrowToWide("Fippyxxx");
|
||||
Plat_Unicode::String suggestedName2 = narrowToWide("");
|
||||
|
||||
if (!strcmp(wideToNarrow(sCharacter).c_str() , "Homer"))
|
||||
{
|
||||
replyValidateMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), suggestedName2.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(dCharacter).c_str() , "Fippy"))
|
||||
{
|
||||
replyValidateMove(server_track, CT_GAMERESULT_NAME_ALREADY_TAKE, reason3.c_str(), suggestedName.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "Bart"))
|
||||
{
|
||||
replyValidateMove(server_track, CT_GAMERESULT_SOFTERROR, reason4.c_str(), suggestedName2.c_str(), (void *)"Test");
|
||||
}
|
||||
else
|
||||
replyValidateMove(server_track, CT_GAMERESULT_SUCCESS, reason2.c_str(), suggestedName2.c_str(), (void *)"Test");
|
||||
|
||||
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyValidateMove(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyValidateMove] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestMove(unsigned server_track, const char *language, const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer, const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String sServer = sourceServer;
|
||||
Plat_Unicode::String dServer = destServer;
|
||||
Plat_Unicode::String sCharacter = sourceCharacter;
|
||||
Plat_Unicode::String dCharacter = destCharacter;
|
||||
printf("\n[onRequestMove] server_track(%d), language(%s), sourceServer(%s), destServer(%s), sourceChar(%s), destChar(%s), uid(%d), destuid(%d), transID(%d) withItems(%d) override(%d)",
|
||||
server_track, language, wideToNarrow(sServer).c_str(), wideToNarrow(dServer).c_str(),
|
||||
wideToNarrow(sCharacter).c_str(), wideToNarrow(dCharacter).c_str(), uid, destuid, transactionID, withItems, override);
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("Character does not exist");
|
||||
// replyMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), "Test");
|
||||
|
||||
if (!strcmp(wideToNarrow(sCharacter).c_str() , "HomerX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("");
|
||||
replyMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "MargeX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
replyMove(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "BartX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Game Server down for routine maitenence");
|
||||
replyMove(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Order completed successfully");
|
||||
replyMove(server_track, CT_GAMERESULT_SUCCESS, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
// replyMove(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), "Test");
|
||||
// }
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("World server is down");
|
||||
// replyMove(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), "Test");
|
||||
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyMove(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyMove] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestDelete(unsigned server_track, const char *language, const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer, const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String sServer = sourceServer;
|
||||
Plat_Unicode::String dServer = destServer;
|
||||
Plat_Unicode::String sCharacter = sourceCharacter;
|
||||
Plat_Unicode::String dCharacter = destCharacter;
|
||||
printf("\n[onRequestDelete] server_track(%d), language(%s), sourceServer(%s), destServer(%s), sourceChar(%s), destChar(%s), uid(%d), destuid(%d), transID(%d), withItems(%d), override(%d)",
|
||||
server_track, language, wideToNarrow(sServer).c_str(), wideToNarrow(dServer).c_str(),
|
||||
wideToNarrow(sCharacter).c_str(), wideToNarrow(dCharacter).c_str(), uid, destuid, transactionID, withItems, override);
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("Character does not exist");
|
||||
// replyMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), "Test");
|
||||
|
||||
if (!strcmp(wideToNarrow(sCharacter).c_str() , "HomerX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("");
|
||||
replyDelete(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "MargeX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
replyDelete(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "BartX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Game Server down for routine maitenence");
|
||||
replyDelete(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Order completed successfully");
|
||||
replyDelete(server_track, CT_GAMERESULT_SUCCESS, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
// replyDelete(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), "Test");
|
||||
// }
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("World server is down");
|
||||
// replyDelete(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), "Test");
|
||||
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyDelete(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyDelete] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestRestore(unsigned server_track, const char *language, const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer, const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String sServer = sourceServer;
|
||||
Plat_Unicode::String dServer = destServer;
|
||||
Plat_Unicode::String sCharacter = sourceCharacter;
|
||||
Plat_Unicode::String dCharacter = destCharacter;
|
||||
printf("\n[onRequestRestore] server_track(%d), language(%s), sourceServer(%s), destServer(%s), sourceChar(%s), destChar(%s), uid(%d), destuid(%d), transID(%d), withItems(%d), override(%d)",
|
||||
server_track, language, wideToNarrow(sServer).c_str(), wideToNarrow(dServer).c_str(),
|
||||
wideToNarrow(sCharacter).c_str(), wideToNarrow(dCharacter).c_str(), uid, destuid, transactionID, withItems, override);
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("Character does not exist");
|
||||
// replyMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), "Test");
|
||||
|
||||
if (!strcmp(wideToNarrow(sCharacter).c_str() , "HomerX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("");
|
||||
replyRestore(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "MargeX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
replyRestore(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sCharacter).c_str() , "BartX"))
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Game Server down for routine maitenence");
|
||||
replyRestore(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Order completed successfully");
|
||||
replyRestore(server_track, CT_GAMERESULT_SUCCESS, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Plat_Unicode::String reason = narrowToWide("Player has a corpse");
|
||||
// replyRestore(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), "Test");
|
||||
// }
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("World server is down");
|
||||
// replyRestore(server_track, CT_GAMERESULT_SOFTERROR, reason.c_str(), "Test");
|
||||
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyRestore(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyRestore] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestTransferAccount(unsigned server_track,
|
||||
const unsigned uid,
|
||||
const unsigned destuid,
|
||||
const unsigned transactionID)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onRequestTransferAccount] server_track(%d), uid(%d), destuid(%d), transID(%d)",
|
||||
server_track, uid, destuid, transactionID);
|
||||
|
||||
// Plat_Unicode::String reason = narrowToWide("Character does not exist");
|
||||
// replyMove(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), "Test");
|
||||
|
||||
if (uid == 521281339)
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Tavish is too cool to move");
|
||||
replyTransferAccount(server_track, CT_GAMERESULT_HARDERROR, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else if (destuid == 549981672)
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("devula as a dest ain't cool, there is a corpse to be rezzed");
|
||||
replyTransferAccount(server_track, CT_GAMERESULT_HAS_CORPSE, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
Plat_Unicode::String reason = narrowToWide("Order completed successfully");
|
||||
replyTransferAccount(server_track, CT_GAMERESULT_SUCCESS, reason.c_str(), (void *)"Test");
|
||||
}
|
||||
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyTransferAccount(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyTransferAccount] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestCharacterList(unsigned server_track, const char *language, const CTUnicodeChar *server, const unsigned uid)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String sServer = server;
|
||||
printf("\n[onRequestCharacterList] server_track(%d), language(%s), server(%s), uid(%d)",
|
||||
server_track, language, wideToNarrow(sServer).c_str(), uid);
|
||||
|
||||
if (!strcmp(wideToNarrow(sServer).c_str() , "Tribunal"))
|
||||
{
|
||||
CTServiceCharacter chars[1];
|
||||
replyCharacterList(server_track, CT_RESULT_FAILURE, 0, chars, (void *)"Test");
|
||||
|
||||
}
|
||||
else if (!strcmp(wideToNarrow(sServer).c_str() , "Hoth"))
|
||||
{
|
||||
CTServiceCharacter chars[1];
|
||||
replyCharacterList(server_track, CT_RESULT_TIMEOUT, 0, chars, (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
CTServiceCharacter chars[3];
|
||||
chars[0].SetCanRename(true);
|
||||
chars[0].SetCanMove(true);
|
||||
chars[0].SetCanTransfer(true);
|
||||
chars[0].SetCharacter(narrowToWide("Fippy").c_str());
|
||||
chars[0].SetRenameReason(narrowToWide("Rename Reason 1").c_str());
|
||||
chars[0].SetMoveReason(narrowToWide("Move Reason 1").c_str());
|
||||
chars[0].SetTransferReason(narrowToWide("Transfer Reason 1").c_str());
|
||||
|
||||
chars[1].SetCanRename(false);
|
||||
chars[1].SetCanMove(false);
|
||||
chars[1].SetCanTransfer(false);
|
||||
chars[1].SetCharacter(narrowToWide("Melyssa").c_str());
|
||||
chars[1].SetRenameReason(narrowToWide("Rename Reason 2").c_str());
|
||||
chars[1].SetMoveReason(narrowToWide("Move Reason 2").c_str());
|
||||
chars[1].SetTransferReason(narrowToWide("Transfer Reason 2").c_str());
|
||||
|
||||
chars[2].SetCanRename(true);
|
||||
chars[2].SetCanMove(false);
|
||||
chars[2].SetCanTransfer(true);
|
||||
chars[2].SetCharacter(narrowToWide("Bald Eagle").c_str());
|
||||
chars[2].SetRenameReason(narrowToWide("Rename Reason 3").c_str());
|
||||
chars[2].SetMoveReason(narrowToWide("Move Reason 3").c_str());
|
||||
chars[2].SetTransferReason(narrowToWide("Transfer Reason 3").c_str());
|
||||
|
||||
replyCharacterList(server_track, CT_RESULT_SUCCESS, 3, chars, (void *)"Test");
|
||||
}
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyCharacterList(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyCharacterList] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestServerList(unsigned server_track, const char *language)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onRequestServerList] server_track(%d), language(%s)", server_track, language);
|
||||
|
||||
if (strcmp(language, "en"))
|
||||
{
|
||||
CTServiceServer s[1];
|
||||
replyServerList(server_track, CT_RESULT_FAILURE, 0, s, (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
CTServiceServer s[4];
|
||||
s[0].SetCanRename(true);
|
||||
s[0].SetCanMove(true);
|
||||
s[0].SetCanTransfer(true);
|
||||
s[0].SetServer(narrowToWide("Server1").c_str());
|
||||
s[0].SetRenameReason(narrowToWide("Server Rename Reason 1").c_str());
|
||||
s[0].SetMoveReason(narrowToWide("Server Move Reason 1").c_str());
|
||||
s[0].SetTransferReason(narrowToWide("Server Transfer Reason 1").c_str());
|
||||
|
||||
s[1].SetCanRename(true);
|
||||
s[1].SetCanMove(true);
|
||||
s[1].SetCanTransfer(false);
|
||||
s[1].SetServer(narrowToWide("Server2").c_str());
|
||||
s[1].SetRenameReason(narrowToWide("Server Rename Reason 2").c_str());
|
||||
s[1].SetMoveReason(narrowToWide("Server Move Reason 2").c_str());
|
||||
s[1].SetTransferReason(narrowToWide("Server Transfer Reason 2").c_str());
|
||||
|
||||
s[2].SetCanRename(true);
|
||||
s[2].SetCanMove(false);
|
||||
s[2].SetCanTransfer(true);
|
||||
s[2].SetServer(narrowToWide("Server3").c_str());
|
||||
s[2].SetRenameReason(narrowToWide("Server Rename Reason 3").c_str());
|
||||
s[2].SetMoveReason(narrowToWide("Server Move Reason 3").c_str());
|
||||
s[2].SetTransferReason(narrowToWide("Server Transfer Reason 3").c_str());
|
||||
|
||||
s[3].SetCanRename(false);
|
||||
s[3].SetCanMove(true);
|
||||
s[3].SetCanTransfer(true);
|
||||
s[3].SetServer(narrowToWide("Server4").c_str());
|
||||
s[3].SetRenameReason(narrowToWide("Server Rename Reason 4").c_str());
|
||||
s[3].SetMoveReason(narrowToWide("Server Move Reason 4").c_str());
|
||||
s[3].SetTransferReason(narrowToWide("Server Transfer Reason 4").c_str());
|
||||
|
||||
replyServerList(server_track, CT_RESULT_SUCCESS, 4, s, (void *)"Test");
|
||||
}
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyServerList(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyServerList] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onRequestDestinationServerList(unsigned server_track, const char *language, const CTUnicodeChar *character, const CTUnicodeChar *server)
|
||||
//-------------------------------------------
|
||||
{
|
||||
Plat_Unicode::String ss = server;
|
||||
Plat_Unicode::String c = character;
|
||||
|
||||
printf("\n[onRequestDestinationServerList] server_track(%d), language(%s), character(%s), server(%s)",
|
||||
server_track, language, wideToNarrow(c).c_str(), wideToNarrow(ss).c_str());
|
||||
|
||||
if (strcmp(language, "en"))
|
||||
{
|
||||
CTServiceServer s[1];
|
||||
replyServerList(server_track, CT_RESULT_FAILURE, 0, s, (void *)"Test");
|
||||
}
|
||||
else
|
||||
{
|
||||
CTServiceServer s[2];
|
||||
s[0].SetCanRename(true);
|
||||
s[0].SetCanMove(true);
|
||||
s[0].SetCanTransfer(true);
|
||||
s[0].SetServer(narrowToWide("Server1").c_str());
|
||||
s[0].SetRenameReason(narrowToWide("Server Rename Reason 1").c_str());
|
||||
s[0].SetMoveReason(narrowToWide("Server Move Reason 1").c_str());
|
||||
s[0].SetTransferReason(narrowToWide("Server Transfer Reason 1").c_str());
|
||||
|
||||
s[1].SetCanRename(true);
|
||||
s[1].SetCanMove(true);
|
||||
s[1].SetCanTransfer(false);
|
||||
s[1].SetServer(narrowToWide("Server2").c_str());
|
||||
s[1].SetRenameReason(narrowToWide("Server Rename Reason 2").c_str());
|
||||
s[1].SetMoveReason(narrowToWide("Server Move Reason 2").c_str());
|
||||
s[1].SetTransferReason(narrowToWide("Server Transfer Reason 2").c_str());
|
||||
|
||||
replyDestinationServerList(server_track, CT_RESULT_SUCCESS, 2, s, (void *)"Test");
|
||||
}
|
||||
openRequests++;
|
||||
}
|
||||
|
||||
//-------------------------------------------
|
||||
void Client::onReplyDestinationServerList(const unsigned track, const int resultCode, void *user)
|
||||
//-------------------------------------------
|
||||
{
|
||||
printf("\n[onReplyDestinationServerList] track(%d) resultCode(%s)", track, ResultString[resultCode]);
|
||||
openRequests--;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#ifndef CLIENT_H
|
||||
#define CLIENT_H
|
||||
|
||||
#include "CTServiceGameAPI/CTServiceAPI.h"
|
||||
#include <Base/Platform.h>
|
||||
#include <Unicode/UnicodeUtils.h>
|
||||
#include "CTServiceGameAPI/CTCommon/RequestStrings.h"
|
||||
|
||||
using namespace CTService;
|
||||
|
||||
#define TEST_MULTIPLE_SERVERS 0
|
||||
#define TEST_FUNCTIONS 0
|
||||
#define ACT_AS_SERVER 1
|
||||
|
||||
#define GING_TEST_STATUS 1 // test OnRequestMoveStatus
|
||||
#define GING_TEST_VALIDATE 2 // test OnRequestValidateMove
|
||||
#define GING_TEST_MOVE 3 // test OnRequestMove
|
||||
#define GING_TEST_CHARACTER 4 // test OnRequestCharacterList
|
||||
#define GING_TEST_SERVER 5 // test OnRequestServerList
|
||||
#define GING_TEST_DESTSERVER 6 // test OnRequestDestinationServerList
|
||||
#define GING_TEST_DELETE 7 // test OnRequestDelete
|
||||
#define GING_TEST_RESTORE 8 // test OnRequestRestore
|
||||
#define GING_TEST_TRANSFER_ACCOUNT 9 // test OnRequestRestore
|
||||
|
||||
//----------------------------------------
|
||||
class Client : public CTServiceAPI
|
||||
//----------------------------------------
|
||||
{
|
||||
public:
|
||||
Client(const char *hostName, const char *game);
|
||||
virtual ~Client();
|
||||
|
||||
void onConnect(const char *host, const short port, const short current, const short max);
|
||||
void onDisconnect(const char *host, const short port, const short current, const short max);
|
||||
|
||||
bool m_connected;
|
||||
|
||||
//callbacks
|
||||
|
||||
// void onTest(const unsigned track, const int resultCode, const unsigned value, void *user);
|
||||
// void onReplyTest(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyMoveStatus(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyValidateMove(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyMove(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyDelete(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyRestore(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyTransferAccount(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyCharacterList(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyServerList(const unsigned track, const int resultCode, void *user);
|
||||
void onReplyDestinationServerList(const unsigned track, const int resultCode, void *user);
|
||||
|
||||
void onServerTest(const unsigned server_track, const char *game, const char *param);
|
||||
void onRequestMoveStatus(const unsigned server_track, const char *language,
|
||||
const unsigned transactionID);
|
||||
void onRequestValidateMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, bool withItems, bool override);
|
||||
void onRequestMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override);
|
||||
void onRequestDelete(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override);
|
||||
void onRequestRestore(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems, bool override);
|
||||
void onRequestTransferAccount(const unsigned server_track,
|
||||
const unsigned uid,
|
||||
const unsigned destuid,
|
||||
const unsigned transactionID);
|
||||
void onRequestCharacterList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *server, const unsigned uid);
|
||||
void onRequestServerList(const unsigned server_track, const char *language);
|
||||
void onRequestDestinationServerList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *character, const CTUnicodeChar *server);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
#include <stdio.h>
|
||||
#pragma warning (disable: 4786)
|
||||
#include "Client.h"
|
||||
|
||||
#ifdef WIN32
|
||||
#include <winsock.h>
|
||||
#include <conio.h>
|
||||
#endif
|
||||
|
||||
using namespace CTService;
|
||||
|
||||
unsigned openRequests = 0;
|
||||
CTServiceAPI *waitclient = NULL;
|
||||
std::map<unsigned, unsigned> m_tests;
|
||||
std::string game_code;
|
||||
|
||||
//--------------------------------------------
|
||||
void wait()
|
||||
//--------------------------------------------
|
||||
{
|
||||
while (openRequests > 0 || m_tests.size())
|
||||
{
|
||||
waitclient->process();
|
||||
Base::sleep(1);
|
||||
#if TEST_MULTIPLE_SERVERS == 1
|
||||
for(std::map<unsigned, unsigned>::iterator iter = m_tests.begin(); iter != m_tests.end(); iter++)
|
||||
{
|
||||
if ((unsigned)time(0) > (*iter).second)
|
||||
{
|
||||
unsigned strack = (*iter).first;
|
||||
printf("\nProcessing send for server track = %d (%d remain)", strack, m_tests.size() - 1);
|
||||
waitclient->replyTest(strack, strack * 100, "Test");
|
||||
openRequests++;
|
||||
m_tests.erase(strack);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------
|
||||
int main(int argc, char *argv[])
|
||||
//--------------------------------------------
|
||||
{
|
||||
if (argc < 2)
|
||||
{
|
||||
printf("\nParams required: <game code>\n");
|
||||
while(1);
|
||||
}
|
||||
game_code = argv[1];
|
||||
|
||||
Client client("localhost:2000", game_code.c_str());
|
||||
waitclient = &client;
|
||||
printf("\nCreated Client object, game = %s", game_code.c_str());
|
||||
|
||||
while (!client.m_connected)
|
||||
{
|
||||
client.process();
|
||||
Base::sleep(1);
|
||||
}
|
||||
|
||||
#if ACT_AS_SERVER == 1
|
||||
printf("\n\nListening for requests from server....\n");
|
||||
while (1)
|
||||
{
|
||||
client.process();
|
||||
Base::sleep(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
//begin the testing !!
|
||||
printf("\nCommencing Tests...\n");
|
||||
|
||||
#if TEST_FUNCTIONS == 1
|
||||
std::string testString = "FIP1";
|
||||
client.requestTest(testString.c_str(), GING_TEST_STATUS, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
client.requestTest(testString.c_str(), GING_TEST_MOVE, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
client.requestTest(testString.c_str(), GING_TEST_VALIDATE, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
client.requestTest(testString.c_str(), GING_TEST_CHARACTER, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
client.requestTest(testString.c_str(), GING_TEST_SERVER, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
client.requestTest(testString.c_str(), GING_TEST_DESTSERVER, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
#endif
|
||||
|
||||
#if TEST_MULTIPLE_SERVERS == 1
|
||||
std::string testString = "FIP1";
|
||||
client.requestTest(testString.c_str(), 10, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP2";
|
||||
client.requestTest(testString.c_str(), 100, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP3";
|
||||
client.requestTest(testString.c_str(), 1000, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP4";
|
||||
client.requestTest(testString.c_str(), 10000, (void *)"Test");
|
||||
openRequests++;
|
||||
|
||||
testString = "FIP2";
|
||||
client.requestTest(testString.c_str(), 10, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP3";
|
||||
client.requestTest(testString.c_str(), 100, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP4";
|
||||
client.requestTest(testString.c_str(), 1000, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP1";
|
||||
client.requestTest(testString.c_str(), 10000, (void *)"Test");
|
||||
openRequests++;
|
||||
|
||||
testString = "FIP3";
|
||||
client.requestTest(testString.c_str(), 10, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP4";
|
||||
client.requestTest(testString.c_str(), 100, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP1";
|
||||
client.requestTest(testString.c_str(), 1000, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP2";
|
||||
client.requestTest(testString.c_str(), 10000, (void *)"Test");
|
||||
openRequests++;
|
||||
|
||||
testString = "FIP4";
|
||||
client.requestTest(testString.c_str(), 10, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP1";
|
||||
client.requestTest(testString.c_str(), 100, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP2";
|
||||
client.requestTest(testString.c_str(), 1000, (void *)"Test");
|
||||
openRequests++;
|
||||
testString = "FIP3";
|
||||
client.requestTest(testString.c_str(), 10000, (void *)"Test");
|
||||
openRequests++;
|
||||
wait();
|
||||
#endif
|
||||
|
||||
wait();
|
||||
return 0;
|
||||
}
|
||||
+142
@@ -0,0 +1,142 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="7.10"
|
||||
Name="TestClient"
|
||||
ProjectGUID="{493B2E28-66F8-4628-84A9-43CF5485CFFE}"
|
||||
Keyword="Win32Proj">
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"/>
|
||||
</Platforms>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="Debug"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="..,../.."
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="TRUE"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="5"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="4"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/TestClient.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="TRUE"
|
||||
ProgramDatabaseFile="$(OutDir)/TestClient.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="Release"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
CharacterSet="2">
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../../utils,../../CTCommon,../"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE,EXTERNAL_DISTRO;NAMESPACE="CTService""
|
||||
RuntimeLibrary="4"
|
||||
UsePrecompiledHeader="0"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="TRUE"
|
||||
DebugInformationFormat="3"/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalDependencies="ws2_32.lib"
|
||||
OutputFile="$(OutDir)/TestClient.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="TRUE"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"/>
|
||||
<Tool
|
||||
Name="VCManagedWrapperGeneratorTool"/>
|
||||
<Tool
|
||||
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
|
||||
<File
|
||||
RelativePath=".\Client.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Main.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}">
|
||||
<File
|
||||
RelativePath=".\Client.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}">
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
||||
@@ -0,0 +1,9 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstUnicode.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// FirstUnicode.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatFirstUnicode_H
|
||||
#define INCLUDED_PlatFirstUnicode_H
|
||||
|
||||
// ======================================================================
|
||||
// stl unref inline func removed
|
||||
|
||||
#ifdef WIN32
|
||||
|
||||
// C4514 unreferenced inline/local function has been removed
|
||||
// C4786 'identifier' : identifier was truncated to 'number' characters in the debug information
|
||||
|
||||
#pragma warning (disable:4514 4786)
|
||||
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Unicode.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
#include "Unicode.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
@@ -0,0 +1,58 @@
|
||||
// ======================================================================
|
||||
// Unicode.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// jwatson
|
||||
//
|
||||
// Basic Unicode primitives and string handling/manipulating functions
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatUnicode_H
|
||||
#define INCLUDED_PlatUnicode_H
|
||||
|
||||
#if WIN32
|
||||
#pragma warning (disable:4710)
|
||||
#pragma warning (disable:4786)
|
||||
// stl warning func not inlined
|
||||
#pragma warning (disable:4514)
|
||||
#endif
|
||||
|
||||
#include <string>
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
typedef unsigned short unicode_char_t;
|
||||
|
||||
/**
|
||||
* Standard Unicode string is UTF-16
|
||||
*/
|
||||
typedef std::basic_string<unicode_char_t> String;
|
||||
|
||||
/**
|
||||
* NarrowString is a ascii string.
|
||||
*/
|
||||
|
||||
typedef std::string NarrowString;
|
||||
|
||||
const unicode_char_t whitespace [] = { ' ', '\n', '\r', '\t', 0 };
|
||||
const unicode_char_t endlines [] = { '\r', '\n', 0 };
|
||||
const char ascii_whitespace [] = { ' ', '\n', '\r', '\t', 0 };
|
||||
const char ascii_endlines [] = { '\r', '\n', 0 };
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeBlocks.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Unicode 3.0 compliant Blocks.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
#include "UnicodeBlocks.h"
|
||||
|
||||
// ======================================================================
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
using namespace Plat_Unicode::Blocks;
|
||||
using Plat_Unicode::unicode_char_t;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
const Plat_Unicode::Blocks::RawData Plat_Unicode::Blocks::Mapping::ms_defaultBlockData [] =
|
||||
{
|
||||
{ Basic_Latin, "Basic Latin",0x0000,0x007F },
|
||||
{ Latin_1_Supplement,"Latin-1 Supplement",0x0080,0x00FF },
|
||||
{ Latin_Extended_A, "Latin Extended-A",0x0100,0x017F },
|
||||
{ Latin_Extended_B, "Latin Extended-B",0x0180,0x024F },
|
||||
{ IPA_Extensions, "IPA Extensions",0x0250,0x02AF },
|
||||
{ Spacing_Modifier_Letters, "Spacing Modifier Letters",0x02B0,0x02FF },
|
||||
{ Combining_Diacritical_Marks, "Combining Diacritical Marks",0x0300,0x036F },
|
||||
{ Greek, "Greek",0x0370,0x03FF },
|
||||
{ Cyrillic, "Cyrillic",0x0400,0x04FF },
|
||||
{ Armenian, "Armenian",0x0530,0x058F },
|
||||
{ Hebrew, "Hebrew",0x0590,0x05FF },
|
||||
{ Arabic, "Arabic",0x0600,0x06FF },
|
||||
{ Syriac, "Syriac ",0x0700,0x074F },
|
||||
{ Thaana, "Thaana",0x0780,0x07BF },
|
||||
{ Devanagari, "Devanagari",0x0900,0x097F },
|
||||
{ Bengali, "Bengali",0x0980,0x09FF },
|
||||
{ Gurmukhi, "Gurmukhi",0x0A00,0x0A7F },
|
||||
{ Gujarati, "Gujarati",0x0A80,0x0AFF },
|
||||
{ Oriya, "Oriya",0x0B00,0x0B7F },
|
||||
{ Tamil, "Tamil",0x0B80,0x0BFF },
|
||||
{ Telugu, "Telugu",0x0C00,0x0C7F },
|
||||
{ Kannada, "Kannada",0x0C80,0x0CFF },
|
||||
{ Malayalam, "Malayalam",0x0D00,0x0D7F },
|
||||
{ Sinhala, "Sinhala",0x0D80,0x0DFF },
|
||||
{ Thai, "Thai",0x0E00,0x0E7F },
|
||||
{ Lao, "Lao",0x0E80,0x0EFF },
|
||||
{ Tibetan, "Tibetan",0x0F00,0x0FFF },
|
||||
{ Myanmar, "Myanmar ",0x1000,0x109F },
|
||||
{ Georgian, "Georgian",0x10A0,0x10FF },
|
||||
{ Hangul_Jamo, "Hangul Jamo",0x1100,0x11FF },
|
||||
{ Ethiopic, "Ethiopic",0x1200,0x137F },
|
||||
{ Cherokee, "Cherokee",0x13A0,0x13FF },
|
||||
{ Unified_Canadian_Aboriginal_Syllabics, "Unified Canadian Aboriginal Syllabics",0x1400,0x167F },
|
||||
{ Ogham, "Ogham",0x1680,0x169F },
|
||||
{ Runic, "Runic",0x16A0,0x16FF },
|
||||
{ Khmer, "Khmer",0x1780,0x17FF },
|
||||
{ Mongolian, "Mongolian",0x1800,0x18AF },
|
||||
{ Latin_Extended_Additional, "Latin Extended Additional",0x1E00,0x1EFF },
|
||||
{ Greek_Extended, "Greek Extended",0x1F00,0x1FFF },
|
||||
{ General_Punctuation, "General Punctuation",0x2000,0x206F },
|
||||
{ Superscripts_and_Subscripts, "Superscripts and Subscripts",0x2070,0x209F },
|
||||
{ Currency_Symbols, "Currency Symbols",0x20A0,0x20CF },
|
||||
{ Combining_Marks_for_Symbols, "Combining Marks for Symbols",0x20D0,0x20FF },
|
||||
{ Letterlike_Symbols, "Letterlike Symbols",0x2100,0x214F },
|
||||
{ Number_Forms, "Number Forms",0x2150,0x218F },
|
||||
{ Arrows, "Arrows",0x2190,0x21FF },
|
||||
{ Mathematical_Operators, "Mathematical Operators",0x2200,0x22FF },
|
||||
{ Miscellaneous_Technical, "Miscellaneous Technical",0x2300,0x23FF },
|
||||
{ Control_Pictures, "Control Pictures",0x2400,0x243F },
|
||||
{ Optical_Character_Recognition, "Optical Character Recognition",0x2440,0x245F },
|
||||
{ Enclosed_Alphanumerics, "Enclosed Alphanumerics",0x2460,0x24FF },
|
||||
{ Box_Drawing, "Box Drawing",0x2500,0x257F },
|
||||
{ Block_Elements, "Block Elements",0x2580,0x259F },
|
||||
{ Geometric_Shapes, "Geometric Shapes",0x25A0,0x25FF },
|
||||
{ Miscellaneous_Symbols, "Miscellaneous Symbols",0x2600,0x26FF },
|
||||
{ Dingbats, "Dingbats",0x2700,0x27BF },
|
||||
{ Braille_Patterns, "Braille Patterns",0x2800,0x28FF },
|
||||
{ CJK_Radicals_Supplement, "CJK Radicals Supplement",0x2E80,0x2EFF },
|
||||
{ Kangxi_Radicals, "Kangxi Radicals",0x2F00,0x2FDF },
|
||||
{ Ideographic_Description_Characters, "Ideographic Description Characters",0x2FF0,0x2FFF },
|
||||
{ CJK_Symbols_and_Punctuation, "CJK Symbols and Punctuation",0x3000,0x303F },
|
||||
{ Hiragana, "Hiragana",0x3040,0x309F },
|
||||
{ Katakana, "Katakana",0x30A0,0x30FF },
|
||||
{ Bopomofo, "Bopomofo",0x3100,0x312F },
|
||||
{ Hangul_Compatibility_Jamo, "Hangul Compatibility Jamo",0x3130,0x318F },
|
||||
{ Kanbun, "Kanbun",0x3190,0x319F },
|
||||
{ Bopomofo_Extended, "Bopomofo Extended",0x31A0,0x31BF },
|
||||
{ Enclosed_CJK_Letters_and_Months, "Enclosed CJK Letters and Months",0x3200,0x32FF },
|
||||
{ CJK_Compatibility, "CJK Compatibility",0x3300,0x33FF },
|
||||
{ CJK_Unified_Ideographs_Extension_A, "CJK Unified Ideographs Extension A",0x3400,0x4DB5 },
|
||||
{ CJK_Unified_Ideographs, "CJK Unified Ideographs",0x4E00,0x9FFF },
|
||||
{ Yi_Syllables, "Yi Syllables",0xA000,0xA48F },
|
||||
{ Yi_Radicals, "Yi Radicals",0xA490,0xA4CF },
|
||||
{ Hangul_Syllables, "Hangul Syllables",0xAC00,0xD7A3 },
|
||||
{ High_Surrogates, "High Surrogates",0xD800,0xDB7F },
|
||||
{ High_Private_Use_Surrogates, "High Private Use Surrogates",0xDB80,0xDBFF },
|
||||
{ Low_Surrogates, "Low Surrogates",0xDC00,0xDFFF },
|
||||
{ Private_Use, "Private Use",0xE000,0xF8FF },
|
||||
{ CJK_Compatibility_Ideographs, "CJK Compatibility Ideographs",0xF900,0xFAFF },
|
||||
{ Alphabetic_Presentation_Forms, "Alphabetic Presentation Forms",0xFB00,0xFB4F },
|
||||
{ Arabic_Presentation_Forms_A, "Arabic Presentation Forms-A",0xFB50,0xFDFF },
|
||||
{ Combining_Half_Marks, "Combining Half Marks",0xFE20,0xFE2F },
|
||||
{ CJK_Compatibility_Forms, "CJK Compatibility Forms",0xFE30,0xFE4F },
|
||||
{ Small_Form_Variants, "Small Form Variants",0xFE50,0xFE6F },
|
||||
{ Arabic_Presentation_Forms_B, "Arabic Presentation Forms-B",0xFE70,0xFEFE },
|
||||
{ Specials_1, "Specials",0xFEFF,0xFEFF },
|
||||
{ Halfwidth_and_Fullwidth_Forms, "Halfwidth and Fullwidth Forms",0xFF00,0xFFEF },
|
||||
{ Specials_2, "Specials 2",0xFFF0,0xFFFD },
|
||||
{ End_Block_Ids, "End Block Ids",0xFFFE,0xFFFF }
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
Mapping * Mapping::ms_singleton = 0;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Initialize the singleton. This must be called before mapping is used.
|
||||
*/
|
||||
|
||||
void Mapping::initSingleton ()
|
||||
{
|
||||
explicitDestroy ();
|
||||
ms_singleton = new Mapping (ms_defaultBlockData);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Destroys the singleton
|
||||
*/
|
||||
|
||||
void Mapping::explicitDestroy ()
|
||||
{
|
||||
if (ms_singleton)
|
||||
delete ms_singleton;
|
||||
|
||||
ms_singleton = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Construct a Mapping from an array of RawData
|
||||
*/
|
||||
|
||||
Mapping::Mapping (const RawData dataArray []) :
|
||||
m_idMap (),
|
||||
m_nameMap (),
|
||||
m_errorData ()
|
||||
{
|
||||
|
||||
size_t i = 0;
|
||||
for (; dataArray [i].m_id != End_Block_Ids; ++i)
|
||||
{
|
||||
m_idMap [dataArray[i].m_id] = Data (dataArray [i]);
|
||||
m_nameMap [dataArray[i].m_name] = Data (dataArray [i]);
|
||||
}
|
||||
|
||||
m_errorData = Data (dataArray [i]);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Construct a complete set of code points in this block.
|
||||
* @param idset should enter this function empty
|
||||
*/
|
||||
|
||||
const std::set<unicode_char_t> & Data::generateFilteredIdSet (std::set<unicode_char_t> & idset) const
|
||||
{
|
||||
{
|
||||
for (unicode_char_t i = m_start; i < m_end; ++i)
|
||||
{
|
||||
idset.insert (i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (RangeGroups_t::const_iterator iter = m_rangeGroups.begin (); iter != m_rangeGroups.end (); ++iter)
|
||||
{
|
||||
const RangeGroup & rg = *iter;
|
||||
|
||||
if (rg.m_isInclusive)
|
||||
{
|
||||
for (RangeGroup::Ranges_t::const_iterator rg_iter = rg.m_ranges.begin (); rg_iter != rg.m_ranges.end (); ++rg_iter)
|
||||
{
|
||||
for (unicode_char_t i = (*rg_iter).m_low; i <= (*rg_iter).m_high; ++i)
|
||||
{
|
||||
idset.insert (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (RangeGroup::Ranges_t::const_iterator rg_iter = rg.m_ranges.begin (); rg_iter != rg.m_ranges.end (); ++rg_iter)
|
||||
{
|
||||
for (unicode_char_t i = (*rg_iter).m_low; i <= (*rg_iter).m_high; ++i)
|
||||
{
|
||||
idset.erase (i);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return idset;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Add a range group with a given string representation. Valid strings include hexadecimal numbers, dashes, and commas.
|
||||
* @param inclusive indicates if this group should be additive or subtractive. It is an error to attempt to add code points outside the Block's gross range.
|
||||
*/
|
||||
|
||||
bool Data::addRangeGroup (bool inclusive, const Plat_Unicode::NarrowString & str)
|
||||
{
|
||||
RangeGroup rg;
|
||||
rg.m_isInclusive = inclusive;
|
||||
|
||||
size_t tokenStartPos = 0;
|
||||
|
||||
while (tokenStartPos != NarrowString::npos)
|
||||
{
|
||||
size_t tokenCommaPos = str.find_first_of (',', tokenStartPos);
|
||||
|
||||
size_t tokenDashPos = str.find_first_of ('-', tokenStartPos);
|
||||
|
||||
Range rng;
|
||||
|
||||
// this is a dashed range
|
||||
if (tokenDashPos < tokenCommaPos)
|
||||
{
|
||||
rng.m_low = static_cast<unicode_char_t> (strtoul ( str.substr (tokenStartPos, tokenDashPos - tokenStartPos).c_str (), 0, 16));
|
||||
tokenStartPos = str.find_first_not_of ('-', tokenDashPos);
|
||||
|
||||
if (tokenStartPos == NarrowString::npos)
|
||||
return false;
|
||||
|
||||
rng.m_high = static_cast<unicode_char_t> (strtoul (str.substr (tokenStartPos, tokenCommaPos - tokenStartPos).c_str (), 0, 16));
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rng.m_high = rng.m_low = static_cast<unicode_char_t> (strtoul ( str.substr (tokenStartPos, tokenCommaPos - tokenStartPos).c_str (), 0, 16));
|
||||
}
|
||||
|
||||
rg.m_ranges.push_back (rng);
|
||||
|
||||
tokenStartPos = str.find_first_not_of (',', tokenCommaPos);
|
||||
}
|
||||
|
||||
m_rangeGroups.push_back (rg);
|
||||
return true;
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
// ===================================================================== },
|
||||
@@ -0,0 +1,404 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeBlocks.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Unicode 3.0 compliant Blocks.
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatUnicodeBlocks_H
|
||||
#define INCLUDED_PlatUnicodeBlocks_H
|
||||
|
||||
#if WIN32
|
||||
// stl warning func not inlined
|
||||
#pragma warning (disable:4710)
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include "Unicode.h"
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
// ======================================================================
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
namespace Blocks
|
||||
{
|
||||
/**
|
||||
* The enum values are precisely the beginning of the represented block range.
|
||||
* These blocks are precisely the blocks defined by Unicode 3.0.
|
||||
*/
|
||||
enum Id
|
||||
{
|
||||
Basic_Latin = 0x0000,
|
||||
Latin_1_Supplement = 0x0080,
|
||||
Latin_Extended_A = 0x0100,
|
||||
Latin_Extended_B = 0x0180,
|
||||
IPA_Extensions = 0x0250,
|
||||
Spacing_Modifier_Letters = 0x02B0,
|
||||
Combining_Diacritical_Marks = 0x0300,
|
||||
Greek = 0x0370,
|
||||
Cyrillic = 0x0400,
|
||||
Armenian = 0x0530,
|
||||
Hebrew = 0x0590,
|
||||
Arabic = 0x0600,
|
||||
Syriac = 0x0700,
|
||||
Thaana = 0x0780,
|
||||
Devanagari = 0x0900,
|
||||
Bengali = 0x0980,
|
||||
Gurmukhi = 0x0A00,
|
||||
Gujarati = 0x0A80,
|
||||
Oriya = 0x0B00,
|
||||
Tamil = 0x0B80,
|
||||
Telugu = 0x0C00,
|
||||
Kannada = 0x0C80,
|
||||
Malayalam = 0x0D00,
|
||||
Sinhala = 0x0D80,
|
||||
Thai = 0x0E00,
|
||||
Lao = 0x0E80,
|
||||
Tibetan = 0x0F00,
|
||||
Myanmar = 0x1000,
|
||||
Georgian = 0x10A0,
|
||||
Hangul_Jamo = 0x1100,
|
||||
Ethiopic = 0x1200,
|
||||
Cherokee = 0x13A0,
|
||||
Unified_Canadian_Aboriginal_Syllabics = 0x1400,
|
||||
Ogham = 0x1680,
|
||||
Runic = 0x16A0,
|
||||
Khmer = 0x1780,
|
||||
Mongolian = 0x1800,
|
||||
Latin_Extended_Additional = 0x1E00,
|
||||
Greek_Extended = 0x1F00,
|
||||
General_Punctuation = 0x2000,
|
||||
Superscripts_and_Subscripts = 0x2070,
|
||||
Currency_Symbols = 0x20A0,
|
||||
Combining_Marks_for_Symbols = 0x20D0,
|
||||
Letterlike_Symbols = 0x2100,
|
||||
Number_Forms = 0x2150,
|
||||
Arrows = 0x2190,
|
||||
Mathematical_Operators = 0x2200,
|
||||
Miscellaneous_Technical = 0x2300,
|
||||
Control_Pictures = 0x2400,
|
||||
Optical_Character_Recognition = 0x2440,
|
||||
Enclosed_Alphanumerics = 0x2460,
|
||||
Box_Drawing = 0x2500,
|
||||
Block_Elements = 0x2580,
|
||||
Geometric_Shapes = 0x25A0,
|
||||
Miscellaneous_Symbols = 0x2600,
|
||||
Dingbats = 0x2700,
|
||||
Braille_Patterns = 0x2800,
|
||||
CJK_Radicals_Supplement = 0x2E80,
|
||||
Kangxi_Radicals = 0x2F00,
|
||||
Ideographic_Description_Characters = 0x2FF0,
|
||||
CJK_Symbols_and_Punctuation = 0x3000,
|
||||
Hiragana = 0x3040,
|
||||
Katakana = 0x30A0,
|
||||
Bopomofo = 0x3100,
|
||||
Hangul_Compatibility_Jamo = 0x3130,
|
||||
Kanbun = 0x3190,
|
||||
Bopomofo_Extended = 0x31A0,
|
||||
Enclosed_CJK_Letters_and_Months = 0x3200,
|
||||
CJK_Compatibility = 0x3300,
|
||||
CJK_Unified_Ideographs_Extension_A = 0x3400,
|
||||
CJK_Unified_Ideographs = 0x4E00,
|
||||
Yi_Syllables = 0xA000,
|
||||
Yi_Radicals = 0xA490,
|
||||
Hangul_Syllables = 0xAC00,
|
||||
High_Surrogates = 0xD800,
|
||||
High_Private_Use_Surrogates = 0xDB80,
|
||||
Low_Surrogates = 0xDC00,
|
||||
Private_Use = 0xE000,
|
||||
CJK_Compatibility_Ideographs = 0xF900,
|
||||
Alphabetic_Presentation_Forms = 0xFB00,
|
||||
Arabic_Presentation_Forms_A = 0xFB50,
|
||||
Combining_Half_Marks = 0xFE20,
|
||||
CJK_Compatibility_Forms = 0xFE30,
|
||||
Small_Form_Variants = 0xFE50,
|
||||
Arabic_Presentation_Forms_B = 0xFE70,
|
||||
Specials_1 = 0xFEFF,
|
||||
Halfwidth_and_Fullwidth_Forms = 0xFF00,
|
||||
Specials_2 = 0xFFF0,
|
||||
End_Block_Ids = 0xFFFE
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A simple pair representing an inclusive range of values
|
||||
*/
|
||||
|
||||
struct Range
|
||||
{
|
||||
unicode_char_t m_high;
|
||||
unicode_char_t m_low;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A group of ranges that can be additive or subtractive (inclusive or non)
|
||||
*/
|
||||
|
||||
struct RangeGroup
|
||||
{
|
||||
bool m_isInclusive;
|
||||
typedef std::vector<Range> Ranges_t;
|
||||
Ranges_t m_ranges;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* RawData is a simple aggregate data struct used to construct the more complex Data objects
|
||||
*/
|
||||
struct RawData
|
||||
{
|
||||
Id m_id;
|
||||
const char * m_name;
|
||||
unicode_char_t m_start;
|
||||
unicode_char_t m_end;
|
||||
};
|
||||
|
||||
/**
|
||||
* Data is the representation of a single Unicode block.
|
||||
* Including the Id, name, gross start-end range, and a set of RangeGroups (usually subtractive)
|
||||
*/
|
||||
struct Data
|
||||
{
|
||||
Id m_id;
|
||||
NarrowString m_name;
|
||||
unicode_char_t m_start;
|
||||
unicode_char_t m_end;
|
||||
|
||||
typedef std::vector <RangeGroup> RangeGroups_t;
|
||||
RangeGroups_t m_rangeGroups;
|
||||
|
||||
explicit Data (const RawData & rhs);
|
||||
Data ();
|
||||
|
||||
const std::set<unicode_char_t> & generateFilteredIdSet (std::set<unicode_char_t> & ) const;
|
||||
|
||||
bool addRangeGroup (bool inclusive, const NarrowString & str);
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Singleton class.
|
||||
*
|
||||
* Mapping creates a method of mapping block Ids _or_ names to Block Data objects.
|
||||
* @todo: Data objects are duplicate for each map, need to optimize.
|
||||
*/
|
||||
|
||||
class Mapping
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
explicit Mapping (const RawData dataArray[]);
|
||||
static const Mapping & getDefaultMapping ();
|
||||
static void explicitDestroy ();
|
||||
|
||||
typedef std::map <Id, Data> IdMap_t;
|
||||
typedef std::map <NarrowString, Data> NameMap_t;
|
||||
|
||||
const Data & findBlock (Id id) const;
|
||||
Data & findBlock (Id id);
|
||||
const Data & findBlock (const NarrowString &) const;
|
||||
const Data & findBlock (unicode_char_t code) const;
|
||||
|
||||
const IdMap_t & getIdMap () const;
|
||||
|
||||
bool addBlock (const Data & data);
|
||||
|
||||
static const RawData ms_defaultBlockData [];
|
||||
|
||||
private:
|
||||
|
||||
Mapping ();
|
||||
Mapping (const Mapping & rhs);
|
||||
Mapping & operator= (const Mapping & rhs);
|
||||
|
||||
static void initSingleton ();
|
||||
|
||||
static Mapping * ms_singleton;
|
||||
|
||||
IdMap_t m_idMap;
|
||||
NameMap_t m_nameMap;
|
||||
|
||||
Data m_errorData;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Convert a RawData into a Data object
|
||||
*/
|
||||
|
||||
inline Data::Data (const RawData & rhs) :
|
||||
m_id (rhs.m_id),
|
||||
m_name (rhs.m_name),
|
||||
m_start (rhs.m_start),
|
||||
m_end (rhs.m_end),
|
||||
m_rangeGroups ()
|
||||
{
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
|
||||
inline Data::Data () :
|
||||
m_id (End_Block_Ids),
|
||||
m_name (),
|
||||
m_start (0),
|
||||
m_end (0),
|
||||
m_rangeGroups ()
|
||||
{
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Static singleton accessor
|
||||
*/
|
||||
|
||||
inline const Mapping & Mapping::getDefaultMapping ()
|
||||
{
|
||||
if (ms_singleton)
|
||||
return *ms_singleton;
|
||||
|
||||
initSingleton ();
|
||||
return *ms_singleton;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Add a block Data object to the mapping. If the block already exists
|
||||
* in the mapping, the new data overwrites the old.
|
||||
*/
|
||||
|
||||
inline bool Mapping::addBlock (const Data & data)
|
||||
{
|
||||
m_idMap [data.m_id] = data;
|
||||
m_nameMap [data.m_name] = data;
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Locate the block data by Id.
|
||||
* @return a Data with End_Block_Ids Id if the block was not found
|
||||
*/
|
||||
|
||||
inline const Data & Mapping::findBlock (Id id) const
|
||||
{
|
||||
|
||||
const IdMap_t::const_iterator iter = m_idMap.find (id);
|
||||
if (iter != m_idMap.end ())
|
||||
return (*iter).second;
|
||||
else
|
||||
return m_errorData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Locate the block data by Id.
|
||||
* @return a Data with End_Block_Ids Id if the block was not found
|
||||
*/
|
||||
|
||||
inline Data & Mapping::findBlock (Id id)
|
||||
{
|
||||
|
||||
const IdMap_t::iterator iter = m_idMap.find (id);
|
||||
if (iter != m_idMap.end ())
|
||||
return (*iter).second;
|
||||
else
|
||||
return m_errorData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Locate the block data by Name.
|
||||
* @return a Data with End_Block_Ids Id if the block was not found
|
||||
*/
|
||||
|
||||
inline const Data & Mapping::findBlock (const NarrowString & name) const
|
||||
{
|
||||
|
||||
const NameMap_t::const_iterator iter = m_nameMap.find (name);
|
||||
if (iter != m_nameMap.end ())
|
||||
return (*iter).second;
|
||||
else
|
||||
return m_errorData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Locate the block data by code point.
|
||||
* @return a Data with End_Block_Ids Id if the block was not found. This only tests if the code point is in the gross range of the located block.
|
||||
*/
|
||||
|
||||
inline const Data & Mapping::findBlock (unicode_char_t code) const
|
||||
{
|
||||
|
||||
const IdMap_t::const_iterator iter = m_idMap.lower_bound (static_cast<Id>(code));
|
||||
if (iter != m_idMap.end () && code <= (*iter).second.m_end)
|
||||
return (*iter).second;
|
||||
else
|
||||
return m_errorData;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Gets the Id->Data map.
|
||||
*/
|
||||
|
||||
inline const Mapping::IdMap_t & Mapping::getIdMap () const
|
||||
{
|
||||
return m_idMap;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Tests a character to see if belongs in an ideograph range
|
||||
*/
|
||||
|
||||
inline bool isIdeograph (unicode_char_t code)
|
||||
{
|
||||
return ((code >= static_cast<unicode_char_t>(CJK_Unified_Ideographs_Extension_A) && code < static_cast<unicode_char_t>(Yi_Syllables)) ||
|
||||
(code >= static_cast<unicode_char_t>(Hangul_Syllables) && code < static_cast<unicode_char_t>(CJK_Compatibility_Ideographs)));
|
||||
}
|
||||
|
||||
} //-- namespace Blocks
|
||||
|
||||
}; // -- namespace Unicode
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
#endif
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
#if defined (linux) && ((__GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL == 3) || (__GNUC__ == 2 && __GNUC_MINOR__ > 96))
|
||||
#include <bits/char_traits.h>
|
||||
#include "Unicode.h"
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
using namespace NAMESPACE::Plat_Unicode;
|
||||
#else
|
||||
using namespace Plat_Unicode;
|
||||
#endif
|
||||
|
||||
namespace std
|
||||
{
|
||||
|
||||
void char_traits<unicode_char_t>::assign(unicode_char_t &__c1, const unicode_char_t &__c2)
|
||||
{
|
||||
__c1 = __c2;
|
||||
}
|
||||
|
||||
bool char_traits<unicode_char_t>::eq(const unicode_char_t &__c1, const unicode_char_t &__c2)
|
||||
{
|
||||
return __c1 == __c2;
|
||||
}
|
||||
|
||||
bool char_traits<unicode_char_t>::lt(const unicode_char_t &__c1, const unicode_char_t &__c2)
|
||||
{
|
||||
return __c1 < __c2;
|
||||
}
|
||||
|
||||
unicode_char_t *char_traits<unicode_char_t>::copy(unicode_char_t *__s1, const unicode_char_t *__s2, size_t __n)
|
||||
{
|
||||
return(__n == 0 ? __s1 : (unicode_char_t*)memcpy(__s1, __s2, __n * sizeof(unicode_char_t)));
|
||||
}
|
||||
|
||||
unicode_char_t *char_traits<unicode_char_t>::move(unicode_char_t *__s1, const unicode_char_t* __s2, size_t _Sz)
|
||||
{
|
||||
return (_Sz == 0 ? __s1 : (unicode_char_t*)memmove(__s1, __s2, _Sz * sizeof(unicode_char_t)));
|
||||
}
|
||||
|
||||
const unicode_char_t *char_traits<unicode_char_t>::find(const unicode_char_t* __s, size_t __n, const unicode_char_t & __c)
|
||||
{
|
||||
for( ; __n > 0; ++__s, --__n)
|
||||
if(eq(*__s, __c))
|
||||
return __s;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t char_traits<unicode_char_t>::length(const unicode_char_t *__s)
|
||||
{
|
||||
size_t __i;
|
||||
for(__i = 0; !eq(__s[__i], 0); ++__i);
|
||||
return __i;
|
||||
}
|
||||
|
||||
unicode_char_t *char_traits<unicode_char_t>::assign(unicode_char_t *__s, size_t __n, unicode_char_t __c)
|
||||
{
|
||||
for(size_t __i = 0; __i < __n; ++__i)
|
||||
__s[__i] = __c;
|
||||
return __s;
|
||||
}
|
||||
|
||||
int char_traits<unicode_char_t>::compare(const unicode_char_t *__s1, const unicode_char_t *__s2, size_t __n)
|
||||
{
|
||||
for(size_t __i = 0; __i < __n; ++__i)
|
||||
if(!eq(__s1[__i], __s2[__i]))
|
||||
return __s1[__i] < __s2[__i] ? -1 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Plat_UnicodeCharData.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Plat_Unicode 3.0 compliant Character data formats
|
||||
// The data is loaded dynamically from the Plat_UnicodeData.txt definition file
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
#include "UnicodeCharacterData.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#define CAT_NAME(s) { CharData::s, #s }
|
||||
|
||||
const CharData::CategoryName CharData::ms_categoryNames [] =
|
||||
{
|
||||
|
||||
CAT_NAME (Lu), // Letter, Uppercase
|
||||
CAT_NAME (Ll), // Letter, Lowercase
|
||||
CAT_NAME (Lt), // Letter, Titlecase
|
||||
CAT_NAME (Lm), // Letter, Modifier
|
||||
CAT_NAME (Lo), // Letter, Other
|
||||
CAT_NAME (Mn), // Mark, Non-Spacing
|
||||
CAT_NAME (Mc), // Mark, Spacing Combining
|
||||
CAT_NAME (Me), // Mark, Enclosing
|
||||
CAT_NAME (Nd), // Number, Decimal Digit
|
||||
CAT_NAME (Nl), // Number, Letter
|
||||
CAT_NAME (No), // Number, Other
|
||||
CAT_NAME (Pc), // Punctuation, Connector
|
||||
CAT_NAME (Pd), // Punctuation, Dash
|
||||
CAT_NAME (Ps), // Punctuation, Open
|
||||
CAT_NAME (Pe), // Punctuation, Close
|
||||
CAT_NAME (Pi), // Punctuation, Initial quote (may behave like Ps or Pe depending on usage)
|
||||
CAT_NAME (Pf), // Punctuation, Final quote (may behave like Ps or Pe depending on usage)
|
||||
CAT_NAME (Po), // Punctuation, Other
|
||||
CAT_NAME (Sm), // Symbol, Math
|
||||
CAT_NAME (Sc), // Symbol, Currency
|
||||
CAT_NAME (Sk), // Symbol, Modifier
|
||||
CAT_NAME (So), // Symbol, Other
|
||||
CAT_NAME (Zs), // Separator, Space
|
||||
CAT_NAME (Zl), // Separator, Line
|
||||
CAT_NAME (Zp), // Separator, Paragraph
|
||||
CAT_NAME (Cc), // Other, Control
|
||||
CAT_NAME (Cf), // Other, Format
|
||||
CAT_NAME (Cs), // Other, Surrogate
|
||||
CAT_NAME (Co), // Other, Private Use
|
||||
CAT_NAME (Cn) // Other, Not Assigned (no characters in the file have this property)
|
||||
};
|
||||
|
||||
#undef CAT_NAME
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
// ======================================================================
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeCharData.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Unicode 3.0 compliant Character data formats
|
||||
// The data is loaded dynamically from the UnicodeData.txt definition file
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatUnicodeCharData_H
|
||||
#define INCLUDED_PlatUnicodeCharData_H
|
||||
|
||||
#if WIN32
|
||||
// stl warning func not inlined
|
||||
#pragma warning (disable:4710)
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
typedef unsigned short unicode_char_t; //lint !e761 redundant typedef
|
||||
|
||||
struct CharData;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
struct CharData
|
||||
{
|
||||
|
||||
enum Category
|
||||
{
|
||||
Lu, // Letter, Uppercase
|
||||
Ll, // Letter, Lowercase
|
||||
Lt, // Letter, Titlecase
|
||||
Lm, // Letter, Modifier
|
||||
Lo, // Letter, Other
|
||||
Mn, // Mark, Non-Spacing
|
||||
Mc, // Mark, Spacing Combining
|
||||
Me, // Mark, Enclosing
|
||||
Nd, // Number, Decimal Digit
|
||||
Nl, // Number, Letter
|
||||
No, // Number, Other
|
||||
Pc, // Punctuation, Connector
|
||||
Pd, // Punctuation, Dash
|
||||
Ps, // Punctuation, Open
|
||||
Pe, // Punctuation, Close
|
||||
Pi, // Punctuation, Initial quote (may behave like Ps or Pe depending on usage)
|
||||
Pf, // Punctuation, Final quote (may behave like Ps or Pe depending on usage)
|
||||
Po, // Punctuation, Other
|
||||
Sm, // Symbol, Math
|
||||
Sc, // Symbol, Currency
|
||||
Sk, // Symbol, Modifier
|
||||
So, // Symbol, Other
|
||||
Zs, // Separator, Space
|
||||
Zl, // Separator, Line
|
||||
Zp, // Separator, Paragraph
|
||||
Cc, // Other, Control
|
||||
Cf, // Other, Format
|
||||
Cs, // Other, Surrogate
|
||||
Co, // Other, Private Use
|
||||
Cn // Other, Not Assigned (no characters in the file have this property)
|
||||
};
|
||||
|
||||
|
||||
struct CategoryName
|
||||
{
|
||||
Category m_category;
|
||||
const char * m_str;
|
||||
};
|
||||
|
||||
static const CategoryName ms_categoryNames[];
|
||||
|
||||
unicode_char_t m_code;
|
||||
Category m_category;
|
||||
|
||||
/**
|
||||
* Note: this Unicode system only supports upper and lower case.
|
||||
* Titlecase is considered uppercase. The case of a character
|
||||
* is determined by its category (Lu,Ll,or Lt)
|
||||
*/
|
||||
|
||||
unicode_char_t m_reverseCase;
|
||||
|
||||
bool isLowerCase () const;
|
||||
bool isUpperCase () const;
|
||||
|
||||
unicode_char_t toUpper () const;
|
||||
unicode_char_t toLower () const;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Is this character lowercase.
|
||||
*/
|
||||
inline bool CharData::isLowerCase () const
|
||||
{
|
||||
return m_category == Ll;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Returns true for upper and title case
|
||||
*/
|
||||
inline bool CharData::isUpperCase () const
|
||||
{
|
||||
return m_category == Lu || m_category == Lt;
|
||||
}
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
+360
@@ -0,0 +1,360 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeCharDataMap.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Unicode 3.0 compliant Character data formats
|
||||
// The data is loaded dynamically from the UnicodeData.txt definition file
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
#include "UnicodeCharacterDataMap.h"
|
||||
#include "UnicodeBlocks.h"
|
||||
#include "UnicodeCharacterData.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <string>
|
||||
#include <cassert>
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
CharDataMap * CharDataMap::ms_singleton = 0;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CharDataMap::CharDataMap () :
|
||||
m_blockIds (),
|
||||
m_contiguousData (0),
|
||||
m_map (),
|
||||
m_dataIsValid (false)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
CharDataMap::~CharDataMap ()
|
||||
{
|
||||
m_map.clear ();
|
||||
m_blockIds.clear ();
|
||||
|
||||
if (m_contiguousData)
|
||||
{
|
||||
delete[] m_contiguousData;
|
||||
m_contiguousData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void CharDataMap::initSingleton ()
|
||||
{
|
||||
explicitDestroy ();
|
||||
|
||||
// TODO: default blocks?
|
||||
ms_singleton = new CharDataMap ();
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
void CharDataMap::explicitDestroy ()
|
||||
{
|
||||
if (ms_singleton)
|
||||
delete ms_singleton;
|
||||
|
||||
ms_singleton = 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
typedef std::map <std::string, CharData::Category> CategoryMap_t;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
|
||||
/**
|
||||
* Load a CharData from a string buffer representing a file.
|
||||
* The bufpos is set to the beginning of a line after this method returns.
|
||||
*/
|
||||
|
||||
|
||||
inline bool populateDataFromBuffer (size_t desiredCode,
|
||||
CharData & charData,
|
||||
const std::string & buffer,
|
||||
size_t & bufpos,
|
||||
const CategoryMap_t & cmap)
|
||||
{
|
||||
|
||||
size_t endpos = 0;
|
||||
|
||||
bool found = false;
|
||||
|
||||
do
|
||||
{
|
||||
size_t tokenNum = 0;
|
||||
|
||||
while ( (endpos = buffer.find ( ';', bufpos)) != std::string::npos ) //lint !e737 // loss of sign in promotion - STL bug
|
||||
{
|
||||
// code value
|
||||
if (tokenNum == 0)
|
||||
{
|
||||
const size_t code = static_cast <size_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
|
||||
|
||||
// we passed the desired line, so it must not exist
|
||||
if (code > desiredCode)
|
||||
return found;
|
||||
// not there yet
|
||||
else if (code < desiredCode)
|
||||
break;
|
||||
|
||||
charData.m_code = static_cast<unicode_char_t> (code);
|
||||
}
|
||||
|
||||
// General Category
|
||||
else if (tokenNum == 2)
|
||||
{
|
||||
// all category codes are currently 2 characters long
|
||||
if (endpos - bufpos > 2)
|
||||
break;
|
||||
|
||||
const CategoryMap_t::const_iterator find_iter = cmap.find (buffer.substr (bufpos, 2));
|
||||
|
||||
if (find_iter == cmap.end ())
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
charData.m_category = (*find_iter).second;
|
||||
}
|
||||
|
||||
// Uppercase mapping
|
||||
else if (charData.isLowerCase ())
|
||||
{
|
||||
if (tokenNum == 12)
|
||||
{
|
||||
if (endpos - bufpos > 1)
|
||||
charData.m_reverseCase = static_cast<unicode_char_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Lowercase mapping
|
||||
else if (tokenNum == 13)
|
||||
{
|
||||
if (endpos - bufpos > 1)
|
||||
charData.m_reverseCase = static_cast<unicode_char_t> (strtoul (buffer.substr (bufpos, endpos - bufpos).c_str (), 0, 16));
|
||||
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
bufpos = endpos + 1;
|
||||
++tokenNum;
|
||||
|
||||
}
|
||||
}
|
||||
while ( (bufpos = buffer.find ('\n', bufpos)) != std::string::npos && //lint !e737 // loss of sign in promotion - STL bug
|
||||
(bufpos = buffer.find_first_not_of ('\n', bufpos + 1)) != std::string::npos); //lint !e737 // loss of sign in promotion - STL bug
|
||||
|
||||
return found;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a map of CharData's from a UnicodeData.txt standard Unicode 3.0 file, which has been packed into a buffer
|
||||
*/
|
||||
|
||||
CharDataMap::ErrorCode CharDataMap::generateMapFromBuffer (const Blocks::Mapping & blockMapping, const std::string & str_buf)
|
||||
{
|
||||
m_dataIsValid = false;
|
||||
|
||||
m_map.clear ();
|
||||
|
||||
//-- create the category map for use by the inline population function
|
||||
CategoryMap_t cmap;
|
||||
|
||||
{
|
||||
size_t i = 0;
|
||||
for (; CharData::ms_categoryNames [i].m_category != CharData::Cn; ++i)
|
||||
{
|
||||
cmap [CharData::ms_categoryNames [i].m_str] = CharData::ms_categoryNames [i].m_category;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::set<unicode_char_t> IdSet_t;
|
||||
|
||||
IdSet_t idSet;
|
||||
|
||||
{
|
||||
for (BlockIdSet_t::const_iterator iter = m_blockIds.begin (); iter != m_blockIds.end (); ++iter)
|
||||
{
|
||||
const Blocks::Data & blockData = blockMapping.findBlock (*iter);
|
||||
|
||||
if (blockData.m_id != Blocks::End_Block_Ids)
|
||||
{
|
||||
blockData.generateFilteredIdSet (idSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//-- read all the desired chars from file.
|
||||
//-- the file must be sorted by code
|
||||
|
||||
size_t bufpos = 0;
|
||||
size_t validChars = 0;
|
||||
|
||||
{
|
||||
|
||||
for (IdSet_t::const_iterator iter = idSet.begin (); iter != idSet.end (); ++iter)
|
||||
{
|
||||
CharData * data = new CharData;
|
||||
|
||||
assert (data); //lint !e1924 // c-style cast. MSVC bug
|
||||
|
||||
data->m_reverseCase = 0;
|
||||
|
||||
if (populateDataFromBuffer (*iter, *data, str_buf, bufpos, cmap) == false)
|
||||
{
|
||||
delete data;
|
||||
continue;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
++validChars;
|
||||
m_map[data->m_code] = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--
|
||||
//-- pack all the char data into a contiguous block of memory
|
||||
//--
|
||||
|
||||
if (m_contiguousData)
|
||||
delete[] m_contiguousData;
|
||||
|
||||
m_contiguousData = new CharData [validChars];
|
||||
|
||||
assert (m_contiguousData); //lint !e1924 // c-style cast. MSVC bug
|
||||
|
||||
size_t dataIndex = 0;
|
||||
|
||||
for (Map_t::iterator iter = m_map.begin (); iter != m_map.end (); ++iter, ++dataIndex)
|
||||
{
|
||||
m_contiguousData [dataIndex] = *(*iter).second;
|
||||
delete (*iter).second;
|
||||
(*iter).second = &m_contiguousData [dataIndex];
|
||||
}
|
||||
|
||||
m_dataIsValid = true;
|
||||
|
||||
return ERR_SUCCESS;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Create a map of CharData's from a UnicodeData.txt standard Unicode 3.0 file, using cstdio
|
||||
*/
|
||||
|
||||
CharDataMap::ErrorCode CharDataMap::generateMap (const Blocks::Mapping & blockMapping, const char * filename)
|
||||
{
|
||||
//-- load data from file as a big std::string
|
||||
//-- read all the desired chars from file.
|
||||
//-- the file must be sorted by code
|
||||
|
||||
FILE * fl = fopen (filename, "rb");
|
||||
|
||||
if (fl == 0)
|
||||
{
|
||||
return ERR_NO_FILE;
|
||||
}
|
||||
|
||||
fseek (fl, 0, SEEK_END);
|
||||
|
||||
size_t fileLen = static_cast<size_t>(ftell (fl));
|
||||
|
||||
fseek (fl, 0, SEEK_SET);
|
||||
|
||||
char * buffer = new char [fileLen + 1];
|
||||
buffer [fileLen] = 0;
|
||||
|
||||
assert (buffer); //lint !e1924 // c-style cast. MSVC bug
|
||||
|
||||
if (fread (buffer, fileLen, 1, fl) != 1)
|
||||
{
|
||||
delete[] buffer;
|
||||
fclose (fl);
|
||||
return ERR_READ_FAILED;
|
||||
}
|
||||
|
||||
if (fclose (fl))
|
||||
{
|
||||
delete[] buffer;
|
||||
return ERR_CLOSE_FAILED;
|
||||
}
|
||||
|
||||
std::string str_buf (buffer, fileLen);
|
||||
|
||||
delete[] buffer;
|
||||
|
||||
return generateMapFromBuffer (blockMapping, str_buf);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Add a block Id that this CharacterDataMap is concerned with. Does not change the data map.
|
||||
*/
|
||||
|
||||
void CharDataMap::addBlock (Blocks::Id id)
|
||||
{
|
||||
m_blockIds.insert (id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Remove a block Id that this CharacterDataMap is concerned with. Does not change the data map.
|
||||
*/
|
||||
|
||||
void CharDataMap::removeBlock (Blocks::Id id)
|
||||
{
|
||||
m_blockIds.erase (id);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Add a block Id that this CharacterDataMap is concerned with. Does not change the data map.
|
||||
*/
|
||||
|
||||
void CharDataMap::clearBlocks ()
|
||||
{
|
||||
m_blockIds.clear ();
|
||||
}
|
||||
|
||||
// ======================================================================
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeCharDataMap.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// This contains Unicode 3.0 compliant Character data formats
|
||||
// The data is loaded dynamically from the UnicodeData.txt definition file
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatUnicodeCharDataMap_H
|
||||
#define INCLUDED_PlatUnicodeCharDataMap_H
|
||||
|
||||
#if WIN32
|
||||
// stl warning func not inlined
|
||||
#pragma warning (disable:4710)
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "UnicodeBlocks.h"
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
struct CharData;
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Singleton class that allows mapping from code points to CharData objects. This will be
|
||||
* used to change case of characters, character category testing, etc...
|
||||
* A CharacterDataMap has a set of Unicode::Block::Id's with which it is solely concerned.
|
||||
* In this way, you may instantiate many different CharDataMaps if needed.
|
||||
*/
|
||||
|
||||
class CharDataMap
|
||||
{
|
||||
public:
|
||||
|
||||
enum ErrorCode
|
||||
{
|
||||
ERR_SUCCESS = 0,
|
||||
ERR_NO_FILE,
|
||||
ERR_READ_FAILED,
|
||||
ERR_CLOSE_FAILED,
|
||||
ERR_CHAR_NOT_FOUND,
|
||||
ERR_FILE_TOO_SHORT
|
||||
};
|
||||
|
||||
typedef std::map <unicode_char_t, CharData *> Map_t;
|
||||
|
||||
static CharDataMap & getDefaultMap ();
|
||||
static void explicitDestroy ();
|
||||
|
||||
CharDataMap ();
|
||||
~CharDataMap ();
|
||||
|
||||
void addBlock (Blocks::Id id);
|
||||
void removeBlock (Blocks::Id id);
|
||||
void clearBlocks ();
|
||||
|
||||
ErrorCode generateMap (const Blocks::Mapping & blockMapping, const char * filename);
|
||||
ErrorCode generateMapFromBuffer (const Blocks::Mapping & blockMapping, const std::string & str_buf);
|
||||
|
||||
bool isValid () const;
|
||||
|
||||
const CharData * findCharData (unicode_char_t code) const;
|
||||
|
||||
const Map_t & getMap () const;
|
||||
|
||||
private:
|
||||
|
||||
static void initSingleton ();
|
||||
|
||||
typedef std::set<Blocks::Id> BlockIdSet_t;
|
||||
|
||||
BlockIdSet_t m_blockIds;
|
||||
CharData * m_contiguousData;
|
||||
Map_t m_map;
|
||||
bool m_dataIsValid;
|
||||
|
||||
static CharDataMap * ms_singleton;
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Singleton accessor.
|
||||
*/
|
||||
|
||||
inline CharDataMap & CharDataMap::getDefaultMap ()
|
||||
{
|
||||
if (ms_singleton)
|
||||
return *ms_singleton;
|
||||
|
||||
initSingleton ();
|
||||
return *ms_singleton;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Has the data been loaded successfully?
|
||||
*/
|
||||
|
||||
inline bool CharDataMap::isValid () const
|
||||
{
|
||||
return m_dataIsValid;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find a CharData for the given code point.
|
||||
* @return null if no CharData exists for this code point
|
||||
*/
|
||||
|
||||
inline const CharData * CharDataMap::findCharData (const unicode_char_t code) const
|
||||
{
|
||||
if (isValid ())
|
||||
{
|
||||
const Map_t::const_iterator iter = m_map.find (code);
|
||||
if (iter != m_map.end ())
|
||||
return (*iter).second;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Get the data mapping
|
||||
*/
|
||||
|
||||
inline const CharDataMap::Map_t & CharDataMap::getMap () const
|
||||
{
|
||||
return m_map;
|
||||
}
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
// ======================================================================
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,285 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// Unicode.cpp
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// ======================================================================
|
||||
|
||||
#include "FirstUnicode.h"
|
||||
#include "UnicodeUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#if defined (linux)
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
// ======================================================================
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return by value a lowered version of nstr
|
||||
*/
|
||||
|
||||
NarrowString toLower (const NarrowString & nstr)
|
||||
{
|
||||
NarrowString retval (nstr.c_str());
|
||||
std::transform (retval.begin (), retval.end (), retval.begin (), tolower);
|
||||
return retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return by value an uppered version of nstr
|
||||
*/
|
||||
|
||||
NarrowString toUpper (const NarrowString & nstr)
|
||||
{
|
||||
NarrowString retval (nstr);
|
||||
std::transform (retval.begin (), retval.end (), retval.begin (), toupper);
|
||||
return retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return by value a lowered version of str.
|
||||
* This currently only works properly with ASCII.
|
||||
* @todo: implement this for all unicode blocks.
|
||||
*/
|
||||
|
||||
String toLower (const String & nstr)
|
||||
{
|
||||
String retval (nstr);
|
||||
std::transform (retval.begin (), retval.end (), retval.begin (), tolower);
|
||||
return retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Return by value an uppered version of str.
|
||||
* This currently only works properly with ASCII.
|
||||
* @todo: implement this for all unicode blocks.
|
||||
*/
|
||||
|
||||
String toUpper (const String & nstr)
|
||||
{
|
||||
String retval (nstr);
|
||||
std::transform (retval.begin (), retval.end (), retval.begin (), toupper);
|
||||
return retval;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Append src to dst, padding the field as needed, and truncating the field if desired.
|
||||
*/
|
||||
|
||||
String & appendStringField (String & dst, const String & src, size_t width, FieldAlignment fa, unicode_char_t pad, bool truncate)
|
||||
{
|
||||
|
||||
if (src.length () > width && truncate)
|
||||
return dst.append (src.substr (0, width));
|
||||
|
||||
if (src.length () >= width)
|
||||
return dst.append (src);
|
||||
|
||||
const size_t diff = width - src.length ();
|
||||
|
||||
if (fa == FA_RIGHT)
|
||||
dst.append (diff, pad);
|
||||
else if (fa == FA_CENTER)
|
||||
dst.append (diff/2, pad);
|
||||
|
||||
dst.append (src);
|
||||
|
||||
if (fa == FA_LEFT)
|
||||
dst.append (diff, pad);
|
||||
else if (fa == FA_CENTER)
|
||||
dst.append (diff - diff/2, pad);
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find the first token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
||||
*/
|
||||
|
||||
bool getFirstToken (const String & str, size_t pos, size_t & endpos, String & token, const unicode_char_t * sepChars)
|
||||
{
|
||||
const size_t first_nonspace = str.find_first_not_of ( sepChars, pos );
|
||||
|
||||
if (first_nonspace != std::string::npos)
|
||||
{
|
||||
const size_t first_space = str.find_first_of (sepChars, first_nonspace );
|
||||
|
||||
if (first_space != std::string::npos)
|
||||
token = str.substr (first_nonspace, first_space - first_nonspace);
|
||||
else
|
||||
token = str.substr (first_nonspace);
|
||||
|
||||
endpos = first_space;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find the first token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
||||
*/
|
||||
|
||||
bool getFirstToken (const NarrowString & str, size_t pos, size_t & endpos, NarrowString & token, const char * sepChars)
|
||||
{
|
||||
const size_t first_nonspace = str.find_first_not_of ( sepChars, pos );
|
||||
|
||||
if (first_nonspace != std::string::npos)
|
||||
{
|
||||
const size_t first_space = str.find_first_of (sepChars, first_nonspace );
|
||||
if (first_space != std::string::npos)
|
||||
token = str.substr (first_nonspace, first_space - first_nonspace);
|
||||
else
|
||||
token = str.substr (first_nonspace);
|
||||
|
||||
endpos = first_space;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find the nth token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
||||
* pos is updated to point to the first character of token in str.
|
||||
*/
|
||||
|
||||
bool getNthToken (const String & str, const size_t n, size_t & pos, size_t & endpos, String & token, const unicode_char_t * sepChars)
|
||||
{
|
||||
size_t desired_first_nonspace = 0;
|
||||
size_t space = 0;
|
||||
|
||||
//check for trivial case
|
||||
if(n == 0)
|
||||
desired_first_nonspace = pos;
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
//find the first whitespace character
|
||||
space = str.find_first_of ( sepChars, pos );
|
||||
if (space == std::string::npos)
|
||||
return false;
|
||||
//now find the next non-whitespace character after it
|
||||
desired_first_nonspace = str.find_first_not_of( sepChars, space );
|
||||
if (desired_first_nonspace == std::string::npos)
|
||||
return false;
|
||||
pos = desired_first_nonspace;
|
||||
}
|
||||
}
|
||||
//find the end of the token
|
||||
const size_t first_space = str.find_first_of (sepChars, desired_first_nonspace );
|
||||
//now get that token
|
||||
if (first_space != std::string::npos)
|
||||
token = str.substr (desired_first_nonspace, first_space - desired_first_nonspace);
|
||||
else
|
||||
token = str.substr (desired_first_nonspace);
|
||||
|
||||
endpos = desired_first_nonspace;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Find the nth token in str, starting at pos. The value of the token is placed in the token field. endpos is updated to point past the token.
|
||||
* pos is updated to point to the first character of token in str.
|
||||
*/
|
||||
|
||||
bool getNthToken (const NarrowString & str, const size_t n, size_t & pos, size_t & endpos, NarrowString & token, const char * sepChars)
|
||||
{
|
||||
size_t desired_first_nonspace = 0;
|
||||
size_t space = 0;
|
||||
|
||||
//check for trivial case
|
||||
if(n == 0)
|
||||
desired_first_nonspace = pos;
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
//find the first whitespace character
|
||||
space = str.find_first_of ( sepChars, pos );
|
||||
if (space == std::string::npos)
|
||||
return false;
|
||||
//now find the next non-whitespace character after it
|
||||
desired_first_nonspace = str.find_first_not_of( sepChars, space );
|
||||
if (desired_first_nonspace == std::string::npos)
|
||||
return false;
|
||||
pos = desired_first_nonspace;
|
||||
}
|
||||
}
|
||||
//find the end of the token
|
||||
const size_t first_space = str.find_first_of (sepChars, desired_first_nonspace );
|
||||
//now get that token
|
||||
if (first_space != std::string::npos)
|
||||
token = str.substr (desired_first_nonspace, first_space - desired_first_nonspace);
|
||||
else
|
||||
token = str.substr (desired_first_nonspace);
|
||||
|
||||
endpos = desired_first_nonspace;
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
// ======================================================================
|
||||
// Extensions to Base/Archive for String
|
||||
// ======================================================================
|
||||
|
||||
namespace Base
|
||||
{
|
||||
void get(Base::ByteStream::ReadIterator& source, Plat_Unicode::String& target)
|
||||
{
|
||||
unsigned int size = 0;
|
||||
get (source, size);
|
||||
|
||||
const unsigned char * const buf = source.getBuffer();
|
||||
const Plat_Unicode::unicode_char_t * const ubuf = reinterpret_cast<const Plat_Unicode::unicode_char_t *>(buf);
|
||||
|
||||
target.assign (ubuf, ubuf + size);
|
||||
|
||||
const unsigned int readSize = size * sizeof (Plat_Unicode::unicode_char_t);
|
||||
source.advance(readSize);
|
||||
// printf("%d\n", target.size());
|
||||
}
|
||||
|
||||
void put(Base::ByteStream& target, const Plat_Unicode::String& source)
|
||||
{
|
||||
const unsigned int size = source.size ();
|
||||
put (target, size);
|
||||
target.put (source.data(), size * sizeof (Plat_Unicode::unicode_char_t));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,362 @@
|
||||
// ======================================================================
|
||||
//
|
||||
// UnicodeUtils.h
|
||||
// copyright (c) 2001 Sony Online Entertainment
|
||||
//
|
||||
// jwatson
|
||||
//
|
||||
// Basic Unicode string handling/manipulating functions
|
||||
// ======================================================================
|
||||
|
||||
#ifndef INCLUDED_PlatUnicodeUtils_H
|
||||
#define INCLUDED_PlatUnicodeUtils_H
|
||||
|
||||
#if WIN32
|
||||
// stl warning func not inlined
|
||||
#pragma warning (disable:4710)
|
||||
#pragma warning (disable:4786)
|
||||
#endif
|
||||
|
||||
#include "Unicode.h"
|
||||
#include <Base/Archive.h>
|
||||
#ifdef WIN32
|
||||
#include <ctype.h>
|
||||
#else
|
||||
#include <wctype.h>
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
namespace NAMESPACE
|
||||
{
|
||||
#endif
|
||||
|
||||
namespace Plat_Unicode
|
||||
{
|
||||
|
||||
String narrowToWide (const NarrowString & nstr);
|
||||
String & narrowToWide (const NarrowString & nstr, String & str); //lint !e1929 // function returning a reference
|
||||
|
||||
NarrowString wideToNarrow (const String & nstr);
|
||||
NarrowString & wideToNarrow (const String & nstr, NarrowString & str); //lint !e1929 // function returning a reference
|
||||
NarrowString toLower (const NarrowString & nstr);
|
||||
NarrowString toUpper (const NarrowString & nstr);
|
||||
String toLower (const String & nstr);
|
||||
String toUpper (const String & nstr);
|
||||
|
||||
const String getTrim (const String & str, const unicode_char_t * white = whitespace);
|
||||
String & trim (String & str, const unicode_char_t * white = whitespace);
|
||||
|
||||
bool getFirstToken (const String & str, size_t pos, size_t & endpos, String & token, const unicode_char_t * sepChars = whitespace);
|
||||
bool getNthToken (const String & str, const size_t n, size_t & pos, size_t & endpos, String & token, const unicode_char_t * sepChars = whitespace);
|
||||
size_t skipWhitespace (const String & str, size_t pos, const unicode_char_t * white = whitespace);
|
||||
|
||||
const NarrowString getTrim (const NarrowString & str, const char * white = ascii_whitespace);
|
||||
NarrowString & trim (NarrowString & str, const char * white = ascii_whitespace);
|
||||
|
||||
bool getFirstToken (const NarrowString & str, size_t pos, size_t & endpos, NarrowString & token, const char * sepChars = ascii_whitespace);
|
||||
bool getNthToken (const NarrowString & str, const size_t n, size_t & pos, size_t & endpos, NarrowString & token, const char * sepChars = ascii_whitespace);
|
||||
size_t skipWhitespace (const NarrowString & str, size_t pos, const char * white = ascii_whitespace);
|
||||
|
||||
enum FieldAlignment
|
||||
{
|
||||
FA_LEFT,
|
||||
FA_RIGHT,
|
||||
FA_CENTER
|
||||
};
|
||||
|
||||
String & appendStringField (String & dst, const String & src, size_t width, FieldAlignment fa = FA_LEFT, unicode_char_t pad = ' ', bool truncate = false);
|
||||
String & appendStringField (String & dst, const NarrowString & src, size_t width, FieldAlignment fa = FA_LEFT, unicode_char_t pad = ' ', bool truncate = false);
|
||||
|
||||
/**
|
||||
* Compare substrings of str2 and str1, each starting with pos and containing n characters
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Compares str1 and str2, where str1 is a String and str2 is templated,
|
||||
* thus could be a std::string as well. Set reverseCompare to true if you
|
||||
* want to begin comparison at end of string--a useful optimization if your
|
||||
* strings tend to differ at the end.
|
||||
*/
|
||||
template <typename T> bool caseInsensitiveCompare (const String & str1, const T & str2, bool reverseCompare = false)
|
||||
{
|
||||
const size_t len1 = str1.size();
|
||||
const size_t len2 = str2.size();
|
||||
|
||||
if (len1 != len2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!reverseCompare)
|
||||
{
|
||||
for (size_t i = 0; i < len1; i++)
|
||||
{
|
||||
if ( towlower(str1[i]) != towlower(str2[i]) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (size_t i = len1; i > 0; i--)
|
||||
{
|
||||
if ( towlower(str1[i-1]) != towlower(str2[i-1]) )
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares str1 and str2, where str1 is a String and str2 is templated,
|
||||
* thus could be a std::string as well. Unlike caseInsensitiveCompare, this
|
||||
* version returns an int for < or > comparisons, and comparison must start
|
||||
* at the front. Note that this kind of comparison does not allow the shortcut
|
||||
* of first comparing sizes--every character must be compared up to the last one.
|
||||
*/
|
||||
template <typename T> int caseInsensitiveCompareInt (const String & str1, const T & str2)
|
||||
{
|
||||
const size_t len1 = str1.size();
|
||||
const size_t len2 = str2.size();
|
||||
|
||||
size_t len;
|
||||
if (len1 < len2)
|
||||
len = len1;
|
||||
else
|
||||
len = len2;
|
||||
|
||||
// iterate over smallest length
|
||||
for (size_t i = 0; i < len; i++)
|
||||
{
|
||||
if ( towlower(str1[i]) < towlower(str2[i]) )
|
||||
return -1;
|
||||
else if ( towlower(str1[i]) > towlower(str2[i]) )
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Equal so far, thus: if len1 < len2, the result is less-than, else
|
||||
// if len1 = len2, the result is equal, else the result is greater-than.
|
||||
|
||||
if (len1 < len2)
|
||||
return -1;
|
||||
else if (len1 == len2)
|
||||
return 0;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Optimized implementation of isWhitespace. Must be kept in line with ::whitespace array
|
||||
*/
|
||||
|
||||
template <typename T> bool isWhitespace (T c)
|
||||
{
|
||||
return c == ' ' || c == '\n' || c == '\r' || c == '\t';
|
||||
}
|
||||
|
||||
/*
|
||||
* @todo: uncomment when caseInsensitiveCompare matures
|
||||
*
|
||||
template <typename T> class CompareNoCasePredicate
|
||||
{
|
||||
public:
|
||||
bool operator()( T & a, T & b ) const
|
||||
{
|
||||
return caseInsensitiveCompare (a, b) < 0;
|
||||
};
|
||||
};
|
||||
|
||||
template <typename T> class EqualsNoCasePredicate
|
||||
{
|
||||
public:
|
||||
bool operator()( T & a, T & b ) const
|
||||
{
|
||||
return caseInsensitiveCompare (a, b) == 0;
|
||||
};
|
||||
};
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
//-- implementation
|
||||
//-----------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Utility to convert a string and obtain the result by value
|
||||
*/
|
||||
|
||||
inline String narrowToWide (const NarrowString & nstr)
|
||||
{
|
||||
// return String (nstr.begin (), nstr.end ()); // STLPort original
|
||||
String s;
|
||||
unsigned index = 0;
|
||||
s.resize(nstr.size());
|
||||
const NarrowString::const_iterator end = nstr.end();
|
||||
for (NarrowString::const_iterator iter = nstr.begin(); iter != end; iter++)
|
||||
{
|
||||
s[index++] = *iter;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Utility to convert a string and obtain the result by reference
|
||||
*/
|
||||
|
||||
inline String & narrowToWide (const NarrowString & nstr, String & str)
|
||||
{
|
||||
// return str.assign (nstr.begin (), nstr.end ()); // STLport original
|
||||
unsigned index = 0;
|
||||
str.resize(nstr.size());
|
||||
const NarrowString::const_iterator end = nstr.end();
|
||||
for (NarrowString::const_iterator iter = nstr.begin(); iter != end; iter++)
|
||||
{
|
||||
str[index++] = *iter;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
|
||||
* Utility to convert a string and obtain the result by value
|
||||
|
||||
* This should only be used when the Unicode string is known to contain only 8 bit assignable values
|
||||
|
||||
*/
|
||||
|
||||
inline NarrowString wideToNarrow (const String & str)
|
||||
{
|
||||
// return NarrowString (str.begin (), str.end ()); // STLPort original
|
||||
NarrowString s;
|
||||
unsigned index = 0;
|
||||
s.resize(str.size());
|
||||
const String::const_iterator end = str.end();
|
||||
for (String::const_iterator iter = str.begin(); iter != end; iter++)
|
||||
{
|
||||
s[index++] = (char)*iter;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
|
||||
* Utility to convert a string and obtain the result by reference
|
||||
|
||||
* This should only be used when the Unicode string is known to contain only 8 bit assignable values
|
||||
|
||||
*/
|
||||
|
||||
inline NarrowString & wideToNarrow (const String & str, NarrowString & nstr)
|
||||
{
|
||||
// return nstr.assign (str.begin (), str.end ()); // STLPort original
|
||||
unsigned index = 0;
|
||||
nstr.resize(str.size());
|
||||
const String::const_iterator end = str.end();
|
||||
for (String::const_iterator iter = str.begin(); iter != end; iter++)
|
||||
{
|
||||
nstr[index++] = (char)*iter;
|
||||
}
|
||||
return nstr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trimmed version of str by value.
|
||||
*/
|
||||
|
||||
inline const String getTrim (const String & str, const unicode_char_t * white)
|
||||
{
|
||||
const size_t first_nonspace = str.find_first_not_of ( white );
|
||||
const size_t last_nonspace = str.find_last_not_of ( white );
|
||||
return (first_nonspace == str.npos ? str : str.substr (first_nonspace, last_nonspace == str.npos ? last_nonspace : (last_nonspace - first_nonspace + 1)));
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Trim the specified string and return a reference to it.
|
||||
*/
|
||||
|
||||
inline String & trim (String & str, const unicode_char_t * white)
|
||||
{
|
||||
return (str = getTrim (str, white));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the trimmed version of str by value.
|
||||
*/
|
||||
|
||||
inline const NarrowString getTrim (const NarrowString & str, const char * white)
|
||||
{
|
||||
const size_t first_nonspace = str.find_first_not_of ( white );
|
||||
const size_t last_nonspace = str.find_last_not_of ( white );
|
||||
return (first_nonspace == str.npos ? str : str.substr (first_nonspace, last_nonspace == str.npos ? last_nonspace : (last_nonspace - first_nonspace + 1)));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Trim the specified string and return a reference to it.
|
||||
*/
|
||||
inline NarrowString & trim (NarrowString & str, const char * white)
|
||||
{
|
||||
return (str = getTrim (str, white));
|
||||
}
|
||||
/**
|
||||
* Return the first non-white position starting with pos. returns str.npos if there is no non-white characer after pos
|
||||
*/
|
||||
inline size_t skipWhitespace (const String & str, size_t pos, const unicode_char_t * white)
|
||||
{
|
||||
return str.find_first_not_of (white, pos);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Return the first non-white position starting with pos. returns str.npos if there is no non-white characer after pos
|
||||
*/
|
||||
|
||||
inline size_t skipWhitespace (const NarrowString & str, size_t pos, const char * white)
|
||||
{
|
||||
return str.find_first_not_of (white, pos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------
|
||||
/**
|
||||
* Append src to dst, padding the field as needed, and truncating the field if desired.
|
||||
*/
|
||||
|
||||
inline String & appendStringField (String & dst, const NarrowString & src, size_t width, FieldAlignment fa, unicode_char_t pad, bool truncate)
|
||||
{
|
||||
return appendStringField (dst, narrowToWide (src), width, fa, pad, truncate);
|
||||
}
|
||||
// ======================================================================
|
||||
};
|
||||
|
||||
// ======================================================================
|
||||
// Extensions to Base/Archive for String
|
||||
// ======================================================================
|
||||
//class Base::ByteStream;
|
||||
//-----------------------------------------------------------------------
|
||||
namespace Base
|
||||
{
|
||||
extern void get(ByteStream::ReadIterator & source, Plat_Unicode::String & target);
|
||||
extern void put(ByteStream & target, const Plat_Unicode::String & source);
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
// namespace Base
|
||||
|
||||
};
|
||||
#ifdef EXTERNAL_DISTRO
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,292 @@
|
||||
#include <conio.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <map>
|
||||
#include "CTServiceGameAPI/CTServiceAPI.h"
|
||||
|
||||
namespace CTService
|
||||
{
|
||||
class Client : public CTServiceAPI
|
||||
{
|
||||
public:
|
||||
Client(const char *hostList, const char *game);
|
||||
virtual ~Client();
|
||||
|
||||
virtual void onConnect(const char *host, const short port, const short current, const short max);
|
||||
virtual void onDisconnect(const char *host, const short port, const short current, const short max);
|
||||
|
||||
virtual void onTest(const unsigned track, const int resultCode, const unsigned value, void *user);
|
||||
virtual void onReplyTest(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyMoveStatus(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyValidateMove(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyMove(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyCharacterList(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyServerList(const unsigned track, const int resultCode, void *user);
|
||||
virtual void onReplyDestinationServerList(const unsigned track, const int resultCode, void *user);
|
||||
|
||||
virtual void onServerTest(const unsigned server_track, const char *game, const char *param);
|
||||
virtual void onRequestMoveStatus(const unsigned server_track, const char *language,
|
||||
const unsigned transactionID);
|
||||
virtual void onRequestValidateMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, bool withItems);
|
||||
virtual void onRequestMove(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter, const unsigned uid,
|
||||
const unsigned destuid, const unsigned transactionID, bool withItems);
|
||||
virtual void onRequestCharacterList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *server, const unsigned uid);
|
||||
virtual void onRequestServerList(const unsigned server_track, const char *language);
|
||||
virtual void onRequestDestinationServerList(const unsigned server_track, const char *language,
|
||||
const CTUnicodeChar *character, const CTUnicodeChar *server);
|
||||
|
||||
std::map<unsigned, unsigned> mTransactionMap;
|
||||
};
|
||||
|
||||
Client::Client(const char *hostList, const char *game) :
|
||||
CTServiceAPI(hostList, game),
|
||||
mTransactionMap()
|
||||
{
|
||||
}
|
||||
|
||||
Client::~Client()
|
||||
{
|
||||
}
|
||||
|
||||
void Client::onConnect(const char *host,
|
||||
const short port,
|
||||
const short current,
|
||||
const short max)
|
||||
{
|
||||
printf("onConnect(%s, %u, %d, %d)\n",host,port,current,max);
|
||||
}
|
||||
|
||||
void Client::onDisconnect(const char *host,
|
||||
const short port,
|
||||
const short current,
|
||||
const short max)
|
||||
{
|
||||
printf("onDisconnect(%s, %u, %d, %d)\n",host,port,current,max);
|
||||
}
|
||||
|
||||
void Client::onTest(const unsigned track,
|
||||
const int resultCode,
|
||||
const unsigned value,
|
||||
void *user)
|
||||
{
|
||||
printf("onTest(%u, %d, %u, 0x%x)\n", track, resultCode, value, user);
|
||||
}
|
||||
|
||||
void Client::onReplyTest(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyTest(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyMoveStatus(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyMoveStatus(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyValidateMove(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyValidateMove(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyMove(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyMove(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyCharacterList(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyCharacterList(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyServerList(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyServerList(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onReplyDestinationServerList(const unsigned track,
|
||||
const int resultCode,
|
||||
void *user)
|
||||
{
|
||||
printf("onReplyDestinationServerList(%u, %d, 0x%x)\n", track, resultCode, user);
|
||||
}
|
||||
|
||||
void Client::onServerTest(const unsigned server_track,
|
||||
const char *game,
|
||||
const char *param)
|
||||
{
|
||||
printf("onServerTest(%u, %s, %s)\n", server_track, game ? game : "(null)", param ? param : "(null)");
|
||||
replyTest(server_track, 999, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestMoveStatus(const unsigned server_track,
|
||||
const char *language,
|
||||
const unsigned transactionID)
|
||||
{
|
||||
unsigned status;
|
||||
unsigned result;
|
||||
unsigned short * reason = L"makes me horny it does";
|
||||
|
||||
printf("#%x onRequestMoveStatus(%s, #%u)\n",
|
||||
server_track,
|
||||
language,
|
||||
transactionID);
|
||||
|
||||
if (mTransactionMap.find(transactionID) != mTransactionMap.end())
|
||||
{
|
||||
status = CT_STATUS_COMPLETE;
|
||||
result = mTransactionMap[transactionID];
|
||||
}
|
||||
else
|
||||
{
|
||||
status = CT_STATUS_UNKNOWN;
|
||||
result = CT_GAMERESULT_SUCCESS;
|
||||
}
|
||||
|
||||
replyMoveStatus(server_track, status, result, reason, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestValidateMove(const unsigned server_track,
|
||||
const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter,
|
||||
const unsigned uid,
|
||||
const unsigned destuid, bool withItems)
|
||||
{
|
||||
static resultArray[4] = {CT_GAMERESULT_SUCCESS, CT_GAMERESULT_SOFTERROR, CT_GAMERESULT_HARDERROR, CT_GAMERESULT_INVALID_NAME};
|
||||
static resultIndex = 0;
|
||||
|
||||
printf("#%x onRequestValidateMove(%s): server(%S > %S) character (%S > %S) user(%u > %u) %s\n",
|
||||
server_track,
|
||||
language,
|
||||
sourceServer,
|
||||
destServer,
|
||||
sourceCharacter,
|
||||
destCharacter,
|
||||
uid,
|
||||
destuid,
|
||||
withItems ? "/w items" : "/wo items");
|
||||
|
||||
int result = resultArray[(resultIndex++)%4];
|
||||
unsigned short * reason = L"makes me horny it does";
|
||||
unsigned short * suggested = L"yoda";
|
||||
|
||||
replyValidateMove(server_track, result, reason, suggested, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestMove(const unsigned server_track,
|
||||
const char *language,
|
||||
const CTUnicodeChar *sourceServer,
|
||||
const CTUnicodeChar *destServer,
|
||||
const CTUnicodeChar *sourceCharacter,
|
||||
const CTUnicodeChar *destCharacter,
|
||||
const unsigned uid,
|
||||
const unsigned destuid,
|
||||
const unsigned transactionID, bool withItems)
|
||||
{
|
||||
static resultArray[4] = {CT_GAMERESULT_SUCCESS, CT_GAMERESULT_SOFTERROR, CT_GAMERESULT_HARDERROR, CT_GAMERESULT_INVALID_NAME};
|
||||
static resultIndex = 0;
|
||||
|
||||
printf("#%x onRequestMove(%s, #%u): server(%S > %S) character (%S > %S) user(%u > %u) %s\n",
|
||||
server_track,
|
||||
language,
|
||||
transactionID,
|
||||
sourceServer,
|
||||
destServer,
|
||||
sourceCharacter,
|
||||
destCharacter,
|
||||
uid,
|
||||
destuid,
|
||||
withItems ? "/w items" : "/wo items");
|
||||
|
||||
int result = resultArray[(resultIndex++)%4];
|
||||
unsigned short * reason = L"makes me horny it does";
|
||||
unsigned short * suggested = L"yoda";
|
||||
mTransactionMap[transactionID] = result;
|
||||
replyMove(server_track, result, reason, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestCharacterList(const unsigned server_track,
|
||||
const char *language,
|
||||
const CTUnicodeChar *server,
|
||||
const unsigned uid)
|
||||
{
|
||||
CTServiceCharacter characters[4] =
|
||||
{
|
||||
L"wussup1",
|
||||
L"wussup2",
|
||||
L"wussup3",
|
||||
L"wussup4"
|
||||
};
|
||||
|
||||
printf("#%x onRequestCharacterList(%s, %S, %u)\n", server_track, language, server,uid);
|
||||
replyCharacterList(server_track, CT_GAMERESULT_SUCCESS, 4, characters, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestServerList(const unsigned server_track,
|
||||
const char *language)
|
||||
{
|
||||
CTServiceServer servers[4] =
|
||||
{
|
||||
L"crib1",
|
||||
L"crib2",
|
||||
L"crib3",
|
||||
L"crib4"
|
||||
};
|
||||
|
||||
printf("#%x onRequestServerList(%s)\n", server_track, language);
|
||||
replyServerList(server_track, CT_GAMERESULT_SUCCESS, 4, servers, 0);
|
||||
}
|
||||
|
||||
void Client::onRequestDestinationServerList(const unsigned server_track,
|
||||
const char *language,
|
||||
const CTUnicodeChar *character,
|
||||
const CTUnicodeChar *server)
|
||||
{
|
||||
CTServiceServer servers[2] =
|
||||
{
|
||||
L"crib5",
|
||||
L"crib6"
|
||||
};
|
||||
|
||||
printf("#%x onRequestDestinationServerList(%s)\n", server_track, language);
|
||||
replyDestinationServerList(server_track, CT_GAMERESULT_SUCCESS, 2, servers, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
char * hostList = "sdplatdev2:2000";
|
||||
char * game = "SWG";
|
||||
CTService::Client client(hostList, game);
|
||||
while (!kbhit())
|
||||
{
|
||||
client.process();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
# Microsoft Developer Studio Project File - Name="test" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Console Application" 0x0103
|
||||
|
||||
CFG=test - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "test.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "test.mak" CFG="test - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "test - Win32 Release" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE "test - Win32 Debug" (based on "Win32 (x86) Console Application")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "test - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "Release"
|
||||
# PROP BASE Intermediate_Dir "Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
|
||||
|
||||
!ELSEIF "$(CFG)" == "test - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../.." /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 ws2_32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "test - Win32 Release"
|
||||
# Name "test - Win32 Debug"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\main.cpp
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
Reference in New Issue
Block a user