From a5b073e4f235ac39e74cf66671c7878b4bd2762e Mon Sep 17 00:00:00 2001 From: Anonymous Date: Sat, 18 Jan 2014 06:31:13 -0700 Subject: [PATCH] Added TransferServer project and CTServiceGameAPI library --- engine/server/application/CMakeLists.txt | 1 + .../application/TransferServer/CMakeLists.txt | 6 + .../TransferServer/src/CMakeLists.txt | 89 ++ .../TransferServer/src/linux/main.cpp | 60 ++ .../src/shared/CTSAPIClient.cpp | 336 +++++++ .../TransferServer/src/shared/CTSAPIClient.h | 65 ++ .../src/shared/CentralServerConnection.cpp | 410 ++++++++ .../src/shared/CentralServerConnection.h | 42 + .../src/shared/ConfigTransferServer.cpp | 137 +++ .../src/shared/ConfigTransferServer.h | 48 + .../src/shared/ConsoleCommandParser.cpp | 139 +++ .../src/shared/ConsoleCommandParser.h | 29 + .../src/shared/ConsoleManager.cpp | 58 ++ .../src/shared/ConsoleManager.h | 27 + .../src/shared/FirstTransferServer.h | 14 + .../src/shared/TransferServer.cpp | 872 ++++++++++++++++++ .../src/shared/TransferServer.h | 71 ++ .../TransferServer/src/win32/WinMain.cpp | 60 ++ .../3rd/library/soePlatform/CMakeLists.txt | 1 + .../CTServiceGameAPI/Base/Archive.cpp | 283 ++++++ .../CTServiceGameAPI/Base/Archive.h | 746 +++++++++++++++ .../CTServiceGameAPI/Base/Platform.h | 105 +++ .../soePlatform/CTServiceGameAPI/Base/Types.h | 23 + .../CTServiceGameAPI/Base/linux/Archive.h | 44 + .../CTServiceGameAPI/Base/linux/Platform.cpp | 55 ++ .../CTServiceGameAPI/Base/linux/Platform.h | 112 +++ .../CTServiceGameAPI/Base/linux/Types.h | 42 + .../CTServiceGameAPI/Base/win32/Archive.h | 42 + .../CTServiceGameAPI/Base/win32/Platform.cpp | 31 + .../CTServiceGameAPI/Base/win32/Platform.h | 98 ++ .../CTServiceGameAPI/Base/win32/Types.h | 42 + .../CTServiceGameAPI/CMakeLists.txt | 77 ++ .../CTServiceGameAPI/CTCommon/CTEnum.h | 434 +++++++++ .../CTCommon/CTServiceCharacter.cpp | 72 ++ .../CTCommon/CTServiceCharacter.h | 70 ++ .../CTCommon/CTServiceCustomer.h | 124 +++ .../CTCommon/CTServiceDBOrder.h | 167 ++++ .../CTCommon/CTServiceDBTransaction.h | 160 ++++ .../CTCommon/CTServiceObjects.h | 42 + .../CTCommon/CTServiceServer.cpp | 71 ++ .../CTCommon/CTServiceServer.h | 69 ++ .../CTCommon/CTServiceWebAPITransaction.h | 95 ++ .../CTCommon/RequestStrings.h | 155 ++++ .../CTGenericAPI/GenericApiCore.cpp | 272 ++++++ .../CTGenericAPI/GenericApiCore.h | 121 +++ .../CTGenericAPI/GenericConnection.cpp | 209 +++++ .../CTGenericAPI/GenericConnection.h | 81 ++ .../CTGenericAPI/GenericMessage.cpp | 44 + .../CTGenericAPI/GenericMessage.h | 75 ++ .../CTServiceGameAPI/CTServiceAPI.cpp | 187 ++++ .../CTServiceGameAPI/CTServiceAPI.h | 112 +++ .../CTServiceGameAPI/CTServiceAPICore.cpp | 259 ++++++ .../CTServiceGameAPI/CTServiceAPICore.h | 39 + .../soePlatform/CTServiceGameAPI/Request.cpp | 243 +++++ .../soePlatform/CTServiceGameAPI/Request.h | 193 ++++ .../soePlatform/CTServiceGameAPI/Response.cpp | 100 ++ .../soePlatform/CTServiceGameAPI/Response.h | 150 +++ .../CTServiceGameAPI/TcpLibrary/Clock.cpp | 119 +++ .../CTServiceGameAPI/TcpLibrary/Clock.h | 71 ++ .../CTServiceGameAPI/TcpLibrary/IPAddress.cpp | 33 + .../CTServiceGameAPI/TcpLibrary/IPAddress.h | 51 + .../TcpLibrary/TcpBlockAllocator.cpp | 94 ++ .../TcpLibrary/TcpBlockAllocator.h | 44 + .../TcpLibrary/TcpConnection.cpp | 784 ++++++++++++++++ .../TcpLibrary/TcpConnection.h | 157 ++++ .../CTServiceGameAPI/TcpLibrary/TcpHandlers.h | 50 + .../TcpLibrary/TcpManager.cpp | 734 +++++++++++++++ .../CTServiceGameAPI/TcpLibrary/TcpManager.h | 287 ++++++ .../CTServiceGameAPI/TestClient/Client.cpp | 535 +++++++++++ .../CTServiceGameAPI/TestClient/Client.h | 92 ++ .../CTServiceGameAPI/TestClient/Main.cpp | 154 ++++ .../TestClient/TestClient.vcproj | 142 +++ .../CTServiceGameAPI/Unicode/FirstUnicode.cpp | 9 + .../CTServiceGameAPI/Unicode/FirstUnicode.h | 26 + .../CTServiceGameAPI/Unicode/Unicode.cpp | 26 + .../CTServiceGameAPI/Unicode/Unicode.h | 58 ++ .../Unicode/UnicodeBlocks.cpp | 267 ++++++ .../CTServiceGameAPI/Unicode/UnicodeBlocks.h | 404 ++++++++ .../Unicode/UnicodeCharTraits.cpp | 71 ++ .../Unicode/UnicodeCharacterData.cpp | 71 ++ .../Unicode/UnicodeCharacterData.h | 125 +++ .../Unicode/UnicodeCharacterDataMap.cpp | 360 ++++++++ .../Unicode/UnicodeCharacterDataMap.h | 156 ++++ .../CTServiceGameAPI/Unicode/UnicodeUtils.cpp | 285 ++++++ .../CTServiceGameAPI/Unicode/UnicodeUtils.h | 362 ++++++++ .../CTServiceGameAPI/test/main.cpp | 292 ++++++ .../CTServiceGameAPI/test/test.dsp | 101 ++ 87 files changed, 13669 insertions(+) create mode 100644 engine/server/application/TransferServer/CMakeLists.txt create mode 100644 engine/server/application/TransferServer/src/CMakeLists.txt create mode 100644 engine/server/application/TransferServer/src/linux/main.cpp create mode 100644 engine/server/application/TransferServer/src/shared/CTSAPIClient.cpp create mode 100644 engine/server/application/TransferServer/src/shared/CTSAPIClient.h create mode 100644 engine/server/application/TransferServer/src/shared/CentralServerConnection.cpp create mode 100644 engine/server/application/TransferServer/src/shared/CentralServerConnection.h create mode 100644 engine/server/application/TransferServer/src/shared/ConfigTransferServer.cpp create mode 100644 engine/server/application/TransferServer/src/shared/ConfigTransferServer.h create mode 100644 engine/server/application/TransferServer/src/shared/ConsoleCommandParser.cpp create mode 100644 engine/server/application/TransferServer/src/shared/ConsoleCommandParser.h create mode 100644 engine/server/application/TransferServer/src/shared/ConsoleManager.cpp create mode 100644 engine/server/application/TransferServer/src/shared/ConsoleManager.h create mode 100644 engine/server/application/TransferServer/src/shared/FirstTransferServer.h create mode 100644 engine/server/application/TransferServer/src/shared/TransferServer.cpp create mode 100644 engine/server/application/TransferServer/src/shared/TransferServer.h create mode 100644 engine/server/application/TransferServer/src/win32/WinMain.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/Platform.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/Types.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Archive.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Archive.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CMakeLists.txt create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTEnum.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCustomer.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBOrder.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBTransaction.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceObjects.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceWebAPITransaction.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/RequestStrings.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Request.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Request.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Response.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Response.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpHandlers.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Main.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/TestClient.vcproj create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharTraits.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.h create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/test/main.cpp create mode 100644 external/3rd/library/soePlatform/CTServiceGameAPI/test/test.dsp diff --git a/engine/server/application/CMakeLists.txt b/engine/server/application/CMakeLists.txt index 14baaa75..337eb1c0 100644 --- a/engine/server/application/CMakeLists.txt +++ b/engine/server/application/CMakeLists.txt @@ -6,3 +6,4 @@ add_subdirectory(LoginServer) add_subdirectory(LogServer) add_subdirectory(PlanetServer) add_subdirectory(TaskManager) +add_subdirectory(TransferServer) diff --git a/engine/server/application/TransferServer/CMakeLists.txt b/engine/server/application/TransferServer/CMakeLists.txt new file mode 100644 index 00000000..166e5134 --- /dev/null +++ b/engine/server/application/TransferServer/CMakeLists.txt @@ -0,0 +1,6 @@ + +cmake_minimum_required(VERSION 2.8) + +project(TransferServer) + +add_subdirectory(src) diff --git a/engine/server/application/TransferServer/src/CMakeLists.txt b/engine/server/application/TransferServer/src/CMakeLists.txt new file mode 100644 index 00000000..9a4f5800 --- /dev/null +++ b/engine/server/application/TransferServer/src/CMakeLists.txt @@ -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() diff --git a/engine/server/application/TransferServer/src/linux/main.cpp b/engine/server/application/TransferServer/src/linux/main.cpp new file mode 100644 index 00000000..7c59eaa9 --- /dev/null +++ b/engine/server/application/TransferServer/src/linux/main.cpp @@ -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; +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/application/TransferServer/src/shared/CTSAPIClient.cpp b/engine/server/application/TransferServer/src/shared/CTSAPIClient.cpp new file mode 100644 index 00000000..6d456516 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/CTSAPIClient.cpp @@ -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 +#include "sharedLog/Log.h" +#include "TransferServer.h" +#include "UnicodeUtils.h" +#include +#include + +class CentralServerConnection; + +//----------------------------------------------------------------------- + +namespace CTSAPIClientNamespace +{ + struct TransactionTrackData + { + const CentralServerConnection * m_sourceCentralServerConnection; + const CentralServerConnection * m_destinationCentralServerConnection; + unsigned int m_track; + }; + + std::map s_activeTransfers; + std::map 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::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(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::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(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 galaxies = CentralServerConnection::getGalaxies(); + std::vector servers; + std::vector::const_iterator i; + + for (i = ConfigTransferServer::getServersAllowedToUploadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToUploadCharacterData().end(); ++i) + { + std::map::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(CTService::CT_RESULT_SUCCESS); + IGNORE_RETURN(replyServerList(server_track, result, servers.size(), &servers[0], NULL)); + } + else + { + const unsigned int result = static_cast(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 galaxies = CentralServerConnection::getGalaxies(); + std::vector servers; + std::vector::const_iterator i; + + for (i = ConfigTransferServer::getServersAllowedToDownloadCharacterData().begin(); i != ConfigTransferServer::getServersAllowedToDownloadCharacterData().end(); ++i) + { + std::map::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(CTService::CT_RESULT_SUCCESS); + IGNORE_RETURN(replyDestinationServerList(server_track, result, servers.size(), &servers[0], NULL)); + } + else + { + const unsigned int result = static_cast(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::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::iterator i; + const unsigned int result = static_cast(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::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) +{ +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/TransferServer/src/shared/CTSAPIClient.h b/engine/server/application/TransferServer/src/shared/CTSAPIClient.h new file mode 100644 index 00000000..1e150ad0 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/CTSAPIClient.h @@ -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 + +//----------------------------------------------------------------------- + +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 diff --git a/engine/server/application/TransferServer/src/shared/CentralServerConnection.cpp b/engine/server/application/TransferServer/src/shared/CentralServerConnection.cpp new file mode 100644 index 00000000..5fb34c0b --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/CentralServerConnection.cpp @@ -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 s_centralServerConnections; +} + +using namespace CentralServerConnectionNamespace; + + +//----------------------------------------------------------------------- + +CentralServerConnection::CentralServerConnection(UdpConnectionMT * u, TcpClient * t) : +ServerConnection(u, t), +m_galaxyName("") +{ +} + +//----------------------------------------------------------------------- + +CentralServerConnection::~CentralServerConnection() +{ + std::map::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::iterator f = s_centralServerConnections.find(galaxyName); + if(f != s_centralServerConnections.end()) + { + result = f->second; + } + return result; +} + +//----------------------------------------------------------------------- + +const std::map & 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 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 auth(ri); + TransferServer::authorizeDownload(auth.getValue()); + } + else if(msg.isType("UnauthorizeDownload")) + { + const GenericValueTypeMessage 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 & avatarList = reply.getAvatarList(); + std::vector::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 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 > 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 > 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 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 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 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 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 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 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 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 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 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 deleteCharacter("DeleteFailedTransfer", fail.getValue()); + centralServerConnection->send(deleteCharacter, true); + TransferServer::failedToApplyTransferData(fail.getValue()); + } + } + else if(msg.isType("TransferCreateCharacterFailed")) + { + const GenericValueTypeMessage 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 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 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 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 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 reply(ri); + TransferServer::failedToRetrieveTransferData(reply.getValue()); + } + else if(msg.isType("TransferFailGameServerClosedConnectionWithConnectionServer")) + { + const GenericValueTypeMessage fail(ri); + TransferServer::failedToTransferCharacterGameConnectionClosed(fail.getValue()); + } + else if(msg.isType("TransferFailConnectionServerClosedConnectionWithCentralServer")) + { + const GenericValueTypeMessage fail(ri); + TransferServer::failedToTransferCharacterConnectionServerConnectionClosed(fail.getValue()); + } + else if(msg.isType("ConGenericMessage")) + { + const ConGenericMessage cm(ri); + std::string result; + ConsoleManager::processString(cm.getMsg(), static_cast(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())); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/TransferServer/src/shared/CentralServerConnection.h b/engine/server/application/TransferServer/src/shared/CentralServerConnection.h new file mode 100644 index 00000000..b3b08145 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/CentralServerConnection.h @@ -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 +#include + +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 & 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 diff --git a/engine/server/application/TransferServer/src/shared/ConfigTransferServer.cpp b/engine/server/application/TransferServer/src/shared/ConfigTransferServer.cpp new file mode 100644 index 00000000..fcff5b32 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConfigTransferServer.cpp @@ -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 + +//----------------------------------------------------------------------- + +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 s_serversAllowedToUploadCharacterData; + std::vector s_serversAllowedToDownloadCharacterData; +} + +using namespace ConfigTransferServerNamespace; + +// ---------------------------------------------------------------------- + +const std::vector & ConfigTransferServer::getServersAllowedToUploadCharacterData() +{ + return s_serversAllowedToUploadCharacterData; +} + +// ---------------------------------------------------------------------- + +const std::vector & 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(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; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/TransferServer/src/shared/ConfigTransferServer.h b/engine/server/application/TransferServer/src/shared/ConfigTransferServer.h new file mode 100644 index 00000000..38f40f97 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConfigTransferServer.h @@ -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 +#include + +//----------------------------------------------------------------------- + +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 & getServersAllowedToUploadCharacterData(); + static const std::vector & getServersAllowedToDownloadCharacterData(); + static const char * getApiServerHostAddress(); + static const bool getTransferChatAvatar(); + private: + static Data * data; +}; + +// ---------------------------------------------------------------------- + +#endif // _ConfigTransferServer_H diff --git a/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.cpp b/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.cpp new file mode 100644 index 00000000..1ce93bdb --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.cpp @@ -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 +#include "Unicode.h" + +//----------------------------------------------------------------------- + +namespace CommandNames +{ +#define MAKE_COMMAND(a) const char * const a = #a +#undef MAKE_COMMAND +} + +const CommandParser::CmdInfo cmds[] = +{ + {"transfer", 4, " ", "Request a character transfer for from to "}, + {"transfer", 2, " ", "Request an account transfer from to "}, + {"", 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(atoi (stationIdString.c_str())); + const unsigned int trackId = static_cast(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 '"; + 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(atoi (sourceStationIdString.c_str())); + const unsigned int destinationStationId = static_cast(atoi (destinationStationIdString.c_str())); + const unsigned int trackId = static_cast(track.getValue()); + + TransferServer::requestTransferAccount(trackId, sourceStationId, destinationStationId, trackId); + successResult = true; + } + else + { + std::string messageString = "not enough arguments to 'requestAccountMove '"; + 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; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.h b/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.h new file mode 100644 index 00000000..4ebf6387 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConsoleCommandParser.h @@ -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 + diff --git a/engine/server/application/TransferServer/src/shared/ConsoleManager.cpp b/engine/server/application/TransferServer/src/shared/ConsoleManager.cpp new file mode 100644 index 00000000..c0208e0d --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConsoleManager.cpp @@ -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(track)), Unicode::narrowToWide(msg), wideResult)); + result = Unicode::wideToNarrow(wideResult); +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/application/TransferServer/src/shared/ConsoleManager.h b/engine/server/application/TransferServer/src/shared/ConsoleManager.h new file mode 100644 index 00000000..2f166dc3 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/ConsoleManager.h @@ -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 + +//----------------------------------------------------------------------- + +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 diff --git a/engine/server/application/TransferServer/src/shared/FirstTransferServer.h b/engine/server/application/TransferServer/src/shared/FirstTransferServer.h new file mode 100644 index 00000000..7d8c22ed --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/FirstTransferServer.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 diff --git a/engine/server/application/TransferServer/src/shared/TransferServer.cpp b/engine/server/application/TransferServer/src/shared/TransferServer.cpp new file mode 100644 index 00000000..adc61cd2 --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/TransferServer.cpp @@ -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 +#include +#include +#include +#include "Unicode.h" +#include "UnicodeUtils.h" + +//----------------------------------------------------------------------- + +namespace TransferServerNamespace +{ + Service * s_transferServerService; + std::map s_transferData; + std::set s_serversAllowedToUpload; + std::set s_serversAllowedToDownload; + std::set 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 >, uint32> s_cacheSourceCharacterTemplateCrc; + + void closePseudoClientConnection(const std::string & galaxyName, const unsigned int stationId) + { + CentralServerConnection * centralServerConnection = CentralServerConnection::getCentralServerConnectionForGalaxy(galaxyName); + if(centralServerConnection) + { + GenericValueTypeMessage 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(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::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::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::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::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 request("TransferRequestCharacterList", characterData); + centralConnection->send(request, true); + } + else + { + // send failure to CTS API backend + if(s_apiClient) + { + const unsigned int result = static_cast(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 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(), // 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 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 > 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(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 galaxies = CentralServerConnection::getGalaxies(); + std::map::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(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(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 > kick("TransferRequestKickConnectedClients", std::make_pair(sourceStationId, destinationStationId)); + sourceCentralConnection->send(kick, true); + + // start the transfer process + const GenericValueTypeMessage 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(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 >, 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(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::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(), 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::const_iterator f = s_serversAllowedToUpload.find(data.fromGalaxy); + + bool authorized = administrative; + if(! authorized) + { + std::set::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::const_iterator i; + std::vector 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(CTService::CT_RESULT_SUCCESS); + + if(! reply.getAvatarList().empty()) + { + characters = &chars[0]; + } + else + { + result = static_cast(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(CTService::CT_GAMERESULT_SUCCESS); + if(! reply.getIsValidName()) + { + LOG("CustomerService", ("CharacterTransfer: replyValidateMove failed name validation for %s", reply.toString().c_str())); + result = static_cast(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 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(reply.getSourceAvatarData()); + for (std::vector::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 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(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(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(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(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(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(CTService::CT_GAMERESULT_MAX_CHAR_ON_DEST_SERVER) : static_cast(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()); + } +} + +//----------------------------------------------------------------------- diff --git a/engine/server/application/TransferServer/src/shared/TransferServer.h b/engine/server/application/TransferServer/src/shared/TransferServer.h new file mode 100644 index 00000000..09dd9a7f --- /dev/null +++ b/engine/server/application/TransferServer/src/shared/TransferServer.h @@ -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 + +//----------------------------------------------------------------------- + +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 diff --git a/engine/server/application/TransferServer/src/win32/WinMain.cpp b/engine/server/application/TransferServer/src/win32/WinMain.cpp new file mode 100644 index 00000000..b1533f7c --- /dev/null +++ b/engine/server/application/TransferServer/src/win32/WinMain.cpp @@ -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; +} + +//----------------------------------------------------------------------- + diff --git a/external/3rd/library/soePlatform/CMakeLists.txt b/external/3rd/library/soePlatform/CMakeLists.txt index b6a0ed46..3cb5ae32 100644 --- a/external/3rd/library/soePlatform/CMakeLists.txt +++ b/external/3rd/library/soePlatform/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(ChatAPI) +add_subdirectory(CTServiceGameAPI) add_subdirectory(VChatAPI) diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.cpp new file mode 100644 index 00000000..e3400df0 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.cpp @@ -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(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::const_iterator i; + unsigned short packedSize=static_cast(members.size()); + put(target,packedSize); + for(i = members.begin(); i != members.end(); ++i) + { + (*i)->pack(target); + } + } + + void AutoByteStream::unpack(ByteStream::ReadIterator & source) + { + std::vector::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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h new file mode 100644 index 00000000..352ad06f --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Archive.h @@ -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 +#include +#include +#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::iterator i; + for(i = freeList.begin(); i != freeList.end(); ++i) + { + delete (*i); + } + }; + std::vector freeList; + }; + Data(); + //explicit Data(unsigned char * buffer); + static std::vector & 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::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 members; + private: + AutoByteStream(const AutoByteStream & source); + }; + + +//////////////////////////////////////////////////////////////////////////////// + + + template + 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 + AutoVariable::AutoVariable() : + AutoVariableBase(), + value() + { + } + + template + AutoVariable::AutoVariable(const ValueType & source) : + AutoVariableBase(), + value(source) + { + } + + template + AutoVariable::~AutoVariable() + { + } + + template + const ValueType & AutoVariable::get() const + { + return value; + } + + template + void AutoVariable::pack(ByteStream & target) const + { + Base::put(target, value); + } + + template + void AutoVariable::set(const ValueType & rhs) + { + value = rhs; + } + + template + void AutoVariable::unpack(ByteStream::ReadIterator & source) + { + Base::get(source, value); + } + + +//////////////////////////////////////////////////////////////////////////////// + + + template + class AutoArray : public AutoVariableBase + { + public: + AutoArray(); + AutoArray(const AutoArray & source); + ~AutoArray(); + + const std::vector & get() const; + void set(const std::vector & source); + + virtual void pack(ByteStream & target) const; + virtual void unpack(ByteStream::ReadIterator & source); + + private: + std::vector array; + }; + + template + inline AutoArray::AutoArray() + { + } + + template + inline AutoArray::AutoArray(const AutoArray & source) : + array(source.array) + { + } + + template + inline AutoArray::~AutoArray() + { + } + + template + inline const std::vector & AutoArray::get() const + { + return array; + } + + template + inline void AutoArray::set(const std::vector & source) + { + array = source; + } + + template + inline void AutoArray::pack(ByteStream & target) const + { + unsigned int arraySize = array.size(); + Base::put(target, arraySize); + + typename std::vector::const_iterator i; + for(i = array.begin(); i != array.end(); ++i) + { + ValueType v = (*i); + Base::put(target, v); + } + } + + template + inline void AutoArray::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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Platform.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Platform.h new file mode 100644 index 00000000..2bdb170b --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Platform.h @@ -0,0 +1,105 @@ +#ifndef BASE_PLATFORM_H +#define BASE_PLATFORM_H + +#include + + +#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 inline T rotlFixed(T x, unsigned int y) + { + assert(y < sizeof(T)*8); + return (T)((x<>(sizeof(T)*8-y))); + } + + template inline T rotrFixed(T x, unsigned int y) + { + assert(y < sizeof(T)*8); + return (x>>y) | (x<<(sizeof(T)*8-y)); + } + + template inline T rotlMod(T x, unsigned int y) + { + y %= sizeof(T)*8; + return (x<>(sizeof(T)*8-y)); + } + + template 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(data); + return *static_cast(data) = rotlFixed(value, 8U); + // return rotlFixed(value, 8U); + } + + inline uint32 byteReverse32(void * data) + { + uint32 value = *static_cast(data); + return *static_cast(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(data); + return *static_cast(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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Types.h new file mode 100644 index 00000000..3f0b27c6 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/Types.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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Archive.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Archive.h new file mode 100644 index 00000000..bb623b49 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Archive.h @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.cpp new file mode 100644 index 00000000..4b24492c --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.cpp @@ -0,0 +1,55 @@ +//////////////////////////////////////// +// Platform.cpp +// +// Purpose: +// 1. Implementation of the global functionality declaired in Platform.h. +// +// Revisions: +// 07/10/2001 Created +// + +#include +#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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.h new file mode 100644 index 00000000..41da3972 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Platform.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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(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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.h new file mode 100644 index 00000000..bc869bac --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/linux/Types.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 + +#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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Archive.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Archive.h new file mode 100644 index 00000000..30ddce43 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Archive.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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.cpp new file mode 100644 index 00000000..3b52563e --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.cpp @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.h new file mode 100644 index 00000000..aaee37b7 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Platform.h @@ -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 +#include +#include +#include +#include +#include +#include +#include +#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(&result))) + result = 0; + return result; + } + + inline uint64 getTimerFrequency(void) + { + uint64 result; + if (!QueryPerformanceFrequency(reinterpret_cast(&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 \ No newline at end of file diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.h new file mode 100644 index 00000000..0c64cb2c --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Base/win32/Types.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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CMakeLists.txt b/external/3rd/library/soePlatform/CTServiceGameAPI/CMakeLists.txt new file mode 100644 index 00000000..4136d3d3 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CMakeLists.txt @@ -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} +) \ No newline at end of file diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTEnum.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTEnum.h new file mode 100644 index 00000000..17654be3 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTEnum.h @@ -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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.cpp new file mode 100644 index 00000000..7677ba18 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.cpp @@ -0,0 +1,72 @@ +#include "CTServiceCharacter.h" +#include +#include + +#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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.h new file mode 100644 index 00000000..c9582d98 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCharacter.h @@ -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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCustomer.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCustomer.h new file mode 100644 index 00000000..e8a580d0 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceCustomer.h @@ -0,0 +1,124 @@ +#ifndef CTSERVICECUSTOMER_H +#define CTSERVICECUSTOMER_H + +#include + +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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBOrder.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBOrder.h new file mode 100644 index 00000000..c10f6890 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBOrder.h @@ -0,0 +1,167 @@ +#ifndef CTSERVICEDBORDER_H +#define CTSERVICEDBORDER_H + +#include +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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBTransaction.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBTransaction.h new file mode 100644 index 00000000..21dace6c --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceDBTransaction.h @@ -0,0 +1,160 @@ +#ifndef CTSERVICEDBTRANSACTION_H +#define CTSERVICEDBTRANSACTION_H + +#include +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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceObjects.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceObjects.h new file mode 100644 index 00000000..f3e6dc97 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceObjects.h @@ -0,0 +1,42 @@ +#if !defined (CTSERVICEOBJECTS_H_) +#define CTSERVICEOBJECTS_H_ + +#pragma warning (disable : 4786) + +#include +#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 + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.cpp new file mode 100644 index 00000000..eaf91947 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.cpp @@ -0,0 +1,71 @@ +#include "CTServiceServer.h" +#include +#include + +#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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.h new file mode 100644 index 00000000..7d76ddff --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceServer.h @@ -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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceWebAPITransaction.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceWebAPITransaction.h new file mode 100644 index 00000000..b51fe366 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/CTServiceWebAPITransaction.h @@ -0,0 +1,95 @@ +#ifndef CTSERVICEWEBAPITRANSACTION_H +#define CTSERVICEWEBAPITRANSACTION_H + +#include + +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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/RequestStrings.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/RequestStrings.h new file mode 100644 index 00000000..68f40855 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTCommon/RequestStrings.h @@ -0,0 +1,155 @@ +#ifndef REQUESTSTRINGS_H +#define REQUESTSTRINGS_H + +#pragma warning (disable : 4786) + +#include "CTEnum.h" +#include + +namespace CTService +{ +static const char * _gamecodeName[] = +{ + "", + "SP", + "EQ", + "EQ2", + "SWG", + "PS", + "EQOA-beta", + "EQOA", + "EQIM", + "EQM" +}; + + +#define key_text std::pair + +// ----- 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 RequestString((const std::map::value_type *)&_requestString[0],(const std::map::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 ResultString((const std::map::value_type *)&_resultString[0],(const std::map::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 ResourceString((const std::map::value_type *)&_ResourceString[0],(const std::map::value_type *)&_ResourceString[_ResourceCount]); +//------------------------------------------------------------------------------------------------ + +}; // namespace + +#endif diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.cpp new file mode 100644 index 00000000..6c412225 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.cpp @@ -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::iterator conIter = m_serverConnections.begin(); conIter != m_serverConnections.end(); conIter++) + { + GenericConnection *con = *conIter; + delete con; + } + m_serverConnections.clear(); + + for(map::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(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 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(res->getTrack(), res)); + --m_outCount; + ++m_pendingCount; + m_outboundQueue.pop(); + delete req; + } + else + { + //no active connections + break; //from while loop + } + + } + } + + for (std::vector::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::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::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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.h new file mode 100644 index 00000000..92d41799 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericApiCore.h @@ -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 +#include +#include +#include + +#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 m_serverConnections; + std::map m_pending; + std::queue > 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 m_serverTracks; + +private: + bool m_suspended; + unsigned m_nextConnectionIndex; + std::string m_game; +}; + +#ifdef EXTERNAL_DISTRO +}; +#endif +#endif diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.cpp new file mode 100644 index 00000000..ef652f08 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.cpp @@ -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::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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.h new file mode 100644 index 00000000..8ace9864 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericConnection.h @@ -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 +#include +#include +#include + + +#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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.cpp new file mode 100644 index 00000000..c01729d8 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.cpp @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.h new file mode 100644 index 00000000..dec032a6 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTGenericAPI/GenericMessage.h @@ -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 +#include + +#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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.cpp new file mode 100644 index 00000000..055c06af --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.cpp @@ -0,0 +1,187 @@ +#pragma warning (disable : 4786) +//test +#include +#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 hostArray; + std::vector 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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.h new file mode 100644 index 00000000..a51104c1 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPI.h @@ -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 + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.cpp new file mode 100644 index 00000000..347c88ea --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.cpp @@ -0,0 +1,259 @@ +#include "CTServiceAPICore.h" +#include "CTServiceAPI.h" +#include "Response.h" +#include + +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(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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.h b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.h new file mode 100644 index 00000000..dad7e3d0 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/CTServiceAPICore.h @@ -0,0 +1,39 @@ +#ifndef APICORE_H +#define APICORE_H + +#pragma warning (disable : 4786) + +#include "CTGenericAPI/GenericApiCore.h" +#include "CTGenericAPI/GenericConnection.h" +#include + +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 + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Request.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Request.cpp new file mode 100644 index 00000000..2eac552d --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Request.cpp @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Request.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Request.h new file mode 100644 index 00000000..8c918d72 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Request.h @@ -0,0 +1,193 @@ +#if !defined (REQUEST_H_) +#define REQUEST_H_ + +#pragma warning (disable : 4786) + +#include "CTGenericAPI/GenericMessage.h" +#include +#include +#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 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 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 m_serverArray; +}; + +}; // namespace + +#endif + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Response.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Response.cpp new file mode 100644 index 00000000..4b3348cd --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Response.cpp @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Response.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Response.h new file mode 100644 index 00000000..776a20e2 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Response.h @@ -0,0 +1,150 @@ +#if !defined (RESPONSE_H_) +#define RESPONSE_H_ + +#pragma warning (disable : 4786) + +#include "CTGenericAPI/GenericMessage.h" +#include +#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_ + + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.cpp new file mode 100644 index 00000000..2f5f47b4 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.cpp @@ -0,0 +1,119 @@ +#include "Clock.h" + +#include + +#ifdef WIN32 + #include +#else //WIN32 + #include + #include + #include +#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(tv.tv_sec) * 1000 + static_cast(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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.h new file mode 100644 index 00000000..89eb2c2a --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/Clock.h @@ -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 + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.cpp new file mode 100644 index 00000000..e1f45c15 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.cpp @@ -0,0 +1,33 @@ +#include "IPAddress.h" + +#if defined(WIN32) + #include + typedef int socklen_t; +#else // for non-windows platforms (linux) + #include + #include + #include +#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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.h new file mode 100644 index 00000000..f6d5f886 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/IPAddress.h @@ -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 + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.cpp new file mode 100644 index 00000000..6d476d78 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.cpp @@ -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 + + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.h new file mode 100644 index 00000000..d34509a0 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpBlockAllocator.h @@ -0,0 +1,44 @@ +#ifndef TCPBLOCKALLOCATOR_H +#define TCPBLOCKALLOCATOR_H + +#include + +#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 + + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.cpp new file mode 100644 index 00000000..da1154dc --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.cpp @@ -0,0 +1,784 @@ +#include "TcpConnection.h" +#include "TcpManager.h" +#include "Clock.h" +#include + +#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(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 + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.h new file mode 100644 index 00000000..07eb4f42 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpConnection.h @@ -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 + typedef int socklen_t; +#else // for non-windows platforms (linux) + #include + #include + #include + #include + #include + #include + #include +#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 + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpHandlers.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpHandlers.h new file mode 100644 index 00000000..440e0ae9 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpHandlers.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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.cpp new file mode 100644 index 00000000..fa4d61a4 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.cpp @@ -0,0 +1,734 @@ +#include "TcpManager.h" +#include +#include "IPAddress.h" +#include "TcpConnection.h" + +#ifndef WIN32 + #include +#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 + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.h new file mode 100644 index 00000000..75eb6df4 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TcpLibrary/TcpManager.h @@ -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 + typedef int socklen_t; +#else // for non-windows platforms (linux) + #include + #include + #include + #include + #include + #include + #include + 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 + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.cpp new file mode 100644 index 00000000..04b4db69 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.cpp @@ -0,0 +1,535 @@ +#include "Client.h" +#include +#include +#include + +using namespace CTService; +using namespace Plat_Unicode; + +extern unsigned openRequests; +extern std::map 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(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--; +} diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.h b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.h new file mode 100644 index 00000000..6320c85c --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Client.h @@ -0,0 +1,92 @@ +#ifndef CLIENT_H +#define CLIENT_H + +#include "CTServiceGameAPI/CTServiceAPI.h" +#include +#include +#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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Main.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Main.cpp new file mode 100644 index 00000000..eb7a09ab --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/Main.cpp @@ -0,0 +1,154 @@ +#include +#pragma warning (disable: 4786) +#include "Client.h" + +#ifdef WIN32 +#include +#include +#endif + +using namespace CTService; + +unsigned openRequests = 0; +CTServiceAPI *waitclient = NULL; +std::map 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::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: \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; +} diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/TestClient.vcproj b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/TestClient.vcproj new file mode 100644 index 00000000..c759a112 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/TestClient/TestClient.vcproj @@ -0,0 +1,142 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.cpp new file mode 100644 index 00000000..5d166f7c --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.cpp @@ -0,0 +1,9 @@ +// ====================================================================== +// +// FirstUnicode.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "FirstUnicode.h" + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/FirstUnicode.h new file mode 100644 index 00000000..70125beb --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.cpp new file mode 100644 index 00000000..5aa7aae2 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.cpp @@ -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 + +// ====================================================================== diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.h new file mode 100644 index 00000000..5288d694 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/Unicode.h @@ -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 + +//----------------------------------------------------------------- + +#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 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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.cpp new file mode 100644 index 00000000..0b8194b1 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.cpp @@ -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 & Data::generateFilteredIdSet (std::set & 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 (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 (strtoul (str.substr (tokenStartPos, tokenCommaPos - tokenStartPos).c_str (), 0, 16)); + + } + + else + { + rng.m_high = rng.m_low = static_cast (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 + +// ===================================================================== }, diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.h new file mode 100644 index 00000000..245e811d --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeBlocks.h @@ -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 +#include +#include + +// ====================================================================== +#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 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 RangeGroups_t; + RangeGroups_t m_rangeGroups; + + explicit Data (const RawData & rhs); + Data (); + + const std::set & generateFilteredIdSet (std::set & ) 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 IdMap_t; + typedef std::map 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(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(CJK_Unified_Ideographs_Extension_A) && code < static_cast(Yi_Syllables)) || + (code >= static_cast(Hangul_Syllables) && code < static_cast(CJK_Compatibility_Ideographs))); + } + + } //-- namespace Blocks + +}; // -- namespace Unicode +#ifdef EXTERNAL_DISTRO +}; +#endif + +// ====================================================================== +#endif + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharTraits.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharTraits.cpp new file mode 100644 index 00000000..33917290 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharTraits.cpp @@ -0,0 +1,71 @@ +#if defined (linux) && ((__GNUC__ == 3 && __GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL == 3) || (__GNUC__ == 2 && __GNUC_MINOR__ > 96)) +#include +#include "Unicode.h" + +#ifdef EXTERNAL_DISTRO +using namespace NAMESPACE::Plat_Unicode; +#else +using namespace Plat_Unicode; +#endif + +namespace std +{ + +void char_traits::assign(unicode_char_t &__c1, const unicode_char_t &__c2) +{ + __c1 = __c2; +} + +bool char_traits::eq(const unicode_char_t &__c1, const unicode_char_t &__c2) +{ + return __c1 == __c2; +} + +bool char_traits::lt(const unicode_char_t &__c1, const unicode_char_t &__c2) +{ + return __c1 < __c2; +} + +unicode_char_t *char_traits::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::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::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::length(const unicode_char_t *__s) +{ + size_t __i; + for(__i = 0; !eq(__s[__i], 0); ++__i); + return __i; +} + +unicode_char_t *char_traits::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::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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.cpp new file mode 100644 index 00000000..bd5b832d --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.cpp @@ -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 +//----------------------------------------------------------------- + +// ====================================================================== diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.h new file mode 100644 index 00000000..22e76cd7 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterData.h @@ -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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.cpp new file mode 100644 index 00000000..71e2c0c8 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.cpp @@ -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 +#include +#include + +// ====================================================================== + +#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 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 (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 (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 (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 (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 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(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 + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.h new file mode 100644 index 00000000..741a6e80 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeCharacterDataMap.h @@ -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 +#include + +#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 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 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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.cpp new file mode 100644 index 00000000..6a1ee55d --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.cpp @@ -0,0 +1,285 @@ +// ====================================================================== +// +// Unicode.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "FirstUnicode.h" +#include "UnicodeUtils.h" + +#include + +#if defined (linux) +#include +#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(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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.h b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.h new file mode 100644 index 00000000..ab466482 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/Unicode/UnicodeUtils.h @@ -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 +#ifdef WIN32 + #include +#else + #include +#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 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 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 bool isWhitespace (T c) + { + return c == ' ' || c == '\n' || c == '\r' || c == '\t'; + } + + /* + * @todo: uncomment when caseInsensitiveCompare matures + * + template class CompareNoCasePredicate + { + public: + bool operator()( T & a, T & b ) const + { + return caseInsensitiveCompare (a, b) < 0; + }; + }; + + template 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 diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/test/main.cpp b/external/3rd/library/soePlatform/CTServiceGameAPI/test/main.cpp new file mode 100644 index 00000000..4f91d382 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/test/main.cpp @@ -0,0 +1,292 @@ +#include +#include +#include +#include +#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 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; +} + diff --git a/external/3rd/library/soePlatform/CTServiceGameAPI/test/test.dsp b/external/3rd/library/soePlatform/CTServiceGameAPI/test/test.dsp new file mode 100644 index 00000000..f1a5a8d1 --- /dev/null +++ b/external/3rd/library/soePlatform/CTServiceGameAPI/test/test.dsp @@ -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