diff --git a/engine/server/library/CMakeLists.txt b/engine/server/library/CMakeLists.txt index 35775a7c..5c295a10 100644 --- a/engine/server/library/CMakeLists.txt +++ b/engine/server/library/CMakeLists.txt @@ -1,4 +1,5 @@ +add_subdirectory(serverDatabase) add_subdirectory(serverGame) add_subdirectory(serverKeyShare) add_subdirectory(serverMetrics) diff --git a/engine/server/library/serverDatabase/CMakeLists.txt b/engine/server/library/serverDatabase/CMakeLists.txt new file mode 100644 index 00000000..c18a8365 --- /dev/null +++ b/engine/server/library/serverDatabase/CMakeLists.txt @@ -0,0 +1,11 @@ +cmake_minimum_required(VERSION 2.8) + +project(serverDatabase) + +if(WIN32) + add_definitions(/D_CRT_SECURE_NO_WARNINGS) +endif() + +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public) + +add_subdirectory(src) diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/AbstractTableBuffer.h b/engine/server/library/serverDatabase/include/public/serverDatabase/AbstractTableBuffer.h new file mode 100644 index 00000000..9519361d --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/AbstractTableBuffer.h @@ -0,0 +1 @@ +#include "../../src/shared/AbstractTableBuffer.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CMLoader.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CMLoader.h new file mode 100644 index 00000000..6f9ec46c --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CMLoader.h @@ -0,0 +1 @@ +#include "../../../../../../game/server/application/SwgDatabaseServer/src/shared/core/CMLoader.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CentralServerConnection.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CentralServerConnection.h new file mode 100644 index 00000000..6c33ae43 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CentralServerConnection.h @@ -0,0 +1 @@ +#include "../../src/shared/CentralServerConnection.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterLocator.h new file mode 100644 index 00000000..097f7b18 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/CharacterLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterNameLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterNameLocator.h new file mode 100644 index 00000000..87b6a67e --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterNameLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/CharacterNameLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterQueries.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterQueries.h new file mode 100644 index 00000000..916a759a --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CharacterQueries.h @@ -0,0 +1 @@ +#include "../../src/shared/CharacterQueries.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ChatServerConnection.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ChatServerConnection.h new file mode 100644 index 00000000..eb3aebed --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ChatServerConnection.h @@ -0,0 +1 @@ +#include "../../src/shared/ChatServerConnection.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ChunkLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ChunkLocator.h new file mode 100644 index 00000000..52e71439 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ChunkLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/ChunkLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CommoditiesServerConnection.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CommoditiesServerConnection.h new file mode 100644 index 00000000..92fe34c2 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CommoditiesServerConnection.h @@ -0,0 +1 @@ +#include "../../src/shared/CommoditiesServerConnection.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ConfigServerDatabase.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ConfigServerDatabase.h new file mode 100644 index 00000000..00bb8795 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ConfigServerDatabase.h @@ -0,0 +1 @@ +#include "../../src/shared/ConfigServerDatabase.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ContainedObjectLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ContainedObjectLocator.h new file mode 100644 index 00000000..78f0c874 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ContainedObjectLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/ContainedObjectLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ContentsLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ContentsLocator.h new file mode 100644 index 00000000..4b8d759e --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ContentsLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/ContentsLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CreateCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CreateCharacterCustomPersistStep.h new file mode 100644 index 00000000..34fb5459 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CreateCharacterCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/CreateCharacterCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/CustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/CustomPersistStep.h new file mode 100644 index 00000000..e462561c --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/CustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/CustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/DataLookup.h b/engine/server/library/serverDatabase/include/public/serverDatabase/DataLookup.h new file mode 100644 index 00000000..f5ecdfc7 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/DataLookup.h @@ -0,0 +1 @@ +#include "../../src/shared/DataLookup.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseMetricsData.h b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseMetricsData.h new file mode 100644 index 00000000..4e5c3f48 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseMetricsData.h @@ -0,0 +1 @@ +#include "../../src/shared/DatabaseMetricsData.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcess.h b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcess.h new file mode 100644 index 00000000..7a69f62b --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcess.h @@ -0,0 +1 @@ +#include "../../src/shared/DatabaseProcess.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcessQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcessQuery.h new file mode 100644 index 00000000..d582b5f8 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/DatabaseProcessQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/DatabaseProcessQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/DeleteCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/DeleteCharacterCustomPersistStep.h new file mode 100644 index 00000000..2b787a99 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/DeleteCharacterCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/DeleteCharacterCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/FirstServerDatabase.h b/engine/server/library/serverDatabase/include/public/serverDatabase/FirstServerDatabase.h new file mode 100644 index 00000000..c889956b --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/FirstServerDatabase.h @@ -0,0 +1 @@ +#include "../../src/shared/FirstServerDatabase.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/FixLoadWithCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/FixLoadWithCustomPersistStep.h new file mode 100644 index 00000000..29111b5d --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/FixLoadWithCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/FixLoadWithCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GameServerConnection.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GameServerConnection.h new file mode 100644 index 00000000..ab30e32a --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GameServerConnection.h @@ -0,0 +1 @@ +#include "../../src/shared/GameServerConnection.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetBiographyQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetBiographyQuery.h new file mode 100644 index 00000000..69470dfc --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetBiographyQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetBiographyQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetChunkQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetChunkQuery.h new file mode 100644 index 00000000..473cd712 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetChunkQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetChunkQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetContentsList.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetContentsList.h new file mode 100644 index 00000000..d99800a8 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetContentsList.h @@ -0,0 +1 @@ +#include "../../src/shared/GetContentsList.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetGoldVersionNumberQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetGoldVersionNumberQuery.h new file mode 100644 index 00000000..11cb0fe0 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetGoldVersionNumberQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetGoldVersionNumberQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetObjectIdsQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetObjectIdsQuery.h new file mode 100644 index 00000000..56100de9 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetObjectIdsQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetObjectIdsQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetTimestampQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetTimestampQuery.h new file mode 100644 index 00000000..270b4ae7 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetTimestampQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetTimestampQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetUniverseQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetUniverseQuery.h new file mode 100644 index 00000000..1c3e5cd1 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetUniverseQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetUniverseQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/GetVersionNumberQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/GetVersionNumberQuery.h new file mode 100644 index 00000000..849c34bc --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/GetVersionNumberQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/GetVersionNumberQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ImmediateDeleteCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ImmediateDeleteCustomPersistStep.h new file mode 100644 index 00000000..7cf8859c --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ImmediateDeleteCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/ImmediateDeleteCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleteQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleteQuery.h new file mode 100644 index 00000000..b0eff3db --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleteQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/LazyDeleteQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleter.h b/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleter.h new file mode 100644 index 00000000..5c1da5b6 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/LazyDeleter.h @@ -0,0 +1 @@ +#include "../../src/shared/LazyDeleter.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/Loader.h b/engine/server/library/serverDatabase/include/public/serverDatabase/Loader.h new file mode 100644 index 00000000..d352c278 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/Loader.h @@ -0,0 +1 @@ +#include "../../src/shared/Loader.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/LoaderSnapshotGroup.h b/engine/server/library/serverDatabase/include/public/serverDatabase/LoaderSnapshotGroup.h new file mode 100644 index 00000000..74a17fae --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/LoaderSnapshotGroup.h @@ -0,0 +1 @@ +#include "../../src/shared/LoaderSnapshotGroup.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/MessageToManager.h b/engine/server/library/serverDatabase/include/public/serverDatabase/MessageToManager.h new file mode 100644 index 00000000..239ba13e --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/MessageToManager.h @@ -0,0 +1 @@ +#include "../../src/shared/MessageToManager.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/MoveToPlayerCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/MoveToPlayerCustomPersistStep.h new file mode 100644 index 00000000..15ee880c --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/MoveToPlayerCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/MoveToPlayerCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ObjectLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ObjectLocator.h new file mode 100644 index 00000000..54997190 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ObjectLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/ObjectLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/Persister.h b/engine/server/library/serverDatabase/include/public/serverDatabase/Persister.h new file mode 100644 index 00000000..cf99fc01 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/Persister.h @@ -0,0 +1 @@ +#include "../../src/shared/Persister.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/PreloadListQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/PreloadListQuery.h new file mode 100644 index 00000000..6b2c4476 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/PreloadListQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/PreloadListQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/PurgeCompleteCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/PurgeCompleteCustomPersistStep.h new file mode 100644 index 00000000..c3ac5b05 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/PurgeCompleteCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/PurgeCompleteCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/RenameCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/RenameCharacterCustomPersistStep.h new file mode 100644 index 00000000..6f42eedf --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/RenameCharacterCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/RenameCharacterCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/SaveTimestampQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/SaveTimestampQuery.h new file mode 100644 index 00000000..b12913c1 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/SaveTimestampQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/SaveTimestampQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/ScriptQueries.h b/engine/server/library/serverDatabase/include/public/serverDatabase/ScriptQueries.h new file mode 100644 index 00000000..b66336b3 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/ScriptQueries.h @@ -0,0 +1 @@ +#include "../../src/shared/ScriptQueries.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/SetBiographyQuery.h b/engine/server/library/serverDatabase/include/public/serverDatabase/SetBiographyQuery.h new file mode 100644 index 00000000..92394fe3 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/SetBiographyQuery.h @@ -0,0 +1 @@ +#include "../../src/shared/SetBiographyQuery.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/Snapshot.h b/engine/server/library/serverDatabase/include/public/serverDatabase/Snapshot.h new file mode 100644 index 00000000..28985779 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/Snapshot.h @@ -0,0 +1 @@ +#include "../../src/shared/Snapshot.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/StructureQueries.h b/engine/server/library/serverDatabase/include/public/serverDatabase/StructureQueries.h new file mode 100644 index 00000000..0be3257d --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/StructureQueries.h @@ -0,0 +1 @@ +#include "../../src/shared/StructureQueries.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TableBuffer.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TableBuffer.h new file mode 100644 index 00000000..b027be70 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TableBuffer.h @@ -0,0 +1 @@ +#include "../../src/shared/TableBuffer.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCSTasks.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCSTasks.h new file mode 100644 index 00000000..15641fef --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCSTasks.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskCSTasks.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskChangeStationId.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskChangeStationId.h new file mode 100644 index 00000000..14ecec4f --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskChangeStationId.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskChangeStationId.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckCharacterName.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckCharacterName.h new file mode 100644 index 00000000..c3278cd4 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckCharacterName.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskCheckCharacterName.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckGoldVersionNumber.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckGoldVersionNumber.h new file mode 100644 index 00000000..1ae8c791 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckGoldVersionNumber.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskCheckGoldVersionNumber.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckVersionNumber.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckVersionNumber.h new file mode 100644 index 00000000..b905415b --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskCheckVersionNumber.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskCheckVersionNumber.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetBiography.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetBiography.h new file mode 100644 index 00000000..8128d788 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetBiography.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskGetBiography.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetObjectIds.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetObjectIds.h new file mode 100644 index 00000000..911f5246 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetObjectIds.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskGetObjectIds.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructures.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructures.h new file mode 100644 index 00000000..3885ba39 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructures.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskGetStructures.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructuresForPurge.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructuresForPurge.h new file mode 100644 index 00000000..a89b1eb9 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskGetStructuresForPurge.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskGetStructuresForPurge.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadClock.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadClock.h new file mode 100644 index 00000000..b5e4dea2 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadClock.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskLoadClock.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadSnapshots.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadSnapshots.h new file mode 100644 index 00000000..019f886c --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskLoadSnapshots.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskLoadSnapshots.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskManagerConnection.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskManagerConnection.h new file mode 100644 index 00000000..005e2404 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskManagerConnection.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskManagerConnection.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSaveSnapshot.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSaveSnapshot.h new file mode 100644 index 00000000..b9dd8b2f --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSaveSnapshot.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskSaveSnapshot.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSetBiography.h b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSetBiography.h new file mode 100644 index 00000000..8e16499b --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/TaskSetBiography.h @@ -0,0 +1 @@ +#include "../../src/shared/TaskSetBiography.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/UniverseLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/UniverseLocator.h new file mode 100644 index 00000000..e1d70414 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/UniverseLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/UniverseLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/UnloadCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/include/public/serverDatabase/UnloadCharacterCustomPersistStep.h new file mode 100644 index 00000000..469eae43 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/UnloadCharacterCustomPersistStep.h @@ -0,0 +1 @@ +#include "../../src/shared/UnloadCharacterCustomPersistStep.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/WorldContainerLocator.h b/engine/server/library/serverDatabase/include/public/serverDatabase/WorldContainerLocator.h new file mode 100644 index 00000000..c647de21 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/WorldContainerLocator.h @@ -0,0 +1 @@ +#include "../../src/shared/WorldContainerLocator.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/dBAuctionRecord.h b/engine/server/library/serverDatabase/include/public/serverDatabase/dBAuctionRecord.h new file mode 100644 index 00000000..a04760d8 --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/dBAuctionRecord.h @@ -0,0 +1 @@ +#include "../../src/shared/dBAuctionRecord.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/dBBidRecord.h b/engine/server/library/serverDatabase/include/public/serverDatabase/dBBidRecord.h new file mode 100644 index 00000000..566b351d --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/dBBidRecord.h @@ -0,0 +1 @@ +#include "../../src/shared/dBBidRecord.h" diff --git a/engine/server/library/serverDatabase/include/public/serverDatabase/dBLocationRecord.h b/engine/server/library/serverDatabase/include/public/serverDatabase/dBLocationRecord.h new file mode 100644 index 00000000..c1c3969f --- /dev/null +++ b/engine/server/library/serverDatabase/include/public/serverDatabase/dBLocationRecord.h @@ -0,0 +1 @@ +#include "../../src/shared/dBLocationRecord.h" diff --git a/engine/server/library/serverDatabase/src/CMakeLists.txt b/engine/server/library/serverDatabase/src/CMakeLists.txt new file mode 100644 index 00000000..4a0b18e6 --- /dev/null +++ b/engine/server/library/serverDatabase/src/CMakeLists.txt @@ -0,0 +1,174 @@ + +set(SHARED_SOURCES + shared/AbstractTableBuffer.cpp + shared/AbstractTableBuffer.h + shared/CentralServerConnection.cpp + shared/CentralServerConnection.h + shared/CharacterLocator.cpp + shared/CharacterLocator.h + shared/CharacterNameLocator.cpp + shared/CharacterNameLocator.h + shared/CharacterQueries.cpp + shared/CharacterQueries.h + shared/ChatServerConnection.cpp + shared/ChatServerConnection.h + shared/ChunkLocator.cpp + shared/ChunkLocator.h + shared/CommoditiesServerConnection.cpp + shared/CommoditiesServerConnection.h + shared/ConfigServerDatabase.cpp + shared/ConfigServerDatabase.h + shared/ConsoleManager.cpp + shared/ConsoleManager.h + shared/ConsoleCommandParser.cpp + shared/ConsoleCommandParser.h + shared/ContainedObjectLocator.cpp + shared/ContainedObjectLocator.h + shared/ContentsLocator.cpp + shared/ContentsLocator.h + shared/CreateCharacterCustomPersistStep.cpp + shared/CreateCharacterCustomPersistStep.h + shared/CustomPersistStep.cpp + shared/CustomPersistStep.h + shared/DatabaseMetricsData.cpp + shared/DatabaseMetricsData.h + shared/DatabaseProcess.cpp + shared/DatabaseProcess.h + shared/DatabaseProcessQuery.cpp + shared/DatabaseProcessQuery.h + shared/DataLookup.cpp + shared/DataLookup.h + shared/DeleteCharacterCustomPersistStep.cpp + shared/DeleteCharacterCustomPersistStep.h + shared/FirstServerDatabase.h + shared/FixLoadWithCustomPersistStep.cpp + shared/FixLoadWithCustomPersistStep.h + shared/GameServerConnection.cpp + shared/GameServerConnection.h + shared/GetBiographyQuery.cpp + shared/GetBiographyQuery.h + shared/GetChunkQuery.cpp + shared/GetChunkQuery.h + shared/GetContentsList.cpp + shared/GetContentsList.h + shared/GetGoldVersionNumberQuery.cpp + shared/GetGoldVersionNumberQuery.h + shared/GetObjectIdsQuery.cpp + shared/GetObjectIdsQuery.h + shared/GetTimestampQuery.cpp + shared/GetTimestampQuery.h + shared/GetUniverseQuery.cpp + shared/GetUniverseQuery.h + shared/GetVersionNumberQuery.cpp + shared/GetVersionNumberQuery.h + shared/ImmediateDeleteCustomPersistStep.cpp + shared/ImmediateDeleteCustomPersistStep.h + shared/LazyDeleteQuery.cpp + shared/LazyDeleteQuery.h + shared/LazyDeleter.cpp + shared/LazyDeleter.h + shared/Loader.cpp + shared/Loader.h + shared/LoaderSnapshotGroup.cpp + shared/LoaderSnapshotGroup.h + shared/MessageToManager.cpp + shared/MessageToManager.h + shared/MoveToPlayerCustomPersistStep.cpp + shared/MoveToPlayerCustomPersistStep.h + shared/ObjectLocator.cpp + shared/ObjectLocator.h + shared/PurgeCompleteCustomPersistStep.cpp + shared/PurgeCompleteCustomPersistStep.h + shared/Persister.cpp + shared/Persister.h + shared/PreloadListQuery.cpp + shared/PreloadListQuery.h + shared/RenameCharacterCustomPersistStep.cpp + shared/RenameCharacterCustomPersistStep.h + shared/SaveTimestampQuery.cpp + shared/SaveTimestampQuery.h + shared/ScriptQueries.cpp + shared/ScriptQueries.h + shared/SetBiographyQuery.cpp + shared/SetBiographyQuery.h + shared/Snapshot.cpp + shared/Snapshot.h + shared/StructureQueries.cpp + shared/StructureQueries.h + shared/TableBuffer.cpp + shared/TableBuffer.h + shared/TaskChangeStationId.cpp + shared/TaskChangeStationId.h + shared/TaskCheckCharacterName.cpp + shared/TaskCheckCharacterName.h + shared/TaskCheckGoldVersionNumber.cpp + shared/TaskCheckGoldVersionNumber.h + shared/TaskCheckVersionNumber.cpp + shared/TaskCheckVersionNumber.h + shared/TaskCSTasks.cpp + shared/TaskCSTasks.h + shared/TaskGetBiography.cpp + shared/TaskGetBiography.h + shared/TaskGetObjectIds.cpp + shared/TaskGetObjectIds.h + shared/TaskGetStructures.cpp + shared/TaskGetStructures.h + shared/TaskGetStructuresForPurge.cpp + shared/TaskGetStructuresForPurge.h + shared/TaskLoadClock.cpp + shared/TaskLoadClock.h + shared/TaskLoadSnapshots.cpp + shared/TaskLoadSnapshots.h + shared/TaskManagerConnection.cpp + shared/TaskManagerConnection.h + shared/TaskSaveSnapshot.cpp + shared/TaskSaveSnapshot.h + shared/TaskSetBiography.cpp + shared/TaskSetBiography.h + shared/UniverseLocator.cpp + shared/UniverseLocator.h + shared/UnloadCharacterCustomPersistStep.cpp + shared/UnloadCharacterCustomPersistStep.h + shared/WorldContainerLocator.cpp + shared/WorldContainerLocator.h +) + +if(WIN32) + set(PLATFORM_SOURCES + win32/FirstServerDatabase.cpp + ) +else() + set(PLATFORM_SOURCES "") +endif() + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/shared + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDatabaseInterface/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedLog/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMath/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMathArchive/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMemoryManager/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedMessageDispatch/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetwork/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSynchronization/include/public + ${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverMetrics/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public + ${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localization/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/localizationArchive/include/public + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/singleton/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicode/include + ${SWG_EXTERNALS_SOURCE_DIR}/ours/library/unicodeArchive/include/public +) + +add_library(serverDatabase STATIC + ${SHARED_SOURCES} + ${PLATFORM_SOURCES} +) diff --git a/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.cpp b/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.cpp new file mode 100644 index 00000000..c7d1c6e7 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.cpp @@ -0,0 +1,41 @@ +// ====================================================================== +// +// AbstractTableBuffer.cpp +// copyright (c) 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/AbstractTableBuffer.h" + +#include +#include +#include + +// ====================================================================== + +AbstractTableBuffer::AbstractTableBuffer() +{ +} + +// ---------------------------------------------------------------------- + +AbstractTableBuffer::~AbstractTableBuffer() +{ +} + +// ---------------------------------------------------------------------- + +/** + * Return TRUE if the two tagsets have at least one tag in common. + * TODO: If this starts showing up on profiles, write a more efficient version + */ + +bool AbstractTableBuffer::hasCommonTags(const DB::TagSet &left, const DB::TagSet &right) +{ + std::vector result; + IGNORE_RETURN(std::set_intersection(left.begin(), left.end(), right.begin(), right.end(), std::back_inserter(result))); + return (!result.empty()); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.h b/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.h new file mode 100644 index 00000000..5c8f253a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/AbstractTableBuffer.h @@ -0,0 +1,60 @@ +// ====================================================================== +// +// AbstractTableBuffer.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_AbstractTableBuffer_H +#define INCLUDED_AbstractTableBuffer_H + +// ====================================================================== + +#include "sharedFoundation/Tag.h" + +// ====================================================================== + +namespace DB +{ + class Session; +} + +class NetworkId; + +// ====================================================================== + +namespace DB +{ + typedef stdset::fwd TagSet; +} + +// ====================================================================== + +/** + * Abstract base class for TableBuffer's. Allows TableBuffers to be + * put in lists, have virtual functions, etc. + */ + +class AbstractTableBuffer +{ + public: + /** + * Load the buffer from the database. + * The TagSet identifies which types of objects are being loaded + * Some buffers may change how they work or skip loading altogether + * based on the contents of this set. + */ + virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase) =0; + virtual bool save(DB::Session *session) =0; + virtual void removeObject(const NetworkId &object) =0; + + static bool hasCommonTags(const DB::TagSet &left, const DB::TagSet &right); + + public: + AbstractTableBuffer(); + virtual ~AbstractTableBuffer(); +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CentralServerConnection.cpp b/engine/server/library/serverDatabase/src/shared/CentralServerConnection.cpp new file mode 100644 index 00000000..ff845939 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CentralServerConnection.cpp @@ -0,0 +1,104 @@ +// ====================================================================== +// +// CentralServerConnection.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "Archive/Archive.h" +#include "ConsoleManager.h" +#include "serverDatabase/CentralServerConnection.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/Persister.h" +#include "serverNetworkMessages/RenameCharacterMessage.h" +#include "serverNetworkMessages/TransferAccountData.h" +#include "serverNetworkMessages/TransferAccountDataArchive.h" +#include "serverNetworkMessages/TransferCharacterData.h" +#include "serverNetworkMessages/TransferCharacterDataArchive.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedLog/Log.h" +#include "sharedNetwork/NetworkSetupData.h" +#include "sharedNetworkMessages/ConsoleChannelMessages.h" +#include "sharedNetworkMessages/GameNetworkMessage.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "Unicode.h" +#include "UnicodeUtils.h" + +// ====================================================================== + +CentralServerConnection::CentralServerConnection(const std::string & a, const unsigned short p) : + ServerConnection(a, p, NetworkSetupData()), + MessageDispatch::Receiver() +{ +} + +// ---------------------------------------------------------------------- + +CentralServerConnection::~CentralServerConnection() +{ + DEBUG_REPORT_LOG(true, ("Deleting central server connection\n")); +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onConnectionClosed() +{ + ServerConnection::onConnectionClosed(); + static MessageConnectionCallback m("CentralConnectionClosed"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onConnectionOpened() +{ + static MessageConnectionCallback m("CentralConnectionOpened"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::onReceive(const Archive::ByteStream & message) +{ + Archive::ReadIterator ri = message.begin(); + const GameNetworkMessage msg(ri); + ri = message.begin(); + + if(msg.isType("TransferRenameCharacter")) + { + const GenericValueTypeMessage request(ri); + const TransferCharacterData & requestData = request.getValue(); + LOG("CustomerService", ("CharacterTransfer: Received TransferRenameCharacter, starting game database name change. %s", requestData.toString().c_str())); + Persister::getInstance().renameCharacter(0, static_cast(RenameCharacterMessageEx::RCMS_cts_rename), request.getValue().getSourceStationId(), request.getValue().getCharacterId(), Unicode::narrowToWide(request.getValue().getDestinationCharacterName()), Unicode::narrowToWide(request.getValue().getSourceCharacterName()), false, NetworkId::cms_invalid, &requestData); + } + else if(msg.isType("ConGenericMessage")) + { + const ConGenericMessage cm(ri); + std::string result; + ConsoleManager::processString(cm.getMsg(), cm.getMsgId(), result); + const ConGenericMessage response(result, cm.getMsgId()); + send(response, true); + } + else if(msg.isType("TransferAccountRequestCentralDatabase")) + { + const GenericValueTypeMessage request(ri); + const TransferAccountData & requestData = request.getValue(); + LOG("CustomerService", ("CharacterTransfer: Received TransferAccountRequestCentralDatabase, starting game database change from station ID %d to station ID %d", request.getValue().getSourceStationId(), request.getValue().getDestinationStationId())); + Persister::getInstance().changeStationId(&requestData); + } + else + { + ServerConnection::onReceive(message); + } +} + +//----------------------------------------------------------------------- + +void CentralServerConnection::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) +{ + UNREF(source); + UNREF(message); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CentralServerConnection.h b/engine/server/library/serverDatabase/src/shared/CentralServerConnection.h new file mode 100644 index 00000000..c273c793 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CentralServerConnection.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// CentralServerConnection.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CentralServerConnection_H +#define INCLUDED_CentralServerConnection_H + +// ====================================================================== + +#include "sharedMessageDispatch/Receiver.h" +#include "serverUtility/ServerConnection.h" + +// ====================================================================== + +class CentralServerConnection : public ServerConnection, public MessageDispatch::Receiver +{ +public: + CentralServerConnection(const std::string & remoteAddress, const unsigned short port); + ~CentralServerConnection(); + + void onConnectionClosed (); + void onConnectionOpened (); + void onReceive (const Archive::ByteStream & message); + void receiveMessage (const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); +private: + CentralServerConnection(CentralServerConnection&); + CentralServerConnection& operator=(CentralServerConnection&); +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CharacterLocator.cpp b/engine/server/library/serverDatabase/src/shared/CharacterLocator.cpp new file mode 100644 index 00000000..61c84a59 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterLocator.cpp @@ -0,0 +1,91 @@ +// ====================================================================== +// +// CharacterLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/CharacterLocator.h" + +#include + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/Loader.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +CharacterLocator::CharacterLocator(const NetworkId &characterId) : + ObjectLocator(), + m_characterId(characterId) +{ +} + +// ---------------------------------------------------------------------- + +CharacterLocator::~CharacterLocator() +{ + Loader::getInstance().onCharacterLocatorDeleted(m_characterId); +} + +// ---------------------------------------------------------------------- + +bool CharacterLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + + int startTime = Clock::timeMs(); + + LocateCharacterQuery qry(m_characterId, schema); + bool rval = session->exec(&qry); + qry.done(); + + LOG("TRACE_LOGIN",("Character locator %s -- %i objects %i ms",m_characterId.getValueString().c_str(), qry.object_count.getValue(), Clock::timeMs()-startTime)); + objectsLocated = qry.object_count.getValue(); + return rval; +} + +// ====================================================================== + +CharacterLocator::LocateCharacterQuery::LocateCharacterQuery(const NetworkId &networkId, const std::string &schema) : + DB::Query(), + object_id(networkId), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void CharacterLocator::LocateCharacterQuery::getSQL(std::string &sql) +{ + sql = std::string("begin :object_count := ") + m_schema + "loader.locate_player (:object_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool CharacterLocator::LocateCharacterQuery::bindParameters() +{ + if (!bindParameter(object_count)) return false; + if (!bindParameter(object_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool CharacterLocator::LocateCharacterQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode CharacterLocator::LocateCharacterQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CharacterLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h new file mode 100644 index 00000000..fc1fa203 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterLocator.h @@ -0,0 +1,63 @@ +// ====================================================================== +// +// CharacterLocator.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CharacterLocator_H +#define INCLUDED_CharacterLocator_H + +#include "serverDatabase/ObjectLocator.h" +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Locate a specified character and add it to the list of objects to be + * loaded by the Snapshot. + */ +class CharacterLocator : public ObjectLocator +{ + public: + CharacterLocator(const NetworkId &characterId); + virtual ~CharacterLocator(); + + public: + bool locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated); + + private: + NetworkId m_characterId; + + private: + class LocateCharacterQuery : public DB::Query + { + public: + LocateCharacterQuery(const NetworkId &networkId, const std::string &schema); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + virtual DB::Query::QueryMode getExecutionMode() const; + + private: + LocateCharacterQuery(const LocateCharacterQuery&); // disable + LocateCharacterQuery& operator=(const LocateCharacterQuery&); //disable + + public: + DB::BindableLong object_count; + DB::BindableNetworkId object_id; + + private: + std::string m_schema; + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.cpp b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.cpp new file mode 100644 index 00000000..c8bc4b45 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.cpp @@ -0,0 +1,108 @@ +// ====================================================================== +// +// CharacterNameLocator.cpp +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/CharacterNameLocator.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverNetworkMessages/CharacterNamesMessage.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +bool CharacterNameLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + int rowsFetched; + DEBUG_REPORT_LOG(ConfigServerDatabase::getLogObjectLoading(),("Loading character names.\n")); + + CharacterNameQuery qry(schema); + if (! (session->exec(&qry))) + { + objectsLocated = 0; + return false; + } + while ((rowsFetched = qry.fetch()) > 0) + { + size_t numRows = qry.getNumRowsFetched(); + size_t count = 0; + const std::vector &data = qry.getData(); + + for (std::vector::const_iterator i=data.begin(); i!=data.end(); ++i) + { + if (++count > numRows) + break; + + m_characterIds.push_back(i->character_id.getValue()); + m_stationIds.push_back(i->character_station_id.getValue()); + m_characterNames.push_back(i->character_name.getValueASCII()); + m_characterFullNames.push_back(i->character_full_name.getValueASCII()); + m_characterCreateTime.push_back(i->character_create_time.getValue() + (7 * 60 * 60)); + m_characterLastLoginTime.push_back(i->character_last_login_time.getValue() + (7 * 60 * 60)); + DEBUG_REPORT_LOG(ConfigServerDatabase::getLogObjectLoading(),("\t%s:%s\n", i->character_id.getValue().getValueString().c_str(), i->character_name.getValueASCII().c_str())); + } + } + + objectsLocated = 0; + return (rowsFetched >= 0); +} + +// ---------------------------------------------------------------------- + +void CharacterNameLocator::sendPostBaselinesCustomData(GameServerConnection &conn) const +{ + CharacterNamesMessage msg(m_characterIds, m_stationIds, m_characterNames, m_characterFullNames, m_characterCreateTime, m_characterLastLoginTime); + conn.send(msg,true); +} + +// ====================================================================== + +CharacterNameLocator::CharacterNameQuery::CharacterNameQuery(const std::string &schema) : + m_data(ConfigServerDatabase::getDefaultFetchBatchSize()), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void CharacterNameLocator::CharacterNameQuery::getSQL(std::string &sql) +{ + sql="begin :result := "+m_schema+"loader.get_character_name_list(); end;"; +} + +// ---------------------------------------------------------------------- + +bool CharacterNameLocator::CharacterNameQuery::bindParameters() +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool CharacterNameLocator::CharacterNameQuery::bindColumns() +{ + size_t skipSize = reinterpret_cast(&(m_data[1])) - reinterpret_cast(&(m_data[0])); + setColArrayMode(skipSize, m_data.size()); + + if (!bindCol(m_data[0].character_id)) return false; + if (!bindCol(m_data[0].character_station_id)) return false; + if (!bindCol(m_data[0].character_name)) return false; + if (!bindCol(m_data[0].character_full_name)) return false; + if (!bindCol(m_data[0].character_create_time)) return false; + if (!bindCol(m_data[0].character_last_login_time)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode CharacterNameLocator::CharacterNameQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h new file mode 100644 index 00000000..3ca8cd55 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterNameLocator.h @@ -0,0 +1,82 @@ +// ====================================================================== +// +// CharacterNameLocator.h +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CharacterNameLocator_H +#define INCLUDED_CharacterNameLocator_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "serverDatabase/ObjectLocator.h" +#include + +// ====================================================================== + +/** + * Load character names and send them to the game server. + * (Doesn't add any objects to the load, handles the names as custom data.) + */ +class CharacterNameLocator : public ObjectLocator +{ + public: + virtual bool locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated); + virtual void sendPostBaselinesCustomData(GameServerConnection &conn) const; + + private: + struct CharacterNameRow + { + DB::BindableNetworkId character_id; + DB::BindableLong character_station_id; + DB::BindableString<127> character_name; + DB::BindableString<127> character_full_name; + DB::BindableLong character_create_time; + DB::BindableLong character_last_login_time; + }; + + class CharacterNameQuery : public DB::Query + { + public: + CharacterNameQuery(const std::string &schema); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + const std::vector & getData() const; + + private: + + std::vector m_data; + std::string m_schema; + + private: + CharacterNameQuery(const CharacterNameQuery&); + CharacterNameQuery& operator=(const CharacterNameQuery&); + }; + + private: + std::vector m_characterIds; + std::vector m_stationIds; + std::vector m_characterNames; + std::vector m_characterFullNames; + std::vector m_characterCreateTime; + std::vector m_characterLastLoginTime; +}; + +// ====================================================================== + +inline const std::vector & CharacterNameLocator::CharacterNameQuery::getData() const +{ + return m_data; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CharacterQueries.cpp b/engine/server/library/serverDatabase/src/shared/CharacterQueries.cpp new file mode 100644 index 00000000..429c2896 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterQueries.cpp @@ -0,0 +1,164 @@ +// ====================================================================== +// +// CharacterQueries.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/CharacterQueries.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +void GetCharacters::getSQL(std::string &sql) +{ + sql="begin :result := "+DatabaseProcess::getInstance().getSchemaQualifier()+"loader.get_characters(:station_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetCharacters::bindParameters() +{ + if (!bindParameter(data.station_id)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +bool GetCharacters::bindColumns() +{ + if (!bindCol(data.object_id)) return false; + if (!bindCol(data.object_template)) return false; + if (!bindCol(data.scene_id)) return false; + if (!bindCol(data.character_name)) return false; + if (!bindCol(data.container_id)) return false; + if (!bindCol(data.x)) return false; + if (!bindCol(data.y)) return false; + if (!bindCol(data.z)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +const GetCharacters::GetCharactersRow &GetCharacters::getData() const +{ + return data; +} + +// ---------------------------------------------------------------------- + +void GetCharacters::setStationId(StationId station_id) +{ + data.station_id.setValue(static_cast(station_id)); +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetCharacters::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ====================================================================== + +AddCharacter::AddCharacter(StationId stationId, const NetworkId &objectId, const Unicode::String &characterName, const std::string &normalizedName) : + DB::Query(), + station_id(static_cast(stationId)), + object_id(objectId), + character_name(characterName), + normalized_name(normalizedName) +{ +} + +// ---------------------------------------------------------------------- + +void AddCharacter::getSQL(std::string &sql) +{ + sql="begin "+DatabaseProcess::getInstance().getSchemaQualifier()+"persister.add_player (:station_id, :character_object, :character_name, :normalized_name); end;"; +// insert into players (station_id, character_object) values (?,?)"); +} + +// ---------------------------------------------------------------------- + +bool AddCharacter::bindParameters() +{ + if (!bindParameter(station_id)) return false; + if (!bindParameter(object_id)) return false; + if (!bindParameter(character_name)) return false; + if (!bindParameter(normalized_name)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +bool AddCharacter::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode AddCharacter::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== + +RenameCharacter::RenameCharacter(const NetworkId &characterId, const Unicode::String &characterName, const Unicode::String &normalizedName) : + DB::Query(), + object_id(characterId), + character_name(characterName), + normalized_name(normalizedName), + result() +{ +} + +// ---------------------------------------------------------------------- + +void RenameCharacter::getSQL(std::string &sql) +{ + sql=std::string("begin :result := ")+DatabaseProcess::getInstance().getSchemaQualifier()+"persister.rename_character (:character_object, :character_name, :normalized_name); end;"; +} + +// ---------------------------------------------------------------------- + +bool RenameCharacter::bindParameters() +{ + if (!bindParameter(result)) return false; + if (!bindParameter(object_id)) return false; + if (!bindParameter(character_name)) return false; + if (!bindParameter(normalized_name)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +bool RenameCharacter::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode RenameCharacter::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ---------------------------------------------------------------------- + +bool RenameCharacter::getResult() const +{ + return (result.getValue()==1); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CharacterQueries.h b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h new file mode 100644 index 00000000..9cc1dfc8 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CharacterQueries.h @@ -0,0 +1,118 @@ +// ====================================================================== +// +// CharacterQueries.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CharacterQueries_H +#define INCLUDED_CharacterQueries_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbRow.h" +#include "sharedFoundation/StationId.h" + +// ====================================================================== + +namespace DBQuery { + + /** A query to get the list of characters for an account. + */ + class GetCharacters : public DB::Query + { + public: + + struct GetCharactersRow : public DB::Row + { + DB::BindableString<128> character_name; + DB::BindableString<128> scene_id; + DB::BindableNetworkId object_id; + DB::BindableString<1000> object_template; + DB::BindableNetworkId container_id; + DB::BindableDouble x; + DB::BindableDouble y; + DB::BindableDouble z; + DB::BindableLong station_id; + }; + + GetCharacters() {} + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + const GetCharactersRow &getData() const; + void setStationId(StationId station_id); + + protected: + virtual QueryMode getExecutionMode() const; + + private: + GetCharactersRow data; + + private: + GetCharacters(const GetCharacters&); // disable + GetCharacters& operator=(const GetCharacters&); //disable + }; + +// ====================================================================== + + /** A query to associate a character with a particular account + */ + class AddCharacter : public DB::Query + { + public: + AddCharacter(StationId stationId, const NetworkId &objectId, const Unicode::String &characterName, const std::string &normalizedName); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + protected: + virtual QueryMode getExecutionMode() const; + + private: + DB::BindableLong station_id; + DB::BindableNetworkId object_id; + DB::BindableString<127> character_name; + DB::BindableString<127> normalized_name; + + private: + AddCharacter(const AddCharacter&); // disable + AddCharacter& operator=(const AddCharacter&); //disable + }; + +// ====================================================================== + + class RenameCharacter : public DB::Query + { + public: + RenameCharacter (const NetworkId &characterId, const Unicode::String &characterName, const Unicode::String &normalizedName); + bool getResult () const; + + virtual void getSQL (std::string &sql); + virtual bool bindParameters (); + virtual bool bindColumns (); + + protected: + virtual QueryMode getExecutionMode () const; + + private: + DB::BindableNetworkId object_id; + DB::BindableString<127> character_name; + DB::BindableString<127> normalized_name; + DB::BindableLong result; + + private: + RenameCharacter (const RenameCharacter&); // disable + RenameCharacter& operator= (const RenameCharacter&); //disable + }; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ChatServerConnection.cpp b/engine/server/library/serverDatabase/src/shared/ChatServerConnection.cpp new file mode 100644 index 00000000..e8a6a5a4 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ChatServerConnection.cpp @@ -0,0 +1,32 @@ +// ChatServerConnection.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.h" +#include "ChatServerConnection.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +ChatServerConnection::ChatServerConnection(const std::string & a, const unsigned short p) : +ServerConnection(a, p, NetworkSetupData()) +{ +} + +//----------------------------------------------------------------------- + +ChatServerConnection::~ChatServerConnection() +{ +} + +//----------------------------------------------------------------------- + +void ChatServerConnection::onConnectionClosed() +{ + static MessageConnectionCallback m("ChatServerConnectionClosed"); + emitMessage(m); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverDatabase/src/shared/ChatServerConnection.h b/engine/server/library/serverDatabase/src/shared/ChatServerConnection.h new file mode 100644 index 00000000..d522d356 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ChatServerConnection.h @@ -0,0 +1,30 @@ +// ChatServerConnection.h +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +#ifndef _INCLUDED_ChatServerConnection_H +#define _INCLUDED_ChatServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class ChatServerConnection : public ServerConnection +{ +public: + ChatServerConnection(const std::string & address, const unsigned short port); + ~ChatServerConnection(); + + void onConnectionClosed(); + +private: + ChatServerConnection & operator = (const ChatServerConnection & rhs); + ChatServerConnection(const ChatServerConnection & source); + +}; + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_ChatServerConnection_H diff --git a/engine/server/library/serverDatabase/src/shared/ChunkLocator.cpp b/engine/server/library/serverDatabase/src/shared/ChunkLocator.cpp new file mode 100644 index 00000000..90dc0bfd --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ChunkLocator.cpp @@ -0,0 +1,75 @@ +// ====================================================================== +// +// ChunkLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ChunkLocator.h" + +#include +#include + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/GetChunkQuery.h" +#include "serverNetworkMessages/ChunkCompleteMessage.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedFoundation/Clock.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +ChunkLocator::ChunkLocator(int nodeX, int nodeZ, const std::string &sceneId, uint32 serverId, bool wantChunkCompleteMessage) : + ObjectLocator(), + m_nodeX(nodeX), + m_nodeZ(nodeZ), + m_sceneId(new std::string(sceneId)), + m_objectCount(0), + m_queryTime(0), + m_serverId(serverId), + m_wantChunkCompleteMessage(wantChunkCompleteMessage) +{ +} + +// ---------------------------------------------------------------------- + +ChunkLocator::~ChunkLocator() +{ + if (ConfigServerDatabase::getLogChunkLoading()) + LOG("ChunkLocator",("Chunk %s (%i,%i) (server %lu) -- %i objects %i ms",m_sceneId->c_str(), m_nodeX, m_nodeZ, m_serverId, m_objectCount,m_queryTime)); + + delete m_sceneId; + m_sceneId=0; +} + +// ====================================================================== + +bool ChunkLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + + DBQuery::GetChunkQuery qry(schema); + qry.setChunk(*m_sceneId, m_nodeX, m_nodeZ); + int startTime = Clock::timeMs(); + + bool rval = session->exec(&qry); + qry.done(); + + m_objectCount = qry.getObjectCount(); + m_queryTime = Clock::timeMs()-startTime; + + objectsLocated = m_objectCount; + return rval; +} + +// ---------------------------------------------------------------------- + +void ChunkLocator::sendPostBaselinesCustomData(GameServerConnection &conn) const +{ + if (m_wantChunkCompleteMessage) + conn.queueCompletedChunk(m_nodeX, m_nodeZ); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ChunkLocator.h b/engine/server/library/serverDatabase/src/shared/ChunkLocator.h new file mode 100644 index 00000000..4b0d414c --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ChunkLocator.h @@ -0,0 +1,49 @@ +// ====================================================================== +// +// ChunkLocator.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ChunkLocator_H +#define INCLUDED_ChunkLocator_H + +#include "serverDatabase/ObjectLocator.h" + +// ====================================================================== + +/** + * Given a sceneID and map coordinates, locates all the objects in that + * chunk. Adds them to the list of objects to be loaded by the Snapshot. + * + * @todo It will be common to have a bunch of these attached to the same + * snapshot. Maybe it would be more efficient to find a way to combine + * them. + */ +class ChunkLocator : public ObjectLocator +{ + public: + ChunkLocator(int nodeX, int nodeZ, const std::string &sceneId, uint32 serverId, bool wantChunkCompleteMessage); + virtual ~ChunkLocator(); + + public: + virtual bool locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated); + virtual void sendPostBaselinesCustomData(GameServerConnection &conn) const; + + private: + int m_nodeX; + int m_nodeZ; + std::string *m_sceneId; + int m_objectCount; + int m_queryTime; + uint32 m_serverId; + bool m_wantChunkCompleteMessage; + + private: + ChunkLocator &operator=(const ChunkLocator&); //disable + ChunkLocator(const ChunkLocator&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.cpp b/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.cpp new file mode 100644 index 00000000..cbc39eb0 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.cpp @@ -0,0 +1,91 @@ +// ====================================================================== +// +// CommoditiesServerConnection.cpp +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. +// Author: Mike Howard +// Server Infrastructure by: Justin Randall +// +// This is message handler for incoming commodities messages. +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "Archive/ByteStream.h" +#include "serverDatabase/CommoditiesServerConnection.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/GameGameServerMessages.h" +#include "serverUtility/ConfigServerUtility.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +namespace CommoditiesServerConnectionNamespace +{ +} + +using namespace CommoditiesServerConnectionNamespace; + +//----------------------------------------------------------------------- + +CommoditiesServerConnection::CommoditiesServerConnection(const std::string & a, const unsigned short p) : + ServerConnection(a, p, NetworkSetupData()), + MessageDispatch::Receiver() +{ +} + +//----------------------------------------------------------------------- + +CommoditiesServerConnection::CommoditiesServerConnection(UdpConnectionMT * u, TcpClient * t) : + ServerConnection(u, t), + MessageDispatch::Receiver() +{ +} + +//----------------------------------------------------------------------- + +CommoditiesServerConnection::~CommoditiesServerConnection() +{ + DEBUG_REPORT_LOG(true, ("Deleting commodities server connection\n")); +} + +//----------------------------------------------------------------------- + +void CommoditiesServerConnection::onConnectionClosed() +{ + ServerConnection::onConnectionClosed(); + static MessageConnectionCallback m("CommoditiesConnectionClosed"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + +void CommoditiesServerConnection::onConnectionOpened() +{ + ServerConnection::onConnectionOpened(); + static MessageConnectionCallback m("CommoditiesConnectionOpened"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + +void CommoditiesServerConnection::onReceive(const Archive::ByteStream & message) +{ + DEBUG_REPORT_LOG(true, ("CommoditiesServerConnection::onReceive.\n")); + ServerConnection::onReceive(message); + + Archive::ReadIterator ri = message.begin(); + const GameNetworkMessage msg(ri); + ri = message.begin(); + DEBUG_REPORT_LOG(true, ("CommoditiesServerConnection::onReceive %s\n", msg.getCmdName().c_str())); +} + +//----------------------------------------------------------------------- + +void CommoditiesServerConnection::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) +{ + DEBUG_REPORT_LOG(true, ("CommoditiesServerConnection::receiveMessage\n")); + UNREF(source); + UNREF(message); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.h b/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.h new file mode 100644 index 00000000..f3afaeac --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CommoditiesServerConnection.h @@ -0,0 +1,43 @@ +// ====================================================================== +// +// CommoditiesServerConnection.h +// Copyright 2004, Sony Online Entertainment Inc., all rights reserved. +// Author: Mike Howard +// +// This is message handler for incoming commodities messages. +// +// ====================================================================== + +#ifndef _INCLUDED_CommoditiesServerConnection_H +#define _INCLUDED_CommoditiesServerConnection_H + + +#include "sharedMessageDispatch/Receiver.h" +#include "serverUtility/ServerConnection.h" + +// ====================================================================== + +class CommoditiesServerConnection : public ServerConnection, public MessageDispatch::Receiver +{ +public: + CommoditiesServerConnection(const std::string & remoteAddress, const unsigned short remotePort); + explicit CommoditiesServerConnection(UdpConnectionMT *, TcpClient * t); + ~CommoditiesServerConnection(); + + virtual void onConnectionClosed (); + virtual void onConnectionOpened (); + virtual void onReceive (const Archive::ByteStream & message); + virtual void receiveMessage (const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); + +private: + int m_gameServerId; + bool m_showAllDebugInfo; + + CommoditiesServerConnection(); + CommoditiesServerConnection & operator = (const CommoditiesServerConnection & rhs); + CommoditiesServerConnection(const CommoditiesServerConnection & source); +}; + +//----------------------------------------------------------------------- + +#endif // _INCLUDED_CommoditiesServerConnection_H diff --git a/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp new file mode 100644 index 00000000..ea303658 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.cpp @@ -0,0 +1,136 @@ +// ====================================================================== +// +// ConfigServerDatabase.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverUtility/ConfigServerUtility.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/NetworkId.h" +#include + +//------------------------------------------------------------------- + +ConfigServerDatabase::Data* ConfigServerDatabase::data; +static ConfigServerDatabase::Data staticData; + +//------------------------------------------------------------------- + +#define KEY_INT(a,b) (data->a = ConfigFile::getKeyInt("dbProcess", #a, b)) +#define KEY_BOOL(a,b) (data->a = ConfigFile::getKeyBool("dbProcess", #a, b)) +#define KEY_FLOAT(a,b) (data->a = ConfigFile::getKeyFloat("dbProcess", #a, b)) +#define KEY_STRING(a,b) (data->a = ConfigFile::getKeyString("dbProcess", #a, b)) + +//------------------------------------------------------------------- + +void ConfigServerDatabase::install(void) +{ + ExitChain::add(ConfigServerDatabase::remove,"ConfigServerDatabase::remove"); + + ConfigServerUtility::install(); + data = &staticData; + + KEY_INT (objvarNameCleanupTime, 0); + KEY_INT (orphanedObjectCleanupTime, 0); + KEY_INT (marketAttributesCleanupTime, 0); + KEY_INT (messagesCleanupTime, 0); + KEY_INT (brokenObjectCleanupTime, 0); + KEY_INT (vendorObjectCleanupTime, 0); + KEY_STRING (customSQLFilename,""); + KEY_BOOL (enableFixBadCells, false); + KEY_STRING (objectTemplateListUpdateFilename,""); + + KEY_STRING (DSN,"gameserver"); + KEY_STRING (alternateDSN,""); + KEY_STRING (databaseUID,"gameserver"); + KEY_STRING (databasePWD,"gameserver"); + KEY_STRING (databaseProtocol,"DEFAULT"); + KEY_STRING (centralServerAddress, "swo-dev1.station.sony.com"); + KEY_INT (centralServerPort, 44451); + KEY_STRING (commoditiesServerAddress, "swo-dev1.station.sony.com"); + KEY_INT (commoditiesServerPort, 44457); //todo: confirm that this is a good port MSH + KEY_INT (taskManagerPort, 60001); + KEY_INT (expectedDBVersion, 270); + KEY_BOOL (correctDBVersionRequired,true); + KEY_INT (saveFrequencyLimit,10); + KEY_STRING (schemaOwner, ""); + KEY_STRING (goldSchemaOwner, ""); + KEY_FLOAT (uniqueMessageCacheTimeSec, 30.0f); + KEY_INT (loaderThreads,2); + KEY_INT (persisterThreads,1); + KEY_INT (newCharacterThreads,1); + KEY_INT (characterImmediateDeleteMinutes,120); + KEY_BOOL (logObjectLoading, false); + KEY_BOOL (enableQueryProfile, false); + KEY_BOOL (verboseQueryMode, false); + KEY_BOOL (logWorkerThreads, false); + KEY_STRING (gameServiceBindInterface, ""); + KEY_BOOL (reportSaveTimes, false); + KEY_BOOL (shouldSleep, true); + KEY_BOOL (enableLoadLocks, true); + KEY_INT (databaseReconnectTime, 0); + KEY_BOOL (logChunkLoading,false); + KEY_BOOL (useMemoryManagerForOCI,true); + KEY_INT (maxCharactersPerLoadRequest,10); + KEY_INT (maxChunksPerLoadRequest,200); + KEY_FLOAT (maxLoadStartDelay,300.0f); + KEY_INT (maxErrorCountBeforeDisconnect,5); + KEY_INT (maxErrorCountBeforeBailout,15); + KEY_INT (errorSleepTime,5000); + KEY_INT (disconnectSleepTime,30000); + KEY_INT (saveAtModulus,-1); + KEY_INT (saveAtDivisor,10); + KEY_INT (backloggedQueueSize,50); + KEY_INT (backloggedRecoveryQueueSize,25); + KEY_INT (maxTimewarp,data->saveFrequencyLimit * 2 < 600 ? 600 : data->saveFrequencyLimit * 2); + KEY_BOOL (enableObjvarPacking, true); + KEY_INT (prefetchNumRows,0); + KEY_INT (prefetchMemory,0); + KEY_INT (defaultFetchBatchSize,1000); + KEY_INT (queryReportingRate,60); + KEY_INT (enableDatabaseErrorLogging, 0); + KEY_INT (defaultMessageBulkBindSize, 1000); + KEY_BOOL (enableGoldDatabase, false); + KEY_STRING (maxGoldNetworkId, "10000000"); + KEY_FLOAT (defaultQueueUpdateTimeLimit, 0.25f); + KEY_BOOL (enableDataCleanup, false); + KEY_INT (defaultLazyDeleteBulkBindSize, 100); + KEY_INT (defaultLazyDeleteSleepTime, 1000); + KEY_INT (writeDelay, 0); + KEY_BOOL (delayUnloadIfObjectStillHasData, true); + KEY_FLOAT (experienceConsolidationTime, 0.0f); + KEY_INT (maxLoaderFinishedTasks, 100); + KEY_FLOAT (reportLongFrameTime, 1.0f); + KEY_BOOL (enableVerboseMessageLogging, false); + KEY_BOOL (profilerExpandAll, true); + KEY_INT (profilerDisplayPercentageMinimum, 0); + KEY_BOOL (fatalOnDataError, false); + KEY_INT (maxUnackedLoadCount, 1000000000); // by default, set to an "unlimited" number, and use maxUnackedLoadCountPerServer as the cap + KEY_INT (maxUnackedLoadCountPerServer, 2); + KEY_INT (auctionLocationLoadBatchSize, 100); + KEY_INT (auctionLoadBatchSize, 100); + KEY_INT (auctionAttributeLoadBatchSize, 100); + KEY_INT (auctionBidLoadBatchSize, 100); + KEY_INT (oldestUnackedLoadAlertThresholdSeconds, 10*60); // seconds +} + +//------------------------------------------------------------------- + +void ConfigServerDatabase::remove(void) +{ + ConfigServerUtility::remove(); +} + +// ---------------------------------------------------------------------- + +const NetworkId & ConfigServerDatabase::getMaxGoldNetworkId(void) +{ + static const NetworkId theValue(std::string(data->maxGoldNetworkId)); + return theValue; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.h b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.h new file mode 100644 index 00000000..f909f5f9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ConfigServerDatabase.h @@ -0,0 +1,772 @@ +// ====================================================================== +// +// ConfigServerDatabase.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ConfigServerDatabase_H +#define INCLUDED_ConfigServerDatabase_H + +// ====================================================================== + +class NetworkId; + +// ====================================================================== + +class ConfigServerDatabase +{ +public: + + struct Data + { + const char * centralServerAddress; + int centralServerPort; + const char * commoditiesServerAddress; + int commoditiesServerPort; + + // database configuration: + const char * DSN; + const char * alternateDSN; + const char * databaseUID; + const char * databasePWD; + const char * databaseProtocol; + const char * schemaOwner; + const char * goldSchemaOwner; + + + int objvarNameCleanupTime; + int orphanedObjectCleanupTime; + int marketAttributesCleanupTime; + int messagesCleanupTime; + int brokenObjectCleanupTime; + int vendorObjectCleanupTime; + const char * customSQLFilename; + bool enableFixBadCells; + const char * objectTemplateListUpdateFilename; + + int taskManagerPort; + int expectedDBVersion; + bool correctDBVersionRequired; + int saveFrequencyLimit; + float uniqueMessageCacheTimeSec; + int loaderThreads; + int persisterThreads; + int newCharacterThreads; + int characterImmediateDeleteMinutes; + bool logObjectLoading; + bool enableQueryProfile; + bool verboseQueryMode; + bool logWorkerThreads; + const char * gameServiceBindInterface; + bool reportSaveTimes; + bool shouldSleep; + bool enableLoadLocks; + int databaseReconnectTime; + bool logChunkLoading; + bool useMemoryManagerForOCI; + int maxCharactersPerLoadRequest; + int maxChunksPerLoadRequest; + float maxLoadStartDelay; + int maxErrorCountBeforeDisconnect; + int maxErrorCountBeforeBailout; + int errorSleepTime; + int disconnectSleepTime; + int saveAtModulus; + int saveAtDivisor; + int backloggedQueueSize; + int backloggedRecoveryQueueSize; + int maxTimewarp; + bool enableObjvarPacking; + int prefetchNumRows; + int prefetchMemory; + int defaultFetchBatchSize; + int queryReportingRate; + int enableDatabaseErrorLogging; + int defaultMessageBulkBindSize; + bool enableGoldDatabase; + const char* maxGoldNetworkId; + float defaultQueueUpdateTimeLimit; + bool enableDataCleanup; + int defaultLazyDeleteBulkBindSize; + int defaultLazyDeleteSleepTime; + int writeDelay; + bool delayUnloadIfObjectStillHasData; + float experienceConsolidationTime; + int maxLoaderFinishedTasks; + float reportLongFrameTime; + bool enableVerboseMessageLogging; + bool profilerExpandAll; + int profilerDisplayPercentageMinimum; + bool fatalOnDataError; + int maxUnackedLoadCount; + int maxUnackedLoadCountPerServer; + int auctionLocationLoadBatchSize; + int auctionLoadBatchSize; + int auctionAttributeLoadBatchSize; + int auctionBidLoadBatchSize; + int oldestUnackedLoadAlertThresholdSeconds; + }; + +private: + + static Data *data; + +public: + + static void install (void); + static void remove (void); + + static const int getObjvarNameCleanupTime (void); + static const int getOrphanedObjectCleanupTime(void); + static const int getMarketAttributesCleanupTime(void); + static const int getMessagesCleanupTime (void); + static const int getBrokenObjectCleanupTime (void); + static const int getVendorObjectCleanupTime(void); + static const char * getCustomSQLFilename (void); + static bool getEnableFixBadCells (void); + static const char * getObjectTemplateListUpdateFilename (void); + + static const char * getCentralServerAddress (void); + static const uint16 getCentralServerPort (void); + static const char * getCommoditiesServerAddress (void); + static const uint16 getCommoditiesServerPort (void); + static const char * getDSN (void); + static const char * getAlternateDSN (void); + static const char * getDatabaseUID (void); + static const char * getDatabasePWD (void); + static const char * getDatabaseProtocol (void); + static const uint16 getTaskManagerPort (void); + static const int getExpectedDBVersion (void); + static const bool isCorrectDBVersionRequired (void); + static const int getSaveFrequencyLimit (void); + static const char * getSchemaOwner (void); + static const char * getGoldSchemaOwner (void); + static const float getUniqueMessageCacheTimeSec(void); + static const int getLoaderThreads (void); + static const int getPersisterThreads (void); + static const int getNewCharacterThreads (void); + static const int getCharacterImmediateDeleteMinutes(void); + static const bool getLogObjectLoading (void); + static const bool getEnableQueryProfile (void); + static const bool getVerboseQueryMode (void); + static const bool getLogWorkerThreads (void); + static const char * getGameServiceBindInterface (void); + static const bool getReportSaveTimes (void); + static const bool getShouldSleep (void); + static const bool getEnableLoadLocks (void); + static const int getDatabaseReconnectTime (void); + static const bool getLogChunkLoading (void); + static const bool getUseMemoryManagerForOCI (void); + static const int getMaxCharactersPerLoadRequest(void); + static const int getMaxChunksPerLoadRequest (void); + static const float getMaxLoadStartDelay (void); + static const int getMaxErrorCountBeforeDisconnect (void); + static const int getMaxErrorCountBeforeBailout (void); + static const int getErrorSleepTime (void); + static const int getDisconnectSleepTime (void); + static const int getSaveAtModulus (void); + static const int getSaveAtDivisor (void); + static const int getBackloggedQueueSize (void); + static const int getBackloggedRecoveryQueueSize(void); + static const int getMaxTimewarp (void); + static const bool getEnableObjvarPacking (void); + static const int getPrefetchNumRows (void); + static const int getPrefetchMemory (void); + static const int getDefaultFetchBatchSize (void); + static const int getQueryReportingRate (void); + static const int getEnableDatabaseErrorLogging (void); + static const int getDefaultMessageBulkBindSize (void); + static const bool getEnableGoldDatabase (void); + static const NetworkId &getMaxGoldNetworkId (void); + static const float getDefaultQueueUpdateTimeLimit(void); + static const bool ConfigServerDatabase::getEnableDataCleanup(void); + static const int getDefaultLazyDeleteBulkBindSize (void); + static const int getDefaultLazyDeleteSleepTime (void); + static const int getWriteDelay (void); + static const bool getDelayUnloadIfObjectStillHasData(void); + static const float getExperienceConsolidationTime (void); + static const int getMaxLoaderFinishedTasks (void); + static const float getReportLongFrameTime (void); + static const bool getEnableVerboseMessageLogging(void); + static const bool getProfilerExpandAll (void); + static const int getProfilerDisplayPercentageMinimum(void); + static const bool getFatalOnDataError (void); + static const int getMaxUnackedLoadCount (void); + static const int getMaxUnackedLoadCountPerServer(void); + static const int getAuctionLocationLoadBatchSize(void); + static const int getAuctionLoadBatchSize(void); + static const int getAuctionAttributeLoadBatchSize(void); + static const int getAuctionBidLoadBatchSize(void); + static const int getOldestUnackedLoadAlertThresholdSeconds(void); +}; + +//----------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getShouldSleep(void) +{ + return data->shouldSleep; +} + + + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getObjvarNameCleanupTime(void) +{ + return data->objvarNameCleanupTime; +} + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getOrphanedObjectCleanupTime(void) +{ + return data->orphanedObjectCleanupTime; +} + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMarketAttributesCleanupTime(void) +{ + return data->marketAttributesCleanupTime; +} + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMessagesCleanupTime(void) +{ + return data->messagesCleanupTime; +} + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getBrokenObjectCleanupTime(void) +{ + return data->brokenObjectCleanupTime; +} + +//----------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getVendorObjectCleanupTime(void) +{ + return data->vendorObjectCleanupTime; +} + + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getCustomSQLFilename(void) +{ + return data->customSQLFilename; +} + + +//----------------------------------------------------------------------- + +inline bool ConfigServerDatabase::getEnableFixBadCells(void) +{ + return data->enableFixBadCells; +} + + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getObjectTemplateListUpdateFilename(void) +{ + return data->objectTemplateListUpdateFilename; +} + + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getCentralServerAddress(void) +{ + return data->centralServerAddress; +} + +//----------------------------------------------------------------------- + +inline const uint16 ConfigServerDatabase::getCentralServerPort(void) +{ + return static_cast(data->centralServerPort); +} + +//----------------------------------------------------------------------- +inline const char * ConfigServerDatabase::getCommoditiesServerAddress(void) +{ + return data->commoditiesServerAddress; +} + +//----------------------------------------------------------------------- + +inline const uint16 ConfigServerDatabase::getCommoditiesServerPort(void) +{ + return static_cast(data->commoditiesServerPort); +} + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getDSN(void) +{ + return data->DSN; +} + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getAlternateDSN(void) +{ + return data->alternateDSN; +} + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getDatabaseUID(void) +{ + return data->databaseUID; +} + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getDatabasePWD(void) +{ + return data->databasePWD; +} + +//----------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getDatabaseProtocol(void) +{ + return data->databaseProtocol; +} + +//----------------------------------------------------------------------- + +inline const uint16 ConfigServerDatabase::getTaskManagerPort(void) +{ + return static_cast(data->taskManagerPort); +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getExpectedDBVersion(void) +{ + return data->expectedDBVersion; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::isCorrectDBVersionRequired(void) +{ + return data->correctDBVersionRequired; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getSaveFrequencyLimit(void) +{ + return data->saveFrequencyLimit; +} + +// ---------------------------------------------------------------------- + +inline const char *ConfigServerDatabase::getSchemaOwner(void) +{ + return data->schemaOwner; +} + +// ---------------------------------------------------------------------- + +inline const char *ConfigServerDatabase::getGoldSchemaOwner(void) +{ + return data->goldSchemaOwner; +} + +// ---------------------------------------------------------------------- + +inline const float ConfigServerDatabase::getUniqueMessageCacheTimeSec(void) +{ + return data->uniqueMessageCacheTimeSec; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getLoaderThreads(void) +{ + return data->loaderThreads; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getPersisterThreads(void) +{ + return data->persisterThreads; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getCharacterImmediateDeleteMinutes(void) +{ + return data->characterImmediateDeleteMinutes; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getLogObjectLoading(void) +{ + return data->logObjectLoading; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getEnableQueryProfile(void) +{ + return data->enableQueryProfile; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getVerboseQueryMode(void) +{ + return data->verboseQueryMode; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getLogWorkerThreads(void) +{ + return data->logWorkerThreads; +} + +// ---------------------------------------------------------------------- + +inline const char * ConfigServerDatabase::getGameServiceBindInterface(void) +{ + return data->gameServiceBindInterface; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getReportSaveTimes(void) +{ + return data->reportSaveTimes; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getEnableLoadLocks(void) +{ + return data->enableLoadLocks; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getNewCharacterThreads(void) +{ + return data->newCharacterThreads; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDatabaseReconnectTime(void) +{ + return data->databaseReconnectTime; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getLogChunkLoading(void) +{ + return data->logChunkLoading; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getUseMemoryManagerForOCI(void) +{ + return data->useMemoryManagerForOCI; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxCharactersPerLoadRequest(void) +{ + return data->maxCharactersPerLoadRequest; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxChunksPerLoadRequest(void) +{ + return data->maxChunksPerLoadRequest; +} + +// ---------------------------------------------------------------------- + +inline const float ConfigServerDatabase::getMaxLoadStartDelay(void) +{ + return data->maxLoadStartDelay; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxErrorCountBeforeDisconnect(void) +{ + return data->maxErrorCountBeforeDisconnect; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxErrorCountBeforeBailout(void) +{ + return data->maxErrorCountBeforeBailout; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getErrorSleepTime(void) +{ + return data->errorSleepTime; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDisconnectSleepTime(void) +{ + return data->disconnectSleepTime; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getSaveAtModulus(void) +{ + return data->saveAtModulus; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getSaveAtDivisor(void) +{ + return data->saveAtDivisor; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getBackloggedQueueSize(void) +{ + return data->backloggedQueueSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getBackloggedRecoveryQueueSize(void) +{ + return data->backloggedRecoveryQueueSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxTimewarp(void) +{ + return data->maxTimewarp; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getEnableObjvarPacking(void) +{ + return data->enableObjvarPacking; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getPrefetchNumRows(void) +{ + return data->prefetchNumRows; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getPrefetchMemory(void) +{ + return data->prefetchMemory; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDefaultFetchBatchSize(void) +{ + return data->defaultFetchBatchSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getQueryReportingRate(void) +{ + return data->queryReportingRate; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getEnableDatabaseErrorLogging(void) +{ + return data->enableDatabaseErrorLogging; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDefaultMessageBulkBindSize(void) +{ + return data->defaultMessageBulkBindSize; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getEnableGoldDatabase(void) +{ + return data->enableGoldDatabase; +} + +// ---------------------------------------------------------------------- + +inline const float ConfigServerDatabase::getDefaultQueueUpdateTimeLimit(void) +{ + return data->defaultQueueUpdateTimeLimit; +} + +// ---------------------------------------------------------------------- + + +inline const bool ConfigServerDatabase::getEnableDataCleanup(void) +{ + return data->enableDataCleanup; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDefaultLazyDeleteBulkBindSize(void) +{ + return data->defaultLazyDeleteBulkBindSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getDefaultLazyDeleteSleepTime(void) +{ + return data->defaultLazyDeleteSleepTime; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getWriteDelay(void) +{ + return data->writeDelay; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getDelayUnloadIfObjectStillHasData(void) +{ + return data->delayUnloadIfObjectStillHasData; +} + +// ---------------------------------------------------------------------- + +inline const float ConfigServerDatabase::getExperienceConsolidationTime(void) +{ + return data->experienceConsolidationTime; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxLoaderFinishedTasks(void) +{ + return data->maxLoaderFinishedTasks; +} + +// ---------------------------------------------------------------------- + +inline const float ConfigServerDatabase::getReportLongFrameTime(void) +{ + return data->reportLongFrameTime; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getEnableVerboseMessageLogging(void) +{ + return data->enableVerboseMessageLogging; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getProfilerExpandAll(void) +{ + return data->profilerExpandAll; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getProfilerDisplayPercentageMinimum(void) +{ + return data->profilerDisplayPercentageMinimum; +} + +// ---------------------------------------------------------------------- + +inline const bool ConfigServerDatabase::getFatalOnDataError(void) +{ + return data->fatalOnDataError; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxUnackedLoadCount(void) +{ + return data->maxUnackedLoadCount; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getMaxUnackedLoadCountPerServer(void) +{ + return data->maxUnackedLoadCountPerServer; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getAuctionLocationLoadBatchSize(void) +{ + return data->auctionLocationLoadBatchSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getAuctionLoadBatchSize(void) +{ + return data->auctionLoadBatchSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getAuctionAttributeLoadBatchSize(void) +{ + return data->auctionAttributeLoadBatchSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getAuctionBidLoadBatchSize(void) +{ + return data->auctionBidLoadBatchSize; +} + +// ---------------------------------------------------------------------- + +inline const int ConfigServerDatabase::getOldestUnackedLoadAlertThresholdSeconds(void) +{ + return data->oldestUnackedLoadAlertThresholdSeconds; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ConsoleCommandParser.cpp b/engine/server/library/serverDatabase/src/shared/ConsoleCommandParser.cpp new file mode 100644 index 00000000..0e7ea03f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ConsoleCommandParser.cpp @@ -0,0 +1,67 @@ +// ConsoleCommandParser.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedLog/Log.h" +#include "ConsoleCommandParser.h" +#include "UnicodeUtils.h" +#include +#include "Unicode.h" + +#pragma warning(disable: 4355) // Passing "this" to a base-class constructor + +//----------------------------------------------------------------------- + +namespace CommandNames +{ +#define MAKE_COMMAND(a) const char * const a = #a +#undef MAKE_COMMAND +} + +const CommandParser::CmdInfo cmds[] = +{ + {"database", 0, "", ""}, + {"", 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], "database")) + { + if(argv.size() > 1) + { + if(isCommand(argv[1], "runState")) + { + successResult = true; + result += Unicode::narrowToWide("running"); + } + } + } + + return successResult; +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverDatabase/src/shared/ConsoleCommandParser.h b/engine/server/library/serverDatabase/src/shared/ConsoleCommandParser.h new file mode 100644 index 00000000..4ebf6387 --- /dev/null +++ b/engine/server/library/serverDatabase/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/library/serverDatabase/src/shared/ConsoleManager.cpp b/engine/server/library/serverDatabase/src/shared/ConsoleManager.cpp new file mode 100644 index 00000000..4e24a67e --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ConsoleManager.cpp @@ -0,0 +1,58 @@ +// ConsoleManager.cpp +// Copyright 2000-02, Sony Online Entertainment Inc., all rights reserved. +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.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/library/serverDatabase/src/shared/ConsoleManager.h b/engine/server/library/serverDatabase/src/shared/ConsoleManager.h new file mode 100644 index 00000000..2f166dc3 --- /dev/null +++ b/engine/server/library/serverDatabase/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/library/serverDatabase/src/shared/ContainedObjectLocator.cpp b/engine/server/library/serverDatabase/src/shared/ContainedObjectLocator.cpp new file mode 100644 index 00000000..a7c2e868 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ContainedObjectLocator.cpp @@ -0,0 +1,95 @@ +// ====================================================================== +// +// ContainedObjectLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ContainedObjectLocator.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverNetworkMessages/LoadContainedObjectMessage.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +ContainedObjectLocator::ContainedObjectLocator(const NetworkId &containerId, const NetworkId &objectId) : + ObjectLocator(), + m_containerId(containerId), + m_objectId(objectId) +{ +} + +// ---------------------------------------------------------------------- + +ContainedObjectLocator::~ContainedObjectLocator() +{ +} + +// ---------------------------------------------------------------------- + +bool ContainedObjectLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + + LocateObjectQuery qry(m_containerId, m_objectId, schema); + bool rval = session->exec(&qry); + qry.done(); + + objectsLocated = 1; //TODO: counts + return rval; +} + +// ====================================================================== + +ContainedObjectLocator::LocateObjectQuery::LocateObjectQuery(const NetworkId &containerId, const NetworkId &objectId, const std::string &schema) : + container_id(containerId), + object_id(objectId), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void ContainedObjectLocator::LocateObjectQuery::getSQL(std::string &sql) +{ + LOG("AuctionRetrieval", ("Loader:: calling LocateObjectQuery::getSQL() for loading object %s for retrieval", object_id.getValue().getValueString().c_str())); + sql = std::string("begin ") + m_schema + "loader.locate_contained_object (:container_id, :object_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool ContainedObjectLocator::LocateObjectQuery::bindParameters() +{ + if (!bindParameter(container_id)) return false; + if (!bindParameter(object_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool ContainedObjectLocator::LocateObjectQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode ContainedObjectLocator::LocateObjectQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ---------------------------------------------------------------------- + +void ContainedObjectLocator::sendPostBaselinesCustomData (GameServerConnection &conn) const +{ + LOG("AuctionRetrieval", ("Loader:: sending post baselines data for loading object %s for retrieval", m_objectId.getValueString().c_str())); + LoadContainedObjectMessage msg(m_containerId, m_objectId); + conn.send(msg,true); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ContainedObjectLocator.h b/engine/server/library/serverDatabase/src/shared/ContainedObjectLocator.h new file mode 100644 index 00000000..b12ba3ae --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ContainedObjectLocator.h @@ -0,0 +1,64 @@ +// ====================================================================== +// +// ContainedObjectLocator.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ContainedObjectLocator_H +#define INCLUDED_ContainedObjectLocator_H + +#include "serverDatabase/ObjectLocator.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Locate a specified character and add it to the list of objects to be + * loaded by the Snapshot. + */ +class ContainedObjectLocator : public ObjectLocator +{ + public: + ContainedObjectLocator (const NetworkId &containerId, const NetworkId &objectId); + virtual ~ContainedObjectLocator (); + + public: + virtual bool locateObjects (DB::Session *session, const std::string &schema, int &objectsLocated); + virtual void sendPostBaselinesCustomData (GameServerConnection &conn) const; + + private: + NetworkId m_containerId; + NetworkId m_objectId; + + private: + class LocateObjectQuery : public DB::Query + { + public: + LocateObjectQuery (const NetworkId &containerId, const NetworkId &objectId, const std::string &schema); + + virtual void getSQL (std::string &sql); + virtual bool bindParameters (); + virtual bool bindColumns (); + + private: + virtual DB::Query::QueryMode getExecutionMode() const; + + private: + LocateObjectQuery (const LocateObjectQuery&); // disable + LocateObjectQuery& operator= (const LocateObjectQuery&); //disable + + public: + DB::BindableNetworkId container_id; + DB::BindableNetworkId object_id; + + private: + std::string m_schema; + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ContentsLocator.cpp b/engine/server/library/serverDatabase/src/shared/ContentsLocator.cpp new file mode 100644 index 00000000..6c4ddefd --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ContentsLocator.cpp @@ -0,0 +1,89 @@ +// ====================================================================== +// +// ContentsLocator.cpp +// copyright (c) 2002 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ContentsLocator.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverNetworkMessages/LoadContentsMessage.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +ContentsLocator::ContentsLocator(const NetworkId &containerId) : + ObjectLocator(), + m_containerId(containerId) +{ +} + +// ---------------------------------------------------------------------- + +ContentsLocator::~ContentsLocator() +{ +} + +// ---------------------------------------------------------------------- + +bool ContentsLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + + LocateObjectQuery qry(m_containerId, schema); + bool rval = session->exec(&qry); + qry.done(); + + objectsLocated = 1; //TODO: counts + return rval; +} + +// ====================================================================== + +ContentsLocator::LocateObjectQuery::LocateObjectQuery(const NetworkId &containerId, const std::string &schema) : + container_id(containerId), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void ContentsLocator::LocateObjectQuery::getSQL(std::string &sql) +{ + sql = std::string("begin ") + m_schema + "loader.locate_contents (:container_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool ContentsLocator::LocateObjectQuery::bindParameters() +{ + if (!bindParameter(container_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool ContentsLocator::LocateObjectQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode ContentsLocator::LocateObjectQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ---------------------------------------------------------------------- + +void ContentsLocator::sendPostBaselinesCustomData (GameServerConnection &conn) const +{ + LoadContentsMessage msg(m_containerId); + conn.send(msg,true); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ContentsLocator.h b/engine/server/library/serverDatabase/src/shared/ContentsLocator.h new file mode 100644 index 00000000..e6a3dea5 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ContentsLocator.h @@ -0,0 +1,62 @@ +// ====================================================================== +// +// ContentsLocator.h +// copyright (c) 2002 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ContentsLocator_H +#define INCLUDED_ContentsLocator_H + +#include "serverDatabase/ObjectLocator.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Locate a specified character and add it to the list of objects to be + * loaded by the Snapshot. + */ +class ContentsLocator : public ObjectLocator +{ + public: + ContentsLocator (const NetworkId &containerId); + virtual ~ContentsLocator (); + + public: + virtual bool locateObjects (DB::Session *session, const std::string &schema, int &objectsLocated); + virtual void sendPostBaselinesCustomData (GameServerConnection &conn) const; + + private: + NetworkId m_containerId; + + private: + class LocateObjectQuery : public DB::Query + { + public: + LocateObjectQuery (const NetworkId &containerId, const std::string &schema); + + virtual void getSQL (std::string &sql); + virtual bool bindParameters (); + virtual bool bindColumns (); + + private: + virtual DB::Query::QueryMode getExecutionMode() const; + + private: + LocateObjectQuery (const LocateObjectQuery&); // disable + LocateObjectQuery& operator= (const LocateObjectQuery&); // disable + + public: + DB::BindableNetworkId container_id; + + private: + std::string m_schema; + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.cpp new file mode 100644 index 00000000..fb6072b9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.cpp @@ -0,0 +1,66 @@ +// ====================================================================== +// +// CreateCharacterCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/CreateCharacterCustomPersistStep.h" + +#include "serverDatabase/CharacterQueries.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/Persister.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +CreateCharacterCustomPersistStep::CreateCharacterCustomPersistStep(uint32 stationId, const NetworkId &characterObject, const Unicode::String &characterName, const std::string &normalizedName, int templateId, bool special) : + m_stationId(stationId), + m_characterObject(characterObject), + m_characterName(characterName), + m_normalizedName(normalizedName), + m_templateId(templateId), + m_clusterName(DatabaseProcess::getInstance().getClusterName()), + m_special(special) +{ +} + +// ---------------------------------------------------------------------- + +CreateCharacterCustomPersistStep::~CreateCharacterCustomPersistStep() +{ +} + +// ---------------------------------------------------------------------- + +bool CreateCharacterCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool CreateCharacterCustomPersistStep::afterPersist(DB::Session *session) +{ +// std::string characterName = Unicode::wideToNarrow(DatabaseProcess::getInstance().getNameByStationId(m_stationId)); + DBQuery::AddCharacter qry(m_stationId,m_characterObject, m_characterName, m_normalizedName); + if (! (session->exec(&qry))) + return false; + qry.done(); + return true; +} + +// ---------------------------------------------------------------------- + +void CreateCharacterCustomPersistStep::onComplete() +{ + Persister::getInstance().onNewCharacterSaved(m_stationId,m_characterObject,m_characterName,m_templateId,m_special); + DataLookup::getInstance().releaseName(m_stationId, NetworkId::cms_invalid); + LOG("TraceCharacterCreation", ("%d CreateCharacterCustomPersistStep(%s) complete", m_stationId, Unicode::wideToNarrow(m_characterName).c_str())); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.h new file mode 100644 index 00000000..232decfd --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CreateCharacterCustomPersistStep.h @@ -0,0 +1,48 @@ +// ====================================================================== +// +// CreateCharacterCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CreateCharacterCustomPersistStep_H +#define INCLUDED_CreateCharacterCustomPersistStep_H + +// ====================================================================== + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedFoundation/NetworkId.h" +#include "Unicode.h" +#include + +class NetworkId; + +// ====================================================================== + +class CreateCharacterCustomPersistStep : public CustomPersistStep +{ + public: + CreateCharacterCustomPersistStep(uint32 stationId, const NetworkId &characterObject, const Unicode::String &characterName, const std::string &normalizedName, const int templateId, bool special); + ~CreateCharacterCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + uint32 m_stationId; + NetworkId m_characterObject; + Unicode::String m_characterName; + std::string m_normalizedName; + int m_templateId; + std::string m_clusterName; + bool m_special; + + private: + CreateCharacterCustomPersistStep &operator= (const CreateCharacterCustomPersistStep&); //disable + CreateCharacterCustomPersistStep(const CreateCharacterCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/CustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/CustomPersistStep.cpp new file mode 100644 index 00000000..b74e3080 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CustomPersistStep.cpp @@ -0,0 +1,17 @@ +// ====================================================================== +// +// CustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/CustomPersistStep.h" + +// ====================================================================== + +CustomPersistStep::~CustomPersistStep() +{ +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/CustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/CustomPersistStep.h new file mode 100644 index 00000000..16724ed5 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/CustomPersistStep.h @@ -0,0 +1,44 @@ +// ====================================================================== +// +// CustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_CustomPersistStep_H +#define INCLUDED_CustomPersistStep_H + +// ====================================================================== + +namespace DB +{ + class Session; +} + +// ====================================================================== + +/** + * CustomPersistStep is an abstract class representing an extra thing + * to do while saving a snapshot. (For example, associating one of the + * saved objects with a player's account.) + * + * CustomPersistSteps can do things before the objects are saved or after + * they are saved, but they always take place within the same database + * transaction. + * + * CustomPersistSteps can also do special things in the main thread + * after completion, e.g. acknowledging to another server. + */ +class CustomPersistStep +{ + public: + virtual bool beforePersist (DB::Session *session) =0; + virtual bool afterPersist (DB::Session *session) =0; + virtual void onComplete () =0; + + virtual ~CustomPersistStep(); +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/DataLookup.cpp b/engine/server/library/serverDatabase/src/shared/DataLookup.cpp new file mode 100644 index 00000000..dd42952a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DataLookup.cpp @@ -0,0 +1,582 @@ +// ====================================================================== +// +// DataLookup.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/DataLookup.h" + +#include "UnicodeUtils.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/TaskCheckCharacterName.h" +#include "serverDatabase/TaskGetStructuresForPurge.h" +#include "serverDatabase/TaskGetBiography.h" +#include "serverDatabase/TaskSetBiography.h" +#include "serverNetworkMessages/BiographyMessage.h" +#include "serverNetworkMessages/CentralGameServerMessages.h" +#include "serverNetworkMessages/RequestBiographyMessage.h" +#include "serverNetworkMessages/RetrievedItemLoadMessage.h" +#include "sharedDatabaseInterface/DbTaskQueue.h" +#include "sharedFoundation/Crc.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/NameErrors.h" +#include "unicodeArchive/UnicodeArchive.h" + +//----------------------------------------------------------------------- + +DataLookup *DataLookup::ms_theInstance = NULL; + +//----------------------------------------------------------------------- + +void DataLookup::install() +{ + DEBUG_FATAL(ms_theInstance,("Called DataLookup::install twice.\n")); + ms_theInstance = new DataLookup; + + ExitChain::add(&remove, "DataLookup::remove"); +} + +// ---------------------------------------------------------------------- + +void DataLookup::remove() +{ + DEBUG_FATAL(!ms_theInstance,("DataLookup was not installed.\n")); + delete ms_theInstance; + ms_theInstance = 0; +} + +// ---------------------------------------------------------------------- + +DataLookup::DataLookup() : + MessageDispatch::Receiver(), + taskQueue(new DB::TaskQueue(1,DatabaseProcess::getInstance().getDBServer(),2)), + m_reservations() +{ + connectToMessage("BiographyMessage"); + connectToMessage("PurgeStructuresForAccountMessage"); + connectToMessage("ReleaseNameMessage"); + connectToMessage("RequestBiographyMessage"); + connectToMessage("VerifyNameRequest"); + connectToMessage("WarnStructuresAboutPurgeMessage"); +} + +//----------------------------------------------------------------------- + +DataLookup::~DataLookup() +{ + DEBUG_FATAL(taskQueue,("Call shutdown() before deleting DataLookup.\n")); + + while (!m_reservations.empty()) + { + deleteReservationList(m_reservations.begin()->first); + } +} + +// ---------------------------------------------------------------------- + +void DataLookup::update(real uptime) +{ + UNREF(uptime); + + taskQueue->update(ConfigServerDatabase::getDefaultQueueUpdateTimeLimit()); +} + +// ---------------------------------------------------------------------- + +void DataLookup::receiveMessage(const MessageDispatch::Emitter &source, const MessageDispatch::MessageBase &message) +{ + UNREF(source); + + if (message.isType("VerifyNameRequest")) + { + const GameServerConnection * g = safe_cast(&source); + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + VerifyNameRequest * vnr = new VerifyNameRequest(ri); + + LOG("TraceCharacterCreation", ("%d received VerifyNameRequest", vnr->getStationId())); + verifyName(g->getProcessId(), vnr); + } + else if (message.isType("ReleaseNameMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ReleaseNameMessage rnm(ri); + + LOG("TraceCharacterCreation", ("%d received ReleaseNameMessage", rnm.getStationId())); + + releaseName(rnm.getStationId(), rnm.getCharacterId()); + } + else if (message.isType("RequestBiographyMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RequestBiographyMessage msg(ri); + + const GameServerConnection *conn = dynamic_cast(&source); + if (conn) + getBiography(msg.getOwner(),conn->getProcessId()); + else + DEBUG_WARNING(true,("Got RequestBiographyMessage from something that wasn't a GameServerConnection.\n")); + } + else if (message.isType("BiographyMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + BiographyMessage msg(ri); + + setBiography(msg.getOwner(),msg.getBio()); + } + else if (message.isType("PurgeStructuresForAccountMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + getStructuresForPurge(msg.getValue(), false); + } + else if (message.isType("WarnStructuresAboutPurgeMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + getStructuresForPurge(msg.getValue(), true); + } + else + { + DEBUG_REPORT_LOG(true,("Unrecognized message recieved by DataLookup.\n")); + } +} + +// ---------------------------------------------------------------------- + +void DataLookup::onRetrieveItemComplete(NetworkId const &ownerId, NetworkId const &itemId) const +{ + RetrievedItemLoadMessage msg(ownerId, itemId); + std::vector gameServerIds; + DatabaseProcess::getInstance().getGameServerProcessIds(gameServerIds); + for (std::vector::iterator i = gameServerIds.begin(); i != gameServerIds.end(); ++i) + DatabaseProcess::getInstance().getConnectionByProcess(*i)->send(msg, true); +} + +// ---------------------------------------------------------------------- + +void DataLookup::verifyName(uint32 gameServer, VerifyNameRequest * request) +{ + DEBUG_REPORT_LOG(true, ("verifyName: stationId %lu, process %lu, name %s: ", request->getStationId(), gameServer, Unicode::wideToNarrow(request->getCharacterName()).c_str())); + Unicode::String name = normalizeName(request->getCharacterName()); + + reservationList * rl = getReservationList(request->getStationId()); + + // if request is to verify name for character rename, free up all + // reservations that have been made for character create; there's + // no possibility that a character create is happening if there's + // a rename happening + if (rl && request->getCharacterId().isValid()) + { + releaseName(request->getStationId(), NetworkId::cms_invalid); + rl = getReservationList(request->getStationId()); + } + + if (rl) // already have m_reservations for this character + { + // see if we have any equivalent m_reservations + reservationList::iterator i; + for (i=rl->begin(); i!=rl->end(); ++i) + { + // equivalent reservation; if it has been approved, + // response immediately; otherwise make a new reservation, + // but don't request a verification. When the original + // is approved, all matching m_reservations will be approved + if ((i->name == name) && (request->getCharacterId() == i->request->getCharacterId())) + { + if (i->approved) + { + DEBUG_REPORT_LOG(true, ("Reserved and already approved.\n")); + GameServerConnection * g = DatabaseProcess::getInstance().getConnectionByProcess(gameServer); + VerifyNameResponse vnr(request->getStationId(), request->getCharacterId(), request->getCreatureTemplate(), request->getCharacterName(), NameErrors::nameApproved); + LOG("TraceCharacterCreation", ("%d Name reservation already approved, sending VeryfyNameResponse(%d, %s, %s) to game server", request->getStationId(), request->getStationId(), request->getCreatureTemplate().c_str(), Unicode::wideToNarrow(request->getCharacterName()).c_str())); + if (g) + g->send(vnr, true); + // now move the reservation to the front of the queue + reservation temp(*i); + IGNORE_RETURN(rl->erase(i)); + addReservation(rl, temp); + delete request; + return; + } + else + { + LOG("TraceCharacterCreation", ("%d Name reservation not yet approved", request->getStationId())); + DEBUG_REPORT_LOG(true, ("Not yet approved.\n")); + reservation temp; + temp.gameServer = gameServer; + temp.name = name; + temp.approved = false; + temp.request = request; + addReservation(rl, temp); + return; + } + } + } + } + + DEBUG_REPORT_LOG(true, ("No matching reservation.\n")); + + // If we get here, there are no matching m_reservations for our client. But there + // may be m_reservations from other clients conflicting with ours. + + std::map::iterator j; + for (j=m_reservations.begin(); j != m_reservations.end(); ++j) + { + reservationList * otherReservationList = j->second; + reservationList::iterator i; + for (i = otherReservationList->begin(); i!=otherReservationList->end(); ++i) + { + if (i->name == name) + { + LOG("TraceCharacterCreation", ("Name (%s) requested by station ID %lu is already reserved by another station ID %lu and/or another character on the same station ID", Unicode::wideToNarrow(request->getCharacterName()).c_str(), request->getStationId(), j->first)); + DEBUG_REPORT_LOG(true, ("Name (%s) requested by station ID %lu is already reserved by another station ID %lu and/or another character on the same station ID\n", Unicode::wideToNarrow(request->getCharacterName()).c_str(), request->getStationId(), j->first)); + GameServerConnection * g = DatabaseProcess::getInstance().getConnectionByProcess(gameServer); + VerifyNameResponse vnr(request->getStationId(), request->getCharacterId(), request->getCreatureTemplate(), request->getCharacterName(), NameErrors::nameDeclinedInUse); + g->send(vnr, true); + delete request; + return; + } + } + } + + // nothing else has this name reserved + + reservation temp; + temp.gameServer = gameServer; + temp.name = name; + temp.request = request; + temp.approved = false; + + if (!rl) + rl = newReservationList(request->getStationId()); + + addReservation(rl, temp); + + LOG("TraceCharacterCreation", ("%d Reserving name and verifying it against the DB", request->getStationId())); + DEBUG_REPORT_LOG(true, ("Reserving and verifying\n")); + + TaskCheckCharacterName *task = new TaskCheckCharacterName(request->getStationId(), name); + taskQueue->asyncRequest(task); +} + +//-------------------------------------------------------------------- + +void DataLookup::onCharacterNameChecked(uint32 stationId, const Unicode::String &name, int resultCode) +{ + StringId reason(NameErrors::nameApproved); + switch (resultCode) + { + case 0: break; + case 1: reason = NameErrors::nameDeclinedInUse; break; + default: reason = NameErrors::nameDeclinedInternalError; break; + } + + reservationList * rl = getReservationList(stationId); + if (!rl) + { + DEBUG_REPORT_LOG(true, ("Received onCharacterNameChecked (%s) for non-pending name stationid %lu\n", reason.getText().c_str(), stationId)); + return; + } + + reservationList::iterator i; + for (i=rl->begin(); i!=rl->end(); ++i) + { + if (i->name == name) + { + LOG("TraceCharacterCreation", ("sending VerifyNameResponse(%d, %s, %s, ?) to game server", stationId, i->request->getCreatureTemplate().c_str(), Unicode::wideToNarrow(i->request->getCharacterName()).c_str())); + VerifyNameResponse vnr(stationId, i->request->getCharacterId(), i->request->getCreatureTemplate(), i->request->getCharacterName(), reason); + GameServerConnection * g = DatabaseProcess::getInstance().getConnectionByProcess(i->gameServer); + if (g) + g->send(vnr, true); + else + DEBUG_REPORT_LOG(true,("VerifyNameResponse for %lu dropped because GameServer has dropped connection.\n",stationId)); + } + } + + if (reason != NameErrors::nameApproved) + { + LOG("TraceCharacterCreation", ("%d name released", stationId)); + DEBUG_REPORT_LOG(true, ("Name %s verified for stationId %lu: %s.\n", Unicode::wideToNarrow(name).c_str(), stationId, reason.getText().c_str())); + releaseName(stationId, name); + } + else + { + LOG("TraceCharacterCreation", ("%d name %s verified", stationId, Unicode::wideToNarrow(name).c_str())); + DEBUG_REPORT_LOG(true, ("Name %s verified for stationId %lu: %s, holding reservation.\n", Unicode::wideToNarrow(name).c_str(), stationId, reason.getText().c_str())); + approveName(stationId, name); + } +} + +//-------------------------------------------------------------------- + +void DataLookup::releaseName(uint32 stationId, const NetworkId & characterId) +{ + reservationList * rl = getReservationList(stationId); + if (!rl) + { + WARNING(true, ("Releasing names for stationId %lu, characterId %s, but no reservations found.\n", stationId, characterId.getValueString().c_str())); + return; + } + + reservationList newReservations; + reservationList::iterator i; + int erased = 0; + for (i=rl->begin(); i!=rl->end(); ++i) + { + if (i->request->getCharacterId() != characterId) + { + newReservations.push_back(*i); + } + else + { + delete const_cast(i->request); // non-const for Lint + ++erased; + } + } + + DEBUG_REPORT_LOG(true, ("Releasing %d names for stationId %lu, characterId %s\n", erased, stationId, characterId.getValueString().c_str())); + + rl->swap(newReservations); + if (rl->empty()) + { + deleteReservationList(stationId); + } +} + +//-------------------------------------------------------------------- + +void DataLookup::releaseName(uint32 stationId, const Unicode::String &i_name) +{ + reservationList * rl = getReservationList(stationId); + if (!rl) + { + WARNING(true, ("Releasing name [%s] for stationId %lu, but no reservations found.\n", Unicode::wideToNarrow(i_name).c_str(), stationId)); + return; + } + + reservationList newReservations; + reservationList::iterator i; + int erased = 0; + for (i=rl->begin(); i!=rl->end(); ++i) + { + if (i->name != i_name) + { + newReservations.push_back(*i); + } + else + { + delete const_cast(i->request); // non-const for Lint + ++erased; + } + } + + DEBUG_REPORT_LOG(true, ("Releasing %d names for stationId %lu, name (%s)\n", erased, stationId, Unicode::wideToNarrow(i_name).c_str())); + + rl->swap(newReservations); + if (rl->empty()) + { + deleteReservationList(stationId); + } +} + +//-------------------------------------------------------------------- + +void DataLookup::approveName(uint32 stationId, const Unicode::String &i_name) +{ + reservationList * rl = getReservationList(stationId); + if (!rl) + { + WARNING_STRICT_FATAL(true, ("Approving name for stationId %lu, but name not found.\n", stationId)); + return; + } + + reservationList::iterator i; + for (i=rl->begin(); i!=rl->end(); ++i) + { + if (i->name == i_name) + { + i->approved = true; + } + } +} + +//-------------------------------------------------------------------- + +void DataLookup::releaseNamesForProcess(uint32 gameServer) +{ + DEBUG_REPORT_LOG(true, ("Release name m_reservations for process %lu\n", gameServer)); + std::map newReservations; + std::map::iterator i; + for (i = m_reservations.begin(); i!=m_reservations.end(); ++i) + { + reservationList * rl = i->second; + reservationList newReservationListLocal; + reservationList::iterator j; + for (j=rl->begin(); j!=rl->end(); ++j) + { + if (j->gameServer != gameServer) + { + newReservationListLocal.push_back(*j); + } + else + { + delete const_cast(j->request); // const-cast to make Lint happy + } + } + rl->swap(newReservationListLocal); + if (rl->empty()) + { + delete rl; + } + else + { + newReservations[i->first] = rl; + } + } + m_reservations.swap(newReservations); +} + +//-------------------------------------------------------------------- + +const Unicode::String DataLookup::normalizeName(const Unicode::String &name) const +{ + Unicode::String result = Unicode::toLower(name); + result = Unicode::String(result, 0, result.find(' ')); + + return result; +} + +//-------------------------------------------------------------------- +/* +const std::string DataLookup::getNameByStationId(uint32 stationId) const +{ + std::map::const_iterator i=m_reservations.find(stationId); + if (i == m_reservations.end()) + { + WARNING_STRICT_FATAL(true, ("asked for name that wasn't in the reservation list")); + return std::string(); + } + return Unicode::wideToNarrow(i->second.originalName); +} + +//-------------------------------------------------------------------- + +const std::string DataLookup::getNormalizedNameByStationId(uint32 stationId) const +{ + std::map::const_iterator i=m_reservations.find(stationId); + if (i == m_reservations.end()) + { + WARNING_STRICT_FATAL(true, ("asked for name that wasn't in the reservation list")); + return std::string(); + } + return Unicode::wideToNarrow(i->second.name); +} + +//-------------------------------------------------------------------- +*/ +DataLookup::reservationList * DataLookup::getReservationList(uint32 stationId) +{ + std::map::iterator i = m_reservations.find(stationId); + if (i == m_reservations.end()) + return 0; + else + return i->second; +} + +//-------------------------------------------------------------------- + +DataLookup::reservationList * DataLookup::newReservationList(uint32 stationId) +{ + reservationList * result = new reservationList; + DEBUG_FATAL(m_reservations.find(stationId) != m_reservations.end(), ("DataLookup::newReservationList called, but there is already a reservationList for this stationId %lu.", stationId)); + m_reservations[stationId] = result; + return result; +} + +//-------------------------------------------------------------------- + +void DataLookup::addReservation(DataLookup::reservationList * rl, const DataLookup::reservation &temp) +{ + rl->push_back(temp); + while (rl->size() > 16) + { + delete const_cast(rl->begin()->request); + rl->pop_front(); + } +} + +//-------------------------------------------------------------------- + +void DataLookup::deleteReservationList(uint32 stationId) +{ + std::map::iterator rlIter = m_reservations.find(stationId); + if (rlIter == m_reservations.end()) + return; + + reservationList * rl = rlIter->second; + if (!rl) + { + WARNING_STRICT_FATAL(true, ("Reservation list for stationID %lu is NULL", stationId)); + return; + } + reservationList::iterator i; + for (i=rl->begin(); i!=rl->end(); ++i) + { + delete const_cast(i->request); + } + delete rl; + IGNORE_RETURN(m_reservations.erase(stationId)); +} + +// ---------------------------------------------------------------------- + +void DataLookup::getBiography(const NetworkId &owner, uint32 requestingProcess) +{ + NOT_NULL(taskQueue); + TaskGetBiography *task = new TaskGetBiography(owner,requestingProcess); + taskQueue->asyncRequest(task); +} + +// ---------------------------------------------------------------------- + +void DataLookup::setBiography(const NetworkId &owner, const Unicode::String &bio) +{ + NOT_NULL(taskQueue); + TaskSetBiography *task = new TaskSetBiography(owner,bio); + taskQueue->asyncRequest(task); +} + +// ---------------------------------------------------------------------- + +void DataLookup::shutdown() +{ + NOT_NULL(taskQueue); + taskQueue->cancel(); + delete taskQueue; + taskQueue=0; +} + +// ---------------------------------------------------------------------- + +bool DataLookup::isIdle() +{ + return taskQueue->isIdle(); +} + +// ---------------------------------------------------------------------- + +void DataLookup::getStructuresForPurge(StationId account, bool warnOnly) +{ + TaskGetStructuresForPurge *task = new TaskGetStructuresForPurge(account, warnOnly); + taskQueue->asyncRequest(task); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/DataLookup.h b/engine/server/library/serverDatabase/src/shared/DataLookup.h new file mode 100644 index 00000000..d5b65f44 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DataLookup.h @@ -0,0 +1,115 @@ +// ====================================================================== +// +// DataLookup.h +// copyright (c) 2002 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_DataLookup_H +#define INCLUDED_DataLookup_H + +// ====================================================================== + +#include +#include + +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedFoundation/StationId.h" +#include "sharedMessageDispatch/Receiver.h" +#include "StringId.h" +#include "Unicode.h" + +namespace DB +{ + class TaskQueue; +} + +class VerifyNameRequest; +class GameNetworkMessage; + +// ====================================================================== + +/** + * Singleton that looks up specific data from the database. + * + * This class manages requests to fetch assorted data from the database. + * This class is set up so that requests for various random items of data + * don't have to compete with persistence or loading for worker thread time. + * + * Because this class is not synchronized in any way with Persister or + * Loader, it should not be used to fetch data about specific in-game + * objects. + * + * For example, one use of this class is to manage fetching the list of + * prohibited character names. + */ +class DataLookup : public MessageDispatch::Receiver +{ +public: + static void install(); + static DataLookup &getInstance(); + + void update (real updateTime); + void receiveMessage (const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); + + void onRetrieveItemComplete(NetworkId const &ownerId, NetworkId const &itemId) const; + +// name reservation and verification: + void onCharacterNameChecked (uint32 stationId, const Unicode::String &name, int resultCode); + void verifyName(uint32 gameServer, VerifyNameRequest * vrn); + void releaseName(uint32 stationId, const NetworkId & characterId); + void releaseName(uint32 stationId, const Unicode::String &name); + void approveName(uint32 stationId, const Unicode::String &name); + void releaseNamesForProcess(uint32 gameServer); + const Unicode::String normalizeName(const Unicode::String &name) const; + const std::string getNameByStationId(StationId stationId) const; + const std::string getNormalizedNameByStationId(StationId stationId) const; + bool isIdle(); + + void shutdown(); + +protected: + DB::TaskQueue *taskQueue; + + struct reservation + { + public: + const VerifyNameRequest * request; + Unicode::String name; + uint32 gameServer; + bool approved; + }; + typedef std::deque reservationList; + reservationList * getReservationList(uint32 stationId); + reservationList * newReservationList(uint32 stationId); + std::map m_reservations; + static void addReservation(reservationList * rl, const reservation &temp); + void deleteReservationList(uint32 stationId); + +private: + void getBiography (const NetworkId &owner, uint32 requestingProcess); + void setBiography (const NetworkId &owner, const Unicode::String &bio); + void getStructuresForPurge (StationId account, bool warnOnly); + + private: + DataLookup(); + ~DataLookup(); + static void remove(); + static DataLookup *ms_theInstance; + + private: + DataLookup &operator=(const DataLookup&); //disable + DataLookup(const DataLookup&); //disable +}; + +// ---------------------------------------------------------------------- + +inline DataLookup &DataLookup::getInstance() +{ + DEBUG_FATAL(!ms_theInstance,("DataLookup was not installed.\n")); + return *ms_theInstance; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.cpp new file mode 100644 index 00000000..5b6764f3 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.cpp @@ -0,0 +1,164 @@ +//DatabaseMetricsData.cpp +//Copyright 2002 Sony Online Entertainment + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/DatabaseMetricsData.h" + +#ifndef WIN32 +#include "MonAPI2/MonitorData.h" +#endif +#include "serverDatabase/CMLoader.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/LazyDeleter.h" +#include "serverDatabase/Loader.h" +#include "serverDatabase/Persister.h" +#include "sharedFoundation/Clock.h" +#include "sharedDatabaseInterface/DbRow.h" +#include "sharedDatabaseInterface/DbTaskQueue.h" +#include "Snapshot.h" + +//----------------------------------------------------------------------- + +DatabaseMetricsData::DatabaseMetricsData() : +MetricsData(), +m_loadQueueTasks(0), +m_preloadsInProgress(0), +m_oldestUnackedLoad(0), +m_oldestUnackedLoadAlert(0), +m_timeSinceLastSaveStarted(0), +m_lastSaveTime(0), +m_lastSaveTotalObjectCount(0), +m_lastSaveNewObjectCount(0), +m_lazyDeleteQueueSize(0), +m_lazyDeleteTotalCount(0), +m_lazyDeletesPerMinute(0), +m_queryRate(0), +m_fetchRate(0), +m_snapshotCreationCount(0), +m_snapshotDeletionCount(0), +m_snapshotPendingCount(0), +m_snapshotRowCreationCount(0), +m_snapshotRowDeletionCount(0), +m_snapshotRowPendingCount(0), +m_taskQueueTotalNumRequests(0), +m_taskQueueTotalNumResults(0), +m_cmLoadTime(0) +{ + MetricsPair p; + + ADD_METRICS_DATA(loadQueueTasks, 0, false); + ADD_METRICS_DATA(preloadsInProgress, 0, false); + ADD_METRICS_DATA(oldestUnackedLoad, 0, false); + ADD_METRICS_DATA(oldestUnackedLoadAlert, 0, false); + ADD_METRICS_DATA(timeSinceLastSaveStarted, 0, false); + ADD_METRICS_DATA(lastSaveTime, 0, true); + ADD_METRICS_DATA(lastSaveTotalObjectCount, 0, true); + ADD_METRICS_DATA(lastSaveNewObjectCount, 0, true); + ADD_METRICS_DATA(lazyDeleteQueueSize, 0, true); + ADD_METRICS_DATA(lazyDeleteTotalCount, 0, true); + ADD_METRICS_DATA(lazyDeletesPerMinute, 0, true); + ADD_METRICS_DATA(queryRate, 0, true); + ADD_METRICS_DATA(fetchRate, 0, true); + + // snapshot data + ADD_METRICS_DATA(snapshotCreationCount, 0, true); + ADD_METRICS_DATA(snapshotDeletionCount, 0, true); + ADD_METRICS_DATA(snapshotPendingCount, 0, true); + + ADD_METRICS_DATA(snapshotRowCreationCount, 0, true); + ADD_METRICS_DATA(snapshotRowDeletionCount, 0, true); + ADD_METRICS_DATA(snapshotRowPendingCount, 0, true); + + // Task Q + ADD_METRICS_DATA(taskQueueTotalNumRequests, 0, true); + ADD_METRICS_DATA(taskQueueTotalNumResults, 0, true); + + // commodities data + ADD_METRICS_DATA(cmLoadTime, 0, true); + m_data[m_cmLoadTime].m_description = "minutes"; +} + +//----------------------------------------------------------------------- + +DatabaseMetricsData::~DatabaseMetricsData() +{ +} + +//----------------------------------------------------------------------- + +void DatabaseMetricsData::updateData() +{ + MetricsData::updateData(); + m_data[m_loadQueueTasks].m_value = std::max(0, Loader::getInstance().getLoadQueueTasksEstimate()); + m_data[m_preloadsInProgress].m_value = Loader::getInstance().getNumPreloads(); + +#ifndef WIN32 + int const ageOldestUnackedLoad = Loader::getInstance().getAgeOldestUnackedLoad(); + if (ageOldestUnackedLoad > ConfigServerDatabase::getOldestUnackedLoadAlertThresholdSeconds()) + { + char buffer[64]; + IGNORE_RETURN(snprintf(buffer, sizeof(buffer)-1, "Threshold %d seconds exceeded by (server %lu)", + ConfigServerDatabase::getOldestUnackedLoadAlertThresholdSeconds(), Loader::getInstance().getServerOldestUnackedLoad())); + buffer[sizeof(buffer)-1] = '\0'; + + m_data[m_oldestUnackedLoadAlert].m_value = STATUS_LOADING; + m_data[m_oldestUnackedLoadAlert].m_description = buffer; + } + else + { + m_data[m_oldestUnackedLoadAlert].m_value = 0; + m_data[m_oldestUnackedLoadAlert].m_description = "No alert"; + } + m_data[m_oldestUnackedLoad].m_value = ageOldestUnackedLoad; + m_data[m_oldestUnackedLoad].m_description = "seconds"; +#else + m_data[m_oldestUnackedLoad].m_value = Loader::getInstance().getAgeOldestUnackedLoad(); + m_data[m_oldestUnackedLoad].m_description = "seconds"; +#endif + + m_data[m_timeSinceLastSaveStarted].m_value = Persister::getInstance().getTimeSinceLastSave(); + m_data[m_lastSaveTime].m_value = Persister::getInstance().getLastSaveTime() / 1000; + m_data[m_lastSaveTotalObjectCount].m_value = Persister::getInstance().getLastSaveTotalObjectCount(); + m_data[m_lastSaveNewObjectCount].m_value = Persister::getInstance().getLastSaveNewObjectCount(); + m_data[m_lazyDeleteQueueSize].m_value = static_cast(LazyDeleter::getInstance().getQueueSize()); + m_data[m_lazyDeleteTotalCount].m_value = LazyDeleter::getInstance().getTotalObjectCount(); + m_data[m_lazyDeletesPerMinute].m_value = static_cast(Clock::getSecondsSinceStart() > 60 ? LazyDeleter::getInstance().getTotalObjectCount() / (Clock::getSecondsSinceStart() / 60) : 0); //lint !e573 !e737 // signed/unsigned int precision + m_data[m_queryRate].m_value = static_cast(DatabaseProcess::getInstance().getQueryExecRate()); + m_data[m_fetchRate].m_value = static_cast(DatabaseProcess::getInstance().getQueryFetchRate()); + + m_data[m_lastSaveTime].m_description = std::string("Completed at ")+Persister::getInstance().getLastSaveCompletionTime(); + + float reportRate = static_cast(ConfigServerDatabase::getQueryReportingRate()); + std::string rateDescription; + if (reportRate == 1) + rateDescription = "per second"; + else if (reportRate == 60) + rateDescription = "per minute"; + else + { + char buffer[100]; + IGNORE_RETURN(snprintf(buffer,10,"per %f seconds",reportRate)); + rateDescription = buffer; + } + m_data[m_queryRate].m_description = rateDescription; + m_data[m_fetchRate].m_description = rateDescription; + m_data[m_loadQueueTasks].m_description = ConfigServerDatabase::getDSN(); + + m_data[m_snapshotCreationCount].m_value = Snapshot::getCreationCount(); + m_data[m_snapshotDeletionCount].m_value = Snapshot::getDeletionCount(); + m_data[m_snapshotPendingCount].m_value = Snapshot::getPendingCount(); + + m_data[m_snapshotRowCreationCount].m_value = DB::Row::getRowsCreated(); + m_data[m_snapshotRowDeletionCount].m_value = DB::Row::getRowsDeleted(); + + int i_rows_pending = DB::Row::getRowsCreated() - DB::Row::getRowsDeleted(); + m_data[m_snapshotRowPendingCount].m_value = i_rows_pending > 0 ? i_rows_pending : 0; + + m_data[m_taskQueueTotalNumRequests].m_value = DB::TaskQueue::getTotalNumRequests(); + m_data[m_taskQueueTotalNumResults].m_value = DB::TaskQueue::getTotalNumResults(); + + m_data[m_cmLoadTime].m_value = CMLoader::getInstance().getLoadTime(); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.h b/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.h new file mode 100644 index 00000000..56af3972 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseMetricsData.h @@ -0,0 +1,59 @@ +//DatabaseMetricsData.h +//Copyright 2002 Sony Online Entertainment + + +#ifndef _DatabaseMetricsData_H +#define _DatabaseMetricsData_H + +//----------------------------------------------------------------------- + +#include "serverMetrics/MetricsData.h" + +//----------------------------------------------------------------------- + +class DatabaseMetricsData : public MetricsData +{ +public: + DatabaseMetricsData(); + ~DatabaseMetricsData(); + + virtual void updateData(); + +private: + unsigned long m_loadQueueTasks; + unsigned long m_preloadsInProgress; + unsigned long m_oldestUnackedLoad; + unsigned long m_oldestUnackedLoadAlert; + unsigned long m_timeSinceLastSaveStarted; + unsigned long m_lastSaveTime; + unsigned long m_lastSaveTotalObjectCount; + unsigned long m_lastSaveNewObjectCount; + unsigned long m_lazyDeleteQueueSize; + unsigned long m_lazyDeleteTotalCount; + unsigned long m_lazyDeletesPerMinute; + unsigned long m_queryRate; + unsigned long m_fetchRate; + + unsigned long m_snapshotCreationCount; + unsigned long m_snapshotDeletionCount; + unsigned long m_snapshotPendingCount; + + unsigned long m_snapshotRowCreationCount; + unsigned long m_snapshotRowDeletionCount; + unsigned long m_snapshotRowPendingCount; + + unsigned long m_taskQueueTotalNumRequests; + unsigned long m_taskQueueTotalNumResults; + + unsigned long m_cmLoadTime; + +private: + + // Disabled. + DatabaseMetricsData(const DatabaseMetricsData&); + DatabaseMetricsData &operator =(const DatabaseMetricsData&); +}; + + +//----------------------------------------------------------------------- +#endif diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp new file mode 100644 index 00000000..2bdfa93a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.cpp @@ -0,0 +1,687 @@ +// ====================================================================== +// +// DatabaseProcess.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" + +#include "ConsoleManager.h" +#include "serverDatabase/CentralServerConnection.h" +#include "serverDatabase/ChatServerConnection.h" +#include "serverDatabase/CMLoader.h" +#include "serverDatabase/CommoditiesServerConnection.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseMetricsData.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/LazyDeleter.h" +#include "serverDatabase/Loader.h" +#include "serverDatabase/Persister.h" +#include "serverDatabase/TaskManagerConnection.h" +#include "serverMetrics/MetricsManager.h" +#include "serverNetworkMessages/CentralGameServerMessages.h" +#include "serverNetworkMessages/CentralPingMessage.h" +#include "serverNetworkMessages/ChatServerOnline.h" +#include "serverNetworkMessages/ExcommunicateGameServerMessage.h" +#include "serverNetworkMessages/GameServerConnectAck.h" +#include "serverNetworkMessages/GameTaskManagerMessages.h" +#include "serverNetworkMessages/ProfilerOperationMessage.h" +#include "serverNetworkMessages/TaskConnectionIdMessage.h" +#include "serverUtility/ServerClock.h" +#include "sharedDatabaseInterface/DbServer.h" +#include "sharedDatabaseInterface/DbTaskQueue.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/ConfigFile.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/Os.h" +#include "sharedLog/Log.h" +#include "sharedNetwork/NetworkSetupData.h" +#include "sharedNetwork/Service.h" +#include "sharedNetworkMessages/FrameEndMessage.h" +#include "UnicodeUtils.h" + +// ---------------------------------------------------------------------- + +DatabaseProcess *DatabaseProcess::ms_theInstance = NULL; + +// ---------------------------------------------------------------------- + +namespace MemoryManagerNamespace +{ + extern int ms_allocateCalls; +} + +//----------------------------------------------------------------------- + +void DatabaseProcess::installDerived(DatabaseProcess *derivedInstance) +{ + DEBUG_FATAL(ms_theInstance,("Called DatabaseProcess::installDerived twice.\n")); + ms_theInstance = derivedInstance; +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::remove() +{ + DEBUG_FATAL(!ms_theInstance,("DatabaseProcess was not installed.\n")); + delete ms_theInstance; + ms_theInstance = 0; +} + +// ---------------------------------------------------------------------- + +DatabaseProcess::DatabaseProcess() : +done(false), +processId(0), +centralServerConnection(0), +dbServer(0), +chatServerConnection(0), +commoditiesConnection(0), +m_metricsData(0), +m_queryExecCount(0), +m_queryFetchCount(0) +{ + ExitChain::add(DatabaseProcess::remove,"DatabaseProcess::remove"); + + centralServerConnection = new CentralServerConnection(ConfigServerDatabase::getCentralServerAddress(), ConfigServerDatabase::getCentralServerPort()); + NetworkSetupData setup; + setup.maxConnections = 100; + setup.port = 0; + setup.bindInterface = ConfigServerDatabase::getGameServiceBindInterface(); + gameService = new Service(ConnectionAllocator(), setup); + + NetworkSetupData cmSetup; + cmSetup.maxConnections = 100; + cmSetup.port = ConfigServerDatabase::getCommoditiesServerPort(); + cmSetup.bindInterface = ConfigServerDatabase::getCommoditiesServerAddress(); + commoditiesService = new Service(ConnectionAllocator(), cmSetup); + + taskService = new TaskManagerConnection("127.0.0.1", ConfigServerDatabase::getTaskManagerPort()); + + dbServer = DB::Server::create(ConfigServerDatabase::getDSN(), + ConfigServerDatabase::getDatabaseUID(), + ConfigServerDatabase::getDatabasePWD(), + DB::Server::getProtocolByName(ConfigServerDatabase::getDatabaseProtocol()), + ConfigServerDatabase::getUseMemoryManagerForOCI()); + + if (ConfigServerDatabase::getEnableQueryProfile()) + DB::Server::enableProfiling(); + + if (ConfigServerDatabase::getVerboseQueryMode()) + DB::Server::enableVerboseMode(); + + DB::TaskQueue::enableWorkerThreadsLogging(ConfigServerDatabase::getLogWorkerThreads()); + + if (ConfigServerDatabase::getPrefetchNumRows()!=0) + DB::Server::enablePrefetch(ConfigServerDatabase::getPrefetchNumRows(), ConfigServerDatabase::getPrefetchMemory()); + + DB::Server::setReconnectTime(ConfigServerDatabase::getDatabaseReconnectTime()); + DB::Server::setMaxErrorCountBeforeDisconnect(ConfigServerDatabase::getMaxErrorCountBeforeDisconnect()); + DB::Server::setMaxErrorCountBeforeBailout(ConfigServerDatabase::getMaxErrorCountBeforeBailout()); + DB::Server::setErrorSleepTime(ConfigServerDatabase::getErrorSleepTime()); + DB::Server::setDisconnectSleepTime(ConfigServerDatabase::getDisconnectSleepTime()); + DB::Server::setFatalOnDataError(ConfigServerDatabase::getFatalOnDataError()); + + // the DatabaseProcess singleton will want to know when major, connection + // oriented events occur. These events are defined in Game, Task and Central + // connection classes. + connectToMessage("CentralConnectionOpened"); + connectToMessage("GameConnectionOpened"); + connectToMessage("TaskConnectionOpened"); + connectToMessage("CommoditiesConnectionOpened"); + + connectToMessage("CentralConnectionClosed"); + connectToMessage("GameConnectionClosed"); + connectToMessage("TaskConnectionClosed"); + connectToMessage("CommoditiesConnectionClosed"); + + connectToMessage("ChatServerOnline"); + connectToMessage("ChatServerConnectionClosed"); + + // other messages the DatabaseProcess singleton will want... + connectToMessage("CentralGameServerSetProcessId"); + connectToMessage("LoadObjectMessage"); + connectToMessage("LoadUniverseMessage"); + connectToMessage("GameSetProcessId"); + connectToMessage("ProfilerOperationMessage"); + connectToMessage("FrameEndMessage"); + connectToMessage("CentralPingMessage"); + connectToMessage("ExcommunicateGameServerMessage"); + + m_metricsData = new DatabaseMetricsData; + MetricsManager::install(m_metricsData, false, "Database", "", 0); + ConsoleManager::install(); + + Profiler::setTemporaryExpandAll(ConfigServerDatabase::getProfilerExpandAll()); + Profiler::setDisplayPercentageMinimum(ConfigServerDatabase::getProfilerDisplayPercentageMinimum()); +} + +//----------------------------------------------------------------------- + +DatabaseProcess::~DatabaseProcess() +{ + ConsoleManager::remove(); + MetricsManager::remove(); + + delete m_metricsData; + m_metricsData = 0; + + dbServer->disconnect(); + if (ConfigServerDatabase::getEnableQueryProfile()) + { + DB::Server::debugOutputProfile(); + DB::Server::endProfiling(); + } + + delete dbServer; + + commoditiesConnection = 0; + chatServerConnection = 0; + centralServerConnection = 0; + commoditiesService = 0; + gameService = 0; + taskService = 0; + dbServer = 0; +} + +//----------------------------------------------------------------------- + +void DatabaseProcess::run(void) +{ + static bool shouldSleep = ConfigServerDatabase::getShouldSleep(); + unsigned long startTime; + bool idle=false; + int loopcount=0; + float nextMemoryReportTime=0; + float nextQueryCountTime=0; + + LOG("ServerStartup",("DatabaseServer starting")); + + while (!done) + { + PROFILER_AUTO_BLOCK_DEFINE("main loop"); + + startTime = Clock::timeMs(); + + if (!Os::update()) + setDone("OS condition (Parent pid change)"); + + real updateTime = Clock::frameTime(); + if (updateTime > ConfigServerDatabase::getReportLongFrameTime()) + { + LOG("profile",("Long loop %f seconds:\n%s",updateTime,Profiler::getLastFrameData())); + DEBUG_REPORT_LOG(true,("Long loop %f seconds:\n%s",updateTime,Profiler::getLastFrameData())); + } + + { + PROFILER_AUTO_BLOCK_DEFINE("Persister::update"); + Persister::getInstance().update(updateTime); + } + { + PROFILER_AUTO_BLOCK_DEFINE("Loader::update"); + Loader::getInstance().update(updateTime); + } + { + PROFILER_AUTO_BLOCK_DEFINE("CMLoader::update"); + CMLoader::getInstance().update(); + } + { + PROFILER_AUTO_BLOCK_DEFINE("DataLookup::update"); + DataLookup::getInstance().update(updateTime); + } + { + PROFILER_AUTO_BLOCK_DEFINE("LazyDeleter::update"); + LazyDeleter::getInstance().update(updateTime); + } + { + PROFILER_AUTO_BLOCK_DEFINE("NetworkHandler::update"); + NetworkHandler::update(); + } + nextMemoryReportTime-=updateTime; + if (nextMemoryReportTime < 0) + { +#ifndef _WIN32 + LOG("DatabaseMemory",("Bytes used: %lu (VmSize %dK) Open allocations: %d Total Allocations %d",MemoryManager::getCurrentNumberOfBytesAllocated(static_cast(Os::getProcessId())),MemoryManager::getProcessVmSizeKBytes(static_cast(Os::getProcessId())),MemoryManager::getCurrentNumberOfAllocations(),MemoryManagerNamespace::ms_allocateCalls)); +#else + LOG("DatabaseMemory",("Bytes used: %lu Open allocations: %d Total Allocations %d",MemoryManager::getCurrentNumberOfBytesAllocated(static_cast(Os::getProcessId())),MemoryManager::getCurrentNumberOfAllocations(),MemoryManagerNamespace::ms_allocateCalls)); +#endif + nextMemoryReportTime=10; + } + + nextQueryCountTime-=updateTime; + if (nextQueryCountTime < 0) + { + takeQueryCountSnapshot(); + nextQueryCountTime = 60.0f; + } + + MetricsManager::update(updateTime*1000); + + // TODO: sleep longer if idle + if (shouldSleep) + { + Os::sleep(1); + } + + NetworkHandler::dispatch(); + + Persister::getInstance().onFrameBarrierReached(); + if (Persister::getInstance().isIdle() && Loader::getInstance().isIdle() && DataLookup::getInstance().isIdle()) + { + DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes() && !idle,("Database process is idle.\n")); + idle=true; + if (taskService) + { + ServerIdleMessage msg(true); + taskService->send(msg,true); + } + } + else + { + idle=false; + if (taskService) + { + ServerIdleMessage msg(false); + taskService->send(msg,true); + } + } + + if (ConfigServerDatabase::getEnableQueryProfile() && ++loopcount>40) + { + loopcount=0; + DB::Server::debugOutputProfile(); + } + + frameTick(); // virtual called 1x per frame + + NetworkHandler::clearBytesThisFrame(); + + ServerClock::getInstance().incrementServerFrame(); + } + + // Give all of the task queues a chance to finish before we delete anything + Persister::getInstance().shutdown(); + Loader::getInstance().shutdown(); + DataLookup::getInstance().shutdown(); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::setDone(char const *reasonfmt, ...) +{ + if (!done) + { + char reason[1024]; + va_list ap; + va_start(ap, reasonfmt); + _vsnprintf(reason, sizeof(reason), reasonfmt, ap); + reason[sizeof(reason)-1] = '\0'; + + LOG( + "ServerShutdown", + ( + "DatabaseServer %d (pid %d) shutdown, reason: %s", + static_cast(getProcessId()), + static_cast(Os::getProcessId()), + reason)); + + REPORT_LOG( + true, + ( + "DatabaseServer %d (pid %d) shutdown, reason: %s\n", + static_cast(getProcessId()), + static_cast(Os::getProcessId()), + reason)); + + done = true; + } +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::setCentralServerConnection(CentralServerConnection *_connection) +{ + centralServerConnection=_connection; +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::setProcessId(uint32 _processId) +{ + processId=_processId; +} + +// ---------------------------------------------------------------------- + +/** + * Establish a connection to a game server (if not already connected). + */ +void DatabaseProcess::connectToGameServer(const char *address, uint16 port, uint32 processId) +{ + DEBUG_REPORT_LOG(true,("connectToGameServer is still getting invoked.\n")); + + std::pair a(std::make_pair(std::string(address), port)); + std::set >::const_iterator i = pendingGameServerConnections.find(a); + if(i == pendingGameServerConnections.end()) + { + // check to see if there is already a connection active + std::hash_map::const_iterator j = gameServerConnections.find(processId); + if(j == gameServerConnections.end()) + { + // make the connection + new GameServerConnection(std::string(address), port); + } + } +} + +//----------------------------------------------------------------------- + +GameServerConnection * DatabaseProcess::getConnectionByProcess(const uint32 processId) +{ + GameServerConnection * result = 0; + std::hash_map::const_iterator j = gameServerConnections.find(processId); + if(j != gameServerConnections.end()) + { + result = (*j).second; + } + return result; +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::getGameServerProcessIds(std::vector &processIds) const +{ + for (std::hash_map::const_iterator i = gameServerConnections.begin(); i != gameServerConnections.end(); ++i) + processIds.push_back((*i).first); +} + +// ---------------------------------------------------------------------- + +uint32 DatabaseProcess::getProcessId(void) +{ + return processId; +} + +//----------------------------------------------------------------------- + +void DatabaseProcess::gameServerGoByeBye(uint32 processId) +{ + DataLookup::getInstance().releaseNamesForProcess(processId); + gameServerConnections.erase(processId); + Loader::getInstance().discardPendingLoadsForServer(processId); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) +{ + UNREF(source); + + //--- + // Connection info messages + // + if(message.isType("CentralConnectionOpened")) + { + DEBUG_REPORT_LOG(true, ("Connection with Central server opened\n")); + DEBUG_FATAL(centralServerConnection != &source,("Got CentralConnectionOpened from something other than our CentralServer connection.\n")); + + //TODO: Make a DatabaseProcessConnect version of this message, perhaps ? + CentralGameServerConnect c("database", "127.0.0.1", 0, gameService->getBindAddress(), gameService->getBindPort()); + centralServerConnection->send(c, true); + + } + else if(message.isType("GameConnectionOpened")) + { + DEBUG_REPORT_LOG(true, ("Connection with Game server opened\n")); + } + else if(message.isType("TaskConnectionOpened")) + { + DEBUG_REPORT_LOG(true, ("Connection with Task manager opened\n")); + + // get cluster name + std::string clusterName; + ConfigFile::Section const * const sec = ConfigFile::getSection("TaskManager"); + if (sec) + { + ConfigFile::Key const * const ky = sec->findKey("clusterName"); + if (ky) + { + clusterName = ky->getAsString(ky->getCount()-1, ""); + } + } + + TaskConnectionIdMessage tid(TaskConnectionIdMessage::Database, "", clusterName); + taskService->send(tid, true); + } + else if(message.isType("CommoditiesConnectionOpened")) + { + DEBUG_REPORT_LOG(true, ("Connection with Commodities Server opened\n")); + CommoditiesServerConnection * con = const_cast(static_cast(&source)); + if (commoditiesConnection) + LOG("CommoditiesConnectionOpened",("Connection Opened while another connection already exists.")); + commoditiesConnection = con; + } + else if(message.isType("CentralConnectionClosed")) + { + DEBUG_REPORT_LOG(true, ("Central server closed its connection, we must die a tragicly heroic death.\n")); + setDone("CentralConnectionClosed : %s", centralServerConnection->getDisconnectReason().c_str()); + centralServerConnection = 0; + WARNING(true,("Database lost connection to central.")); + } + else if(message.isType("GameConnectionClosed")) + { + DEBUG_REPORT_LOG(true, ("a Game server closed its connection\n")); + } + else if(message.isType("TaskConnectionClosed")) + { + DEBUG_REPORT_LOG(true, ("Task manager closed its connection\n")); + taskService=0; + } + else if(message.isType("CommoditiesConnectionClosed")) + { + DEBUG_REPORT_LOG(true, ("Commodities Server closed its connection\n")); + commoditiesService = 0; + commoditiesConnection = 0; + } + // end connection info messages + //--- + + else if(message.isType("CentralGameServerSetProcessId")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + CentralGameServerSetProcessId id(ri); + setProcessId(id.getProcessId()); + clusterName = id.getClusterName(); + + Loader::getInstance().checkVersionNumber(ConfigServerDatabase::getExpectedDBVersion(), ConfigServerDatabase::isCorrectDBVersionRequired()); + Loader::getInstance().loadClock(); + } + else if(message.isType("LoadObjectMessage")) + { +#if 0 + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadObjectMessage lom(ri); + connectToGameServer(lom.getAddress().c_str(),lom.getPort(),lom.getProcess()); +#endif + } + else if (message.isType("LoadUniverseMessage")) + { +#if 0 + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadUniverseMessage lom(ri); + connectToGameServer(lom.getAddress().c_str(),lom.getPort(),lom.getProcess()); +#endif + } + + else if(message.isType("GameSetProcessId") || message.isType("GameGameServerConnect")) + { + GameServerConnection * g = const_cast(static_cast(&source)); + gameServerConnections[g->getProcessId()] = g; + + GameServerConnectAck reply; + g->send(reply,true); + } + else if(message.isType("ProfilerOperationMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ProfilerOperationMessage m(ri); + uint32 processId = m.getProcessId(); + if (processId == 0 || processId == getProcessId()) + Profiler::handleOperation(m.getOperation().c_str()); + } + else if(message.isType("ChatServerOnline")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ChatServerOnline cso(ri); + + // establish a connection with the chat server if one doesn't already exist + if (!chatServerConnection) + { + REPORT_LOG(true, ("New chat server connection active\n")); + chatServerConnection = new ChatServerConnection(cso.getAddress(), cso.getPort()); + } + } + else if(message.isType("ChatServerConnectionClosed")) + { + REPORT_LOG(true, ("DatabaseProcess: Chat Server connection closed\n")); + chatServerConnection = 0; + } + else if(message.isType("FrameEndMessage")) + { + // TODO: handle this game server's frame ending + } + else if (message.isType("CentralPingMessage")) + { + CentralPingMessage reply; + sendToCentralServer(reply,true); + } + else if (message.isType("ExcommunicateGameServerMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ri = static_cast(message).getByteStream().begin(); + ExcommunicateGameServerMessage msg(ri); + + LOG("GameGameConnect",("Database Process was told to drop connection to %lu by Central",msg.getServerId())); + + FATAL (msg.getServerId() == getProcessId(),("Crashing because Central told us to (probably indicates we weren't responding to pings)")); + GameServerConnection *conn =getConnectionByProcess(msg.getServerId()); + if (conn) + { + conn->setDisconnectReason("Told to excommunicate by central"); + conn->disconnect(); + } + } +} + +// ---------------------------------------------------------------------- + +const std::string DatabaseProcess::getSchemaQualifier() const +{ + if (ConfigServerDatabase::getSchemaOwner()[0]!='\0') + return std::string(ConfigServerDatabase::getSchemaOwner())+'.'; + else + return std::string(); +} + +// ---------------------------------------------------------------------- + +const std::string DatabaseProcess::getGoldSchemaQualifier() const +{ + static std::string result = std::string(ConfigServerDatabase::getGoldSchemaOwner()) + '.'; + return result; +} + +// ---------------------------------------------------------------------- + +const std::string DatabaseProcess::getSchema() const +{ + if (ConfigServerDatabase::getSchemaOwner()[0]!='\0') + return std::string(Unicode::toUpper(ConfigServerDatabase::getSchemaOwner())); + else + return std::string(Unicode::toUpper(ConfigServerDatabase::getDatabaseUID())); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToChatServer(GameNetworkMessage const &message) +{ + if (chatServerConnection) + chatServerConnection->send(message, true); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToCentralServer(GameNetworkMessage const &message, bool reliable) +{ + if (centralServerConnection) + centralServerConnection->send(message,reliable); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToCommoditiesServer(GameNetworkMessage const &message, bool reliable) +{ + if (commoditiesConnection) + { + commoditiesConnection->send(message,reliable); + } + else + DEBUG_REPORT_LOG(true, ("commoditiesConnection is NULL\n")); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToAllGameServers(GameNetworkMessage const &message, bool reliable) +{ + for (std::hash_map::const_iterator i=gameServerConnections.begin(); i!=gameServerConnections.end(); ++i) + i->second->send(message,reliable); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToGameServer(uint32 serverId, GameNetworkMessage const &message) +{ + std::hash_map::const_iterator i=gameServerConnections.find(serverId); + if (i!=gameServerConnections.end()) + i->second->send(message,true); + else + DEBUG_WARNING(true,("Tried to send to game server %lu without connection.\n",serverId)); +} + +// ---------------------------------------------------------------------- + +void DatabaseProcess::sendToAnyGameServer(GameNetworkMessage const &message) +{ + if (!gameServerConnections.empty()) + gameServerConnections.begin()->second->send(message,true); +} +// ---------------------------------------------------------------------- + +float DatabaseProcess::getQueryExecRate() const +{ + return ((static_cast(m_queryExecCount) / 60.0f) * static_cast(ConfigServerDatabase::getQueryReportingRate())); +} + +// ---------------------------------------------------------------------- + +float DatabaseProcess::getQueryFetchRate() const +{ + return ((static_cast(m_queryFetchCount) / 60.0f) * static_cast(ConfigServerDatabase::getQueryReportingRate())); +} + +// ---------------------------------------------------------------------- + +/** + * Record the current rate of queries and fetches for the metrics system + * (averages over 1 minute, because the instantaneous rate would fluctuate too much) + */ +void DatabaseProcess::takeQueryCountSnapshot() +{ + dbServer->getAndResetQueryCount(m_queryExecCount, m_queryFetchCount); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcess.h b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.h new file mode 100644 index 00000000..9ab24885 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcess.h @@ -0,0 +1,133 @@ +// ====================================================================== +// +// DatabaseProcess.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_DatabaseProcess_H +#define INCLUDED_DatabaseProcess_H + +// ====================================================================== + +#include +#include +#include +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedMessageDispatch/Receiver.h" + +class CentralServerConnection; +class ChatServerConnection; +class CommoditiesServerConnection; +class DatabaseMetricsData; +class GameNetworkMessage; +class GameServerConnection; +class Service; +class StringId; +class TaskManagerConnection; + +namespace DB +{ + class Server; +} + +// ====================================================================== + +class DatabaseProcess : public MessageDispatch::Receiver +{ + public: + static DatabaseProcess &getInstance(); + +// running: + virtual void run (void) = 0; + void setDone(char const *reasonfmt, ...); + + virtual void frameTick(void) {} + +// setters: + void setCentralServerConnection(CentralServerConnection *_connection); + void setProcessId(uint32 _processId); + +// getters: + GameServerConnection * getConnectionByProcess(const uint32 processId); + void getGameServerProcessIds(stdvector::fwd &processIds) const; + uint32 getProcessId(void); + DB::Server *getDBServer(void); + const std::string &getClusterName() const; + const std::string getSchemaQualifier() const; + const std::string getGoldSchemaQualifier() const; + const std::string getSchema() const; + float getQueryExecRate() const; + float getQueryFetchRate() const; + +// communication: + void connectToGameServer(const char *addres, uint16 port, uint32 processId); + + void receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); + void gameServerGoByeBye(uint32 processId); + void sendToChatServer(GameNetworkMessage const &message); + void sendToCentralServer(GameNetworkMessage const &message, bool reliable); + void sendToCommoditiesServer(GameNetworkMessage const &message, bool reliable); + void sendToAllGameServers(GameNetworkMessage const &message, bool reliable); + void sendToGameServer(uint32 serverId, GameNetworkMessage const &message); + void sendToAnyGameServer(GameNetworkMessage const &message); + + private: + + bool done; + + uint32 processId; + std::string clusterName; + CentralServerConnection *centralServerConnection; + DB::Server *dbServer; + + Service * gameService; + TaskManagerConnection * taskService; + ChatServerConnection * chatServerConnection; + Service * commoditiesService; + CommoditiesServerConnection * commoditiesConnection; + DatabaseMetricsData * m_metricsData; + + std::hash_map gameServerConnections; + std::set > pendingGameServerConnections; + + int m_queryExecCount; + int m_queryFetchCount; + +//creation + protected: + static void installDerived(DatabaseProcess *derivedInstance); + DatabaseProcess(); + virtual ~DatabaseProcess(); + + private: + void takeQueryCountSnapshot(); + + static void remove(); + static DatabaseProcess *ms_theInstance; +}; + +// ====================================================================== + +inline DB::Server *DatabaseProcess::getDBServer(void) +{ + return dbServer; +} + +// ---------------------------------------------------------------------- + +inline const std::string &DatabaseProcess::getClusterName() const +{ + return clusterName; +} + +// ---------------------------------------------------------------------- + +inline DatabaseProcess &DatabaseProcess::getInstance() +{ + DEBUG_FATAL(!ms_theInstance,("DatabaseProcess was not installed.\n")); + return *ms_theInstance; +} + +// ====================================================================== +#endif diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.cpp b/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.cpp new file mode 100644 index 00000000..a741a463 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.cpp @@ -0,0 +1,28 @@ +// ====================================================================== +// +// DatabaseProcessQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/DatabaseProcessQuery.h" + +// ====================================================================== + +DatabaseProcessQuery::DatabaseProcessQuery(DB::Row *derivedRow) : + DB::ModeQuery(derivedRow) +{ +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode DatabaseProcessQuery::getExecutionMode() const +{ + if ((mode==mode_SELECT) && (getProtocol()==DB::PROTOCOL_OCI)) + return (MODE_PLSQL_REFCURSOR); + else + return (MODE_SQL); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.h b/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.h new file mode 100644 index 00000000..bc3639d2 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DatabaseProcessQuery.h @@ -0,0 +1,39 @@ +// ====================================================================== +// +// DatabaseProcessQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_DatabaseProcessQuery_H +#define INCLUDED_DatabaseProcessQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbModeQuery.h" + +// ====================================================================== + +/** + * ModeQuery specialized for how DatabaseProcess uses them. + * + * The main difference is that this query uses Oracle refcursor mode + * when appropriate. + */ + +class DatabaseProcessQuery : public DB::ModeQuery +{ + public: + explicit DatabaseProcessQuery(DB::Row *derivedRow); + + protected: + virtual QueryMode getExecutionMode() const; + + private: + DatabaseProcessQuery(const DatabaseProcessQuery &); // disable + DatabaseProcessQuery &operator=(DatabaseProcessQuery &); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.cpp new file mode 100644 index 00000000..67ec7bd2 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.cpp @@ -0,0 +1,98 @@ +// ====================================================================== +// +// DeleteCharacterCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/DeleteCharacterCustomPersistStep.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +DeleteCharacterCustomPersistStep::DeleteCharacterCustomPersistStep(uint32 stationId, const NetworkId &characterId) : + m_characterId(characterId), + m_stationId(stationId) +{ +} + +// ---------------------------------------------------------------------- + +bool DeleteCharacterCustomPersistStep::beforePersist(DB::Session *) +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool DeleteCharacterCustomPersistStep::afterPersist(DB::Session *session) +{ + DeleteCharacterQuery qry(m_stationId, m_characterId); + + if (! (session->exec(&qry))) + return false; + qry.done(); + + m_resultCode=qry.result.getValue(); + return true; +} + +// ---------------------------------------------------------------------- + +void DeleteCharacterCustomPersistStep::onComplete() +{ + if (m_resultCode == 2) + { + GenericValueTypeMessage msg("ReleaseCharacterNameByIdMessage",m_characterId); + DatabaseProcess::getInstance().sendToAllGameServers(msg,true); + } +} + +// ====================================================================== + +DeleteCharacterCustomPersistStep::DeleteCharacterQuery::DeleteCharacterQuery(uint32 stationId, const NetworkId &characterId) : + station_id(stationId), + character_id(characterId), + delete_minutes(ConfigServerDatabase::getCharacterImmediateDeleteMinutes()), + result() +{ +} + +// ---------------------------------------------------------------------- + +void DeleteCharacterCustomPersistStep::DeleteCharacterQuery::getSQL(std::string &sql) +{ + sql="begin :result := " + DatabaseProcess::getInstance().getSchemaQualifier() + "persister.delete_character (:station_id, :character_id, :delete_minutes); end;"; +} + +// ---------------------------------------------------------------------- + +bool DeleteCharacterCustomPersistStep::DeleteCharacterQuery::bindParameters() +{ + if (!bindParameter(result)) return false; + if (!bindParameter(station_id)) return false; + if (!bindParameter(character_id)) return false; + if (!bindParameter(delete_minutes)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool DeleteCharacterCustomPersistStep::DeleteCharacterQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode DeleteCharacterCustomPersistStep::DeleteCharacterQuery::getExecutionMode() const +{ + return DB::Query::MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h new file mode 100644 index 00000000..0ab8a0cc --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/DeleteCharacterCustomPersistStep.h @@ -0,0 +1,61 @@ +// ====================================================================== +// +// DeleteCharacterCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_DeleteCharacterCustomPersistStep_H +#define INCLUDED_DeleteCharacterCustomPersistStep_H + +// ====================================================================== + +#include + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +class DeleteCharacterCustomPersistStep : public CustomPersistStep +{ + public: + DeleteCharacterCustomPersistStep(uint32 stationId, const NetworkId &characterId); + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + NetworkId m_characterId; + uint32 m_stationId; + uint32 m_resultCode; + + class DeleteCharacterQuery : public DB::Query + { + public: + DeleteCharacterQuery(uint32 stationId, const NetworkId &characterId); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + protected: + virtual QueryMode getExecutionMode() const; + + public: + DB::BindableLong station_id; + DB::BindableNetworkId character_id; + DB::BindableLong delete_minutes; + DB::BindableLong result; + + private: // disable: + DeleteCharacterQuery(const DeleteCharacterQuery&); + DeleteCharacterQuery& operator=(const DeleteCharacterQuery&); + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/FirstServerDatabase.h b/engine/server/library/serverDatabase/src/shared/FirstServerDatabase.h new file mode 100644 index 00000000..8f490a68 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/FirstServerDatabase.h @@ -0,0 +1,7 @@ +#ifndef INCLUDED_FirstServerDatabase_H +#define INCLUDED_FirstServerDatabase_H + +#include "sharedFoundation/FirstSharedFoundation.h" +#include "sharedMemoryManager/FirstSharedMemoryManager.h" + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.cpp new file mode 100644 index 00000000..3904f4b6 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.cpp @@ -0,0 +1,91 @@ +// ====================================================================== +// +// FixLoadWithCustomPersistStep.cpp +// Copyright (c) 2007 Sony Online Entertainment, LLC +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/FixLoadWithCustomPersistStep.h" + +#include "serverDatabase/CharacterQueries.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/Persister.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +FixLoadWithCustomPersistStep::FixLoadWithCustomPersistStep(const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth) : + m_topmostObject(topmostObject), + m_startingLoadWith(startingLoadWith), + m_maxDepth(maxDepth) +{ +} + +// ---------------------------------------------------------------------- + +FixLoadWithCustomPersistStep::~FixLoadWithCustomPersistStep() +{ +} + +// ---------------------------------------------------------------------- + +bool FixLoadWithCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool FixLoadWithCustomPersistStep::afterPersist(DB::Session *session) +{ + FixLoadWithQuery qry(m_topmostObject, m_startingLoadWith, m_maxDepth); + if (! (session->exec(&qry))) + return false; + qry.done(); + return true; +} + +// ---------------------------------------------------------------------- + +void FixLoadWithCustomPersistStep::onComplete() +{ +} + +// ---------------------------------------------------------------------- + +FixLoadWithCustomPersistStep::FixLoadWithQuery::FixLoadWithQuery(const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth) : + topmost_object(topmostObject), + starting_loadwith(startingLoadWith), + max_depth(maxDepth) +{ +} + +// ---------------------------------------------------------------------- + +void FixLoadWithCustomPersistStep::FixLoadWithQuery::getSQL(std::string &sql) +{ + sql="begin "+DatabaseProcess::getInstance().getSchemaQualifier()+"admin.fix_load_with_depth (:topmost_object, :starting_loadwith, :max_depth); end;"; +} + +// ---------------------------------------------------------------------- + +bool FixLoadWithCustomPersistStep::FixLoadWithQuery::bindParameters() +{ + if (!bindParameter(topmost_object)) return false; + if (!bindParameter(starting_loadwith)) return false; + if (!bindParameter(max_depth)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool FixLoadWithCustomPersistStep::FixLoadWithQuery::bindColumns() +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h new file mode 100644 index 00000000..e5e24bea --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/FixLoadWithCustomPersistStep.h @@ -0,0 +1,63 @@ +// ====================================================================== +// +// FixLoadWithCustomPersistStep.h +// Copyright (c) 2007 Sony Online Entertainment, LLC +// +// ====================================================================== + +#ifndef INCLUDED_FixLoadWithCustomPersistStep_H +#define INCLUDED_FixLoadWithCustomPersistStep_H + +// ====================================================================== + +#include "Unicode.h" +#include "serverDatabase/CustomPersistStep.h" +#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" +#include + +class NetworkId; + +// ====================================================================== + +class FixLoadWithCustomPersistStep : public CustomPersistStep +{ + public: + FixLoadWithCustomPersistStep(const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth); + ~FixLoadWithCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + NetworkId m_topmostObject; + NetworkId m_startingLoadWith; + int m_maxDepth; + + class FixLoadWithQuery: public DB::Query + { + public: + FixLoadWithQuery(const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth); + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + FixLoadWithQuery(FixLoadWithQuery const &); + FixLoadWithQuery &operator=(FixLoadWithQuery const &); + DB::BindableNetworkId topmost_object; + DB::BindableNetworkId starting_loadwith; + DB::BindableLong max_depth; + }; + + private: + FixLoadWithCustomPersistStep &operator= (const FixLoadWithCustomPersistStep&); //disable + FixLoadWithCustomPersistStep(const FixLoadWithCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GameServerConnection.cpp b/engine/server/library/serverDatabase/src/shared/GameServerConnection.cpp new file mode 100644 index 00000000..201ce2e1 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GameServerConnection.cpp @@ -0,0 +1,100 @@ +// GameServerConnection.cpp +// copyright 2001 Verant Interactive +// Author: Justin Randall + + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.h" +#include "Archive/ByteStream.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverNetworkMessages/ChunkCompleteMessage.h" +#include "serverNetworkMessages/GameGameServerMessages.h" +#include "serverUtility/ConfigServerUtility.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +GameServerConnection::GameServerConnection(const std::string & a, const unsigned short p) : + ServerConnection(a, p, NetworkSetupData()), + m_chunkCompleteQueue(new ChunkCompleteQueueType) +{ +} + +//----------------------------------------------------------------------- + +GameServerConnection::GameServerConnection(UdpConnectionMT * u, TcpClient * t) : + ServerConnection(u, t), + m_chunkCompleteQueue(new ChunkCompleteQueueType) +{ +} + +//----------------------------------------------------------------------- + +GameServerConnection::~GameServerConnection() +{ + delete m_chunkCompleteQueue; +} + +//----------------------------------------------------------------------- + +void GameServerConnection::onConnectionClosed() +{ + ServerConnection::onConnectionClosed(); + static MessageConnectionCallback m("GameConnectionClosed"); + emitMessage(m); + + DatabaseProcess::getInstance().gameServerGoByeBye(getProcessId()); +} + +//----------------------------------------------------------------------- + +void GameServerConnection::onConnectionOpened() +{ + ServerConnection::onConnectionOpened(); + static MessageConnectionCallback m("GameConnectionOpened"); + emitMessage(m); + + GameGameServerConnect ggsc(DatabaseProcess::getInstance().getProcessId(), true, ConfigServerUtility::getSpawnCookie(), 0); + send(ggsc,true); +} + +//----------------------------------------------------------------------- + +void GameServerConnection::onReceive(const Archive::ByteStream & message) +{ + ServerConnection::onReceive(message); + Archive::ReadIterator ri = message.begin(); + GameNetworkMessage m(ri); + if (m.isType("GameGameServerConnect")) + { + static MessageConnectionCallback m("GameSetProcessId"); + emitMessage(m); + } +} + +//----------------------------------------------------------------------- + +void GameServerConnection::queueCompletedChunk (int nodeX, int nodeZ) +{ + m_chunkCompleteQueue->push_back(std::make_pair(nodeX, nodeZ)); +} + +// ---------------------------------------------------------------------- + +void GameServerConnection::sendChunkCompleteMessage() +{ + ChunkCompleteMessage msg(*m_chunkCompleteQueue); + send(msg, true); + m_chunkCompleteQueue->clear(); +} + +// ---------------------------------------------------------------------- + +void GameServerConnection::clearChunkCompleteQueue() +{ + m_chunkCompleteQueue->clear(); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GameServerConnection.h b/engine/server/library/serverDatabase/src/shared/GameServerConnection.h new file mode 100644 index 00000000..3cb47a73 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GameServerConnection.h @@ -0,0 +1,41 @@ +// GameServerConnection.h +// copyright 2001 Verant Interactive +// Author: Justin Randall + +#ifndef _GameServerConnection_H +#define _GameServerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class GameServerConnection : public ServerConnection +{ +public: + GameServerConnection (const std::string & remoteAddress, const unsigned short remotePort); + explicit GameServerConnection (UdpConnectionMT *, TcpClient *); + virtual ~GameServerConnection (); + + void onConnectionClosed (); + void onConnectionOpened (); + void onReceive (const Archive::ByteStream & message); + + void queueCompletedChunk (int nodeX, int nodeZ); + void sendChunkCompleteMessage(); + void clearChunkCompleteQueue(); + +private: + typedef stdvector >::fwd ChunkCompleteQueueType; + ChunkCompleteQueueType * const m_chunkCompleteQueue; + +private: + GameServerConnection(GameServerConnection&); + GameServerConnection& operator=(GameServerConnection&); +}; + +//----------------------------------------------------------------------- + +#endif // _GameServerConnection_H + diff --git a/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.cpp new file mode 100644 index 00000000..d0fa5f01 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.cpp @@ -0,0 +1,59 @@ +// ====================================================================== +// +// GetBiographyQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetBiographyQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +GetBiographyQuery::GetBiographyQuery(const NetworkId &newOwner) : + owner(newOwner) +{ +} + +// ---------------------------------------------------------------------- + +void GetBiographyQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :rc := ") + DatabaseProcess::getInstance().getSchemaQualifier() + "biography.get_biography(:owner); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetBiographyQuery::bindParameters() +{ + if (!bindParameter(owner)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetBiographyQuery::bindColumns() +{ + if (!bindCol(bio)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +void GetBiographyQuery::getBio(Unicode::String &buffer) const +{ + bio.getValue(buffer); +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetBiographyQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.h b/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.h new file mode 100644 index 00000000..10965784 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetBiographyQuery.h @@ -0,0 +1,49 @@ +// ====================================================================== +// +// GetBiographyQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetBiographyQuery_H +#define INCLUDED_GetBiographyQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery { + + class GetBiographyQuery : public DB::Query + { + public: + + GetBiographyQuery(const NetworkId &newOwner); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + void getBio(Unicode::String &buffer) const; + + protected: + virtual QueryMode getExecutionMode() const; + + private: + DB::BindableNetworkId owner; + DB::BindableUnicode<1024> bio; + + private: + GetBiographyQuery(const GetBiographyQuery&); // disable + GetBiographyQuery& operator=(const GetBiographyQuery&); //disable + }; + +} //namespace + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.cpp new file mode 100644 index 00000000..e0e9a3f1 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.cpp @@ -0,0 +1,63 @@ +// ====================================================================== +// +// GetChunkQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetChunkQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +GetChunkQuery::GetChunkQuery(const std::string &schema) : + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void GetChunkQuery::setChunk(const std::string &sceneId, int nodeX, int nodeZ) +{ + scene_id.setValue(sceneId); + node_x.setValue(nodeX); + node_z.setValue(nodeZ); +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetChunkQuery::getExecutionMode() const +{ + return (MODE_PROCEXEC); +} + +// ---------------------------------------------------------------------- + +void GetChunkQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :object_count := ") + m_schema + "loader.load_chunk_object_list (:scene_id, :node_x, :node_z); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetChunkQuery::bindParameters() +{ + if (!bindParameter(object_count)) return false; + if (!bindParameter(scene_id)) return false; + if (!bindParameter(node_x)) return false; + if (!bindParameter(node_z)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetChunkQuery::bindColumns() +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h new file mode 100644 index 00000000..60ee1d29 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetChunkQuery.h @@ -0,0 +1,63 @@ +// ====================================================================== +// +// GetChunkQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetChunkQuery_H +#define INCLUDED_GetChunkQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery { + + /** A query to get the list of chunk objects. + */ + class GetChunkQuery : public DB::Query + { + public: + void setChunk(const std::string &sceneId, int nodeX, int nodeZ); + + public: + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + int getObjectCount() const; + + public: + GetChunkQuery(const std::string &schema); + + private: + virtual DB::Query::QueryMode GetChunkQuery::getExecutionMode() const; + + private: + GetChunkQuery(const GetChunkQuery&); // disable + GetChunkQuery& operator=(const GetChunkQuery&); //disable + + private: + DB::BindableLong object_count; + DB::BindableString<50> scene_id; + DB::BindableLong node_x; + DB::BindableLong node_z; + + std::string m_schema; + }; + +} + +// ---------------------------------------------------------------------- + +inline int DBQuery::GetChunkQuery::getObjectCount() const +{ + return object_count.getValue(); +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetContentsList.cpp b/engine/server/library/serverDatabase/src/shared/GetContentsList.cpp new file mode 100644 index 00000000..ee436d89 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetContentsList.cpp @@ -0,0 +1,72 @@ +// ====================================================================== +// +// GetContentsList.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetContentsList.h" + +#include "sharedFoundation/NetworkId.h" + +using namespace DBQuery; + +// ====================================================================== + +GetContentsList::GetContentsList() +{ +} + +// ---------------------------------------------------------------------- + +GetContentsList::~GetContentsList() +{ +} + +// ---------------------------------------------------------------------- + +void GetContentsList::setContainerId(const NetworkId &id) +{ + containerId=id; +} + +// ---------------------------------------------------------------------- + +NetworkId GetContentsList::getContainedId() const +{ + return containedId.getValue(); +} + +// ---------------------------------------------------------------------- + +bool GetContentsList::bindParameters() +{ + if (!bindParameter(containerId)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetContentsList::bindColumns() +{ + if (!bindCol(containedId)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +void GetContentsList::getSQL(std::string &sql) +{ + // return ("select object_id from objects where contained_by=? and deleted=0 and player_controlled='N'"); + sql="begin :result := loader.get_contents(:object_id); end;"; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetContentsList::getExecutionMode() const +{ + return (MODE_PLSQL_REFCURSOR); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetContentsList.h b/engine/server/library/serverDatabase/src/shared/GetContentsList.h new file mode 100644 index 00000000..2fd39835 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetContentsList.h @@ -0,0 +1,53 @@ +// ====================================================================== +// +// GetContentsList.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetContentsList_H +#define INCLUDED_GetContentsList_H + +// ====================================================================== + +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +class NetworkId; + +// ====================================================================== + +namespace DBQuery +{ + + class GetContentsList : public DB::Query + { + public: + GetContentsList(); + virtual ~GetContentsList(); + + public: + void setContainerId(const NetworkId &id); + NetworkId getContainedId() const; + + public: + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual void getSQL(std::string &sql); + + private: + virtual QueryMode getExecutionMode() const; + + private: + GetContentsList(const GetContentsList&); // disable + GetContentsList& operator=(const GetContentsList&); // disable + + private: + DB::BindableNetworkId containerId; + DB::BindableNetworkId containedId; + }; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.cpp new file mode 100644 index 00000000..3e204756 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.cpp @@ -0,0 +1,59 @@ +// ====================================================================== +// +// GetGoldVersionNumberQuery.cpp +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetGoldVersionNumberQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +using namespace DBQuery; + +// ---------------------------------------------------------------------- + +GetGoldVersionNumberQuery::GetGoldVersionNumberQuery() : + Query(), + current_version_number(), + min_version_number() +{ +} + +// ---------------------------------------------------------------------- + +void GetGoldVersionNumberQuery::getSQL(std::string &sql) +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + sql="select version_number from version_number;"; + else + sql=std::string("begin ")+DatabaseProcess::getInstance().getGoldSchemaQualifier() + "loader.get_version_number(:current_version_number, :min_version_number); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetGoldVersionNumberQuery::bindParameters() +{ + if (getProtocol()!=DB::PROTOCOL_ODBC) + { + if (!bindParameter(current_version_number)) return false; + if (!bindParameter(min_version_number)) return false; + } + return true; +} + +// ---------------------------------------------------------------------- + +bool GetGoldVersionNumberQuery::bindColumns() +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + { + if (!bindCol(current_version_number)) return false; + } + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h new file mode 100644 index 00000000..5e854cc0 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetGoldVersionNumberQuery.h @@ -0,0 +1,60 @@ +// ====================================================================== +// +// GetGoldVersionNumberQuery.h +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetGoldVersionNumberQuery_H +#define INCLUDED_GetGoldVersionNumberQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery +{ + + class GetGoldVersionNumberQuery : public DB::Query + { + public: + GetGoldVersionNumberQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + int getVersionNumber(); + int getMinVersionNumber(); + + private: + DB::BindableLong current_version_number; + DB::BindableLong min_version_number; + + private: + GetGoldVersionNumberQuery (const GetGoldVersionNumberQuery &); // disable + GetGoldVersionNumberQuery & operator= (const GetGoldVersionNumberQuery &); // disable + }; + +} + +// ====================================================================== + +inline int DBQuery::GetGoldVersionNumberQuery::getVersionNumber() +{ + return current_version_number.getValue(); +} + +// ---------------------------------------------------------------------- + +inline int DBQuery::GetGoldVersionNumberQuery::getMinVersionNumber() +{ + return min_version_number.getValue(); +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.cpp new file mode 100644 index 00000000..b935c583 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.cpp @@ -0,0 +1,58 @@ +// ====================================================================== +// +// GetOIDsQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetObjectIdsQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +using namespace DBQuery; + +// ---------------------------------------------------------------------- + +GetOIDsQuery::GetOIDsQuery() : + min_count(0) +{ +} + +// ---------------------------------------------------------------------- + +void GetOIDsQuery::getSQL(std::string &sql) +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + sql="select getOidBlock(?)"; + else + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "objectidmanager.get_ids(:desired_count, :start_id, :end_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetOIDsQuery::bindParameters() +{ + if (!bindParameter(min_count)) return false; + if (!bindParameter(start_id)) return false; + if (!bindParameter(end_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetOIDsQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetOIDsQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h new file mode 100644 index 00000000..5e8f70b3 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetObjectIdsQuery.h @@ -0,0 +1,86 @@ +// ====================================================================== +// +// GetOIDsQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetOIDsQuery_H +#define INCLUDED_GetOIDsQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery +{ + +/** + * A query to get a block of object ID's. + */ + class GetOIDsQuery : public DB::Query + { + public: + GetOIDsQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + void setHowMany(int howMany); + int getHowMany() const; + NetworkId getStartId() const; + NetworkId getEndId() const; + + protected: + virtual QueryMode getExecutionMode() const; + + private: + GetOIDsQuery(const GetOIDsQuery&); + GetOIDsQuery& operator=(const GetOIDsQuery&); + + DB::BindableLong min_count; + DB::BindableNetworkId start_id; + DB::BindableNetworkId end_id; + }; + +} + +// ---------------------------------------------------------------------- + +inline NetworkId DBQuery::GetOIDsQuery::getStartId() const +{ + FATAL(start_id.isNull(),("The database has run out of object ids.\n")); + return start_id.getValue(); +} + +// ---------------------------------------------------------------------- + +inline NetworkId DBQuery::GetOIDsQuery::getEndId() const +{ + if (end_id.isNull()) //TODO: remove when done with Postgres + return NetworkId(start_id.getValue().getValue() + min_count.getValue() - 1); // for Postgres, query doesn't return the end id, so we assume we got the number of id's we wanted. + return end_id.getValue(); +} + +// ---------------------------------------------------------------------- + +inline int DBQuery::GetOIDsQuery::getHowMany() const +{ + return min_count.getValue(); +} + +// ---------------------------------------------------------------------- + +inline void DBQuery::GetOIDsQuery::setHowMany(int howMany) +{ + min_count = howMany; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.cpp new file mode 100644 index 00000000..8e7afcbe --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.cpp @@ -0,0 +1,54 @@ +// ====================================================================== +// +// GetTimestampQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetTimestampQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +GetTimestampQuery::GetTimestampQuery() : + Query() +{ +} + +// ====================================================================== + +void GetTimestampQuery::getSQL(std::string &sql) +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + sql="select last_save_time from clock"; + else + sql=std::string("begin :result:=")+DatabaseProcess::getInstance().getSchemaQualifier()+"serverclock.get_last_save_time(); end;"; +} + +// ====================================================================== + +bool GetTimestampQuery::bindParameters() +{ + if (getProtocol()!=DB::PROTOCOL_ODBC) + { + if (!bindParameter(timestamp)) return false; + } + return true; +} + +// ====================================================================== + +bool GetTimestampQuery::bindColumns() +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + { + if (!bindCol(timestamp)) return false; + } + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h new file mode 100644 index 00000000..08563f61 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetTimestampQuery.h @@ -0,0 +1,51 @@ +// ====================================================================== +// +// GetTimestampQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetTimestampQuery_H +#define INCLUDED_GetTimestampQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery +{ + + class GetTimestampQuery : public DB::Query + { + public: + GetTimestampQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + int getTimestamp(); + + private: + DB::BindableLong timestamp; + + private: + GetTimestampQuery(const GetTimestampQuery &); // disable + GetTimestampQuery & operator=(const GetTimestampQuery &); //disable + }; + +} + +// ====================================================================== + +inline int DBQuery::GetTimestampQuery::getTimestamp() +{ + return timestamp.getValue(); +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.cpp new file mode 100644 index 00000000..7208824f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.cpp @@ -0,0 +1,44 @@ +// ====================================================================== +// +// GetUniverseQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetUniverseQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +GetUniverseQuery::GetUniverseQuery(const std::string &schema) : + Query(), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void GetUniverseQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + m_schema + "loader.locate_universe; end;"; +} + +// ---------------------------------------------------------------------- + +bool GetUniverseQuery::bindParameters() +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool GetUniverseQuery::bindColumns() +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.h b/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.h new file mode 100644 index 00000000..035c8b97 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetUniverseQuery.h @@ -0,0 +1,55 @@ +// ====================================================================== +// +// GetUniverseQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetUniverseQuery_H +#define INCLUDED_GetUniverseQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery { + + /** A query to get the list of universe objects. + */ + class GetUniverseQuery : public DB::Query + { + public: + NetworkId getObjectId(); + + public: + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + public: + GetUniverseQuery(const std::string &schema); + + private: + GetUniverseQuery(const GetUniverseQuery&); // disable + GetUniverseQuery& operator=(const GetUniverseQuery&); //disable + + private: + DB::BindableNetworkId object_id; + std::string m_schema; + }; + +// ---------------------------------------------------------------------- + + inline NetworkId GetUniverseQuery::getObjectId() + { + return object_id.getValue(); + } + +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.cpp b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.cpp new file mode 100644 index 00000000..a1936143 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.cpp @@ -0,0 +1,59 @@ +// ====================================================================== +// +// GetVersionNumberQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/GetVersionNumberQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +using namespace DBQuery; + +// ---------------------------------------------------------------------- + +GetVersionNumberQuery::GetVersionNumberQuery() : + Query(), + current_version_number(), + min_version_number() +{ +} + +// ---------------------------------------------------------------------- + +void GetVersionNumberQuery::getSQL(std::string &sql) +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + sql="select version_number from version_number;"; + else + sql=std::string("begin ")+DatabaseProcess::getInstance().getSchemaQualifier() + "loader.get_version_number(:current_version_number, :min_version_number); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetVersionNumberQuery::bindParameters() +{ + if (getProtocol()!=DB::PROTOCOL_ODBC) + { + if (!bindParameter(current_version_number)) return false; + if (!bindParameter(min_version_number)) return false; + } + return true; +} + +// ---------------------------------------------------------------------- + +bool GetVersionNumberQuery::bindColumns() +{ + if (getProtocol()==DB::PROTOCOL_ODBC) + { + if (!bindCol(current_version_number)) return false; + } + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h new file mode 100644 index 00000000..8871468f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/GetVersionNumberQuery.h @@ -0,0 +1,60 @@ +// ====================================================================== +// +// GetVersionNumberQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_GetVersionNumberQuery_H +#define INCLUDED_GetVersionNumberQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery +{ + + class GetVersionNumberQuery : public DB::Query + { + public: + GetVersionNumberQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + int getVersionNumber(); + int getMinVersionNumber(); + + private: + DB::BindableLong current_version_number; + DB::BindableLong min_version_number; + + private: + GetVersionNumberQuery (const GetVersionNumberQuery &); // disable + GetVersionNumberQuery & operator= (const GetVersionNumberQuery &); // disable + }; + +} + +// ====================================================================== + +inline int DBQuery::GetVersionNumberQuery::getVersionNumber() +{ + return current_version_number.getValue(); +} + +// ---------------------------------------------------------------------- + +inline int DBQuery::GetVersionNumberQuery::getMinVersionNumber() +{ + return min_version_number.getValue(); +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.cpp new file mode 100644 index 00000000..e1c3d149 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.cpp @@ -0,0 +1,62 @@ +// ====================================================================== +// +// ImmediateDeleteCustomPersistStep.cpp +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ImmediateDeleteCustomPersistStep.h" + +#include "serverDatabase/LazyDeleter.h" +#include + +// ====================================================================== + +ImmediateDeleteCustomPersistStep::ImmediateDeleteCustomPersistStep() : + m_objects(new std::set) +{ +} + +// ---------------------------------------------------------------------- + +ImmediateDeleteCustomPersistStep::~ImmediateDeleteCustomPersistStep() +{ + delete m_objects; + m_objects = NULL; +} + +// ---------------------------------------------------------------------- + +void ImmediateDeleteCustomPersistStep::addObject(const NetworkId &deletedObject) +{ + m_objects->insert(deletedObject); +} + +// ---------------------------------------------------------------------- + +/** + * After the object is flagged for deletion and the rest of the data from the snapshot has + * been saved, give the immediate delete objects to the LazyDeleter. + */ +void ImmediateDeleteCustomPersistStep::onComplete() +{ + for (std::set::const_iterator i=m_objects->begin(); i!=m_objects->end(); ++i) + LazyDeleter::getInstance().addObject(*i); +} + +// ---------------------------------------------------------------------- + +bool ImmediateDeleteCustomPersistStep::beforePersist(DB::Session *) +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool ImmediateDeleteCustomPersistStep::afterPersist(DB::Session *) +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.h new file mode 100644 index 00000000..1e5ecd5f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ImmediateDeleteCustomPersistStep.h @@ -0,0 +1,40 @@ +// ====================================================================== +// +// ImmediateDeleteCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ImmediateDeleteCustomPersistStep_H +#define INCLUDED_ImmediateDeleteCustomPersistStep_H + +// ====================================================================== + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +class ImmediateDeleteCustomPersistStep : public CustomPersistStep +{ + public: + ImmediateDeleteCustomPersistStep(); + ~ImmediateDeleteCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + void addObject (const NetworkId &deletedObject); + + private: + stdset::fwd *m_objects; // using set instead of vector to enforce uniqueness + + private: + ImmediateDeleteCustomPersistStep &operator= (const ImmediateDeleteCustomPersistStep&); //disable + ImmediateDeleteCustomPersistStep(const ImmediateDeleteCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.cpp b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.cpp new file mode 100644 index 00000000..9b1e90f2 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.cpp @@ -0,0 +1,92 @@ +// ====================================================================== +// +// LazyDeleteQuery.cpp +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/LazyDeleteQuery.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/ConfigServerDatabase.h" + +// ====================================================================== + +bool LazyDeleteQuery::setupData(DB::Session *session) +{ + return m_object_ids.create(session, "VAOFSTRING", DatabaseProcess::getInstance().getSchema(),1000); + +} + +// ---------------------------------------------------------------------- + +bool LazyDeleteQuery::addData(const NetworkId &object) +{ + if (!m_object_ids.push_back(object.getValueString())) + return false; + + m_numItems=m_numItems.getValue() + 1; + + return true; +} + +// ---------------------------------------------------------------------- + +int LazyDeleteQuery::getNumItems() const +{ + return m_numItems.getValue(); +} + +// ---------------------------------------------------------------------- + +void LazyDeleteQuery::clearData() +{ + m_object_ids.clear(); + m_numItems=0; + +} + +// ---------------------------------------------------------------------- + +void LazyDeleteQuery::freeData() +{ + m_object_ids.free(); +} + +// ---------------------------------------------------------------------- + +void LazyDeleteQuery::getSQL(std::string &sql) +{ + sql = std::string("begin ")+DatabaseProcess::getInstance().getSchemaQualifier()+"lazy_deleter.purge_objects_bulk(:object_id, :chunk_size, :enable_db_logging ); end;"; +} + +// ---------------------------------------------------------------------- + +bool LazyDeleteQuery::bindParameters() +{ + + if (!bindParameter(m_object_ids)) return false; + if (!bindParameter(m_numItems)) return false; + if (!bindParameter(m_enableDatabaseLogging)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +bool LazyDeleteQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +LazyDeleteQuery::LazyDeleteQuery() : + m_object_ids(), + m_numItems(0), + m_enableDatabaseLogging(ConfigServerDatabase::getEnableDatabaseErrorLogging()) +{ +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h new file mode 100644 index 00000000..65e40e63 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleteQuery.h @@ -0,0 +1,47 @@ +// ====================================================================== +// +// LazyDeleteQuery.h +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_LazyDeleteQuery_H +#define INCLUDED_LazyDeleteQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbBindableVarray.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +class LazyDeleteQuery : public DB::Query +{ + public: + LazyDeleteQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + bool setupData(DB::Session *session); + bool addData(const NetworkId &object); + void clearData(); + void freeData(); + + int getNumItems() const; + + private: + DB::BindableVarrayString m_object_ids; + DB::BindableLong m_numItems; + DB::BindableLong m_enableDatabaseLogging; + + private: + LazyDeleteQuery(const LazyDeleteQuery&); //disable + LazyDeleteQuery& operator=(const LazyDeleteQuery&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleter.cpp b/engine/server/library/serverDatabase/src/shared/LazyDeleter.cpp new file mode 100644 index 00000000..16baa713 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleter.cpp @@ -0,0 +1,230 @@ +// ====================================================================== +// +// LazyDeleter.cpp +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/LazyDeleter.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/LazyDeleteQuery.h" +#include "serverDatabase/Loader.h" +#include "serverDatabase/Persister.h" +#include "sharedDatabaseInterface/DbException.h" +#include "sharedDatabaseInterface/DbServer.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/Os.h" +#include "sharedSynchronization/Mutex.h" +#include "sharedThread/RunThread.h" +#include "sharedThread/Thread.h" +#include "sharedLog/Log.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include +#include + +// ====================================================================== + +LazyDeleter * LazyDeleter::ms_instance=NULL; + +// ====================================================================== + +/** + * Add an object to be purged from the database when time allows + * These objects are put on a separate queue then copied to m_objectsToDelete + * to avoid having to acquire and release the lock for each object + */ +void LazyDeleter::addObject(const NetworkId &objectId) +{ + m_incomingObjects->push_back(objectId); + ++m_totalObjectCount; +} + +// ---------------------------------------------------------------------- + +void LazyDeleter::update(float updateTime) +{ + UNREF(updateTime); + + if (!m_incomingObjects->empty()) + { + m_objectListLock->enter(); + + for (std::vector::iterator i=m_incomingObjects->begin(); i!=m_incomingObjects->end(); ++i) + m_objectsToDelete->push_back(*i); + m_incomingObjects->clear(); + + m_objectListLock->leave(); + } + + if (Persister::getInstance().isSaveInProgress() || Loader::getInstance().isBacklogged() || (Loader::getInstance().getNumPreloads() != 0)) + m_paused=true; + else + m_paused=false; +} + +// ---------------------------------------------------------------------- + +void LazyDeleter::install() +{ + DEBUG_FATAL(ms_instance,("LazyDeleter::install was called twice.")); + ExitChain::add(&remove,"LazyDeleter::remove"); + ms_instance = new LazyDeleter; +} + +// ---------------------------------------------------------------------- + +void LazyDeleter::remove() +{ + NOT_NULL(ms_instance); + delete ms_instance; + ms_instance = NULL; +} + +// ---------------------------------------------------------------------- + +LazyDeleter::LazyDeleter() : + m_workerThread(NULL), // Avoid starting the worker thread until the other member variables are initialized + m_incomingObjects(new std::vector), + m_objectsToDelete(new std::deque), + m_objectListLock(new Mutex), + m_shutdown(false), + m_paused(false), + m_batchSize(10), + m_session(DatabaseProcess::getInstance().getDBServer()->getSession()), + m_totalObjectCount(0) +{ + m_workerThread = new MemberFunctionThreadZero("LazyDeleter", *this, &LazyDeleter::workerThreadLoop); + ThreadHandle tempThreadHandle(m_workerThread); // for some obscure reason, the thread doesn't run unless you create a handle, but we don't need the handle for anything + UNREF(tempThreadHandle); +} + +// ---------------------------------------------------------------------- + +LazyDeleter::~LazyDeleter() +{ + m_shutdown = true; + m_workerThread->wait(); + DatabaseProcess::getInstance().getDBServer()->releaseSession(m_session); + + delete m_incomingObjects; + delete m_objectsToDelete; + delete m_objectListLock; + + m_workerThread = NULL; + m_incomingObjects = NULL; + m_objectsToDelete = NULL; + m_objectListLock = NULL; + m_session = NULL; +} + +// ---------------------------------------------------------------------- + +void LazyDeleter::workerThreadLoop() +{ + bool done = false; + int size = 0; + bool succeeded; + + while (!done) + { + if ((!m_paused) || m_shutdown) + { + m_objectListLock->enter(); + + size = m_objectsToDelete->size(); + + if (size!=0) + { + LazyDeleteQuery qry; + std::vector batch; + + for (int c=0; !m_objectsToDelete->empty() && c < m_batchSize; ++c) + { + NetworkId &object = m_objectsToDelete->front(); + batch.push_back(object); + m_objectsToDelete->pop_front(); + } + + m_objectListLock->leave(); + + succeeded = true; + if (!qry.setupData(m_session)) + succeeded = false; + else + { + for (std::vector::iterator i=batch.begin(); i!=batch.end(); ++i) + { + if (!qry.addData(*i)) + { + succeeded = false; + break; + } + if (qry.getNumItems() == ConfigServerDatabase::getDefaultLazyDeleteBulkBindSize()) + { + if (! (m_session->exec(&qry))) + { + succeeded = false; + break; + } + qry.clearData(); + qry.done(); + m_session->commitTransaction(); + } + } + } + + if (succeeded && (qry.getNumItems() != 0)) + succeeded = m_session->exec(&qry); + qry.done(); + qry.freeData(); + if (succeeded) + m_session->commitTransaction(); + else + { + m_session->rollbackTransaction(); + m_session->disconnect(); + while (! (m_session->connect())) + { + m_session->disconnect(); + Os::sleep(DB::Server::getDisconnectSleepTime()); + }; + LOG("DatabaseError", ("Database connection reestablished")); + m_objectListLock->enter(); + m_objectsToDelete->insert(m_objectsToDelete->begin(),batch.begin(),batch.end()); // retry this batch + m_objectListLock->leave(); + } + } + else + { + m_objectListLock->leave(); + if (m_shutdown) + done = true; + } + } + if (!m_shutdown) + { + if ( size > (ConfigServerDatabase::getDefaultLazyDeleteBulkBindSize())) + Os::sleep(ConfigServerDatabase::getDefaultLazyDeleteSleepTime()); // just multi-batch bulk delete so wait a bit to start again + else + Os::sleep(10); + + } + } +} + +// ---------------------------------------------------------------------- + +size_t LazyDeleter::getQueueSize() const +{ + size_t result; + m_objectListLock->enter(); + result = m_objectsToDelete->size(); + m_objectListLock->leave(); + + return result; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/LazyDeleter.h b/engine/server/library/serverDatabase/src/shared/LazyDeleter.h new file mode 100644 index 00000000..e93816ec --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LazyDeleter.h @@ -0,0 +1,83 @@ +// ====================================================================== +// +// LazyDeleter.h +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_LazyDeleter_H +#define INCLUDED_LazyDeleter_H + +// ====================================================================== + +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +namespace DB +{ + class Session; +} + +class Thread; +class Mutex; + +// ====================================================================== + +/** + * Singleton that purges deleted objects from the database. + */ +class LazyDeleter +{ + public: + static LazyDeleter &getInstance(); + static void install(); + + void addObject(const NetworkId &objectId); + void update(float updateTime); + size_t getQueueSize() const; + int getTotalObjectCount() const; + + private: + void workerThreadLoop(); + + private: + static void remove(); + LazyDeleter(); + ~LazyDeleter(); + + private: + LazyDeleter(LazyDeleter&); //disable + LazyDeleter &operator=(const LazyDeleter&); //disable + + private: + static LazyDeleter *ms_instance; + Thread *m_workerThread; + stdvector::fwd *m_incomingObjects; + stddeque::fwd *m_objectsToDelete; + Mutex *m_objectListLock; + bool m_shutdown; + bool m_paused; + int m_batchSize; + DB::Session *m_session; + int m_totalObjectCount; +}; + +// ---------------------------------------------------------------------- + +inline LazyDeleter &LazyDeleter::getInstance() +{ + NOT_NULL(ms_instance); + return *ms_instance; +} + +// ---------------------------------------------------------------------- + +inline int LazyDeleter::getTotalObjectCount() const +{ + return m_totalObjectCount; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/Loader.cpp b/engine/server/library/serverDatabase/src/shared/Loader.cpp new file mode 100644 index 00000000..a03476e9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Loader.cpp @@ -0,0 +1,971 @@ +// ====================================================================== +// +// Loader.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/Loader.h" + +#include "UnicodeUtils.h" +#include "serverDatabase/CharacterLocator.h" +#include "serverDatabase/CharacterNameLocator.h" +#include "serverDatabase/ChunkLocator.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/ContainedObjectLocator.h" +#include "serverDatabase/ContentsLocator.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/LoaderSnapshotGroup.h" +#include "serverDatabase/TaskCheckGoldVersionNumber.h" +#include "serverDatabase/TaskCheckVersionNumber.h" +#include "serverDatabase/TaskCSTasks.h" +#include "serverDatabase/TaskGetObjectIds.h" +#include "serverDatabase/TaskGetStructures.h" +#include "serverDatabase/TaskLoadClock.h" +#include "serverDatabase/TaskLoadSnapshots.h" +#include "serverDatabase/UniverseLocator.h" +#include "serverNetworkMessages/CentralGameServerMessages.h" +#include "serverNetworkMessages/ChunkObjectListMessage.h" +#include "serverNetworkMessages/CSDBNetMessages.h" +#include "serverNetworkMessages/LoadContainedObjectMessage.h" +#include "serverNetworkMessages/LoadContentsMessage.h" +#include "serverNetworkMessages/LoadObjectMessage.h" +#include "serverNetworkMessages/LoadUniverseMessage.h" +#include "serverNetworkMessages/LocateStructureMessage.h" +#include "serverNetworkMessages/PlanetLoadCharacterMessage.h" +#include "serverNetworkMessages/PreloadRequestCompleteMessage.h" +#include "serverNetworkMessages/ReleaseAuthoritativeMessage.h" +#include "serverNetworkMessages/RequestChunkMessage.h" +#include "serverNetworkMessages/RequestObjectIdsMessage.h" +#include "serverNetworkMessages/TransferCharacterData.h" +#include "serverNetworkMessages/TransferCharacterDataArchive.h" +#include "serverNetworkMessages/ValidateCharacterForLoginMessage.h" +#include "serverUtility/ServerClock.h" +#include "sharedDatabaseInterface/DbTaskQueue.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "unicodeArchive/UnicodeArchive.h" + +// ====================================================================== + +Loader *Loader::ms_instance = NULL; + +// ====================================================================== + +void Loader::installDerived(Loader *derivedInstance) +{ + DEBUG_FATAL(ms_instance,("Installed loader twice.\n")); + ms_instance = derivedInstance; + ExitChain::add(&remove, "Loader::remove"); +} + +// ---------------------------------------------------------------------- + +void Loader::remove() +{ + NOT_NULL(ms_instance); + delete ms_instance; + ms_instance = NULL; +} + +// ---------------------------------------------------------------------- + +Loader::Loader() : + MessageDispatch::Receiver(), + outgoingQueue(), + m_serverDiscardList(), + m_loadLock(), + m_multipleLoginLock(), + m_characterLoadCount(), + m_chunkLoadCount(), + m_nextLoadStartTime(), + m_backlogged(false), + m_currentTime(0), + m_locatorList(), + m_loadSerialNumber(0), + m_unackedLoads(), + m_unackedLoadsTime(), + m_numQueuedLocators(0), + taskQ(new DB::TaskQueue(static_cast(ConfigServerDatabase::getLoaderThreads()),DatabaseProcess::getInstance().getDBServer(),0)) +{ + connectToMessage("LoadAckMessage"); + connectToMessage("LoadContainedObjectMessage"); + connectToMessage("LoadContentsMessage"); + connectToMessage("LoadObjectMessage"); + connectToMessage("LoadUniverseMessage"); + connectToMessage("LocateStructureMessage"); + connectToMessage("PlanetLoadCharacterMessage"); + connectToMessage("PreloadRequestCompleteMessage"); + connectToMessage("RequestChunkMessage"); + connectToMessage("RequestOIDsMessage"); + connectToMessage("TransferGetLoginLocationData"); + connectToMessage("ValidateCharacterForLoginMessage"); + connectToMessage("CSGetCharactersRequestMessage"); + connectToMessage("CSGetDeletedItemsRequestMessage"); + connectToMessage("DBCSRequestMessage"); +} + +//----------------------------------------------------------------------- + +Loader::~Loader() +{ + DEBUG_FATAL(taskQ,("Call shutdown() before deleting the Loader singleton.\n")); +} + +// ---------------------------------------------------------------------- + +void Loader::update(real updateTime) +{ + static float reportTime = 0; + + m_currentTime += updateTime; + + //TODO The outgoing queue isn't very efficient, since we check the + // whole thing every loop. Maybe make something better if going + // through this queue turns out to be a big time waster. + { + PROFILER_AUTO_BLOCK_DEFINE("Outgoing Queue"); + for (OutgoingQueueType::iterator i=outgoingQueue.begin(); i!=outgoingQueue.end(); ++i) + { + if ((*i)->send()) + { + DEBUG_REPORT_LOG(true,("Queued snapshot was sent.\n")); + delete *i; + i=outgoingQueue.erase(i); + } + else + { + if (m_serverDiscardList.find((*i)->getRequestingProcessId())!=m_serverDiscardList.end()) + { + DEBUG_REPORT_LOG(true,("Discarding queued snapshot because server has disconnected.\n")); + delete *i; + i=outgoingQueue.erase(i); + } + } + } + } + + startLoad(); + + { + PROFILER_AUTO_BLOCK_DEFINE("Task Queue Update"); + taskQ->update(ConfigServerDatabase::getDefaultQueueUpdateTimeLimit()); + if (taskQ->getNumFinishedTasks() > ConfigServerDatabase::getMaxLoaderFinishedTasks()) + taskQ->pause(); + else + taskQ->unpause(); + } + + reportTime+=updateTime; + if (reportTime > 5) + { + reportTime=0; + + if ((m_numQueuedLocators != 0) || (!m_unackedLoadsTime.empty()) || (taskQ->getNumPendingTasks() != 0) || (taskQ->getNumActiveTasks() != 0) || (taskQ->getNumFinishedTasks() != 0)) + { + if (m_unackedLoadsTime.empty()) + { + LOG("LoadTimes",("Load queue status: %i queued locators, 0 unacked loads, %i pending tasks, %i active threads, %i completed tasks", m_numQueuedLocators, taskQ->getNumPendingTasks(), taskQ->getNumActiveTasks(), taskQ->getNumFinishedTasks())); + } + else + { + UnackedLoadsTimeType::const_iterator i = m_unackedLoadsTime.begin(); + + LOG("LoadTimes",("Load queue status: %i queued locators, %i unacked loads (oldest is %i/%is), %i pending tasks, %i active threads, %i completed tasks", m_numQueuedLocators, m_unackedLoadsTime.size(), i->second.first, (time(0) - i->first), taskQ->getNumPendingTasks(), taskQ->getNumActiveTasks(), taskQ->getNumFinishedTasks())); + } + } + + bool updateNeeded = false; + int loadQueueSize=taskQ->getNumPendingTasks(); + if (!m_backlogged) + { + if (loadQueueSize >= ConfigServerDatabase::getBackloggedQueueSize()) + { + m_backlogged = true; + updateNeeded = true; + } + } + else + { + if (loadQueueSize <= ConfigServerDatabase::getBackloggedRecoveryQueueSize()) + { + m_backlogged = false; + updateNeeded = true; + } + } + + if (updateNeeded) + { + GenericValueTypeMessage backlogMessage("DatabaseBackloggedMessage",m_backlogged); + DatabaseProcess::getInstance().sendToCentralServer(backlogMessage,true); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Start asychronous loads if there is no backlog of load requests, or + * if any of the early-start conditions have been met. + */ +void Loader::startLoad() +{ + PROFILER_AUTO_BLOCK_DEFINE("Loader::startLoad"); + + if (static_cast(m_unackedLoadsTime.size()) >= ConfigServerDatabase::getMaxUnackedLoadCount()) + return; + + for (LocatorListType::iterator i=m_locatorList.begin(); i!=m_locatorList.end(); ) + { + if (getUnackedLoadCount(i->first) == 0) + { + LocatorListType::iterator next=i; // startLoadForServer() may erase the element we're looking at + ++next; + startLoadForServer(i->first); + i=next; + } + else + ++i; + + if (static_cast(m_unackedLoadsTime.size()) >= ConfigServerDatabase::getMaxUnackedLoadCount()) + return; + } + + if (static_cast(m_unackedLoadsTime.size()) >= ConfigServerDatabase::getMaxUnackedLoadCount()) + return; + + // if task queue isn't busy, start additional loads for servers that + // still have unacked pending loads; pick servers in round-robin + // fashion, but don't pick servers that have too many unacked pending loads + if (ConfigServerDatabase::getMaxUnackedLoadCountPerServer() <= 1) + return; + + int numberOfIterationsWithoutMatch = 0; + while (!m_unackedLoads.empty() && !m_locatorList.empty() && taskQ->getNumPendingTasks()first; + + if ((static_cast(i->second.size()) < ConfigServerDatabase::getMaxUnackedLoadCountPerServer()) && (m_locatorList.find(lastEarlyServer) != m_locatorList.end())) + { + numberOfIterationsWithoutMatch = 0; + LOG("LoadTimes",("Early load (server %lu unacked loads=%i, all server unacked loads=%i)", lastEarlyServer, i->second.size(), m_unackedLoadsTime.size())); + startLoadForServer(lastEarlyServer); + + if (static_cast(m_unackedLoadsTime.size()) >= ConfigServerDatabase::getMaxUnackedLoadCount()) + return; + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Queue up a batch of loads for the specified server. Include as many + * locators as possible, up to the limits specified in the config file. + */ +void Loader::startLoadForServer(uint32 serverId) +{ + std::list > *locators = m_locatorList[serverId]; + DEBUG_FATAL(!locators,("Programmer bug: called startLoadForServer(%lu), but the server had no pending ObjectLocators",serverId)); + if (locators) + { + if (!locators->empty()) + { + // if server has been disconnected, toss out all pending load request for the server + if (m_serverDiscardList.find(serverId) != m_serverDiscardList.end()) + { + int discardCount = 0; + while (!locators->empty()) + { + delete locators->front().first; + delete locators->front().second; + + locators->pop_front(); + --m_numQueuedLocators; + ++discardCount; + } + + LOG("LoadTimes",("Discarding %d pending load request for disconnected server %lu", discardCount, serverId)); + } + else + { + int chunkCount = 0; + int characterCount = 0; + LoaderSnapshotGroup * snapshot = makeLoaderSnapshotGroup(serverId); + while (!locators->empty() && chunkCount < ConfigServerDatabase::getMaxChunksPerLoadRequest() && characterCount < ConfigServerDatabase::getMaxCharactersPerLoadRequest()) + { + ObjectLocator * const regularLocator = NON_NULL(locators->front().first); + ObjectLocator * const goldLocator = locators->front().second; + if (dynamic_cast(regularLocator)) + chunkCount++; + if (dynamic_cast(regularLocator)) + chunkCount++; + snapshot->addLocator(regularLocator); + if (goldLocator) + snapshot->addGoldLocator(goldLocator); + + locators->pop_front(); + --m_numQueuedLocators; + } + + snapshot->setLoadSerialNumber(++m_loadSerialNumber); + m_unackedLoads[serverId].push_back(m_loadSerialNumber); + IGNORE_RETURN(m_unackedLoadsTime.insert(std::make_pair(time(0), std::make_pair(serverId, m_loadSerialNumber)))); + + TaskLoadSnapshots *task=new TaskLoadSnapshots(snapshot); + taskQ->asyncRequest(task); + } + } + + if (locators->empty()) + { + delete locators; + IGNORE_RETURN(m_locatorList.erase(serverId)); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Enqueue all the universe objects to be loaded. + * This particular load is started right away, instead of being + * queued in m_locatorsList (due to the setUniverseAuthHack() call) + */ +void Loader::loadUniverse(uint32 processId) +{ + LoaderSnapshotGroup * snapshot = makeLoaderSnapshotGroup(processId); + snapshot->addLocator(new CharacterNameLocator); + snapshot->addLocator(new UniverseLocator); + snapshot->setUniverseAuthHack(); + + TaskLoadSnapshots *task=new TaskLoadSnapshots(snapshot); + taskQ->asyncRequest(task); +} + +// ---------------------------------------------------------------------- + +/** + * Called when a snapshot has been successfully loaded. + * + * Will send the snapshot to whichever server requested the object(s) it + * contains. + * @param snapshot The new snapshot. The Loader takes ownership of the snapshot, + * the caller does not need to delete it. + * @see TaskLoadObjects + */ +void Loader::snapshotLoaded(LoaderSnapshotGroup *snapshot) +{ + PROFILER_AUTO_BLOCK_DEFINE("Loader::snapshotLoaded"); + + if (snapshot->send()) + { + PROFILER_AUTO_BLOCK_DEFINE("delete snapshot"); + delete snapshot; + } + else + { + if (m_serverDiscardList.find(snapshot->getRequestingProcessId())!=m_serverDiscardList.end()) + { + DEBUG_REPORT_LOG(true,("Discarding pending snapshot because server has disconnected.\n")); + delete snapshot; + } + else + { + DEBUG_REPORT_LOG(true,("Snapshot could not be sent, queueing for later.\n")); + queueOutgoingSnapshot(snapshot); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Save a Snapshot that couldn't be sent because there's no connection to the server. + * + * The Loader will attempt to send the Snapshot again later. + * + */ + +void Loader::queueOutgoingSnapshot(LoaderSnapshotGroup *outgoingSnapshot) +{ + outgoingQueue.push_back(outgoingSnapshot); +} + +// ---------------------------------------------------------------------- + +void Loader::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) +{ + UNREF(source); + if(message.isType("LoadObjectMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadObjectMessage lom(ri); + DEBUG_FATAL(true,("LoadObjectMessage is deprecated on the database process.\n")); +// requestObject(lom.getId(),lom.getProcess()); + } + else if(message.isType("RequestChunkMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RequestChunkMessage m(ri); + + std::vector const & chunks = m.getChunks(); + for (std::vector::const_iterator i=chunks.begin(); i!=chunks.end(); ++i) + requestChunk(i->m_process, i->m_nodeX, i->m_nodeZ, m.getSceneId()); + } + else if(message.isType("RequestOIDsMessage")) + { +// DEBUG_REPORT_LOG(true,("Got RequestOIDsMessage.\n")); + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RequestOIDsMessage m(ri); + + if (m.getLogRequest()) + LOG("ObjectIdManager", ("Received RequestOIDsMessage for %lu more object ids for pid %lu", m.getHowMany(), m.getServerId())); + + getObjectIds(static_cast(m.getServerId()),static_cast(m.getHowMany()), m.getLogRequest()); + } + else if(message.isType("ValidateCharacterForLoginMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ValidateCharacterForLoginMessage msg(ri); + verifyCharacter(msg.getSuid(), msg.getCharacterId(), NULL); + } + else if(message.isType("TransferGetLoginLocationData")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage request(ri); + TransferCharacterData * transferData = new TransferCharacterData(request.getValue()); + verifyCharacter(transferData->getSourceStationId(), transferData->getCharacterId(), transferData); + }//lint !e429 not freed : suppressed because verifyCharacter will own this copy of the data + else if(message.isType("LoadUniverseMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadUniverseMessage m(ri); + DEBUG_REPORT_LOG(true,("Got LoadUniverseMessage\n")); + loadUniverse(m.getProcess()); + } + else if(message.isType("PlanetLoadCharacterMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + PlanetLoadCharacterMessage m(ri); + DEBUG_REPORT_LOG(true,("Got PlanetLoadCharacterMessage\n")); + requestCharacter(m.getCharacterId(), m.getGameServerId()); + } + else if(message.isType("LoadContainedObjectMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadContainedObjectMessage msg(ri); + + const GameServerConnection * g = dynamic_cast(&source); + if (g) + loadContainedObject(msg.getContainerId(), msg.getObjectId(), g->getProcessId()); + else + WARNING_STRICT_FATAL(true,("Got LoadContainedObjectMessage for %s, but sender was not a GameServerConnection.\n",msg.getObjectId().getValueString().c_str())); + } + else if(message.isType("LoadContentsMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LoadContentsMessage msg(ri); + + const GameServerConnection * g = dynamic_cast(&source); + if (g) + loadContents(msg.getContainerId(), g->getProcessId()); + else + WARNING_STRICT_FATAL(true,("Got LoadContentsMessage for container %s, but sender was not a GameServerConnection.\n",msg.getContainerId().getValueString().c_str())); + } + else if(message.isType("LocateStructureMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + LocateStructureMessage msg(ri); + + const GameServerConnection * g = dynamic_cast(&source); + if (g) + locateStructure(msg.getStructureId(), msg.getWhoRequested()); + else + WARNING_STRICT_FATAL(true,("Got LocateStructureMessage for %s, but sender was not a GameServerConnection.\n",msg.getStructureId().getValueString().c_str())); + } + else if(message.isType("PreloadRequestCompleteMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + PreloadRequestCompleteMessage msg(ri); + + preloadRequestComplete(msg.getGameServerId(), msg.getPreloadAreaId()); + } + else if(message.isType("LoadAckMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + const GameServerConnection * g = dynamic_cast(&source); + if (g) + handleLoadAck(g->getProcessId(), msg.getValue()); + else + WARNING_STRICT_FATAL(true,("Got LoadAckMessage, but sender was not a GameServerConnection.")); + } + else if( message.isType("CSGetCharactersRequestMessage") ) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + CSGetCharactersRequestMessage const msg( ri ); + handleCSGetCharacters( msg ); + } + else if( message.isType("CSGetDeletedItemsRequestMessage") ) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + CSGetDeletedItemsRequestMessage const msg( ri ); + handleCSGetDeletedItems( msg ); + + } + else if( message.isType("DBCSRequestMessage" ) ) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + DBCSRequestMessage const msg( ri ); + handleCSRequest( msg ); + } +} + +void Loader::handleCSRequest( const DBCSRequestMessage & msg ) +{ + DEBUG_REPORT_LOG( true, ( "Message:%s\n", msg.getCommand().c_str() ) ); + if( msg.getCommand() == "get_characters" ) + { + handleCSGetCharacters( msg ); + } + else if( msg.getCommand() == "get_deleted_items" ) + { + handleCSGetDeletedItems( msg ); + } + else if( msg.getCommand() == "list_structures" ) + { + handleCSGetStructures( msg ); + } + else if( msg.getCommand() == "get_player_id" ) + { + handleCSGetPlayerId( msg ); + } +} +// ---------------------------------------------------------------------- + +/** + * Called to request that the Loader obtain more object ID's and send + * them to the identified process. + */ +void Loader::getObjectIds(int processId, int numWanted, bool logRequest) +{ + TaskGetObjectIds *tgo=new TaskGetObjectIds(processId, numWanted, logRequest); + taskQ->asyncRequest(tgo); +} + +// ---------------------------------------------------------------------- + +void Loader::loadClock() +{ + taskQ->asyncRequest(new TaskLoadClock); +} + +// ---------------------------------------------------------------------- + +/** + * After the clock has been loaded, do any additional tasks needed + */ +void Loader::loadClockCompleted() +{ + DEBUG_FATAL(!ServerClock::getInstance().isSet(),("Clock was not set.\n")); + loadStartupData(); +} + +// ---------------------------------------------------------------------- + +/** + * After all initial data is loaded, tell Central we are ready. + */ +void Loader::startupLoadCompleted() const +{ + CentralGameServerDbProcessServerProcessId m(DatabaseProcess::getInstance().getProcessId(), ServerClock::getInstance().getSubtractInterval()); + DatabaseProcess::getInstance().sendToCentralServer(m,true); +} + +// ---------------------------------------------------------------------- + +/** + * @todo We'll need to add a map of game server -> load request at some point. + * when we do, revisit this function. The list of crashed game servers + * can grow without bounds right now, because we can't tell when we're + * all done loading data for a server. + */ +void Loader::discardPendingLoadsForServer(uint32 processId) +{ + IGNORE_RETURN(m_serverDiscardList.insert(processId)); + IGNORE_RETURN(m_preloadingProcesses.erase(processId)); + + for (UnackedLoadsTimeType::iterator iter = m_unackedLoadsTime.begin(); iter != m_unackedLoadsTime.end();) + { + if (iter->second.first == processId) + m_unackedLoadsTime.erase(iter++); + else + ++iter; + } + + UnackedLoadsType::iterator iterFind = m_unackedLoads.find(processId); + + if (iterFind != m_unackedLoads.end()) + m_unackedLoads.erase(iterFind); +} + +// ---------------------------------------------------------------------- + +/** + * Check that the database version number matches what this compile of the + * code needs. + */ +void Loader::checkVersionNumber(int expectedVersion, bool fatalOnMismatch) +{ + taskQ->asyncRequest(new TaskCheckVersionNumber(expectedVersion, fatalOnMismatch)); + + if (ConfigServerDatabase::getEnableGoldDatabase()) + { + DEBUG_REPORT_LOG(true,("Checking GOLD database version.\n")); + + taskQ->asyncRequest(new TaskCheckGoldVersionNumber(expectedVersion, fatalOnMismatch)); + } +} + +// ---------------------------------------------------------------------- + +void Loader::requestChunk(uint32 processId,int nodeX, int nodeZ, const std::string &sceneId) +{ + ObjectLocator * const regularLocator=new ChunkLocator(nodeX, nodeZ, sceneId, processId, true); + ObjectLocator * goldLocator=NULL; + if (ConfigServerDatabase::getEnableGoldDatabase()) + goldLocator = new ChunkLocator(nodeX, nodeZ, sceneId, processId, false); + addLocatorsForServer(processId, regularLocator, goldLocator); +} + +// ---------------------------------------------------------------------- + +void Loader::requestCharacter(const NetworkId &characterId, uint32 gameServerId) +{ + if (ConfigServerDatabase::getEnableLoadLocks()) + { + LoadLockType::iterator i=m_loadLock.find(characterId); + if (i!=m_loadLock.end()) + { + DEBUG_REPORT_LOG(true,("Delaying login for character %s because there is remaining data to be saved\n",characterId.getValueString().c_str())); + DEBUG_REPORT_LOG(i->second!=0,("Character %s already had a pending login request -- replacing it with the new request.\n",characterId.getValueString().c_str())); + i->second=gameServerId; + } + else + { + i=m_multipleLoginLock.find(characterId); + if (i==m_multipleLoginLock.end()) + { + addLocatorsForServer(gameServerId, new CharacterLocator(characterId), NULL); + + DEBUG_REPORT_LOG(true,("Adding multipleLoginLock for %s\n",characterId.getValueString().c_str())); + m_multipleLoginLock[characterId] = gameServerId; + } + else + { + LOG("TRACE_LOGIN",("Ignoring duplicate request to load character %s",characterId.getValueString().c_str())); + DEBUG_REPORT_LOG(true,("Ignoring duplicate request to load character %s\n",characterId.getValueString().c_str())); + } + } + } + else + addLocatorsForServer(gameServerId, new CharacterLocator(characterId), NULL); +} + +// ---------------------------------------------------------------------- + +void Loader::loadContainedObject(const NetworkId &containerId, const NetworkId &objectId, uint32 gameServerId) +{ + LOG("AuctionRetrieval", ("Loader::received loadContainedObject for loading object %s for retrieval", objectId.getValueString().c_str())); + addLocatorsForServer(gameServerId, new ContainedObjectLocator(containerId,objectId), NULL); +} + + +// ---------------------------------------------------------------------- + +void Loader::loadContents(const NetworkId &containerId, uint32 gameServerId) +{ + addLocatorsForServer(gameServerId, new ContentsLocator(containerId), NULL); +} + +// ---------------------------------------------------------------------- + +void Loader::shutdown() +{ + NOT_NULL(taskQ); + taskQ->cancel(); + delete taskQ; + taskQ = 0; +} + +// ---------------------------------------------------------------------- + +void Loader::preloadRequestComplete(uint32 processId, uint32 preloadAreaId) +{ + LOG("Preload",("Received all preload requests for server %lu",processId)); + if (getUnackedLoadCount(processId) > 0 || m_locatorList.find(processId)!=m_locatorList.end()) + { + if (m_serverDiscardList.find(processId) == m_serverDiscardList.end()) + m_preloadingProcesses.insert(std::make_pair(processId,preloadAreaId)); + else + IGNORE_RETURN(m_preloadingProcesses.erase(processId)); + } + else + { + LOG("Preload",("Done sending preload objects to server %lu.",processId)); + PreloadRequestCompleteMessage msg(processId, preloadAreaId); + DatabaseProcess::getInstance().sendToGameServer(processId, msg); + } +} + +// ---------------------------------------------------------------------- + +void Loader::addLoadLock(const NetworkId &characterId) +{ + m_loadLock[characterId]=0; +} + +void Loader::handleCSGetPlayerId( const DBCSRequestMessage & msg ) +{ + std::string charNameString; + std::string::size_type pos = msg.getCommandLine().find( ' ' ); + if( pos == std::string::npos ) + return; + + charNameString = msg.getCommandLine().substr( pos + 1 ); + TaskGetCharacterId * task = new TaskGetCharacterId( charNameString, msg.getLoginServerId(), msg.getToolId() ); + taskQ->asyncRequest( task ); + +} + +void Loader::handleCSGetStructures( const DBCSRequestMessage & msg ) +{ + std::string charIdString; + std::string::size_type pos = msg.getCommandLine().find( ' ' ); + if( pos == std::string::npos ) + return; // bad parameters. + charIdString = msg.getCommandLine().substr( pos + 1 ); + NetworkId characterId( charIdString ); + if( characterId.isValid() ) + { + TaskGetStructures * req = new TaskGetStructures( characterId, msg.getToolId(), msg.getLoginServerId() ); + taskQ->asyncRequest( req ); + } + +} + +void Loader::handleCSGetCharacters( const DBCSRequestMessage & msg ) +{ + uint32 account_id = 0; + sscanf( msg.getCommandLine().c_str(), "get_characters %lu", &account_id ); + TaskGetCharactersForAccount * req = new TaskGetCharactersForAccount( account_id, msg.getLoginServerId(), msg.getToolId() ); + taskQ->asyncRequest( req ); + +} + +void Loader::handleCSGetCharacters( const CSGetCharactersRequestMessage & msg ) +{ + TaskGetCharactersForAccount * req = new TaskGetCharactersForAccount( msg.getTargetAccountId(), msg.getLoginServerId(), msg.getToolId() ); + taskQ->asyncRequest( req ); + +} + +void Loader::handleCSGetDeletedItems( const DBCSRequestMessage & msg ) +{ + + uint32 page_num; + char buf [21]; + + if (sscanf (msg.getCommandLine().c_str(), "get_deleted_items %20s %lu", buf, &page_num) == 2) + { + NetworkId netId(buf); + if(!netId.isValid()) + return; + TaskGetDeletedItems *req = new TaskGetDeletedItems(netId, msg.getLoginServerId(), msg.getToolId(), page_num); + taskQ->asyncRequest( req ); + } +} + +void Loader::handleCSGetDeletedItems( const CSGetDeletedItemsRequestMessage & msg ) +{ + UNREF(msg); +// TaskGetDeletedItems * req = new TaskGetDeletedItems( msg.getTargetAccountId(), msg.getLoginServerId(), msg.getToolId() ); +// taskQ->asyncRequest( req ); +} +// ---------------------------------------------------------------------- + +void Loader::removeLoadLock(const NetworkId &characterId) +{ + LoadLockType::iterator i=m_loadLock.find(characterId); + if (i==m_loadLock.end()) + { + DEBUG_REPORT_LOG(true,("Tried to remove the load lock for character %s, but it wasn't locked. Probably indicates the player logged out twice within the same save cycle.\n",characterId.getValueString().c_str())); + return; + } + if (i->second!=0) + { + DEBUG_REPORT_LOG(true,("Now handling delayed login request for character %s\n",characterId.getValueString().c_str())); + addLocatorsForServer(i->second, new CharacterLocator(characterId), NULL); + } + + m_loadLock.erase(i); +} + +// ---------------------------------------------------------------------- + +bool Loader::isIdle() +{ + bool result = false; + if(taskQ) + result = (m_locatorList.empty() && taskQ->isIdle()); + return result; +} + +// ---------------------------------------------------------------------- + +/** + * Estimate the number of tasks waiting for the load queue. This is the + * number of actual tasks scheduled plus an estimate of how many tasks + * the queued locators will produce. + */ +int Loader::getLoadQueueTasksEstimate() const +{ + int result = 0; + if(taskQ) + result = (taskQ->getNumPendingTasks() + taskQ->getNumActiveTasks()) + m_numQueuedLocators/ConfigServerDatabase::getMaxChunksPerLoadRequest(); + return result; +} + +// ---------------------------------------------------------------------- + +void Loader::onCharacterLocatorDeleted(const NetworkId &characterId) +{ + DEBUG_REPORT_LOG(true,("Removing multipleLoginLock for %s\n",characterId.getValueString().c_str())); + IGNORE_RETURN(m_multipleLoginLock.erase(characterId)); +} + +// ---------------------------------------------------------------------- + +unsigned int Loader::getUnackedLoadCount(uint32 serverId) const +{ + UnackedLoadsType::const_iterator iterFind = m_unackedLoads.find(serverId); + + if (iterFind == m_unackedLoads.end()) + return 0; + + return iterFind->second.size(); +} + +// ---------------------------------------------------------------------- + +/** + * The game server has acknowledged a batch of objects we sent. Remove the + * record of the unacknowledged load. + */ +void Loader::handleLoadAck(uint32 serverId, int serialNumber) +{ + for (UnackedLoadsTimeType::iterator iter = m_unackedLoadsTime.begin(); iter != m_unackedLoadsTime.end(); ++iter) + { + if ((iter->second.first == serverId) && (iter->second.second == serialNumber)) + { + m_unackedLoadsTime.erase(iter); + break; + } + } + + UnackedLoadsType::iterator iterFind = m_unackedLoads.find(serverId); + + if (iterFind == m_unackedLoads.end()) + return; + + std::vector::iterator iterFind2 = std::find(iterFind->second.begin(), iterFind->second.end(), serialNumber); + + if (iterFind2 == iterFind->second.end()) + return; + + IGNORE_RETURN(iterFind->second.erase(iterFind2)); + + bool hasMoreUnacked = true; + if (iterFind->second.empty()) + { + m_unackedLoads.erase(iterFind); + hasMoreUnacked = false; + } + + PreloadingProcessesType::iterator j=m_preloadingProcesses.find(serverId); + if (j != m_preloadingProcesses.end() && + !hasMoreUnacked && + m_locatorList.find(serverId) == m_locatorList.end()) + { + // Server was preloading, and it has acknowledged all the requested loads + // Tell it that preloading is done + LOG("Preload",("Done sending preload objects to server %lu.",serverId)); + PreloadRequestCompleteMessage msg(serverId, j->second); + DatabaseProcess::getInstance().sendToGameServer(serverId, msg); + m_preloadingProcesses.erase(j); + } +} + +// ---------------------------------------------------------------------- + +void Loader::addLocatorsForServer(uint32 serverId, ObjectLocator * regularLocator, ObjectLocator * goldLocator) +{ + LocatorListType::iterator i=m_locatorList.find(serverId); + if (i==m_locatorList.end()) + i=m_locatorList.insert(std::make_pair(serverId, new std::list >)).first; + + NON_NULL(i->second)->push_back(std::make_pair(regularLocator, goldLocator)); + ++m_numQueuedLocators; +} + +// ---------------------------------------------------------------------- + +int Loader::getNumPreloads() const +{ + return m_preloadingProcesses.size(); +} + +// ---------------------------------------------------------------------- + +int Loader::getAgeOldestUnackedLoad() const +{ + if (m_unackedLoadsTime.empty()) + { + return 0; + } + else + { + UnackedLoadsTimeType::const_iterator i = m_unackedLoadsTime.begin(); + return static_cast(time(0) - i->first); + } +} + +// ---------------------------------------------------------------------- + +uint32 Loader::getServerOldestUnackedLoad() const +{ + if (m_unackedLoadsTime.empty()) + { + return 0; + } + else + { + UnackedLoadsTimeType::const_iterator i = m_unackedLoadsTime.begin(); + return i->second.first; + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/Loader.h b/engine/server/library/serverDatabase/src/shared/Loader.h new file mode 100644 index 00000000..0e5f88b1 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Loader.h @@ -0,0 +1,156 @@ +// ====================================================================== +// +// Loader.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Loader_H +#define INCLUDED_Loader_H + +// ====================================================================== + +#include +#include +#include +#include + +#include "Singleton/Singleton2.h" +#include "Unicode.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedFoundation/StationId.h" +#include "sharedMessageDispatch/Receiver.h" + +namespace DB +{ + class TaskQueue; + class Server; +} +class LoaderSnapshotGroup; +class ObjectLocator; +class TransferCharacterData; +class CSGetCharactersRequestMessage; +class CSGetDeletedItemsRequestMessage; +class DBCSRequestMessage; + +// ====================================================================== + +/** + * Singleton that organizes and queues requests to load objects from the database. + */ +class Loader : public MessageDispatch::Receiver +{ +public: + static Loader &getInstance(); + virtual void update(real updateTime); + + void requestChunk(uint32 processId,int nodeX, int nodeZ, const std::string &sceneId); + void loadUniverse(uint32 processId); + + void snapshotLoaded(LoaderSnapshotGroup *snapshot); + + void getObjectIds(int processId, int numWanted, bool logRequest); + virtual void verifyCharacter(StationId suid, const NetworkId &characterId, const TransferCharacterData *) =0; + void checkVersionNumber(int expectedVersion, bool fatalOnMismatch); + void loadClock(); + void loadClockCompleted(); + void startupLoadCompleted() const; + void discardPendingLoadsForServer(uint32 processId); + void addLoadLock(const NetworkId &characterId); + void removeLoadLock(const NetworkId &characterId); + bool isIdle(); + bool isBacklogged(); + int getLoadQueueTasksEstimate() const; + int getNumPreloads() const; + int getAgeOldestUnackedLoad() const; + uint32 getServerOldestUnackedLoad() const; + void onCharacterLocatorDeleted(const NetworkId &characterId); + virtual void locateStructure(const NetworkId &structureId, const std::string whoRequested) =0; + + // CS DB requests + void handleCSGetCharacters( const CSGetCharactersRequestMessage & msg ); + void handleCSGetDeletedItems( const CSGetDeletedItemsRequestMessage & msg ); + void handleCSRequest( const DBCSRequestMessage & msg ); + void handleCSGetCharacters( const DBCSRequestMessage & msg ); + void handleCSGetDeletedItems( const DBCSRequestMessage & msg ); + void handleCSGetStructures( const DBCSRequestMessage & msg ); + void handleCSGetPlayerId( const DBCSRequestMessage & msg ); + + void receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); + + void shutdown(); + +private: + void queueOutgoingSnapshot (LoaderSnapshotGroup *outgoingSnapshot); + void requestCharacter (const NetworkId &characterId, uint32 gameServerId); + void loadContainedObject (const NetworkId &containerId, const NetworkId &objectId, uint32 gameServerId); + void loadContents (const NetworkId &containerId, uint32 gameServerId); + virtual LoaderSnapshotGroup * makeLoaderSnapshotGroup (uint32 processId) =0; + void preloadRequestComplete (uint32 processId, uint32 preloadAreaId); + virtual void loadStartupData () =0; + void startLoad (); + void startLoadForServer (uint32 serverId); + unsigned int getUnackedLoadCount (uint32 serverId) const; + void addLocatorsForServer (uint32 serverId, ObjectLocator * regularLocator, ObjectLocator * goldLocator); + void handleLoadAck (uint32 serverId, int serialNumber); + +private: + typedef std::list OutgoingQueueType; + typedef std::set ServerDiscardListType; + typedef std::map LoadLockType; // map of character -> server with a pending load for that character + typedef std::map LoadCountType; + typedef std::map NextLoadStartTimeType; + typedef std::map >* > LocatorListType; // map of server -> list of locators requested for that server + typedef std::map > UnackedLoadsType; // map of server -> last load sent to server + typedef std::multimap > UnackedLoadsTimeType; // how long we've been waiting for each ack + typedef std::map PreloadingProcessesType; // map of server -> numerical ID for area preloaded + + OutgoingQueueType outgoingQueue; + ServerDiscardListType m_serverDiscardList; + LoadLockType m_loadLock; // prevent loading objects that are being saved + LoadLockType m_multipleLoginLock; // prevent loading the same character multiple times + LoadCountType m_characterLoadCount; + LoadCountType m_chunkLoadCount; + NextLoadStartTimeType m_nextLoadStartTime; + bool m_backlogged; + float m_currentTime; + LocatorListType m_locatorList; + int m_loadSerialNumber; + UnackedLoadsType m_unackedLoads; + UnackedLoadsTimeType m_unackedLoadsTime; + int m_numQueuedLocators; + PreloadingProcessesType m_preloadingProcesses; + + protected: + DB::TaskQueue *taskQ; + + protected: + Loader(); + virtual ~Loader(); + Loader(const Loader &); + Loader & operator = (const Loader &); + static void installDerived(Loader *derivedInstance); + + private: + static void remove(); + static Loader *ms_instance; +}; + +// ---------------------------------------------------------------------- + +inline Loader &Loader::getInstance() +{ + NOT_NULL(ms_instance); + return *ms_instance; +} + +// ---------------------------------------------------------------------- + +inline bool Loader::isBacklogged() +{ + return m_backlogged; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.cpp b/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.cpp new file mode 100644 index 00000000..4eec24ee --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.cpp @@ -0,0 +1,143 @@ +// ====================================================================== +// +// LoaderSnapshotGroup.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/LoaderSnapshotGroup.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/Snapshot.h" +#include "serverDatabase/WorldContainerLocator.h" +#include "sharedDebug/Profiler.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +LoaderSnapshotGroup::LoaderSnapshotGroup(uint32 requestingProcess, Snapshot *snapshot) : + m_requestingProcess(requestingProcess), + m_snapshot(snapshot), + m_goldSnapshot(0), + m_loadSerialNumber(0) +{ + NOT_NULL(m_snapshot); +} + +// ---------------------------------------------------------------------- + +LoaderSnapshotGroup::~LoaderSnapshotGroup() +{ + delete m_snapshot; + m_snapshot=0; + delete m_goldSnapshot; + m_goldSnapshot=0; +} + +// ---------------------------------------------------------------------- + +bool LoaderSnapshotGroup::load(DB::Session *session) +{ + if (m_goldSnapshot) + { + if (! (m_goldSnapshot->load(session))) + return false; + + std::vector containers; + m_goldSnapshot->getWorldContainers(containers); + WorldContainerLocator *loc = new WorldContainerLocator(containers); + m_snapshot->addLocator(loc); + } + + NOT_NULL(m_snapshot); + return (m_snapshot->load(session)); +} + +// ---------------------------------------------------------------------- + +//TODO: rather have Loader keep track of connections, pass them as parameter to send() +bool LoaderSnapshotGroup::send() const +{ + bool success = true; + + NOT_NULL(m_snapshot); + GameServerConnection *connection = DatabaseProcess::getInstance().getConnectionByProcess(m_requestingProcess); + + if (!connection) + return false; + + if (m_goldSnapshot) + { + if (!m_goldSnapshot->send(connection)) + success=false; + } + if (success && !m_snapshot->send(connection)) + success=false; + + if (success) + { + PROFILER_AUTO_BLOCK_DEFINE("send ChunkCompleteMessage"); + + connection->sendChunkCompleteMessage(); + + // Request an acknowledgement for this load + if (m_loadSerialNumber != 0) + { + GenericValueTypeMessage msg("RequestLoadAckMessage",m_loadSerialNumber); + connection->send(msg,true); + } + } + else + connection->clearChunkCompleteQueue(); + + return success; +} + +// ---------------------------------------------------------------------- + +void LoaderSnapshotGroup::addLocator(ObjectLocator *newLocator) +{ + NOT_NULL(m_snapshot); + m_snapshot->addLocator(newLocator); +} + +// ---------------------------------------------------------------------- + +void LoaderSnapshotGroup::addGoldLocator(ObjectLocator *newLocator) +{ + if (!m_goldSnapshot) + m_goldSnapshot = makeGoldSnapshot(); + + NOT_NULL(m_goldSnapshot); + m_goldSnapshot->addLocator(newLocator); +} + +// ---------------------------------------------------------------------- + +void LoaderSnapshotGroup::setUniverseAuthHack() +{ + NOT_NULL(m_snapshot); + m_snapshot->setUniverseAuthHack(); +} + +// ---------------------------------------------------------------------- + +int LoaderSnapshotGroup::getLocatorCount() const +{ + int result=0; + if (m_goldSnapshot) + result = m_goldSnapshot->getLocatorCount(); + NOT_NULL(m_snapshot); + return result + m_snapshot->getLocatorCount(); +} + +// ---------------------------------------------------------------------- + +void LoaderSnapshotGroup::setLoadSerialNumber(int loadSerialNumber) +{ + m_loadSerialNumber = loadSerialNumber; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.h b/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.h new file mode 100644 index 00000000..31c08d86 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/LoaderSnapshotGroup.h @@ -0,0 +1,60 @@ +// ====================================================================== +// +// LoaderSnapshotGroup.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_LoaderSnapshotGroup_H +#define INCLUDED_LoaderSnapshotGroup_H + +// ====================================================================== + +#include "sharedFoundation/NetworkId.h" + +namespace DB +{ + class Session; +} +class Snapshot; +class ObjectLocator; + +// ====================================================================== + +class LoaderSnapshotGroup +{ + public: + LoaderSnapshotGroup(uint32 requestingProcess, Snapshot *snapshot); + virtual ~LoaderSnapshotGroup() =0; //insure class gets derived + + bool load (DB::Session *session); + bool send () const; + void addLocator (ObjectLocator *newLocator); + void addGoldLocator (ObjectLocator *newLocator); + int getLocatorCount () const; + void setUniverseAuthHack (); + uint32 getRequestingProcessId () const; + void setLoadSerialNumber (int loadSerialNumber); + + private: + virtual Snapshot *makeGoldSnapshot()=0; + + private: + uint32 m_requestingProcess; + + private: + Snapshot *m_snapshot; + Snapshot *m_goldSnapshot; + int m_loadSerialNumber; +}; + +// ---------------------------------------------------------------------- + +inline uint32 LoaderSnapshotGroup::getRequestingProcessId() const +{ + return m_requestingProcess; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/MessageToManager.cpp b/engine/server/library/serverDatabase/src/shared/MessageToManager.cpp new file mode 100644 index 00000000..6773ccca --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/MessageToManager.cpp @@ -0,0 +1,149 @@ +// ====================================================================== +// +// MessageToManager.cpp +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/MessageToManager.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverNetworkMessages/MessageToMessage.h" +#include "sharedFoundation/ExitChain.h" +#include + +// ====================================================================== + +MessageToManager *MessageToManager::ms_instance=NULL; + +// ====================================================================== + +void MessageToManager::install() +{ + DEBUG_FATAL(ms_instance,("Installed MessageToManager twice\n")); + ms_instance = new MessageToManager; + + ExitChain::add(&remove, "MessageToManager::remove"); +} + +// ---------------------------------------------------------------------- + +void MessageToManager::remove() +{ + NOT_NULL(ms_instance); + delete ms_instance; + ms_instance = NULL; +} + +// ---------------------------------------------------------------------- + +MessageToManager::MessageToManager() +{ +} + +// ---------------------------------------------------------------------- + +MessageToManager::~MessageToManager() +{ + DEBUG_WARNING(!m_messagesByObject.empty(),("Shut down with messages outstanding that were not persisted.")); + for (MessagesByObjectType::iterator i=m_messagesByObject.begin(); i!=m_messagesByObject.end(); ++i) + { + delete i->second; + i->second=NULL; + } +} + +// ---------------------------------------------------------------------- + +/** + * Called when we receive a message from the game servers. Save it in the + * map, in case the object it refers to is loaded before the message is + * persisted. + */ +void MessageToManager::handleMessageTo(const MessageToPayload &data) +{ + IndexKey theKey(data.getNetworkId(), data.getMessageId()); + + MessagesByObjectType::iterator i=m_messagesByObject.find(theKey); + if (i!=m_messagesByObject.end()) + { + DEBUG_WARNING(true,("Received message %s twice.",data.getMessageId().getValueString().c_str())); + delete i->second; + i->second = NULL; + } + + m_messagesByObject[theKey]=new MessageToPayload(data); + m_messageToObjectMap[data.getMessageId()]=data.getNetworkId(); +} + +// ---------------------------------------------------------------------- + +/** + * Called when a message is acknowledged by the game servers. If we were + * tracking it, we don't need to any more. + */ +void MessageToManager::handleMessageToAck(const MessageToId &messageId) +{ + removeMessage(messageId); +} + +// ---------------------------------------------------------------------- + +/** + * Called when a message is persisted. We don't need to track it any more + * because it will be reloaded from the database. + */ +void MessageToManager::onMessagePersisted(const MessageToId &messageId) +{ + removeMessage(messageId); +} + +// ---------------------------------------------------------------------- + +/** + * Send any messages still in memory for this object. + */ +void MessageToManager::sendMessagesForObject(const NetworkId &objectId, GameServerConnection &conn) const +{ + for (MessagesByObjectType::const_iterator j=m_messagesByObject.lower_bound(IndexKey(objectId, NetworkId::cms_invalid)); + (j != m_messagesByObject.end()) && (j->first.m_object == objectId); + ++j) + { + MessageToMessage const message(*(j->second), DatabaseProcess::getInstance().getProcessId()); + conn.send(message, true); + } +} + +// ---------------------------------------------------------------------- + +void MessageToManager::removeMessage(const MessageToId &messageId) +{ + MessageToObjectMapType::iterator i=m_messageToObjectMap.find(messageId); + if (i!=m_messageToObjectMap.end()) + { + MessagesByObjectType::iterator j=m_messagesByObject.find(IndexKey(i->second, messageId)); + if (j!=m_messagesByObject.end()) + { + delete j->second; + j->second=NULL; + m_messagesByObject.erase(j); + } + m_messageToObjectMap.erase(i); + } +} + +// ---------------------------------------------------------------------- + +/** + * Returns true if we have the message in memory. Used to prevent + * sending the message twice if we load it from the database and still + * have it in memory. + */ +bool MessageToManager::hasMessage(const MessageToId &messageId) const +{ + return (m_messageToObjectMap.find(messageId) != m_messageToObjectMap.end()); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/MessageToManager.h b/engine/server/library/serverDatabase/src/shared/MessageToManager.h new file mode 100644 index 00000000..fa2dada3 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/MessageToManager.h @@ -0,0 +1,101 @@ +// ====================================================================== +// +// MessageToManager.h +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_MessageToManager_H +#define INCLUDED_MessageToManager_H + +// ====================================================================== + +#include "sharedFoundation/NetworkId.h" +#include "serverNetworkMessages/MessageToPayload.h" +#include + +class GameServerConnection; + +// ====================================================================== + +/** + * Unlike all the other types of data, messages can be sent to an object + * that is offline. This class stores messages until they are saved, so + * that if an object is loaded while messages are pending, it will get + * those messages. + */ +class MessageToManager +{ + public: + typedef stdvector::fwd MessageVector; + + public: + static void install(); + static void remove(); + static MessageToManager &getInstance(); + + public: + void handleMessageTo(const MessageToPayload &data); + void handleMessageToAck(const MessageToId &messageId); + void onMessagePersisted(const MessageToId &messageId); + void sendMessagesForObject(const NetworkId &objectId, GameServerConnection &conn) const; + bool hasMessage(const MessageToId &messageId) const; + + private: + MessageToManager(); + ~MessageToManager(); + + private: + void removeMessage(const MessageToId &messageId); + + private: + struct IndexKey + { + IndexKey(const NetworkId &object, const MessageToId &message); + + NetworkId m_object; + MessageToId m_message; + bool operator< (const IndexKey &rhs) const; + }; + typedef std::map MessagesByObjectType; + typedef std::map MessageToObjectMapType; + + private: + MessagesByObjectType m_messagesByObject; + MessageToObjectMapType m_messageToObjectMap; + + private: + static MessageToManager *ms_instance; +}; + +// ====================================================================== + +inline MessageToManager & MessageToManager::getInstance() +{ + NOT_NULL(ms_instance); + return *ms_instance; +} + +// ====================================================================== + +inline MessageToManager::IndexKey::IndexKey(const NetworkId &object, const MessageToId &message) : + m_object(object), + m_message(message) +{ +} + +// ---------------------------------------------------------------------- + +inline bool MessageToManager::IndexKey::operator< (const IndexKey &rhs) const +{ + if (m_object < rhs.m_object) + return true; + else if ((m_object == rhs.m_object) && (m_message < rhs.m_message)) + return true; + else + return false; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.cpp new file mode 100644 index 00000000..c1eb3c57 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.cpp @@ -0,0 +1,100 @@ +// ====================================================================== +// +// MoveToPlayerCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/MoveToPlayerCustomPersistStep.h" + +#include "serverDatabase/CharacterQueries.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/Persister.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +MoveToPlayerCustomPersistStep::MoveToPlayerCustomPersistStep(const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad) : + m_objectId(objectId), + m_targetPlayer(targetPlayer), + m_maxDepth(maxDepth), + m_useBank(useBank), + m_useDatapad(useDatapad) +{ +} + +// ---------------------------------------------------------------------- + +MoveToPlayerCustomPersistStep::~MoveToPlayerCustomPersistStep() +{ +} + +// ---------------------------------------------------------------------- + +bool MoveToPlayerCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool MoveToPlayerCustomPersistStep::afterPersist(DB::Session *session) +{ + MoveToPlayerQuery qry(m_objectId, m_targetPlayer, m_maxDepth, m_useBank, m_useDatapad); + if (! (session->exec(&qry))) + return false; + qry.done(); + return true; +} + +// ---------------------------------------------------------------------- + +void MoveToPlayerCustomPersistStep::onComplete() +{ +} + +// ---------------------------------------------------------------------- + +MoveToPlayerCustomPersistStep::MoveToPlayerQuery::MoveToPlayerQuery(const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad) : + object_id(objectId), + target_player(targetPlayer), + max_depth(maxDepth), + m_useBank(useBank), + m_useDatapad(useDatapad) +{ +} + +// ---------------------------------------------------------------------- + +void MoveToPlayerCustomPersistStep::MoveToPlayerQuery::getSQL(std::string &sql) +{ + if (m_useBank) + sql="begin "+DatabaseProcess::getInstance().getSchemaQualifier()+"admin.move_to_player_bank (:object_id, :target_player); end;"; + else if (m_useDatapad) + sql="begin "+DatabaseProcess::getInstance().getSchemaQualifier()+"admin.move_to_player_datapad (:object_id, :target_player, :max_depth); end;"; + else + sql="begin "+DatabaseProcess::getInstance().getSchemaQualifier()+"admin.move_to_player (:object_id, :target_player); end;"; +} + +// ---------------------------------------------------------------------- + +bool MoveToPlayerCustomPersistStep::MoveToPlayerQuery::bindParameters() +{ + if (!bindParameter(object_id)) return false; + if (!bindParameter(target_player)) return false; + if (m_useDatapad && !bindParameter(max_depth)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool MoveToPlayerCustomPersistStep::MoveToPlayerQuery::bindColumns() +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h new file mode 100644 index 00000000..b5851bc9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/MoveToPlayerCustomPersistStep.h @@ -0,0 +1,67 @@ +// ====================================================================== +// +// MoveToPlayerCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_MoveToPlayerCustomPersistStep_H +#define INCLUDED_MoveToPlayerCustomPersistStep_H + +// ====================================================================== + +#include "Unicode.h" +#include "serverDatabase/CustomPersistStep.h" +#include "sharedDatabaseInterface/DbBindableLong.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" +#include + +class NetworkId; + +// ====================================================================== + +class MoveToPlayerCustomPersistStep : public CustomPersistStep +{ + public: + MoveToPlayerCustomPersistStep(const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad); + ~MoveToPlayerCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + NetworkId m_objectId; + NetworkId m_targetPlayer; + int m_maxDepth; + bool m_useBank; + bool m_useDatapad; + + class MoveToPlayerQuery: public DB::Query + { + public: + MoveToPlayerQuery(const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad); + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + MoveToPlayerQuery(MoveToPlayerQuery const &); + MoveToPlayerQuery &operator=(MoveToPlayerQuery const &); + DB::BindableNetworkId object_id; + DB::BindableNetworkId target_player; + DB::BindableLong max_depth; + bool m_useBank; + bool m_useDatapad; + }; + + private: + MoveToPlayerCustomPersistStep &operator= (const MoveToPlayerCustomPersistStep&); //disable + MoveToPlayerCustomPersistStep(const MoveToPlayerCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ObjectLocator.cpp b/engine/server/library/serverDatabase/src/shared/ObjectLocator.cpp new file mode 100644 index 00000000..fb736434 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ObjectLocator.cpp @@ -0,0 +1,54 @@ +// ====================================================================== +// +// ObjectLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ObjectLocator.h" + +#include + +#include "serverDatabase/GameServerConnection.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +ObjectLocator::ObjectLocator() +{ +} + +// ---------------------------------------------------------------------- + +ObjectLocator::~ObjectLocator() +{ +} + +// ---------------------------------------------------------------------- + +/** + * Override this function to send any additional non-object data. + * This is invoked before any of the objects are sent. For example, + * this could be used to tell the game server that one of the objects + * we are loading is a character. + */ +void ObjectLocator::sendPreBaselinesCustomData(GameServerConnection &conn) const +{ + UNREF(conn); +} + +// ---------------------------------------------------------------------- + +/** + * Override this function to send any additional non-object data. + * This is invoked after all the objects are sent. For example, + * this is used to send the UniverseComplete message to indicate that + * the Snapshot contained all the universe objects. + */ +void ObjectLocator::sendPostBaselinesCustomData(GameServerConnection &conn) const +{ + UNREF(conn); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ObjectLocator.h b/engine/server/library/serverDatabase/src/shared/ObjectLocator.h new file mode 100644 index 00000000..cad32c59 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ObjectLocator.h @@ -0,0 +1,48 @@ +// ====================================================================== +// +// ObjectLocator.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== +#include "sharedDatabaseInterface/DbSession.h" + +#ifndef INCLUDED_ObjectLocator_H +#define INCLUDED_ObjectLocator_H + +class GameServerConnection; + +// ====================================================================== + +/** + * Abstract base class for classes that can locate objects in the database. + * + * The job of classes derived from ObjectLocator is to get a list of + * objectID's matching particular criteria. This is used by Snapshot to + * identify which objects to load. + * + * The list of objects is left in a temporary table on the database. + * + * For example, a derived ObjectLocator might find all the objects in a + * particular spatial chunk. If an instance of that ObjectLocator is + * attached to a Snapshot, then the snapshot will load all the objects + * in a chunk. + * + * This class allows Snapshots to be used for different types of loads + * without deriving different types of snapshots, and it allows a single + * Snapshot to be used for several logically distinct load operations. + */ +class ObjectLocator +{ + public: + virtual bool locateObjects (DB::Session *session, const std::string &schema, int &objectsLocated) =0; + virtual void sendPreBaselinesCustomData (GameServerConnection &conn) const; + virtual void sendPostBaselinesCustomData (GameServerConnection &conn) const; + + public: + ObjectLocator(); + virtual ~ObjectLocator(); +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/Persister.cpp b/engine/server/library/serverDatabase/src/shared/Persister.cpp new file mode 100644 index 00000000..85d94e4f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Persister.cpp @@ -0,0 +1,1197 @@ +// ====================================================================== +// +// Persister.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/Persister.h" + +#include "serverDatabase/CentralServerConnection.h" +#include "serverDatabase/CommoditiesServerConnection.h" +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/CreateCharacterCustomPersistStep.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/DeleteCharacterCustomPersistStep.h" +#include "serverDatabase/FixLoadWithCustomPersistStep.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/MessageToManager.h" +#include "serverDatabase/MoveToPlayerCustomPersistStep.h" +#include "serverDatabase/PurgeCompleteCustomPersistStep.h" +#include "serverDatabase/RenameCharacterCustomPersistStep.h" +#include "serverDatabase/Snapshot.h" +#include "serverDatabase/TaskCSTasks.h" +#include "serverDatabase/TaskSaveSnapshot.h" +#include "serverDatabase/TaskChangeStationId.h" +#include "serverDatabase/UnloadCharacterCustomPersistStep.h" +#include "serverNetworkMessages/AddCharacterMessage.h" +#include "serverNetworkMessages/AddResourceTypeMessage.h" +#include "serverNetworkMessages/BountyHunterTargetMessage.h" +#include "serverNetworkMessages/CMCreateAuctionBidMessage.h" +#include "serverNetworkMessages/CMCreateAuctionMessage.h" +#include "serverNetworkMessages/CMCreateLocationMessage.h" +#include "serverNetworkMessages/CMDeleteAuctionMessage.h" +#include "serverNetworkMessages/CMDeleteLocationMessage.h" +#include "serverNetworkMessages/CMUpdateAuctionMessage.h" +#include "serverNetworkMessages/CMUpdateLocationMessage.h" +#include "serverNetworkMessages/CentralGameServerMessages.h" +#include "serverNetworkMessages/CreateObjectMessage.h" +#include "serverNetworkMessages/CSDBNetMessages.h" +#include "serverNetworkMessages/EndBaselinesMessage.h" +#include "serverNetworkMessages/FlagObjectForDeleteMessage.h" +#include "serverNetworkMessages/GetMoneyFromOfflineObjectMessage.h" +#include "serverNetworkMessages/MessageToAckMessage.h" +#include "serverNetworkMessages/MessageToMessage.h" +#include "serverNetworkMessages/RenameCharacterMessage.h" +#include "serverNetworkMessages/ServerDeleteCharacterMessage.h" +#include "serverNetworkMessages/TransferAccountData.h" +#include "serverNetworkMessages/UnloadedPlayerMessage.h" +#include "serverNetworkMessages/UpdateObjectPositionMessage.h" +#include "sharedDatabaseInterface/DbServer.h" +#include "sharedDatabaseInterface/DbTaskQueue.h" +#include "sharedNetworkMessages/DeleteCharacterMessage.h" +#include "sharedDebug/Profiler.h" +#include "sharedFoundation/Clock.h" +#include "sharedFoundation/ExitChain.h" +#include "sharedFoundation/FormattedString.h" +#include "sharedFoundation/GameControllerMessage.h" +#include "sharedFoundation/Os.h" +#include "sharedLog/Log.h" +#include "sharedMessageDispatch/Emitter.h" +#include "sharedNetworkMessages/BaselinesMessage.h" +#include "sharedNetworkMessages/DeltasMessage.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedNetworkMessages/ObjectChannelMessages.h" + +#include +#include + +// ====================================================================== + +Persister *Persister::ms_instance=NULL; + +// ====================================================================== + +void Persister::installDerived(Persister *derivedInstance) +{ + DEBUG_FATAL(ms_instance,("Installed Persister twice\n")); + ms_instance = derivedInstance; + + ExitChain::add(&remove, "Persister::remove"); +} + +// ---------------------------------------------------------------------- + +void Persister::remove() +{ + NOT_NULL(ms_instance); + delete ms_instance; + ms_instance = NULL; +} + +//----------------------------------------------------------------------- + +Persister::Persister() : + MessageDispatch::Receiver(), + taskQueue(new DB::TaskQueue(ConfigServerDatabase::getPersisterThreads(),DatabaseProcess::getInstance().getDBServer(),1)), + m_newCharacterTaskQueue(new DB::TaskQueue(ConfigServerDatabase::getNewCharacterThreads(),DatabaseProcess::getInstance().getDBServer(),3)), + m_currentSnapshots(), + m_newObjectSnapshots(), + m_newCharacterSnapshots(), + m_objectSnapshotMap(), + m_pendingCharacters(), + m_savingSnapshots(), + m_savingCharacterSnapshots(), + m_newCharacterLock(), + m_charactersToDeleteThisSaveCycle(new CharactersToDeleteType), + m_charactersToDeleteNextSaveCycle(new CharactersToDeleteType), + m_timeSinceLastSave(0), + m_messageSnapshot(NULL), + m_commoditiesSnapshot(NULL), + m_arbitraryGameDataSnapshot(NULL), + m_saveStartTime(0), + m_totalSaveTime(0), + m_maxSaveTime(0), + m_saveCount(0), + m_newObjectCount(0), + m_lastSaveTime(0), + m_lastSaveTotalObjectCount(0), + m_lastSaveNewObjectCount(0), + m_lastSaveCompletionTime(), + m_saveCounter(0), + m_startSaveWhenPossible(false), + m_inMagicMinute(false), + m_clusterShuttingDown(false) +{ + connectToMessage("AddCharacterMessage"); + connectToMessage("AddResourceTypeMessage"); + connectToMessage("BaselinesMessage"); + connectToMessage("BountyHunterTargetMessage"); + connectToMessage("CentralRequestSave"); + connectToMessage("ClusterShutdownMessage"); + connectToMessage("CMCreateAuctionBidMessage"); + connectToMessage("CMCreateAuctionMessage"); + connectToMessage("CMCreateLocationMessage"); + connectToMessage("CMDeleteAuctionMessage"); + connectToMessage("CMDeleteLocationMessage"); + connectToMessage("CMUpdateAuctionMessage"); + connectToMessage("CMUpdateLocationMessage"); + connectToMessage("CreateObjectByCrcMessage"); + connectToMessage("DeltasMessage"); + connectToMessage("EndBaselinesMessage"); + connectToMessage("FixLoadWith"); + connectToMessage("FlagObjectForDeleteMessage"); + connectToMessage("GetMoneyFromOfflineObjectMessage"); + connectToMessage("LoadCommodities"); + connectToMessage("MessageToAckMessage"); + connectToMessage("MessageToMessage"); + connectToMessage("MoveToPlayer"); + connectToMessage("MoveToPlayerBankMessage"); + connectToMessage("MoveToPlayerDatapadMessage"); + connectToMessage("MoveToPlayerMessage"); + connectToMessage("PlanetRequestSave"); + connectToMessage("PurgeCompleteMessage"); + connectToMessage("RenameCharacterMessageEx"); + connectToMessage("RestoreCharacterMessage"); + connectToMessage("RestoreHouseMessage"); + connectToMessage("ServerDeleteCharacterMessage"); + connectToMessage("StartSaveMessage"); + connectToMessage("UndeleteItemMessage"); + connectToMessage("UnloadObjectMessage"); + connectToMessage("UnloadedPlayerMessage"); + connectToMessage("UpdateObjectPositionMessage"); + connectToMessage("DBCSRequestMessage"); + connectToMessage("UndeleteItemForCsMessage"); +} + +//----------------------------------------------------------------------- + +Persister::~Persister() +{ + DEBUG_FATAL(taskQueue,("Call shutdown() before deleting Persister.\n")); + + ServerSnapshotMap::iterator i; + for (i=m_currentSnapshots.begin(); i!=m_currentSnapshots.end(); ++i) + delete i->second; + for (i=m_newObjectSnapshots.begin(); i!=m_newObjectSnapshots.end(); ++i) + delete i->second; + + m_currentSnapshots.clear(); + m_newObjectSnapshots.clear(); + m_objectSnapshotMap.clear(); + m_messageSnapshot = NULL; + m_commoditiesSnapshot = NULL; + m_arbitraryGameDataSnapshot = NULL; + + delete m_charactersToDeleteThisSaveCycle; + m_charactersToDeleteThisSaveCycle = NULL; + + delete m_charactersToDeleteNextSaveCycle; + m_charactersToDeleteNextSaveCycle = NULL; +} + +// ---------------------------------------------------------------------- + +void Persister::update(real updateTime) +{ + m_timeSinceLastSave += updateTime; + + { + PROFILER_AUTO_BLOCK_DEFINE("taskQueue->update"); + taskQueue->update(ConfigServerDatabase::getDefaultQueueUpdateTimeLimit()); + } + { + PROFILER_AUTO_BLOCK_DEFINE("m_newCharacterTaskQueue->update"); + m_newCharacterTaskQueue->update(ConfigServerDatabase::getDefaultQueueUpdateTimeLimit()); + } +} + +// ---------------------------------------------------------------------- + +void Persister::onFrameBarrierReached() +{ + if (m_newCharacterTaskQueue->getNumPendingTasks() == 0) + { + ServerSnapshotMap delayedSaves; + + for (ServerSnapshotMap::iterator i=m_newCharacterSnapshots.begin(); i!=m_newCharacterSnapshots.end(); ++i) + { + if (m_newCharacterLock.find(i->first)==m_newCharacterLock.end()) + { + DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes(),("Starting new character save\n")); + m_savingCharacterSnapshots.push_back(i->second); + m_newCharacterTaskQueue->asyncRequest(new TaskSaveSnapshot(i->second)); + for (ObjectSnapshotMap::iterator obj=m_objectSnapshotMap.begin(); obj!=m_objectSnapshotMap.end();) + { + if (obj->second == i->second) + m_objectSnapshotMap.erase(obj++); + else + ++obj; + } + } + else + { + delayedSaves[i->first]=i->second; + DEBUG_REPORT_LOG(true,("New character persistence for server %lu delayed because the server split character baselines across a frame boundary.\n",i->first)); + } + } + m_newCharacterSnapshots.swap(delayedSaves); + } + + // Check for whether it is time to save + + FATAL(m_timeSinceLastSave > ConfigServerDatabase::getMaxTimewarp(),("Save was not completed within %i seconds. Shutting down to avoid a longer timewarp.\n",ConfigServerDatabase::getMaxTimewarp())); + + if (ConfigServerDatabase::getSaveAtModulus()!=-1) + { + // save based on being a certain # of minutes past the hour + tm zulu; + Os::convertTimeToGMT(Os::getRealSystemTime(),zulu); + if ((zulu.tm_min % ConfigServerDatabase::getSaveAtDivisor())==ConfigServerDatabase::getSaveAtModulus()) + { + if (!m_inMagicMinute) + { + m_inMagicMinute = true; // to make sure we don't start multiple saves in the same minute + m_startSaveWhenPossible = true; + } + } + else + m_inMagicMinute = false; + } + + if (m_timeSinceLastSave > ConfigServerDatabase::getSaveFrequencyLimit()) + m_startSaveWhenPossible = true; + + if (m_startSaveWhenPossible) + { + if (m_savingSnapshots.empty()) + { + m_startSaveWhenPossible = false; + startSave(); + } + else if (ConfigServerDatabase::getReportSaveTimes()) + { + DEBUG_REPORT_LOG(true,("Waiting for previous save. %i objects queued (%i new).\n",m_objectSnapshotMap.size(),m_newObjectCount)); + taskQueue->report(); + } + } +} + +// ---------------------------------------------------------------------- +/** + * Moves the current & new object snapshots onto the queue to be saved. + * + * Does nothing if these snapshots are null. + */ + +void Persister::startSave(void) +{ + DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes(),("Starting save with data for %i objects (%i new)\n",m_objectSnapshotMap.size(), m_newObjectCount)); + LOG("SaveTimes",("Starting save with data for %i objects (%i new)",m_objectSnapshotMap.size(), m_newObjectCount)); + // notify Central that a save is starting. It needs this to determine when it can perform graceful shutdowns + LOG("Database",("Sending DatabaseSaveStart network message to Central.")); + DatabaseSaveStart const startSaveMessage; + DatabaseProcess::getInstance().sendToCentralServer(startSaveMessage, true); + // record metrics data + m_lastSaveTotalObjectCount=m_objectSnapshotMap.size(); + m_lastSaveNewObjectCount=m_newObjectCount; + + m_newObjectCount=0; + + // delete any characters for this save cycle + if (m_charactersToDeleteNextSaveCycle && m_charactersToDeleteThisSaveCycle) + { + for (CharactersToDeleteType::const_iterator iter = m_charactersToDeleteThisSaveCycle->begin(); iter != m_charactersToDeleteThisSaveCycle->end(); ++iter) + { + DeleteCharacterCustomPersistStep *cps = new DeleteCharacterCustomPersistStep(iter->first, iter->second); + getSnapshotForObject(iter->second, 0).addCustomPersistStep(cps); + } + + // if this is the final save before the cluster is brought down, + // delete characters for the next save cycle as well since there + // won't be a next save cycle + if (m_clusterShuttingDown) + { + for (CharactersToDeleteType::const_iterator iter2 = m_charactersToDeleteNextSaveCycle->begin(); iter2 != m_charactersToDeleteNextSaveCycle->end(); ++iter2) + { + DeleteCharacterCustomPersistStep *cps = new DeleteCharacterCustomPersistStep(iter2->first, iter2->second); + getSnapshotForObject(iter2->second, 0).addCustomPersistStep(cps); + } + } + } + + // pick an arbitrary snapshot to save the clock + if (!m_currentSnapshots.empty()) + m_currentSnapshots.begin()->second->takeTimestamp(); + + // queue up snapshots to be saved + ServerSnapshotMap::iterator i; + for (i=m_currentSnapshots.begin(); i!=m_currentSnapshots.end(); ++i) + { + m_savingSnapshots.push_back(i->second); + taskQueue->asyncRequest(new TaskSaveSnapshot(i->second)); + } + for (i=m_newObjectSnapshots.begin(); i!=m_newObjectSnapshots.end(); ++i) + { + m_savingSnapshots.push_back(i->second); + taskQueue->asyncRequest(new TaskSaveSnapshot(i->second)); + } + + // nothing changed so send a complete message for the shutdown process + if( m_savingSnapshots.empty() ) + { + GenericValueTypeMessage const saveCompleteMessage("DatabaseSaveComplete", ++m_saveCounter); + DatabaseProcess::getInstance().sendToCentralServer(saveCompleteMessage, true); + LOG("Database",("Sending DatabaseSaveComplete network message to Central.")); + } + + // clear the buffers + m_currentSnapshots.clear(); + m_newObjectSnapshots.clear(); + m_objectSnapshotMap.clear(); + m_messageSnapshot = NULL; + m_commoditiesSnapshot = NULL; + m_arbitraryGameDataSnapshot = NULL; + + // prepare the list of characters to delete during the next save cycle + if (m_charactersToDeleteNextSaveCycle && m_charactersToDeleteThisSaveCycle) + { + m_charactersToDeleteThisSaveCycle->clear(); + + if (m_clusterShuttingDown) + m_charactersToDeleteNextSaveCycle->clear(); + else + std::swap(m_charactersToDeleteThisSaveCycle, m_charactersToDeleteNextSaveCycle); + } + + m_timeSinceLastSave = 0; + + if (ConfigServerDatabase::getReportSaveTimes()) + m_saveStartTime = Clock::timeMs(); +} + +// ---------------------------------------------------------------------- + +/** + * Determine the appropriate snapshot to put an object in. (If this is + * the first time we've seen the object, remember which snapshot we + * decided to use for it.) + */ +Snapshot & Persister::getSnapshotForObject(const NetworkId &networkId, uint32 serverId) +{ + ObjectSnapshotMap::const_iterator i=m_objectSnapshotMap.find(networkId); + if (i!=m_objectSnapshotMap.end()) + { + NOT_NULL(i->second); + return *(i->second); + } + else + { + Snapshot &snap = getSnapshotForServer(serverId); + m_objectSnapshotMap[networkId]=&snap; + return snap; + } +} + +// ---------------------------------------------------------------------- + +bool Persister::hasDataForObject(const NetworkId &objectId) const +{ + ObjectSnapshotMap::const_iterator i=m_objectSnapshotMap.find(objectId); + return (i!=m_objectSnapshotMap.end()); +} + +// ---------------------------------------------------------------------- + +Snapshot & Persister::getSnapshotForServer(uint32 serverId) +{ + if (serverId==0) + { + if (!m_arbitraryGameDataSnapshot) + { + m_arbitraryGameDataSnapshot = makeSnapshot(DB::ModeQuery::mode_UPDATE); + m_currentSnapshots[0] = m_arbitraryGameDataSnapshot; + } + return *m_arbitraryGameDataSnapshot; + } + else + { + ServerSnapshotMap::const_iterator j=m_currentSnapshots.find(serverId); + + if (j==m_currentSnapshots.end()) + { + Snapshot *snap = makeSnapshot(DB::ModeQuery::mode_UPDATE); + m_currentSnapshots[serverId]=snap; + if (!m_arbitraryGameDataSnapshot) + m_arbitraryGameDataSnapshot = snap; + return *snap; + } + else + { + NOT_NULL (j->second); + return *(j->second); + } + } +} + +// ---------------------------------------------------------------------- + +Snapshot & Persister::getCommoditiesSnapshot(uint32 serverId) +{ + if (m_commoditiesSnapshot) + { + return *m_commoditiesSnapshot; + } + else + { + ServerSnapshotMap::const_iterator j; + + j=m_currentSnapshots.find(serverId); + + if (j==m_currentSnapshots.end()) + { + Snapshot *snap = makeCommoditiesSnapshot(DB::ModeQuery::mode_INSERT); + m_currentSnapshots[serverId]=snap; + m_commoditiesSnapshot = snap; + return *snap; + } + else + { + NOT_NULL (j->second); + m_commoditiesSnapshot = j->second; + return *(j->second); + } + } +} + +// ---------------------------------------------------------------------- + +void Persister::handleDeltasMessage(uint32 serverId, const DeltasMessage &msg) +{ + NetworkId objectId=msg.getTarget(); +// DEBUG_REPORT_LOG(true,("Got deltas message for object %s.\n",objectId.getValueString().c_str())); + getSnapshotForObject(objectId,serverId).handleDeltasMessage(objectId, msg); +} + +// ---------------------------------------------------------------------- + +void Persister::handleBaselinesMessage(uint32 serverId, const BaselinesMessage &msg) +{ +// DEBUG_REPORT_LOG(true,("Got baselines message.\n")); + + NetworkId objectId=msg.getTarget(); + getSnapshotForObject(objectId,serverId).handleBaselinesMessage(objectId, msg); +} + +// ---------------------------------------------------------------------- +/** + * Called when we receive a delete message for an object. + * @param objectID The object to delete. + */ + +void Persister::handleDeleteMessage(uint32 serverId, const NetworkId &objectId, int reasonCode, bool immediate, bool demandLoadedContainer, bool cascadeReason) +{ + getSnapshotForObject(objectId,serverId).handleDeleteMessage(objectId, reasonCode, immediate, demandLoadedContainer, cascadeReason); +} + +// ---------------------------------------------------------------------- + +/** + * Invoked when we receive a CreateObject message. + * + * Creates a Snapshot to hold the new object and prepares to receive baselines. + */ + +void Persister::newObject(uint32 serverId, const NetworkId &objectId, int templateId, Tag typeId, const NetworkId &container) +{ + UNREF(serverId); + +// DEBUG_REPORT_LOG (true,("Recieved new object message for %s\n",objectId.getValueString().c_str())); + if (m_objectSnapshotMap.find(objectId)!=m_objectSnapshotMap.end()) + { + DEBUG_WARNING(true,("Database received multiple new object messages for object %s",objectId.getValueString().c_str())); + return; + } + + Snapshot *snap=NULL; + + PendingCharactersType::iterator chardata=m_pendingCharacters.find(objectId); + if (chardata!=m_pendingCharacters.end()) + { + // Object is a new character + ServerSnapshotMap::iterator i=m_newCharacterSnapshots.find(serverId); + if (i!=m_newCharacterSnapshots.end()) + { + snap = i->second; + } + else + { + snap=makeSnapshot(DB::ModeQuery::mode_INSERT); + m_newCharacterSnapshots[serverId]=snap; + } + + snap->addCustomPersistStep( + new CreateCharacterCustomPersistStep(chardata->second.stationId, + chardata->first, + chardata->second.name, + Unicode::wideToNarrow(DataLookup::getInstance().normalizeName(chardata->second.name)), + templateId, + chardata->second.special)); + } + else + { + // Add the object to the appropriate snapshot + snap=NULL; + { + ObjectSnapshotMap::const_iterator j=m_objectSnapshotMap.find(container); + if (j!=m_objectSnapshotMap.end() && j->second->getMode() == DB::ModeQuery::mode_INSERT) + snap = j->second; + else + { + ServerSnapshotMap::const_iterator i=m_newObjectSnapshots.find(serverId); + if (i==m_newObjectSnapshots.end()) + { + snap=makeSnapshot(DB::ModeQuery::mode_INSERT); + m_newObjectSnapshots[serverId]=snap; + } + else + snap = i->second; + } + } + } + + ++m_newObjectCount; + NOT_NULL(snap); + snap->newObject(objectId, templateId, typeId); + m_objectSnapshotMap[objectId]=snap; +} + +// ---------------------------------------------------------------------- + +/** + * Invoked when we receive an EndBaselines message. + * + * Starts saving the object to the database. + */ + +void Persister::endBaselines(const NetworkId &objectId, uint32 serverId) +{ + //TODO: This is a hack until we remove frame boundaries and have "end frame" messages from the game server. Apparently the game + // server can split baselines across frame boundaries, so we can't assume we have all the data for a character when we hit a + // frame bounday. + PendingCharactersType::iterator chardata=m_pendingCharacters.find(objectId); + if (chardata!=m_pendingCharacters.end()) + { + m_pendingCharacters.erase(chardata); + m_newCharacterLock.erase(serverId); + } +} + +// ---------------------------------------------------------------------- + +/** + * Called by TaskSaveSnapshot when it finishes. + */ + +void Persister::saveCompleted(Snapshot *completedSnapshot) +{ + SnapshotListType::iterator i=std::remove(m_savingSnapshots.begin(),m_savingSnapshots.end(),completedSnapshot); + if (i!=m_savingSnapshots.end()) + { + m_savingSnapshots.erase(i, m_savingSnapshots.end()); + + delete completedSnapshot; + + if (m_savingSnapshots.empty() && ConfigServerDatabase::getReportSaveTimes()) + { + int saveTime = Clock::timeMs() - m_saveStartTime; + ++m_saveCount; + m_totalSaveTime += saveTime; + if (saveTime > m_maxSaveTime) + m_maxSaveTime = saveTime; + + DEBUG_REPORT_LOG(true,("Save completed in %i. (Average %i, max %i)\n", saveTime, m_totalSaveTime/m_saveCount, m_maxSaveTime)); + LOG("SaveTimes",("Save completed in %i. (Average %i, max %i)", saveTime, m_totalSaveTime/m_saveCount, m_maxSaveTime)); + m_lastSaveTime = saveTime; + } + + if (m_savingSnapshots.empty()) + { + // message Central Server that the current save cycle is complete + GenericValueTypeMessage const saveCompleteMessage("DatabaseSaveComplete", ++m_saveCounter); + DatabaseProcess::getInstance().sendToCentralServer(saveCompleteMessage, true); + LOG("Database",("Sending DatabaseSaveComplete network message to Central.")); + } + + { + // set the last save completion time (for the monitoring program) + time_t theTime = time(0); + m_lastSaveCompletionTime = ctime(&theTime); + } + } + else + { + SnapshotListType::iterator j=std::remove(m_savingCharacterSnapshots.begin(),m_savingCharacterSnapshots.end(),completedSnapshot); + DEBUG_FATAL(i==m_savingCharacterSnapshots.end(),("Programmer bug: SaveCompleted() called with a snapshot that wasn't in m_savingSnapshots or m_savingCharacterSnapshots.")); + m_savingCharacterSnapshots.erase(j, m_savingCharacterSnapshots.end()); + delete completedSnapshot; + DEBUG_REPORT_LOG(ConfigServerDatabase::getReportSaveTimes(),("New character save completed\n")); + } +} + +// ---------------------------------------------------------------------- + +void Persister::receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message) +{ + const GameServerConnection * gameConnection = dynamic_cast(&source); + uint32 sourceGameServer = 0; + if (gameConnection) + sourceGameServer = gameConnection->getProcessId(); + + if(message.isType("FlagObjectForDeleteMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + FlagObjectForDeleteMessage m(ri); + handleDeleteMessage(sourceGameServer, m.getId(),m.getReason(),m.getImmediate(),m.getDemandLoadedContainer(),m.getCascadeReason()); + } + else if(message.isType("CreateObjectByCrcMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + CreateObjectByCrcMessage t(ri); +// DEBUG_REPORT_LOG(true,("Got CreateObjectByCrcMessage for %s\n", t.getId().getValueString().c_str())); + newObject(sourceGameServer, t.getId(), t.getCrc(), t.getObjectType(), t.getContainer()); + } + else if(message.isType("EndBaselinesMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + EndBaselinesMessage t(ri); + endBaselines(t.getId(),sourceGameServer); + } + else if(message.isType("DeltasMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + DeltasMessage msg(ri); + + handleDeltasMessage(sourceGameServer,msg); + } + else if(message.isType("BaselinesMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + BaselinesMessage msg(ri); + + handleBaselinesMessage(sourceGameServer,msg); + } + else if(message.isType("UpdateObjectPositionMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + UpdateObjectPositionMessage msg(ri); + + getSnapshotForObject(msg.getNetworkId(), sourceGameServer).handleUpdateObjectPosition(msg); + } + else if(message.isType("AddCharacterMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + AddCharacterMessage ocm(ri); + DEBUG_REPORT_LOG(true, ("Got AddCharacterMessage for object %s.\n",ocm.getObjectId().getValueString().c_str())); + + addCharacter(ocm.getAccountNumber(), ocm.getObjectId(), ocm.getProcess(), ocm.getName(), ocm.getSpecial()); + } + else if (message.isType("UnloadObjectMessage")) + { + // TODO: keep track of when it's done saving so we know when we can reload it + } + else if (message.isType("MessageToMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + MessageToMessage m(ri); + + handleMessageTo (sourceGameServer, m.getData()); + } + else if (message.isType("MessageToAckMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + MessageToAckMessage m(ri); + + handleMessageToAck (sourceGameServer, m.getMessageId()); + } + else if (message.isType("ServerDeleteCharacterMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + ServerDeleteCharacterMessage m(ri); + + deleteCharacter(m.getStationId(), m.getCharacterId()); + } + else if (message.isType("RenameCharacterMessageEx")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + RenameCharacterMessageEx msg(ri); + + renameCharacter(sourceGameServer, static_cast(msg.getRenameCharacterMessageSource()), msg.getStationId(), msg.getCharacterId(), msg.getNewName(), msg.getOldName(), msg.getLastNameChangeOnly(), msg.getRequestedBy(), NULL); + } + else if (message.isType("UnloadedPlayerMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + UnloadedPlayerMessage msg(ri); + + unloadCharacter(msg.getPlayerId(),sourceGameServer); + } + else if (message.isType("MoveToPlayer")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > msg(ri); + + moveToPlayer(sourceGameServer, msg.getValue().first, msg.getValue().second, -1, false, false); + } + else if (message.isType("MoveToPlayerBankMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > msg(ri); + + moveToPlayer(sourceGameServer, msg.getValue().first, msg.getValue().second, -1, true, false); + } + else if (message.isType("MoveToPlayerDatapadMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage, int> > msg(ri); + + moveToPlayer(sourceGameServer, msg.getValue().first.first, msg.getValue().first.second, msg.getValue().second, false, true); + } + else if (message.isType("FixLoadWith")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage, int> > msg(ri); + + fixLoadWith(sourceGameServer, msg.getValue().first.first, msg.getValue().first.second, msg.getValue().second); + } + else if (message.isType("ClusterShutdownMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + m_clusterShuttingDown = msg.getValue(); + } + else if (message.isType("StartSaveMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + + userRequestedSave(sourceGameServer, msg.getValue()); + } + else if (message.isType("RestoreHouseMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > msg(ri); + + restoreHouse(msg.getValue().first, msg.getValue().second); + } + else if (message.isType("RestoreCharacterMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > msg(ri); + + restoreCharacter(msg.getValue().first, msg.getValue().second); + } + else if (message.isType("UndeleteItemMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage > msg(ri); + + LOG("CustomerService", ("undeleteItem %s request from %s", msg.getValue().first.getValueString().c_str(), msg.getValue().second.c_str())); + undeleteItem(msg.getValue().first, msg.getValue().second); + } + else if (message.isType("MoveToPlayerMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage, std::string> > msg(ri); + + LOG("CustomerService", ("moveToPlayer %s, %s request from %s", msg.getValue().first.first.getValueString().c_str(), msg.getValue().first.second.getValueString().c_str(), msg.getValue().second.c_str())); + moveToPlayer(msg.getValue().first.first, msg.getValue().first.second, msg.getValue().second); + } + else if (message.isType("CentralRequestSave")) + { + centralRequestedSave(); + } + else if (message.isType("PlanetRequestSave")) + { + planetRequestedSave(); + } + else if (message.isType("AddResourceTypeMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + AddResourceTypeMessage msg(ri); + handleAddResourceTypeMessage(sourceGameServer, msg); + } + else if (message.isType("BountyHunterTargetMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + BountyHunterTargetMessage msg(ri); + getSnapshotForServer(sourceGameServer).handleBountyHunterTargetMessage(msg); + } + else if ( (message.isType("CMCreateAuctionMessage")) || + (message.isType("CMCreateAuctionBidMessage")) || + (message.isType("CMCreateLocationMessage")) || + (message.isType("CMUpdateAuctionMessage")) || + (message.isType("CMUpdateLocationMessage")) || + (message.isType("CMDeleteAuctionMessage")) || + (message.isType("CMDeleteLocationMessage")) ) + { + const CommoditiesServerConnection * commConnection = dynamic_cast(&source); + uint32 commServerId = 0; + if (commConnection) + commServerId = commConnection->getProcessId(); + + getCommoditiesSnapshot(commServerId).handleCommoditiesDataMessage(message); + } + else if (message.isType("LoadCommodities")) + { + if (m_commoditiesSnapshot) + { + m_commoditiesSnapshot->startLoadAfterSaveComplete(); + if (!isSaveInProgress()) + m_startSaveWhenPossible = true; + } + else + { + startLoadCommodities(); + } + } + else if (message.isType("GetMoneyFromOfflineObjectMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GetMoneyFromOfflineObjectMessage msg(ri); + getMoneyFromOfflineObject(sourceGameServer, msg.getSourceObject(), msg.getAmount(), msg.getReplyTo(), msg.getSuccessCallback(), msg.getFailCallback(), msg.getPackedDictionary()); + } + else if (message.isType("PurgeCompleteMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage msg(ri); + handlePurgeCompleteMessage(sourceGameServer, msg.getValue()); + } + else if( message.isType("DBCSRequestMessage" ) ) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + DBCSRequestMessage const msg( ri ); + handleCSRequest( msg ); + } + else if (message.isType("UndeleteItemForCsMessage")) + { + Archive::ReadIterator ri = static_cast(message).getByteStream().begin(); + GenericValueTypeMessage, std::string>, bool> > undeleteRequest(ri); + handleCsUndelete(undeleteRequest.getValue().first.first.first, + undeleteRequest.getValue().first.first.second, + undeleteRequest.getValue().first.second, + undeleteRequest.getValue().second); + } + else + { + DEBUG_REPORT_LOG(true,("Unrecognized message recieved by Persister.\n")); + } +} + +// ---------------------------------------------------------------------- +void Persister::handleCSRequest( const DBCSRequestMessage & msg ) +{ + if( msg.getCommand() == "warp_player" ) + { + handleCSMovePlayer( msg ); + } +} + +void Persister::handleCsUndelete(const NetworkId & character, const NetworkId & item, const std::string & message, bool move) +{ + UNREF(message); + DEBUG_REPORT_LOG(true,("Undeleting at db: %s %s\n", character.getValueString().c_str(), item.getValueString().c_str())); + taskQueue->asyncRequest(new TaskCsUndeleteItem(character, item, move)); +} + +void Persister::handleCSMovePlayer( const DBCSRequestMessage & msg ) +{ + char buffer[ 256 ]; + char scene_buf[ 32 ]; + float x = 0.0f; + float y = 0.0f; + float z = 0.0f; + int num_params; + if( ( num_params = sscanf( msg.getCommandLine().c_str(), "warp_player %s %s %f %f %f", buffer, scene_buf, &x, &y, &z ) ) == 5 ) + { + NetworkId id( buffer ); + if( id.isValid() ) + { + taskQueue->asyncRequest(new TaskMovePlayer(id, scene_buf, x, y, z)); + } + } +} + +// ---------------------------------------------------------------------- + +void Persister::addCharacter(uint32 stationId, const NetworkId &characterObject, uint32 creationGameServer, const Unicode::String &name, bool special) +{ + PendingCharacter temp; + temp.stationId = stationId; + temp.name = name; + temp.special = special; + m_pendingCharacters[characterObject]=temp; + + //TODO: remove this hack: match up create and end messages because we can't count on having all the data at a frame bounday + NewCharacterLockType::iterator i=m_newCharacterLock.find(creationGameServer); + UNREF(i); + DEBUG_FATAL(i!=m_newCharacterLock.end(),("Programmer bug: got an addCharacter from server %i before we received EndBaselines from the previous addCharacter. Indicates we're getting network messages out of order.\n",creationGameServer)); + m_newCharacterLock.insert(creationGameServer); +} + +// ---------------------------------------------------------------------- + +void Persister::onNewCharacterSaved (uint32 stationId, const NetworkId &characterObject, const Unicode::String &characterName, const int templateId, bool special) const +{ + DEBUG_REPORT_LOG(true,("Sending DatabaseCreateCharacterSuccess(%s)\n",characterObject.getValueString().c_str())); + DatabaseCreateCharacterSuccess const successMessage(characterObject, stationId, characterName, templateId, special); + DatabaseProcess::getInstance().sendToCentralServer(successMessage, true); +} + +// ---------------------------------------------------------------------- + +/** + * Save a delayed message in the database. + * Will be delivered to the object when the object is loaded, or removed + * from the database when it is acknowledged. + */ +void Persister::handleMessageTo(uint32 sourceServer, const MessageToPayload &data) +{ + if (data.getMessageId() == NetworkId::cms_invalid) + { + DEBUG_WARNING(true,("Database received a messageTo with serial number 0. Message method: %s, target: %s\n", data.getMethod().c_str(), data.getNetworkId().getValueString().c_str())); + } + else + { + if (!m_messageSnapshot) + m_messageSnapshot = &getSnapshotForServer(sourceServer); + + m_messageSnapshot->handleMessageTo(data); + } + MessageToManager::getInstance().handleMessageTo(data); +} + +// ---------------------------------------------------------------------- + +/** + * Mark that a delayed message has been handled + * Will be removed from the database. + */ +void Persister::handleMessageToAck(uint32 sourceServer, const MessageToId &messageId) +{ + if (!m_messageSnapshot) + m_messageSnapshot = &getSnapshotForServer(sourceServer); + + m_messageSnapshot->handleMessageToAck(messageId); + MessageToManager::getInstance().handleMessageToAck(messageId); +} + +// ---------------------------------------------------------------------- + +void Persister::deleteCharacter(StationId stationId, const NetworkId &characterId) +{ + // we cannot do the character delete in the current save cycle because + // the SQL that deletes a character also deletes items contained inside + // the character, but those items may have been transferred in the current + // save cycle, and the individual snapshots are updated in the DB in a + // non-deterministic order, possibly causing the delete character snapshot + // to execute before the snapshot that contains the containment update for + // the item, thus causing the item to get deleted incorrectly; to avoid + // this problem, we will delete the character during the next save cycle + if (m_charactersToDeleteNextSaveCycle && m_charactersToDeleteThisSaveCycle) + { + m_charactersToDeleteNextSaveCycle->push_back(std::make_pair(stationId, characterId)); + } + else + { + DeleteCharacterCustomPersistStep *cps = new DeleteCharacterCustomPersistStep(stationId, characterId); + getSnapshotForObject(characterId, 0).addCustomPersistStep(cps); + } + + // send delete character message to CommoditiesServer to delete auction items from this character + DeleteCharacterMessage msg(0, characterId); + DatabaseProcess::getInstance().sendToCommoditiesServer(msg, true); +} + +// ---------------------------------------------------------------------- + +void Persister::shutdown() +{ + delete taskQueue; + taskQueue=0; + + delete m_newCharacterTaskQueue; + m_newCharacterTaskQueue=0; +} + +// ---------------------------------------------------------------------- + +void Persister::renameCharacter(uint32 sourceServer, int8 renameCharacterMessageSource, uint32 stationId, const NetworkId &characterId, const Unicode::String &newName, const Unicode::String &oldName, bool lastNameChangeOnly, const NetworkId &requestedBy, const TransferCharacterData * renameRequest) +{ + // don't queue up another rename for the character + if (RenameCharacterCustomPersistStep::hasPendingRenameCharacterCustomPersistStep(characterId)) + { + if (static_cast(renameCharacterMessageSource) == RenameCharacterMessageEx::RCMS_player_request) + { + // send "player friendly" message + MessageToMessage const mtm( + MessageToPayload(characterId, NetworkId::cms_invalid, "C++RenameFailed", "There is already an outstanding rename request for this character.", 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(), 0), + DatabaseProcess::getInstance().getProcessId()); + + if ((sourceServer > 0) && DatabaseProcess::getInstance().getConnectionByProcess(sourceServer)) + DatabaseProcess::getInstance().sendToGameServer(sourceServer, mtm); + else + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + else if (requestedBy.isValid()) + { + // send GM message + MessageToMessage const mtm( + MessageToPayload(requestedBy, NetworkId::cms_invalid, "C++RenameFailed", FormattedString<512>().sprintf("Rename request for %s (%s) failed because the character currently has a pending rename request, which will be performed during the next save cycle.", characterId.getValueString().c_str(), Unicode::wideToNarrow(newName).c_str()), 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(), 0), + DatabaseProcess::getInstance().getProcessId()); + + if ((sourceServer > 0) && DatabaseProcess::getInstance().getConnectionByProcess(sourceServer)) + DatabaseProcess::getInstance().sendToGameServer(sourceServer, mtm); + else + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + + return; + } + + RenameCharacterCustomPersistStep *cps = new RenameCharacterCustomPersistStep(renameCharacterMessageSource, stationId, characterId, newName, oldName, requestedBy, renameRequest); + getSnapshotForServer(sourceServer).addCustomPersistStep(cps); + + if (static_cast(renameCharacterMessageSource) == RenameCharacterMessageEx::RCMS_player_request) + { + // if player requested, send confirmation message back to player character + MessageToMessage const mtm( + MessageToPayload(characterId, NetworkId::cms_invalid, (lastNameChangeOnly ? "C++PlayerLastNameRenameRequestSubmitted" : "C++PlayerRenameRequestSubmitted"), Unicode::wideToNarrow(newName), 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(), 0), + DatabaseProcess::getInstance().getProcessId()); + + if ((sourceServer > 0) && DatabaseProcess::getInstance().getConnectionByProcess(sourceServer)) + DatabaseProcess::getInstance().sendToGameServer(sourceServer, mtm); + else + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + else if (requestedBy.isValid()) + { + // if GM requested, send confirmation message to GM + MessageToMessage const mtm( + MessageToPayload(requestedBy, NetworkId::cms_invalid, "C++GmRenameRequestSubmitted", FormattedString<512>().sprintf("Rename request for %s (%s) has been submitted, and will be performed during the next save cycle.", characterId.getValueString().c_str(), Unicode::wideToNarrow(newName).c_str()), 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(), 0), + DatabaseProcess::getInstance().getProcessId()); + + if ((sourceServer > 0) && DatabaseProcess::getInstance().getConnectionByProcess(sourceServer)) + DatabaseProcess::getInstance().sendToGameServer(sourceServer, mtm); + else + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + + if (requestedBy.isValid()) + LOG("CustomerService", ("Player:rename character request submitted for %s (%s -> %s) for stationId %lu by %s", characterId.getValueString().c_str(), Unicode::wideToNarrow(oldName).c_str(), Unicode::wideToNarrow(newName).c_str(), stationId, requestedBy.getValueString().c_str())); + else + LOG("CustomerService", ("Player:rename character request submitted for %s (%s -> %s) for stationId %lu", characterId.getValueString().c_str(), Unicode::wideToNarrow(oldName).c_str(), Unicode::wideToNarrow(newName).c_str(), stationId)); +} + +// ---------------------------------------------------------------------- + +void Persister::changeStationId(const TransferAccountData * transferRequest) +{ + taskQueue->asyncRequest(new TaskChangeStationId(transferRequest->getSourceStationId(), transferRequest->getDestinationStationId(), transferRequest)); +} + +// ---------------------------------------------------------------------- + +void Persister::unloadCharacter(const NetworkId &characterId, uint32 sourceServer) +{ + UnloadCharacterCustomPersistStep *cps = new UnloadCharacterCustomPersistStep(characterId, sourceServer); + getSnapshotForObject(characterId, sourceServer).addCustomPersistStep(cps); +} + +// ---------------------------------------------------------------------- + +bool Persister::isIdle() +{ + return (m_currentSnapshots.empty() && m_newObjectSnapshots.empty() && m_savingSnapshots.empty() && taskQueue->isIdle() && m_newCharacterTaskQueue->isIdle()); +} + +// ---------------------------------------------------------------------- + +bool Persister::isSaveInProgress() +{ + return (!m_savingSnapshots.empty()); +} + +// ---------------------------------------------------------------------- + +void Persister::moveToPlayer(uint32 sourceServer, const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad) +{ + MoveToPlayerCustomPersistStep *cps = new MoveToPlayerCustomPersistStep(objectId, targetPlayer, maxDepth, useBank, useDatapad); + getSnapshotForObject(objectId, sourceServer).addCustomPersistStep(cps); +} + +// ---------------------------------------------------------------------- + +void Persister::fixLoadWith(uint32 sourceServer, const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth) +{ + FixLoadWithCustomPersistStep *cps = new FixLoadWithCustomPersistStep(topmostObject, startingLoadWith, maxDepth); + getSnapshotForObject(topmostObject, sourceServer).addCustomPersistStep(cps); +} + +// ---------------------------------------------------------------------- + +std::string Persister::getLastSaveCompletionTime() +{ + return m_lastSaveCompletionTime; +} + +// ---------------------------------------------------------------------- + +void Persister::userRequestedSave(uint32 sourceGameServer, const NetworkId &whoRequested) +{ + bool started = false; + if (!isSaveInProgress()) + { + started = true; + m_startSaveWhenPossible = true; + } + + if (sourceGameServer != 0) + { + GenericValueTypeMessage > reply("StartSaveReplyMessage", std::make_pair(whoRequested, started)); + DatabaseProcess::getInstance().sendToGameServer(sourceGameServer, reply); + } +} + +// ---------------------------------------------------------------------- + +void Persister::centralRequestedSave() +{ + m_startSaveWhenPossible = true; +} + +// ---------------------------------------------------------------------- + +void Persister::planetRequestedSave() +{ + m_startSaveWhenPossible = true; +} + +// ---------------------------------------------------------------------- + +void Persister::handleAddResourceTypeMessage(uint32 const serverId, AddResourceTypeMessage const & message) +{ + getSnapshotForServer(serverId).handleAddResourceTypeMessage(message); +} + +// ---------------------------------------------------------------------- + +void Persister::handlePurgeCompleteMessage(uint32 const serverId, StationId stationId) +{ + PurgeCompleteCustomPersistStep * cps = new PurgeCompleteCustomPersistStep(stationId); + getSnapshotForServer(serverId).addCustomPersistStep(cps); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/Persister.h b/engine/server/library/serverDatabase/src/shared/Persister.h new file mode 100644 index 00000000..b4e12afc --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Persister.h @@ -0,0 +1,240 @@ +// ====================================================================== +// +// Persister.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Persister_H +#define INCLUDED_Persister_H + +// ====================================================================== + +#include +#include +#include +#include +#include //TODO: remove when we clean up newCharacterLock hack + +#include "Unicode.h" +#include "serverNetworkMessages/MessageToPayload.h" +#include "sharedDatabaseInterface/DbModeQuery.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedFoundation/StationId.h" +#include "sharedFoundation/Tag.h" +#include "sharedMessageDispatch/Receiver.h" + +class AddResourceTypeMessage; +class BaselinesMessage; +class BountyHunterTargetMessage; +class DeltasMessage; +class Snapshot; +class TransferAccountData; +class TransferCharacterData; +class DBCSRequestMessage; + +namespace DB +{ + class TaskQueue; +} + +// ====================================================================== + +/** + * Singleton that organizes messages to be persisted to the database. + * + * For now, directs all changes to a "snapshot" object. For the future, + * may want to have a snapshot for each server so that we can do more in + * parallel. This might be implemented by having multiple instances + * of Persister. + * + * This is an abstract base class. A game-specific Persister should + * be derived from it. + */ +class Persister : public MessageDispatch::Receiver +{ + public: + static Persister &getInstance(); + + void handleDeleteMessage (uint32 serverId, const NetworkId &objectId, int reasonCode, bool immediate, bool demandLoadedContainer, bool cascadeReason); + void handleMessageTo (uint32 sourceServer, const MessageToPayload &data); + void handleMessageToAck (uint32 sourceServer, const MessageToId &messageId); + + void update(real updateTime); + void onFrameBarrierReached(); + bool isIdle(); + bool isSaveInProgress(); + + void newObject(uint32 serverId, const NetworkId &objectId, int templateId, Tag typeId, const NetworkId &container); + void beginBaselines(const NetworkId &newObject) const; + void endBaselines(const NetworkId &newObject, uint32 serverId); + + void saveCompleted (Snapshot *completedSnapshot); + void onNewCharacterSaved (uint32 stationId, const NetworkId &characterObject, const Unicode::String &characterName, const int templateId, bool special) const; + + void receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message); + + void shutdown(); + + int getTimeSinceLastSave(); + int getLastSaveTime(); + int getLastSaveTotalObjectCount(); + int getLastSaveNewObjectCount(); + std::string getLastSaveCompletionTime(); + + void unloadCharacter(const NetworkId &characterId, uint32 sourceServer); + bool hasDataForObject(const NetworkId &objectId) const; + void renameCharacter(uint32 sourceServer, int8 renameCharacterMessageSource, uint32 stationId, const NetworkId &characterId, const Unicode::String &newName, const Unicode::String &oldName, bool lastNameChangeOnly, const NetworkId &requestedBy, const TransferCharacterData * renameRequest); + void changeStationId(const TransferAccountData * transferRequest); + + void handleCSRequest( const DBCSRequestMessage & msg ); + void handleCSMovePlayer( const DBCSRequestMessage & msg ); + void handleCsUndelete(const NetworkId & character, const NetworkId & item, const std::string & message, bool move); + + virtual void startLoadCommodities() =0; + protected: + DB::TaskQueue *taskQueue; + DB::TaskQueue *m_newCharacterTaskQueue; + + private: + struct PendingCharacter + { + uint32 stationId; + Unicode::String name; + bool special; + }; + + typedef std::map ServerSnapshotMap; + typedef std::hash_map ObjectSnapshotMap; + typedef std::map PendingCharactersType; + typedef std::vector SnapshotListType; + typedef std::set NewCharacterLockType; + typedef std::vector > CharactersToDeleteType; + + ServerSnapshotMap m_currentSnapshots; + ServerSnapshotMap m_newObjectSnapshots; + ServerSnapshotMap m_newCharacterSnapshots; + ObjectSnapshotMap m_objectSnapshotMap; + PendingCharactersType m_pendingCharacters; + SnapshotListType m_savingSnapshots; + SnapshotListType m_savingCharacterSnapshots; + NewCharacterLockType m_newCharacterLock; + CharactersToDeleteType * m_charactersToDeleteThisSaveCycle; + CharactersToDeleteType * m_charactersToDeleteNextSaveCycle; + real m_timeSinceLastSave; + Snapshot * m_messageSnapshot; + Snapshot * m_commoditiesSnapshot; + Snapshot * m_arbitraryGameDataSnapshot; + int m_saveStartTime; + int m_totalSaveTime; + int m_maxSaveTime; + int m_saveCount; + int m_newObjectCount; + + int m_lastSaveTime; + int m_lastSaveTotalObjectCount; + int m_lastSaveNewObjectCount; + std::string m_lastSaveCompletionTime; + int m_saveCounter; + + bool m_startSaveWhenPossible; + bool m_inMagicMinute; + bool m_clusterShuttingDown; + + protected: + + virtual void startSave() = 0; + + Snapshot & getSnapshotForObject(const NetworkId &networkId, uint32 serverId); + Snapshot & getSnapshotForServer(uint32 serverId); + + private: + + void handleDeltasMessage (uint32 serverId, const DeltasMessage &msg); + void handleBaselinesMessage (uint32 serverId, const BaselinesMessage &msg); + void handleAddResourceTypeMessage(uint32 const serverId, AddResourceTypeMessage const & message); + void handlePurgeCompleteMessage(uint32 const serverId, StationId stationId); + void addCharacter (uint32 stationId, const NetworkId &characterObject, uint32 creationGameServer, const Unicode::String &name, bool special); + void deleteCharacter (StationId stationId, const NetworkId &characterId); + void recordMoneyTransaction (uint32 sourceServer, const NetworkId &transactionId, const int transactionType, const NetworkId &sourceId, const std::string &sourceString, const NetworkId &targetId, const std::string &targetString, int amount); + void moveToPlayer (uint32 sourceServer, const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad); + void fixLoadWith (uint32 sourceServer, const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth); + void moveToContainer (uint32 sourceServer, NetworkId const & objectId, NetworkId const & targetContainer); + void userRequestedSave (uint32 sourceGameServer, const NetworkId &whoRequested); + void centralRequestedSave (); + void planetRequestedSave (); + + Snapshot & getCommoditiesSnapshot(uint32 serverId); + + /** + * Derived class should override this to make a game-specific derived Snapshot. + */ + virtual Snapshot *makeSnapshot(DB::ModeQuery::Mode mode) const =0; + virtual Snapshot *makeCommoditiesSnapshot(DB::ModeQuery::Mode mode) const =0; + + /** + * Admin functions + */ + virtual void restoreHouse(const NetworkId &houseId, const std::string &whoRequested)=0; + virtual void restoreCharacter(const NetworkId &characterId, const std::string &whoRequested)=0; + virtual void undeleteItem(const NetworkId &itemId, const std::string &whoRequested)=0; + virtual void moveToPlayer(const NetworkId &oid, const NetworkId &player, const std::string &whoRequested)=0; + + /** + * Misc game-specific persistence steps + */ + virtual void getMoneyFromOfflineObject(uint32 replyServer, NetworkId const & sourceObject, int amount, NetworkId const & replyTo, std::string const & successCallback, std::string const & failCallback, stdvector::fwd const & packedDictionary)=0; + + protected: + Persister(); + virtual ~Persister(); + static void installDerived(Persister *derivedInstance); + + private: + Persister(Persister&); //disable + Persister &operator=(const Persister&); //disable + + private: + static void remove(); + static Persister *ms_instance; +}; + +// ---------------------------------------------------------------------- + +inline Persister &Persister::getInstance() +{ + NOT_NULL(ms_instance); + return *ms_instance; +} + +// ---------------------------------------------------------------------- + +inline int Persister::getTimeSinceLastSave() +{ + return static_cast(m_timeSinceLastSave); +} + +// ---------------------------------------------------------------------- + +inline int Persister::getLastSaveTime() +{ + return m_lastSaveTime; +} + +// ---------------------------------------------------------------------- + +inline int Persister::getLastSaveTotalObjectCount() +{ + return m_lastSaveTotalObjectCount; +} + +// ---------------------------------------------------------------------- + +inline int Persister::getLastSaveNewObjectCount() +{ + return m_lastSaveNewObjectCount; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.cpp b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.cpp new file mode 100644 index 00000000..8e903747 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.cpp @@ -0,0 +1,65 @@ +// ====================================================================== +// +// PreloadListQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/PreloadListQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +using namespace DBQuery; + +// ---------------------------------------------------------------------- + +PreloadListQuery::PreloadListQuery(const std::string &sceneId) +{ + scene_id.setValue(sceneId); +} + +// ---------------------------------------------------------------------- + +PreloadListQuery::~PreloadListQuery() +{ +} + +// ---------------------------------------------------------------------- + +void PreloadListQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :result := ") + DatabaseProcess::getInstance().getSchemaQualifier() + "loader.get_preload_list(:planet); end;"; +} + +// ---------------------------------------------------------------------- + +bool PreloadListQuery::bindParameters() +{ + if (!bindParameter(scene_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool PreloadListQuery::bindColumns() +{ + if (!bindCol(object_id)) return false; + if (!bindCol(chunk_x)) return false; + if (!bindCol(chunk_z)) return false; + if (!bindCol(preload_range)) return false; + if (!bindCol(city_server_id)) return false; + if (!bindCol(wilderness_server_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode PreloadListQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h new file mode 100644 index 00000000..3f7695b8 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/PreloadListQuery.h @@ -0,0 +1,55 @@ +// ====================================================================== +// +// PreloadListQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_PreloadListQuery_H +#define INCLUDED_PreloadListQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +class NetworkId; + +// ====================================================================== + +namespace DBQuery +{ + + class PreloadListQuery : public DB::Query + { + public: + PreloadListQuery(const std::string &sceneId); + virtual ~PreloadListQuery(); + + public: + DB::BindableString<50> scene_id; + DB::BindableNetworkId object_id; + DB::BindableLong chunk_x; + DB::BindableLong chunk_z; + DB::BindableLong preload_range; + DB::BindableLong city_server_id; + DB::BindableLong wilderness_server_id; + + public: + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual void getSQL(std::string &sql); + + private: + virtual QueryMode getExecutionMode() const; + + private: + PreloadListQuery(const PreloadListQuery&); // disable + PreloadListQuery& operator=(const PreloadListQuery&); // disable + }; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.cpp new file mode 100644 index 00000000..a9c23f64 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.cpp @@ -0,0 +1,51 @@ +// ====================================================================== +// +// PurgeCompleteCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/PurgeCompleteCustomPersistStep.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +PurgeCompleteCustomPersistStep::PurgeCompleteCustomPersistStep(StationId stationId) : + m_stationId(stationId) +{ +} + +// ---------------------------------------------------------------------- + +PurgeCompleteCustomPersistStep::~PurgeCompleteCustomPersistStep() +{ +} + +// ---------------------------------------------------------------------- + +bool PurgeCompleteCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool PurgeCompleteCustomPersistStep::afterPersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +void PurgeCompleteCustomPersistStep::onComplete() +{ + GenericValueTypeMessage msg("PurgeCompleteMessage", m_stationId); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.h new file mode 100644 index 00000000..f0db5f1b --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/PurgeCompleteCustomPersistStep.h @@ -0,0 +1,43 @@ +// ====================================================================== +// +// PurgeCompleteCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_PurgeCompleteCustomPersistStep_H +#define INCLUDED_PurgeCompleteCustomPersistStep_H + +// ====================================================================== + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedFoundation/StationId.h" + +// ====================================================================== + +/** + * A custom persist step when a step in the purge cycle has been + * completed for the specified account and saved to the database. + * Sends an acknowledgement to the Login Server (via Central) + */ +class PurgeCompleteCustomPersistStep : public CustomPersistStep +{ + public: + explicit PurgeCompleteCustomPersistStep(StationId stationId); + ~PurgeCompleteCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + StationId m_stationId; + + private: + PurgeCompleteCustomPersistStep &operator= (const PurgeCompleteCustomPersistStep&); //disable + PurgeCompleteCustomPersistStep(const PurgeCompleteCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.cpp new file mode 100644 index 00000000..062e3d2d --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.cpp @@ -0,0 +1,177 @@ +// ====================================================================== +// +// RenameCharacterCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/RenameCharacterCustomPersistStep.h" + +#include "serverDatabase/CharacterQueries.h" +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/MessageToMessage.h" +#include "serverNetworkMessages/RenameCharacterMessage.h" +#include "serverNetworkMessages/TransferCharacterData.h" +#include "serverNetworkMessages/TransferCharacterDataArchive.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedFoundation/FormattedString.h" +#include "sharedLog/Log.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +namespace RenameCharacterCustomPersistStepNamespace +{ + std::map s_pendingRenameCharacterCustomPersistStep; +} + +using namespace RenameCharacterCustomPersistStepNamespace; + +// ====================================================================== + +RenameCharacterCustomPersistStep::RenameCharacterCustomPersistStep(int8 renameCharacterMessageSource, uint32 stationId, const NetworkId &characterId, const Unicode::String &characterName, const Unicode::String &characterOldName, const NetworkId &requestedBy, const TransferCharacterData * requestData) : + m_renameCharacterMessageSource(renameCharacterMessageSource), + m_stationId(stationId), + m_characterId(characterId), + m_characterName(new Unicode::String(characterName)), + m_characterOldName(new Unicode::String(characterOldName)), + m_requestedBy(requestedBy), + m_success(false), + m_requestData(0) +{ + if(requestData) + { + m_requestData = new TransferCharacterData(*requestData); + } + + if (m_characterId.isValid()) + { + std::map::iterator iterFind = s_pendingRenameCharacterCustomPersistStep.find(m_characterId); + if (iterFind != s_pendingRenameCharacterCustomPersistStep.end()) + ++(iterFind->second); + else + s_pendingRenameCharacterCustomPersistStep.insert(std::make_pair(m_characterId, 1)); + } +} + +// ---------------------------------------------------------------------- + +RenameCharacterCustomPersistStep::~RenameCharacterCustomPersistStep() +{ + delete m_characterName; + delete m_characterOldName; + delete m_requestData; + m_characterName = 0; + m_characterOldName = 0; + m_requestData = 0; + + if (m_characterId.isValid()) + { + std::map::iterator iterFind = s_pendingRenameCharacterCustomPersistStep.find(m_characterId); + if (iterFind != s_pendingRenameCharacterCustomPersistStep.end()) + { + if (iterFind->second <= 1) + s_pendingRenameCharacterCustomPersistStep.erase(iterFind); + else + --(iterFind->second); + } + + // if player requested, let CentralServer know that the request has + // been completed, so CentralServer will allow the character to log back in + if (static_cast(m_renameCharacterMessageSource) == RenameCharacterMessageEx::RCMS_player_request) + { + GenericValueTypeMessage > const msg("PlayerRenameRequestCompleted", std::make_pair(static_cast(m_stationId), m_characterId)); + DatabaseProcess::getInstance().sendToCentralServer(msg, true); + } + } +} + +// ---------------------------------------------------------------------- + +bool RenameCharacterCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool RenameCharacterCustomPersistStep::afterPersist(DB::Session *session) +{ + DBQuery::RenameCharacter qry(m_characterId, *m_characterName, DataLookup::getInstance().normalizeName(*m_characterName)); + if (! (session->exec(&qry))) + return false; + m_success=qry.getResult(); + qry.done(); + return true; +} + +// ---------------------------------------------------------------------- + +void RenameCharacterCustomPersistStep::onComplete() +{ + if (! m_requestData) + { + if (m_success) + { + // send to login server (by way of central) + RenameCharacterMessageEx msg(static_cast(m_renameCharacterMessageSource), m_stationId, m_characterId, *m_characterName, *m_characterOldName, m_requestedBy); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); + + // have all the game servers update their name managers + DatabaseProcess::getInstance().sendToAllGameServers(msg,true); + + // update name if the character is logged in + MessageToMessage const mtm( + MessageToPayload(m_characterId, NetworkId::cms_invalid, "C++RenameCharacter", Unicode::wideToNarrow(*m_characterName), 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(),0), + DatabaseProcess::getInstance().getProcessId()); + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + else + { + // send failure message to person who requested rename + if ((static_cast(m_renameCharacterMessageSource) != RenameCharacterMessageEx::RCMS_player_request) && m_requestedBy.isValid()) + { + // send GM message + MessageToMessage const mtm( + MessageToPayload(m_requestedBy, NetworkId::cms_invalid, "C++RenameFailed", FormattedString<512>().sprintf("Rename request for %s (%s) failed because the name is already in use.", m_characterId.getValueString().c_str(), Unicode::wideToNarrow(*m_characterName).c_str()), 0, false, MessageToPayload::DT_c, NetworkId::cms_invalid, std::string(), 0), + DatabaseProcess::getInstance().getProcessId()); + DatabaseProcess::getInstance().sendToAnyGameServer(mtm); + } + } + } + else + { + TransferCharacterData replyData(*m_requestData); + replyData.setIsValidName(m_success); + + GenericValueTypeMessage reply("TransferRenameCharacterReplyFromDatabase", replyData); + DatabaseProcess::getInstance().sendToCentralServer(reply, true); + } + + if (m_success) + { + if (m_requestedBy.isValid()) + LOG("CustomerService", ("Player:rename character request SUCCESS for %s (%s -> %s) for stationId %lu by %s", m_characterId.getValueString().c_str(), Unicode::wideToNarrow(*m_characterOldName).c_str(), Unicode::wideToNarrow(*m_characterName).c_str(), m_stationId, m_requestedBy.getValueString().c_str())); + else + LOG("CustomerService", ("Player:rename character request SUCCESS for %s (%s -> %s) for stationId %lu", m_characterId.getValueString().c_str(), Unicode::wideToNarrow(*m_characterOldName).c_str(), Unicode::wideToNarrow(*m_characterName).c_str(), m_stationId)); + } + else + { + if (m_requestedBy.isValid()) + LOG("CustomerService", ("Player:rename character request FAILED for %s (%s -> %s) for stationId %lu by %s", m_characterId.getValueString().c_str(), Unicode::wideToNarrow(*m_characterOldName).c_str(), Unicode::wideToNarrow(*m_characterName).c_str(), m_stationId, m_requestedBy.getValueString().c_str())); + else + LOG("CustomerService", ("Player:rename character request FAILED for %s (%s -> %s) for stationId %lu", m_characterId.getValueString().c_str(), Unicode::wideToNarrow(*m_characterOldName).c_str(), Unicode::wideToNarrow(*m_characterName).c_str(), m_stationId)); + } +} + +// ---------------------------------------------------------------------- + +bool RenameCharacterCustomPersistStep::hasPendingRenameCharacterCustomPersistStep(const NetworkId &characterId) +{ + return (s_pendingRenameCharacterCustomPersistStep.count(characterId) > 0); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.h new file mode 100644 index 00000000..710fc8f8 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/RenameCharacterCustomPersistStep.h @@ -0,0 +1,46 @@ +// ====================================================================== +// +// RenameCharacterCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_RenameCharacterCustomPersistStep_H +#define INCLUDED_RenameCharacterCustomPersistStep_H + +// ====================================================================== + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedFoundation/NetworkId.h" + +class NetworkId; +class TransferCharacterData; + +// ====================================================================== + +class RenameCharacterCustomPersistStep : public CustomPersistStep +{ + public: + RenameCharacterCustomPersistStep(int8 renameCharacterMessageSource, uint32 stationId, const NetworkId &characterId, const Unicode::String &characterName, const Unicode::String &characterOldName, const NetworkId &requestedBy, const TransferCharacterData * requestData); + ~RenameCharacterCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + static bool hasPendingRenameCharacterCustomPersistStep(const NetworkId &characterId); + + private: + int8 m_renameCharacterMessageSource; + uint32 m_stationId; + NetworkId m_characterId; + Unicode::String * m_characterName; + Unicode::String * m_characterOldName; + NetworkId m_requestedBy; + bool m_success; + TransferCharacterData * m_requestData; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.cpp b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.cpp new file mode 100644 index 00000000..cf4e7641 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.cpp @@ -0,0 +1,44 @@ +// ====================================================================== +// +// SaveTimestampQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/SaveTimestampQuery.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +SaveTimestampQuery::SaveTimestampQuery(int _timestamp) : + timestamp(_timestamp) +{ +} + +// ====================================================================== + +void SaveTimestampQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "persister.set_clock (:time); end;"; +} + +// ====================================================================== + +bool SaveTimestampQuery::bindParameters() +{ + if (!bindParameter(timestamp)) return false; + return true; +} + +// ====================================================================== + +bool SaveTimestampQuery::bindColumns() +{ + return true; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h new file mode 100644 index 00000000..77d4e077 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/SaveTimestampQuery.h @@ -0,0 +1,42 @@ +// ====================================================================== +// +// SaveTimestampQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_SaveTimestampQuery_H +#define INCLUDED_SaveTimestampQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery +{ + + class SaveTimestampQuery : public DB::Query + { + public: + SaveTimestampQuery(int _timestamp); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + DB::BindableLong timestamp; + + private: + SaveTimestampQuery(const SaveTimestampQuery &); // disable + SaveTimestampQuery & operator=(const SaveTimestampQuery &); //disable + }; + +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/ScriptQueries.cpp b/engine/server/library/serverDatabase/src/shared/ScriptQueries.cpp new file mode 100644 index 00000000..9a4a5e7a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ScriptQueries.cpp @@ -0,0 +1,92 @@ +// ====================================================================== +// +// ScriptQueries.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/ScriptQueries.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +using namespace DBQuery; + +// ====================================================================== + +void ScriptClearQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "persister.clear_scripts(:oid); end;"; +} + +// ---------------------------------------------------------------------- + +bool ScriptClearQuery::bindParameters() +{ + if (!bindParameter(object_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool ScriptClearQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +void ScriptClearQuery::setNetworkId(NetworkId objectID) +{ + object_id.setValue(objectID); +} + +// ====================================================================== + +GetScripts::GetScripts(const std::string &schema) : + m_data(ConfigServerDatabase::getDefaultFetchBatchSize()), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void GetScripts::getSQL(std::string &sql) +{ + sql=std::string("begin :result := ") + m_schema + "loader.load_scripts; end;"; +} + +// ---------------------------------------------------------------------- + +bool GetScripts::bindParameters() +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool GetScripts::bindColumns() +{ + size_t skipSize = reinterpret_cast(&(m_data[1])) - reinterpret_cast(&(m_data[0])); + setColArrayMode(skipSize, m_data.size()); + + if (!bindCol(m_data[0].object_id)) return false; + if (!bindCol(m_data[0].script_name)) return false; + if (!bindCol(m_data[0].index)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetScripts::getExecutionMode() const +{ + if (getProtocol()==DB::PROTOCOL_OCI) + return (MODE_PLSQL_REFCURSOR); + else + return (MODE_SQL); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/ScriptQueries.h b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h new file mode 100644 index 00000000..ec916eec --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/ScriptQueries.h @@ -0,0 +1,82 @@ +// ====================================================================== +// +// ScriptQueries.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_ScriptQueries_H +#define INCLUDED_ScriptQueries_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include + +// ====================================================================== + +namespace DBQuery +{ + class ScriptClearQuery : public DB::Query + { + public: + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + void setNetworkId(NetworkId objectID); + + ScriptClearQuery() {} + + private: + DB::BindableNetworkId object_id; + + ScriptClearQuery(const ScriptClearQuery&); + ScriptClearQuery &operator=(const ScriptClearQuery&); + }; + +// ---------------------------------------------------------------------- + + class GetScripts : public DB::Query + { + public: + struct ScriptRow + { + DB::BindableNetworkId object_id; + DB::BindableLong index; + DB::BindableString<128> script_name; + }; + + public: + GetScripts(const std::string &schema); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + QueryMode getExecutionMode() const; + + const std::vector & getData() const; + + private: + std::vector m_data; + const std::string m_schema; + + GetScripts(const GetScripts&); + GetScripts &operator=(const GetScripts&); + }; + +} // namespace + +// ====================================================================== + +inline const std::vector & DBQuery::GetScripts::getData() const +{ + return m_data; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.cpp b/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.cpp new file mode 100644 index 00000000..a233a59d --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.cpp @@ -0,0 +1,53 @@ +// ====================================================================== +// +// SetBiographyQuery.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/SetBiographyQuery.h" + +using namespace DBQuery; + +#include "serverDatabase/DatabaseProcess.h" + +// ====================================================================== + +SetBiographyQuery::SetBiographyQuery(const NetworkId &newOwner, const Unicode::String &newBio) : + owner(newOwner), + bio(newBio) +{ +} + +// ---------------------------------------------------------------------- + +void SetBiographyQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "biography.set_biography(:owner, :bio); end;"; +} + +// ---------------------------------------------------------------------- + +bool SetBiographyQuery::bindParameters() +{ + if (!bindParameter(owner)) return false; + if (!bindParameter(bio)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool SetBiographyQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode SetBiographyQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.h b/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.h new file mode 100644 index 00000000..4a16983a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/SetBiographyQuery.h @@ -0,0 +1,47 @@ +// ====================================================================== +// +// SetBiographyQuery.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_SetBiographyQuery_H +#define INCLUDED_SetBiographyQuery_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" + +// ====================================================================== + +namespace DBQuery { + + class SetBiographyQuery : public DB::Query + { + public: + + SetBiographyQuery(const NetworkId &newOwner, const Unicode::String &newBio); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + protected: + virtual QueryMode getExecutionMode() const; + + private: + DB::BindableNetworkId owner; + DB::BindableUnicode<1024> bio; + + private: + SetBiographyQuery(const SetBiographyQuery&); // disable + SetBiographyQuery& operator=(const SetBiographyQuery&); //disable + }; + +} //namespace + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/Snapshot.cpp b/engine/server/library/serverDatabase/src/shared/Snapshot.cpp new file mode 100644 index 00000000..ab3203bc --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Snapshot.cpp @@ -0,0 +1,262 @@ +// ====================================================================== +// +// Snapshot.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/Snapshot.h" + +#include "serverDatabase/AbstractTableBuffer.h" +#include "serverDatabase/CustomPersistStep.h" +#include "serverDatabase/ObjectLocator.h" +#include "serverDatabase/SaveTimestampQuery.h" +#include "serverUtility/ServerClock.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedFoundation/NetworkIdArchive.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +int Snapshot::ms_creationCount=0; +int Snapshot::ms_deletionCount=0; + +// ====================================================================== + +Snapshot::Snapshot(DB::ModeQuery::Mode mode, bool useGoldDatabase) : + m_universeAuthorityHack(false), + m_isBeingSaved(false), + m_useGoldDatabase(useGoldDatabase), + m_mode(mode), + m_timestamp(0) +{ + LOG("Snapshot",("Created snapshot")); + ++ms_creationCount; +} + +// ---------------------------------------------------------------------- + +Snapshot::~Snapshot() +{ + for (LocatorListType::iterator i=m_locatorList.begin(); i!=m_locatorList.end(); ++i) + { + delete *i; + *i=0; + } + + for (CustomStepListType::iterator j=m_customStepList.begin(); j!=m_customStepList.end(); ++j) + delete *j; + + ++ms_deletionCount; + LOG("Snapshot",("Deleted snapshot. %i outstanding, %i created, %i deleted", ms_creationCount-ms_deletionCount,ms_creationCount,ms_deletionCount)); +} + +// ---------------------------------------------------------------------- + +/** + * Called by a worker thread. Saves the snapshot to the database + * + * Saves all the buffers in the list and runs any custom steps. + */ + +bool Snapshot::saveToDB(DB::Session *session) +{ + NOT_NULL(session); + + CustomStepListType::iterator step; + for (step=m_customStepList.begin(); step !=m_customStepList.end(); ++step) + { + NOT_NULL(*step); + if (!(*step)->beforePersist(session)) + return false; + } + + if (m_timestamp!=0) + if (! saveTimestamp(session)) + return false; + + for (BufferListType::iterator buffer=m_bufferList.begin(); buffer!=m_bufferList.end(); ++buffer) + { + if (! (*buffer)->save(session)) + return false; + } + + for (step=m_customStepList.begin(); step !=m_customStepList.end(); ++step) + { + NOT_NULL(*step); + if (!(*step)->afterPersist(session)) + return false; + } + + return true; +} +// ---------------------------------------------------------------------- + +/** + * Called when a message is received to update an object's data. + * + * Identifies what package the message is part of, and invokes the + * appropriate (virtual) function. + */ + +void Snapshot::handleDeltasMessage(NetworkId objectId, const DeltasMessage &msg) +{ + unsigned char packageId=msg.getPackageId(); + Tag typeId=msg.getTypeId(); + Archive::ReadIterator bs=msg.getPackage().begin(); + uint16 count; + Archive::get(bs,count); + DEBUG_REPORT_LOG(count==0,("Deltas package was empty.\n")); + for (uint16 i=0; i< count; ++i) + { + unsigned short int index; + Archive::get(bs,index); + if (packageId==DeltasMessage::DELTAS_SERVER) + { + decodeServerData(objectId,typeId,index,bs,false); + } + else if (packageId==DeltasMessage::DELTAS_SHARED) + { + decodeSharedData(objectId,typeId,index,bs,false); + } + else if (packageId==DeltasMessage::DELTAS_CLIENT_SERVER) + { + decodeClientData(objectId,typeId,index,bs,false); + } + else if (packageId==DeltasMessage::DELTAS_SERVER_NP) + { + } + else if (packageId==DeltasMessage::DELTAS_SHARED_NP) + { + } + else if (packageId==DeltasMessage::DELTAS_CLIENT_SERVER_NP) + { + } + else if (packageId==DeltasMessage::DELTAS_FIRST_PARENT_CLIENT_SERVER) + { + decodeParentClientData(objectId,typeId,index,bs,false); + } + else if (packageId==DeltasMessage::DELTAS_FIRST_PARENT_CLIENT_SERVER_NP) + { + } + else if (packageId==DeltasMessage::DELTAS_UI) + { + } + else + { + FATAL(true,("PackageId was invalid.")); + } + } +} + +// ---------------------------------------------------------------------- + +/** + * Called when a message is received to update an object's data. + * + * Identifies what package the message is part of, and invokes the + * appropriate (virtual) function. + */ + +void Snapshot::handleBaselinesMessage(NetworkId objectId, const BaselinesMessage &msg) +{ + unsigned char packageId=msg.getPackageId(); + Tag typeId=msg.getTypeId(); + Archive::ReadIterator bs=msg.getPackage().begin(); + uint16 count; + Archive::get(bs,count); + for (uint16 i=0; i< count; ++i) + { + if (packageId==BaselinesMessage::BASELINES_SERVER) + { + decodeServerData(objectId,typeId,i,bs,true); + } + else if (packageId==BaselinesMessage::BASELINES_SHARED) + { + decodeSharedData(objectId,typeId,i,bs,true); + } + else if (packageId==BaselinesMessage::BASELINES_CLIENT_SERVER) + { + decodeClientData(objectId,typeId,i,bs,true); + } + else if (packageId==BaselinesMessage::BASELINES_SERVER_NP) + { + } + else if (packageId==BaselinesMessage::BASELINES_SHARED_NP) + { + } + else if (packageId==BaselinesMessage::BASELINES_CLIENT_SERVER_NP) + { + } + else if (packageId==BaselinesMessage::BASELINES_UI) + { + } + else if (packageId==BaselinesMessage::BASELINES_FIRST_PARENT_CLIENT_SERVER) + { + decodeParentClientData(objectId,typeId,i,bs,true); + } + else if (packageId==BaselinesMessage::BASELINES_FIRST_PARENT_CLIENT_SERVER_NP) + { + } + else + { + FATAL(true,("PackageId was not BASELINES_SERVER, BASELINES_SHARED, or BASELINES_CLIENT.\n")); + } + } +} + +// ---------------------------------------------------------------------- + +void Snapshot::addLocator(ObjectLocator *newLocator) +{ + NOT_NULL(newLocator); + m_locatorList.push_back(newLocator); +} + +// ---------------------------------------------------------------------- + +int Snapshot::getLocatorCount() const +{ + return m_locatorList.size(); +} + +// ---------------------------------------------------------------------- + +void Snapshot::takeTimestamp() +{ + DEBUG_FATAL(m_timestamp!=0,("takeTimestamp was invoked more than once.\n")); + m_timestamp=ServerClock::getInstance().getGameTimeSeconds(); +} + +// ---------------------------------------------------------------------- + +bool Snapshot::saveTimestamp(DB::Session *session) +{ + DEBUG_FATAL(m_timestamp==0,("Can't save unset timestamp.\n")); + NOT_NULL(session); + + DBQuery::SaveTimestampQuery stq(m_timestamp); + return session->exec(&stq); +} + +// ---------------------------------------------------------------------- + +void Snapshot::addCustomPersistStep(CustomPersistStep *newStep) +{ + NOT_NULL(newStep); + m_customStepList.push_back(newStep); +} + +// ---------------------------------------------------------------------- + +void Snapshot::saveCompleted() +{ + for (CustomStepListType::iterator step=m_customStepList.begin(); step !=m_customStepList.end(); ++step) + { + NOT_NULL(*step); + (*step)->onComplete(); + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/Snapshot.h b/engine/server/library/serverDatabase/src/shared/Snapshot.h new file mode 100644 index 00000000..65cc879a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/Snapshot.h @@ -0,0 +1,160 @@ +// ====================================================================== +// +// Snapshot.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_Snapshot_H +#define INCLUDED_Snapshot_H + +// ====================================================================== + +#include "serverNetworkMessages/MessageToPayload.h" +#include "sharedDatabaseInterface/DbModeQuery.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedNetworkMessages/BaselinesMessage.h" +#include "sharedNetworkMessages/BatchBaselinesMessage.h" +#include "sharedNetworkMessages/DeltasMessage.h" + +namespace DB +{ + class Session; +} + +class AbstractTableBuffer; +class AddResourceTypeMessage; +class BountyHunterTargetMessage; +class CustomPersistStep; +class GameServerConnection; +class ObjectLocator; +class UpdateObjectPositionMessage; + +// ====================================================================== + +/** + * A Snapshot is a collection of TableBuffers. + * + * This class is an abstract base class for Snapshots, to define the + * interface. It is not game-specific. + */ +class Snapshot +{ +public: + Snapshot(DB::ModeQuery::Mode mode, bool useGoldDatabase); + virtual ~Snapshot(); + + virtual void handleUpdateObjectPosition(const UpdateObjectPositionMessage &msg) =0; + virtual void handleDeleteMessage (const NetworkId &objectID, int reasonCode, bool immediate, bool demandLoadedContainer, bool cascadeReason) =0; + virtual void handleMessageTo (const MessageToPayload &data) =0; + virtual void handleMessageToAck (const MessageToId &messageId) =0; + virtual void handleAddResourceTypeMessage (const AddResourceTypeMessage &message) =0; + virtual void handleBountyHunterTargetMessage (const BountyHunterTargetMessage &message) =0; + + virtual void getWorldContainers (stdvector::fwd &containers) const = 0; + + void handleDeltasMessage (NetworkId objectId, const DeltasMessage &msg); + void handleBaselinesMessage (NetworkId objectId, const BaselinesMessage &msg); + + virtual bool saveToDB (DB::Session *session) =0; + virtual bool load (DB::Session *session) =0; + virtual bool send (GameServerConnection *connection) const =0; + virtual void saveCompleted (); + + void takeTimestamp(); + + virtual void newObject (NetworkId const & objectId, int templateId, Tag typeId) =0; +// virtual void addObjectIdForLoad (NetworkId objectId)=0; //TODO: the load list could be moved into Snapshot, intead of being in the derived class + + void addLocator (ObjectLocator *newLocator); + void addCustomPersistStep (CustomPersistStep *newStep); + int getLocatorCount () const; + bool getUseGoldDatabase () const; + + DB::ModeQuery::Mode getMode() const; + + void setUniverseAuthHack(); + + virtual void handleCommoditiesDataMessage(const MessageDispatch::MessageBase & message) =0; + virtual void startLoadAfterSaveComplete() =0; + + protected: + typedef std::vector BufferListType; + typedef std::vector LocatorListType; + typedef std::vector CustomStepListType; + + /** + * This is a list of buffers. They will likely be members of a derived Snapshot. + * The base class deals with the buffers using only the interface of + * AbstractTableBuffer. + */ + BufferListType m_bufferList; + LocatorListType m_locatorList; ///< List of ObjectLocators that find objects in the database + CustomStepListType m_customStepList; ///< List of extra things to do while saving this snapshot (e.g. associating characters with accounts) + + bool m_universeAuthorityHack; //TODO: remove after cleaning up authority transfer code + + int getTimeStamp () const; + bool saveTimestamp (DB::Session *session); + + private: + bool m_isBeingSaved; + bool m_useGoldDatabase; + DB::ModeQuery::Mode m_mode; + int m_timestamp; + + +public: + static int getCreationCount() { return ms_creationCount; } + static int getDeletionCount() { return ms_deletionCount; } + static int getPendingCount() { return ms_creationCount - ms_deletionCount; } +private: + static int ms_creationCount; + static int ms_deletionCount; + + protected: + virtual void decodeServerData(NetworkId const & objectId, Tag typeId, uint16 index, Archive::ReadIterator &bs, bool isBaseline) = 0; + virtual void decodeSharedData(NetworkId const & objectId, Tag typeId, uint16 index, Archive::ReadIterator &bs, bool isBaseline) = 0; + virtual void decodeClientData(NetworkId const & objectId, Tag typeId, uint16 index, Archive::ReadIterator &bs, bool isBaseline) = 0; + virtual void decodeParentClientData(NetworkId const & objectId, Tag typeId, uint16 index, Archive::ReadIterator &bs, bool isBaseline) = 0; + + virtual bool encodeParentClientData(NetworkId const & objectId, Tag typeId, stdvector::fwd &baselines) const = 0; + virtual bool encodeClientData(NetworkId const & objectId, Tag typeId, stdvector::fwd &baselines) const = 0; + virtual bool encodeServerData(NetworkId const & objectId, Tag typeId, stdvector::fwd &baselines) const = 0; + virtual bool encodeSharedData(NetworkId const & objectId, Tag typeId, stdvector::fwd &baselines) const = 0; + + private: + Snapshot(const Snapshot&); //disable + Snapshot &operator=(const Snapshot&); //disable +}; + +// ---------------------------------------------------------------------- + +inline void Snapshot::setUniverseAuthHack() +{ + m_universeAuthorityHack=true; +} + +// ---------------------------------------------------------------------- + +inline bool Snapshot::getUseGoldDatabase() const +{ + return m_useGoldDatabase; +} + +// ---------------------------------------------------------------------- + +inline DB::ModeQuery::Mode Snapshot::getMode() const +{ + return m_mode; +} + +// ---------------------------------------------------------------------- + +inline int Snapshot::getTimeStamp() const +{ + return m_timestamp; +} + +// ====================================================================== +#endif diff --git a/engine/server/library/serverDatabase/src/shared/StructureQueries.cpp b/engine/server/library/serverDatabase/src/shared/StructureQueries.cpp new file mode 100644 index 00000000..ebef9ab5 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/StructureQueries.cpp @@ -0,0 +1,67 @@ +// ====================================================================== +// +// StructureQueries.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/StructureQueries.h" + +#include "serverDatabase/DatabaseProcess.h" + +using namespace DBQuery; + +// ====================================================================== + +void GetStructures::getSQL(std::string &sql) +{ + sql="begin :result := "+DatabaseProcess::getInstance().getSchemaQualifier()+"custserv_procs.get_structures(:character_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetStructures::bindParameters() +{ + if (!bindParameter(data.character_id)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +bool GetStructures::bindColumns() +{ + if (!bindCol(data.object_id)) return false; + if (!bindCol(data.x)) return false; + if (!bindCol(data.y)) return false; + if (!bindCol(data.z)) return false; + if (!bindCol(data.scene_id)) return false; + if (!bindCol(data.object_template)) return false; + if (!bindCol(data.deleted)) return false; + + return true; +} + +// ---------------------------------------------------------------------- + +const GetStructures::GetStructuresRow &GetStructures::getData() const +{ + return data; +} + +// ---------------------------------------------------------------------- + +void GetStructures::setCharacterId(NetworkId & characterId) +{ + data.character_id.setValue(characterId); + // data.station_id.setValue(static_cast(station_id)); +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode GetStructures::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + diff --git a/engine/server/library/serverDatabase/src/shared/StructureQueries.h b/engine/server/library/serverDatabase/src/shared/StructureQueries.h new file mode 100644 index 00000000..cee4458d --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/StructureQueries.h @@ -0,0 +1,65 @@ +// ====================================================================== +// +// CharacterQueries.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_StructureQueries_H +#define INCLUDED_StructureQueries_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbRow.h" +#include "sharedFoundation/StationId.h" + +// ====================================================================== + +namespace DBQuery { + + /** A query to get the list of characters for an account. + */ + class GetStructures : public DB::Query + { + public: + + struct GetStructuresRow : public DB::Row + { + DB::BindableString<128> scene_id; + DB::BindableNetworkId object_id; + DB::BindableString<1000> object_template; + DB::BindableDouble x; + DB::BindableDouble y; + DB::BindableDouble z; + DB::BindableNetworkId character_id; + DB::BindableLong deleted; + }; + + GetStructures() {} + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + const GetStructuresRow &getData() const; + void setCharacterId(NetworkId & characterId); + + protected: + virtual QueryMode getExecutionMode() const; + + private: + GetStructuresRow data; + + private: + GetStructures(const GetStructures&); // disable + GetStructures& operator=(const GetStructures&); //disable + }; + +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TableBuffer.cpp b/engine/server/library/serverDatabase/src/shared/TableBuffer.cpp new file mode 100644 index 00000000..a1330758 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TableBuffer.cpp @@ -0,0 +1,16 @@ +// ====================================================================== +// +// TableBuffer.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TableBuffer.h" + +#include "sharedDatabaseInterface/DbModeQuery.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TableBuffer.h b/engine/server/library/serverDatabase/src/shared/TableBuffer.h new file mode 100644 index 00000000..a28241f2 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TableBuffer.h @@ -0,0 +1,175 @@ +// ====================================================================== +// +// TableBuffer.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TableBuffer_H +#define INCLUDED_TableBuffer_H + +// ====================================================================== + +#include +#include "serverDatabase/AbstractTableBuffer.h" +#include "sharedDatabaseInterface/DbModeQuery.h" +#include "sharedDatabaseInterface/DbSession.h" + +namespace DB +{ + class Session; + struct Row; +} + +// ====================================================================== + +/** + * A TableBuffer is a list of updates to be sent to a table, or a list + * of rows retrieved from a table. + * @todo Move to database interface. + * + * Note that we do not use the RowsType typedef inside this file to avoid + * compile problems when trying to get this one file to compile under vs6, + * vs7, and gcc 2.95.3. gcc 3.x has not yet been tested. + * + */ +template +class TableBuffer : public AbstractTableBuffer +{ + public: + typedef std::vector RowsType; + + virtual ~TableBuffer(void); + + DB::ModeQuery::Mode getMode(void) const; + + virtual bool load(DB::Session *session); + virtual bool save(DB::Session *session); + + protected: + + typename std::vector::iterator addRow(ROW *newRow); + + TableBuffer(DB::ModeQuery::Mode mode); + + std::vector m_rows; + + private: +/** + * The TableBuffer can be for the purpose of selecting, adding, changing, or deleting rows. + * + * For now, not supporting holding different types of changes within the same buffer. + * This may change in the future. + */ + DB::ModeQuery::Mode m_mode; +}; + +// ====================================================================== + +template +TableBuffer::TableBuffer(DB::ModeQuery::Mode mode) : + m_mode(mode) +{ +} + +// ---------------------------------------------------------------------- + +template +TableBuffer::~TableBuffer(void) +{ + for (typename std::vector::iterator i=m_rows.begin(); i!=m_rows.end(); ++i) + { + delete *i; + } +} + +// ---------------------------------------------------------------------- + +template +DB::ModeQuery::Mode TableBuffer::getMode(void) const +{ + return m_mode; +} + +// ---------------------------------------------------------------------- + +/** + * Write all the rows in the buffer to the database. + * + * The mode determines whether these rows will be sent as inserts, updates, or deletes. + * If the mode is select, this function will FATAL. + */ +template +bool TableBuffer::save(DB::Session *session) +{ + QUERY qry; + + if (getMode()==DB::ModeQuery::mode_INSERT) + qry.insertMode(); + else + qry.updateMode(); + + for (typename std::vector::iterator i=m_rows.begin(); i!=m_rows.end(); ++i) + { + qry.setData(**i); + if (! (session->exec(&qry))) + return false; + + } + qry.done(); + return true; +} + +// ---------------------------------------------------------------------- + +/** + * Load rows into the buffer from the database. + * + * The query is assumed to return 0 or more rows, which will be placed + * in the buffer. The virtual addRow function is used to make sure indexes, + * etc., are updated as needed. + */ +template +bool TableBuffer::load(DB::Session *session) +{ + int rowsFetched; + QUERY qry; + + FATAL (getMode()!=DB::ModeQuery::mode_SELECT,("load() was invoked on a TableBuffer that was not in tbm_select mode.")); + + qry.selectMode(); + + if (! (session->exec(&qry))) + return false; + + while ((rowsFetched = qry.fetch()) > 0) + { + ROW *newRow=new ROW(dynamic_cast(qry.getData())); + addRow(newRow); + } + + qry.done(); + return (rowsFetched >= 0); +} + +// ---------------------------------------------------------------------- + +/** + * Add a row to the list of rows in the buffer. + * + * Derived classes may override this function (to keep an index + * of the rows, for example), but they should always back-chain to this + * function. + */ + +template +typename std::vector::iterator TableBuffer::addRow(ROW *newRow) +{ + m_rows.push_back(newRow); + typename std::vector::iterator retval=m_rows.end(); + return --retval; +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.cpp b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.cpp new file mode 100644 index 00000000..6482ad3b --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.cpp @@ -0,0 +1,579 @@ +// ====================================================================== +// +// TaskVerifyCharacter.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "TaskCSTasks.h" + +#include "Unicode.h" +#include "serverDatabase/CharacterQueries.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/CharacterListMessage.h" +#include "serverNetworkMessages/CSDBNetMessages.h" +#include "serverNetworkMessages/TransferCharacterData.h" +#include "serverNetworkMessages/TransferCharacterDataArchive.h" +#include "serverNetworkMessages/ValidateCharacterForLoginReplyMessage.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" +#include "sharedLog/Log.h" +#include "unicodeArchive/UnicodeArchive.h" + +// ====================================================================== + +TaskGetCharactersForAccount::TaskGetCharactersForAccount( uint32 accountId, uint32 loginServerId, uint32 toolId) : + TaskRequest(), + m_loginServerId( loginServerId ), + m_toolId( toolId ), + m_accountId( accountId ) +{ + LOG("TRACE_LOGIN", ("Create DB TaskGetCharactersForAccount")); +} + +//----------------------------------------------------------------------- + +TaskGetCharactersForAccount::~TaskGetCharactersForAccount() +{ +} + +//----------------------------------------------------------------------- + +bool TaskGetCharactersForAccount::process(DB::Session *session) +{ + LOG("TRACE_LOGIN", ("TaskVerifyCharacter -- starting process")); + + int rowsFetched = 0; + { + // add query info here. + CSGetCharactersQuery qry; + DEBUG_REPORT_LOG( true, ( "Sending query for sid %lu\n", m_accountId ) ); + qry.station_id = m_accountId; // debug, my station id. Should have a char on here, hopefully! + if (! (session->exec(&qry))) + return false; + while ((rowsFetched = qry.fetch()) > 0) + { + size_t numRows = qry.getNumRowsFetched(); + size_t count = 0; + const std::vector &data = qry.getData(); + + for (std::vector::const_iterator i=data.begin(); i!=data.end(); ++i) + { + if (++count > numRows) + break; + // store + CharacterRecord* rec = new CharacterRecord(); + rec->m_characterId = i->characterId.getValue(); + rec->m_characterName = i->characterName.getValue(); + m_characters.push_back( rec ); + } + } + qry.done(); + } + + LOG("TRACE_LOGIN", ("TaskVerifyCharacter -- finished process")); + return true; +} + +//----------------------------------------------------------------------- + +void TaskGetCharactersForAccount::onComplete() +{ +// REPORT_LOG(true, ("TaskGetCharactersForAccount::onComplete()\n")); + std::string response = ""; + for (std::vector::iterator i=m_characters.begin(); i!=m_characters.end(); ++i) + { + + response = response + (*i)->m_characterId.getValueString() + ":" + Unicode::wideToNarrow( (*i)->m_characterName ) + "\r\n"; + + // store variable amounts of data... + delete *i; + } + m_characters.clear(); + GetCharactersForAccountCSReplyMsg msg( 17619, 0, 17619, m_toolId, m_loginServerId, response ); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); + +// dynamic_cast(SwgLoader::getInstance()).verifyCharacterFinished(this); +} + +// ====================================================================== + +void TaskGetCharactersForAccount::CSGetCharactersQuery::getSQL(std::string &sql) +{ + // Note: station id and character id are input parameters. The rest are pass-by-reference output parameters. + sql=std::string("begin :result := ") + DatabaseProcess::getInstance().getSchemaQualifier()+"custserv_procs.get_characters_for_account (:station_id ); end;"; +} + +// ---------------------------------------------------------------------- + +bool TaskGetCharactersForAccount::CSGetCharactersQuery::bindParameters() +{ + if (!bindParameter(station_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool TaskGetCharactersForAccount::CSGetCharactersQuery::bindColumns() +{ + if( m_data.size() < 2 ) + m_data.resize( 2 ); + size_t skipSize = reinterpret_cast(&(m_data[1])) - reinterpret_cast(&(m_data[0])); + setColArrayMode(skipSize, m_data.size()); + if (!bindCol(m_data[0].characterId)) return false; + if (!bindCol(m_data[0].characterName)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode TaskGetCharactersForAccount::CSGetCharactersQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ---------------------------------------------------------------------- + +TaskGetCharactersForAccount::CSGetCharactersQuery::CSGetCharactersQuery() : + Query(), + station_id(), + character_id(), + character_name() +{ +} + +// ---------------------------------------------------------------------- +// + + + +TaskGetDeletedItems::TaskGetDeletedItems(const NetworkId &characterId, uint32 loginServerId, uint32 toolId, uint32 pageNumber) : + TaskRequest(), + m_loginServerId( loginServerId ), + m_toolId( toolId ), + m_characterId( characterId ), + m_pageNumber( pageNumber ) +{ + LOG("TRACE_LOGIN", ("Create DB TaskGetCharactersForAccount")); +} + +//----------------------------------------------------------------------- + +TaskGetDeletedItems::~TaskGetDeletedItems() +{ +} + +//----------------------------------------------------------------------- + +bool TaskGetDeletedItems::process(DB::Session *session) +{ + LOG("TRACE_LOGIN", ("TaskVerifyCharacter -- starting process")); + + int rowsFetched = 0; + { + // add query info here. + CSGetDeletedItemsQuery qry; + DEBUG_REPORT_LOG( true, ( "Sending query for sid %s\n", m_characterId.getValueString().c_str() ) ); + qry.character_id = m_characterId; + qry.page_number = m_pageNumber; + if (! (session->exec(&qry))) + return false; + while ((rowsFetched = qry.fetch()) > 0) + { + size_t numRows = qry.getNumRowsFetched(); + size_t count = 0; + const std::vector &data = qry.getData(); + + for (std::vector::const_iterator i=data.begin(); i!=data.end(); ++i) + { + if (++count > numRows) + break; + // store + DeletedItemRecord* rec = new DeletedItemRecord(); + rec->m_itemId = i->itemId.getValue(); + rec->m_itemTable = i->itemTable.getValue(); + rec->m_itemName= i->itemName.getValue(); + rec->m_displayName = i->displayName.getValue(); + m_items.push_back( rec ); + } + } + qry.done(); + } + + LOG("TRACE_CS_DB", ("TaskGetDeletedItems -- finished process")); + return true; +} + +//----------------------------------------------------------------------- + +void TaskGetDeletedItems::onComplete() +{ + LOG("TRACE_CS_DB", ("TaskGetDeletedItems::onComplete() for account %s", m_characterId.getValueString().c_str())); + std::string response = ""; + for (std::vector::iterator i=m_items.begin(); i!=m_items.end(); ++i) + { + LOG("TRACE_CS_DB", ("TaskGetDeletedItems::onComplete() reading record")); + + response = response + (*i)->m_itemId.getValueString() + ":" + Unicode::wideToNarrow( (*i)->m_itemTable ) + ":" + Unicode::wideToNarrow( (*i)->m_itemName ) + + "(" + Unicode::wideToNarrow((*i)->m_displayName) + ")\r\n"; + + // store variable amounts of data... + delete *i; + } + m_items.clear(); + + GetDeletedItemsReplyMessage msg( 0, 0, m_characterId, m_toolId, m_loginServerId, response ); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); + LOG("TRACE_CS_DB", ("TaskGetDeletedItems::onComplete() finished")); +// dynamic_cast(SwgLoader::getInstance()).verifyCharacterFinished(this); +} + +// ====================================================================== + +void TaskGetDeletedItems::CSGetDeletedItemsQuery::getSQL(std::string &sql) +{ + // Note: station id and character id are input parameters. The rest are pass-by-reference output parameters. + sql=std::string("begin :result := ") + DatabaseProcess::getInstance().getSchemaQualifier()+"custserv_procs.get_deleted_items(:character_id, :page_number ); end;"; +} + +// ---------------------------------------------------------------------- + +bool TaskGetDeletedItems::CSGetDeletedItemsQuery::bindParameters() +{ + if (!bindParameter(character_id)) return false; + if (!bindParameter(page_number)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool TaskGetDeletedItems::CSGetDeletedItemsQuery::bindColumns() +{ + if( m_data.size() < 2 ) + m_data.resize( 2 ); + size_t skipSize = reinterpret_cast(&(m_data[1])) - reinterpret_cast(&(m_data[0])); + setColArrayMode(skipSize, m_data.size()); + if (!bindCol(m_data[0].itemId)) return false; + if (!bindCol( m_data[ 0 ].itemTable )) return false; + if (!bindCol(m_data[0].itemName)) return false; + if (!bindCol(m_data[0].displayName)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode TaskGetDeletedItems::CSGetDeletedItemsQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ---------------------------------------------------------------------- + +TaskGetDeletedItems::CSGetDeletedItemsQuery::CSGetDeletedItemsQuery() : + Query(), + character_id() +{ +} + +//---------------------------------------------------------------------- + + + + +TaskGetCharacterId::TaskGetCharacterId(const std::string &characterName, uint32 loginServerId, uint32 toolId) : + TaskRequest(), + m_loginServerId( loginServerId ), + m_toolId( toolId ), + m_characterName( characterName ) +{ + LOG("TRACE_LOGIN", ("Create DB TaskGetCharacterId")); +} + +//----------------------------------------------------------------------- + +TaskGetCharacterId::~TaskGetCharacterId() +{ +} + +//----------------------------------------------------------------------- + +bool TaskGetCharacterId::process(DB::Session *session) +{ + LOG("TRACE_LOGIN", ("TaskGetCharacterId -- starting process")); + + int rowsFetched = 0; + { + // add query info here. + CSGetCharacterIdQuery qry; + DEBUG_REPORT_LOG( true, ( "Sending query for sid %s\n", m_characterName.c_str() ) ); + std::string temporaryName = m_characterName; + if (temporaryName.length() > TaskGetCharacterId::MAX_NAME_LENGTH - 1) + { + temporaryName = temporaryName.substr(0, TaskGetCharacterId::MAX_NAME_LENGTH - 1); + } + qry.character_name = temporaryName; + if (! (session->exec(&qry))) + return false; + while ((rowsFetched = qry.fetch()) > 0) + { + size_t numRows = qry.getNumRowsFetched(); + size_t count = 0; + const std::vector &data = qry.getData(); + + for (std::vector::const_iterator i=data.begin(); i!=data.end(); ++i) + { + if (++count > numRows) + break; + // store + CharacterIdRecord* rec = new CharacterIdRecord(); + rec->m_characterId = i->characterId.getValue(); + rec->m_stationId = i->stationId.getValue(); + m_characterIds.push_back( rec ); + } + } + qry.done(); + } + + LOG("TRACE_LOGIN", ("TaskGetCharacterId -- finished process")); + return true; +} + +//----------------------------------------------------------------------- + +void TaskGetCharacterId::onComplete() +{ +// REPORT_LOG(true, ("TaskGetCharactersForAccount::onComplete()\n")); + std::string response = ""; + NetworkId characterId; + uint32 stationId = 0; + if(m_characterIds.size() > 1 ) + { + DEBUG_REPORT_LOG(true,("Got more than one result looking up a character named %s\n", m_characterName.c_str())); + } + for (std::vector::iterator i=m_characterIds.begin(); i!=m_characterIds.end(); ++i) + { + characterId = (*i)->m_characterId; + stationId = (*i)->m_stationId; + delete *i; + } + m_characterIds.clear(); + + GetCharacterIdReplyMessage msg( stationId, characterId, m_toolId, m_loginServerId, m_characterName ); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); + DEBUG_REPORT_LOG( true, ( "Finished deleted item query\n" ) ); +// dynamic_cast(SwgLoader::getInstance()).verifyCharacterFinished(this); +} + +// ====================================================================== + +void TaskGetCharacterId::CSGetCharacterIdQuery::getSQL(std::string &sql) +{ + // Note: station id and character id are input parameters. The rest are pass-by-reference output parameters. + sql=std::string("begin :result := ") + DatabaseProcess::getInstance().getSchemaQualifier()+"custserv_procs.get_player_id(:character_name); end;"; +} + +// ---------------------------------------------------------------------- + +bool TaskGetCharacterId::CSGetCharacterIdQuery::bindParameters() +{ + if (!bindParameter(character_name)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool TaskGetCharacterId::CSGetCharacterIdQuery::bindColumns() +{ + if( m_data.size() < 2 ) + m_data.resize( 2 ); + size_t skipSize = reinterpret_cast(&(m_data[1])) - reinterpret_cast(&(m_data[0])); + setColArrayMode(skipSize, m_data.size()); + if (!bindCol(m_data[0].characterId)) return false; + if (!bindCol( m_data[ 0 ].stationId )) return false; + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode TaskGetCharacterId::CSGetCharacterIdQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ---------------------------------------------------------------------- + +TaskGetCharacterId::CSGetCharacterIdQuery::CSGetCharacterIdQuery() : + Query(), + character_name() +{ +} + +TaskMovePlayer::TaskMovePlayer( const NetworkId & id, const std::string & scene, double x, double y, double z ) : + TaskRequest(), + m_characterId(id), + m_scene(scene), + m_x(x), + m_y(y), + m_z(z) +{ +} + +//----------------------------------------------------------------------- + +TaskMovePlayer::~TaskMovePlayer() +{ +} + +//----------------------------------------------------------------------- + +bool TaskMovePlayer::process(DB::Session *session) +{ + + { + // add query info here. + std::string temporaryString = m_scene; + if (m_scene.length() > TaskMovePlayer::MAX_SCENE_NAME_LENGTH - 1) + { + temporaryString = temporaryString.substr(0, TaskMovePlayer::MAX_SCENE_NAME_LENGTH - 1); + } + CSMovePlayerQuery qry(m_characterId, temporaryString, static_cast(m_x), static_cast(m_y), static_cast(m_z)); + if (! (session->exec(&qry))) + { + return false; + } + qry.done(); + } + + LOG("TRACE_LOGIN", ("TaskMovePlayer -- finished process")); + return true; +} + +//----------------------------------------------------------------------- + +void TaskMovePlayer::onComplete() +{ +} +//---------------------------------------------------------------------- + +TaskMovePlayer::CSMovePlayerQuery::CSMovePlayerQuery(const NetworkId & characterIdIn, + const std:: string & scene, + float xIn, + float yIn, + float zIn) : + characterId(characterIdIn), + newScene(scene), + x(xIn), + y(yIn), + z(zIn) +{ +} + +// ====================================================================== + +void TaskMovePlayer::CSMovePlayerQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "custserv_procs.move_player (:character_id, :x, :y, :z, :scene_id); end;"; +} + +// ====================================================================== + +bool TaskMovePlayer::CSMovePlayerQuery::bindParameters() +{ + if (!bindParameter(characterId)) return false; + if (!bindParameter(x)) return false; + if (!bindParameter(y)) return false; + if (!bindParameter(z)) return false; + if (!bindParameter(newScene)) return false; + return true; +} + +// ====================================================================== + +bool TaskMovePlayer::CSMovePlayerQuery::bindColumns() +{ + return true; +} + +// ====================================================================== + +// ---------------------------------------------------------------------- + + +TaskCsUndeleteItem::TaskCsUndeleteItem(const NetworkId & characterId, const NetworkId & itemId, bool move) : + TaskRequest(), + m_characterId(characterId), + m_itemId(itemId), + m_move(move) +{ +} + +//----------------------------------------------------------------------- + +TaskCsUndeleteItem::~TaskCsUndeleteItem() +{ +} + +//----------------------------------------------------------------------- + +bool TaskCsUndeleteItem::process(DB::Session *session) +{ + + { + // add query info here. + CsUndeleteItemQuery qry(m_characterId, m_itemId, m_move); + if (! (session->exec(&qry))) + { + return false; + } + qry.done(); + } + + LOG("TRACE_LOGIN", ("CsUndeleteItemQuery -- finished process")); + return true; +} + +//----------------------------------------------------------------------- + +void TaskCsUndeleteItem::onComplete() +{ +} +//---------------------------------------------------------------------- + +TaskCsUndeleteItem::CsUndeleteItemQuery::CsUndeleteItemQuery(const NetworkId & characterIdIn, + const NetworkId & itemIdIn, + bool moveIn): + characterId(characterIdIn), + itemId(itemIdIn), + move(0) +{ + if(moveIn) + move.setValue(1); + DEBUG_REPORT_LOG(true,("Undeleltion query: %s %s %s\n", characterIdIn.getValueString().c_str(), itemIdIn.getValueString().c_str(), moveIn ? "Moving" : "Not moving")); +} + +// ====================================================================== + +void TaskCsUndeleteItem::CsUndeleteItemQuery::getSQL(std::string &sql) +{ + sql=std::string("begin ") + DatabaseProcess::getInstance().getSchemaQualifier() + "custserv_procs.undelete_item (:character_id, :item_id, :move); end;"; +} + +// ====================================================================== + +bool TaskCsUndeleteItem::CsUndeleteItemQuery::bindParameters() +{ + if (!bindParameter(characterId)) return false; + if (!bindParameter(itemId)) return false; + if (!bindParameter(move)) return false; + return true; +} + +// ====================================================================== + +bool TaskCsUndeleteItem::CsUndeleteItemQuery::bindColumns() +{ + return true; +} +//---------------------------------------------------------------------- + diff --git a/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h new file mode 100644 index 00000000..db26fc16 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCSTasks.h @@ -0,0 +1,326 @@ +// ====================================================================== +// +// TaskCSTasks.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskCSTasks_H +#define INCLUDED_TaskCSTasks_H + +// ====================================================================== + +#include + +#include "Unicode.h" +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/StationId.h" + +//----------------------------------------------------------------------- + +class TaskGetCharactersForAccount:public DB::TaskRequest +{ + public: + explicit TaskGetCharactersForAccount( uint32 accountId, uint32 loginServerId, uint32 toolId ); + virtual ~TaskGetCharactersForAccount(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + + + private: + class CSGetCharactersQuery : public DB::Query + { + public: + CSGetCharactersQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + public: + // input: + DB::BindableLong station_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class + + //output: + DB::BindableString<128> character_name; //lint !e1925 public data member Suppresed because it's in a private inner class + + private: + CSGetCharactersQuery(const CSGetCharactersQuery&); + CSGetCharactersQuery& operator=(const CSGetCharactersQuery&); + + public: + struct CharacterRow + { + DB::BindableNetworkId characterId; + DB::BindableString< 40 > characterName; + }; + + private: + std::vector m_data; + + public: + const std::vector & getData() const; + + + }; + + private: + class CharacterRecord + { + public: + StationId m_suid; //lint !e1925 public data member Suppresed because it's in a private inner class + NetworkId m_characterId; //lint !e1925 public data member Suppresed because it's in a private inner class + + Unicode::String m_characterName; //lint !e1925 public data member Suppresed because it's in a private inner class + }; + + std::vector m_characters; + + uint32 m_loginServerId; + uint32 m_toolId; + uint32 m_accountId; // target account ID + + private: + //Disabled: + TaskGetCharactersForAccount(); + TaskGetCharactersForAccount(const TaskGetCharactersForAccount&); + TaskGetCharactersForAccount& operator=(const TaskGetCharactersForAccount& rhs); +}; + +inline const std::vector & TaskGetCharactersForAccount::CSGetCharactersQuery::getData() const +{ + return m_data; +} +//----------------------------------------------------------------------- + +class TaskGetDeletedItems:public DB::TaskRequest +{ + public: + explicit TaskGetDeletedItems(const NetworkId &characterId, uint32 loginServerId, uint32 toolId, uint32 pageNumber); + virtual ~TaskGetDeletedItems(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + + private: + class CSGetDeletedItemsQuery : public DB::Query + { + public: + CSGetDeletedItemsQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + public: + // input: + DB::BindableNetworkId character_id; //lint !e1925 public data member Suppresed because it's in a private inner class + DB::BindableLong page_number; + + private: + CSGetDeletedItemsQuery(const CSGetDeletedItemsQuery&); + CSGetDeletedItemsQuery& operator=(const CSGetDeletedItemsQuery&); + + public: + struct DeletedItemRow + { + DB::BindableNetworkId itemId; + DB::BindableString<501> itemTable; + DB::BindableString<501> itemName; + DB::BindableString<129> displayName; + }; + + private: + std::vector m_data; + + public: + const std::vector & getData() const; + + + }; + private: + class DeletedItemRecord + { + public: + NetworkId m_itemId; //lint !e1925 public data member Suppresed because it's in a private inner class + + Unicode::String m_itemTable; + Unicode::String m_itemName; //lint !e1925 public data member Suppresed because it's in a private inner class + Unicode::String m_displayName; + }; + + std::vector m_items; + + + uint32 m_loginServerId; + uint32 m_toolId; + NetworkId m_characterId; // target account ID + uint32 m_pageNumber; // starting number of list + +}; + +inline const std::vector & TaskGetDeletedItems::CSGetDeletedItemsQuery::getData() const +{ + return m_data; +} + + +//----------------------------------------------------------------------- + +class TaskGetCharacterId:public DB::TaskRequest +{ + public: + explicit TaskGetCharacterId( const std::string &characterName, uint32 loginServerId, uint32 toolId ); + virtual ~TaskGetCharacterId(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + + enum + { + MAX_NAME_LENGTH = 40 + }; + + private: + class CSGetCharacterIdQuery : public DB::Query + { + public: + CSGetCharacterIdQuery(); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + public: + // input: + DB::BindableString character_name; //lint !e1925 public data member Suppresed because it's in a private inner class + + private: + CSGetCharacterIdQuery(const CSGetCharacterIdQuery&); + CSGetCharacterIdQuery& operator=(const CSGetCharacterIdQuery&); + + public: + struct CharacterIdRow + { + DB::BindableNetworkId characterId; + DB::BindableLong stationId; + DB::BindableString characterName; + }; + + private: + std::vector m_data; + + public: + const std::vector & getData() const; + + + }; + private: + class CharacterIdRecord + { + public: + NetworkId m_characterId; //lint !e1925 public data member Suppresed because it's in a private inner class + uint32 m_stationId; + }; + + std::vector m_characterIds; + + + uint32 m_loginServerId; + uint32 m_toolId; + std::string m_characterName; // target account ID + +}; + +inline const std::vector & TaskGetCharacterId::CSGetCharacterIdQuery::getData() const +{ + return m_data; +} + +class TaskMovePlayer : public DB::TaskRequest +{ + public: + explicit TaskMovePlayer( const NetworkId & id, const std::string & scene, double x, double y, double z ); + virtual ~TaskMovePlayer(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + + enum + { + MAX_SCENE_NAME_LENGTH = 40 + }; + private: + class CSMovePlayerQuery : public DB::Query + { + public: + CSMovePlayerQuery(const NetworkId & characterIdIn, const std::string & scene, const float xIn, const float yIn, const float zIn); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + DB::BindableNetworkId characterId; + DB::BindableString newScene; + DB::BindableDouble x; + DB::BindableDouble y; + DB::BindableDouble z; + + private: + CSMovePlayerQuery(const CSMovePlayerQuery &); // disable + CSMovePlayerQuery & operator=(const CSMovePlayerQuery &); //disable + }; + NetworkId m_characterId; + std::string m_scene; + double m_x; + double m_y; + double m_z; + +}; + +//----------------------------------------------------------------------- + +class TaskCsUndeleteItem : public DB::TaskRequest +{ + public: + explicit TaskCsUndeleteItem( const NetworkId & characterId, const NetworkId & itemId, bool move ); + virtual ~TaskCsUndeleteItem(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + private: + class CsUndeleteItemQuery : public DB::Query + { + public: + CsUndeleteItemQuery(const NetworkId & characterIdIn, const NetworkId & itemIdIn, bool moveIn); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + private: + DB::BindableNetworkId characterId; + DB::BindableNetworkId itemId; + DB::BindableLong move; + + private: + CsUndeleteItemQuery(const CsUndeleteItemQuery &); // disable + CsUndeleteItemQuery & operator=(const CsUndeleteItemQuery &); //disable + }; + NetworkId m_characterId; + NetworkId m_itemId; + bool m_move; + +}; + +#endif // INCLUDED_TaskCSTasks_H + diff --git a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.cpp b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.cpp new file mode 100644 index 00000000..b9c40637 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.cpp @@ -0,0 +1,103 @@ +// ====================================================================== +// +// TaskChangeStationId.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "TaskChangeStationId.h" + +#include +#include "sharedLog/Log.h" +#include "serverNetworkMessages/TransferAccountData.h" +#include "serverNetworkMessages/TransferAccountDataArchive.h" +#include "serverDatabase/DatabaseProcess.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +TaskChangeStationId::TaskChangeStationId(StationId sourceStationId, StationId destinationStationId, const TransferAccountData *requestData) : + TaskRequest(), + m_sourceStationId(sourceStationId), + m_destinationStationId(destinationStationId), + m_requestData(0), + m_success(false) +{ + if(requestData) + { + m_requestData = new TransferAccountData(*requestData); + } +} + +// ---------------------------------------------------------------------- + +TaskChangeStationId::~TaskChangeStationId() +{ + delete m_requestData; + m_requestData = 0; +} + +// ---------------------------------------------------------------------- + +bool TaskChangeStationId::process(DB::Session *session) +{ + ChangeStationIdQuery qry; + qry.source_station_id = m_sourceStationId; + qry.destination_station_id = m_destinationStationId; + + m_success = session->exec(&qry); + + qry.done(); + return m_success; +} + +// ---------------------------------------------------------------------- + +void TaskChangeStationId::onComplete() +{ + LOG("CustomerService", ("CharacterTransfer: Completed changing station id from %lu to %lu in game database", m_sourceStationId, m_destinationStationId)); +} + +// ====================================================================== + +TaskChangeStationId::ChangeStationIdQuery::ChangeStationIdQuery() : + Query(), + destination_station_id(0), + source_station_id(0) +{ +} + +// ---------------------------------------------------------------------- + +void TaskChangeStationId::ChangeStationIdQuery::getSQL(std::string &sql) +{ + sql = std::string("begin Update ")+DatabaseProcess::getInstance().getSchemaQualifier()+"players Set station_id = :destination_station_id Where station_id = :source_station_id; end;"; +// DEBUG_REPORT_LOG(true, ("TaskChangeStationId SQL: %s\n", sql.c_str())); +} + +// ---------------------------------------------------------------------- + +bool TaskChangeStationId::ChangeStationIdQuery::bindParameters() +{ + if (!bindParameter(destination_station_id)) return false; + if (!bindParameter(source_station_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool TaskChangeStationId::ChangeStationIdQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode TaskChangeStationId::ChangeStationIdQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h new file mode 100644 index 00000000..6ed1dad4 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskChangeStationId.h @@ -0,0 +1,61 @@ +// ====================================================================== +// +// TaskChangeStationId.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskChangeStationId_H +#define INCLUDED_TaskChangeStationId_H + +// ====================================================================== + +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/StationId.h" + +class TransferAccountData; + +// ====================================================================== + +class TaskChangeStationId : public DB::TaskRequest +{ + public: + TaskChangeStationId(StationId sourceStationId, StationId destinationStationId, const TransferAccountData * requestData); + ~TaskChangeStationId(); + public: + virtual bool process (DB::Session *session); + virtual void onComplete (); + + private: + TaskChangeStationId(); // disabled default constructor + class ChangeStationIdQuery : public DB::Query + { + public: + ChangeStationIdQuery(); + + DB::BindableLong destination_station_id; //lint !e1925 // public data member + DB::BindableLong source_station_id; //lint !e1925 // public data member + + virtual void getSQL (std::string &sql); + virtual bool bindParameters (); + virtual bool bindColumns (); + virtual QueryMode getExecutionMode () const; + + private: //disable + ChangeStationIdQuery (const ChangeStationIdQuery&); + ChangeStationIdQuery &operator= (const ChangeStationIdQuery&); + }; + + private: + StationId m_sourceStationId; + StationId m_destinationStationId; + TransferAccountData *m_requestData; + bool m_success; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.cpp b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.cpp new file mode 100644 index 00000000..fbb863ff --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.cpp @@ -0,0 +1,82 @@ +// ====================================================================== +// +// TaskCheckCharacterName.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskCheckCharacterName.h" + +#include "serverDatabase/DataLookup.h" +#include "serverDatabase/DatabaseProcess.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +TaskCheckCharacterName::TaskCheckCharacterName(uint32 stationId, const Unicode::String &name) : + m_name(name), + m_stationId(stationId) +{ +} + +// ---------------------------------------------------------------------- + +bool TaskCheckCharacterName::process(DB::Session *session) +{ + CheckCharacterNameQuery qry(Unicode::wideToNarrow(m_name)); + + bool rval = session->exec(&qry); + qry.done(); + + m_resultCode=qry.result.getValue(); + return rval; +} + +// ---------------------------------------------------------------------- + +void TaskCheckCharacterName::onComplete() +{ + DataLookup::getInstance().onCharacterNameChecked(m_stationId, m_name,m_resultCode); + LOG("TraceCharacterCreation", ("%d TaskCheckCharacterName(%s) complete with result code %d", m_stationId, Unicode::wideToNarrow(m_name).c_str(), m_resultCode)); +} + +// ====================================================================== + +TaskCheckCharacterName::CheckCharacterNameQuery::CheckCharacterNameQuery(const std::string &name) : + character_name(name) +{ +} + +// ---------------------------------------------------------------------- + +void TaskCheckCharacterName::CheckCharacterNameQuery::getSQL(std::string &sql) +{ + sql="begin :result := " + DatabaseProcess::getInstance().getSchemaQualifier() + "datalookup.check_character_name (:name); end;"; +} + +// ---------------------------------------------------------------------- + +bool TaskCheckCharacterName::CheckCharacterNameQuery::bindParameters() +{ + if (!bindParameter(result)) return false; + if (!bindParameter(character_name)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool TaskCheckCharacterName::CheckCharacterNameQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode TaskCheckCharacterName::CheckCharacterNameQuery::getExecutionMode() const +{ + return DB::Query::MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h new file mode 100644 index 00000000..6cf4d3e9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckCharacterName.h @@ -0,0 +1,57 @@ +// ====================================================================== +// +// TaskCheckCharacterName.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskCheckCharacterName_H +#define INCLUDED_TaskCheckCharacterName_H + +// ====================================================================== + +#include + +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/DbTaskRequest.h" + +// ====================================================================== + +class TaskCheckCharacterName : public DB::TaskRequest +{ + public: + TaskCheckCharacterName(uint32 stationId, const Unicode::String &normalizedName); + bool process(DB::Session *session); + void onComplete(); + + private: + Unicode::String m_name; + int m_resultCode; + uint32 m_stationId; + + class CheckCharacterNameQuery : public DB::Query + { + public: + CheckCharacterNameQuery(const std::string &name); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + + protected: + virtual QueryMode getExecutionMode() const; + + public: + DB::BindableString<127> character_name; + DB::BindableLong result; + + private: + CheckCharacterNameQuery(const CheckCharacterNameQuery&); + CheckCharacterNameQuery& operator=(const CheckCharacterNameQuery&); + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.cpp b/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.cpp new file mode 100644 index 00000000..9eb0bb6f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.cpp @@ -0,0 +1,62 @@ +// ====================================================================== +// +// TaskCheckGoldVersionNumber.cpp +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskCheckGoldVersionNumber.h" + +#include "serverDatabase/GetGoldVersionNumberQuery.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +TaskCheckGoldVersionNumber::TaskCheckGoldVersionNumber(int codeVersion, bool fatalOnMismatch) : + m_codeVersion(codeVersion), + m_databaseVersion(0), + m_minVersion(0), + m_fatalOnMismatch(fatalOnMismatch) +{ +} + +// ---------------------------------------------------------------------- + +TaskCheckGoldVersionNumber::~TaskCheckGoldVersionNumber() +{ +} + +// ---------------------------------------------------------------------- + +bool TaskCheckGoldVersionNumber::process(DB::Session *session) +{ + int rowsFetched; + DBQuery::GetGoldVersionNumberQuery qry; + + if (! (session->exec(&qry))) + return false; + rowsFetched = qry.fetch(); + m_databaseVersion=qry.getVersionNumber(); + m_minVersion=qry.getMinVersionNumber(); + return (rowsFetched >= 0); +} + +// ---------------------------------------------------------------------- + +void TaskCheckGoldVersionNumber::onComplete() +{ + if ((m_codeVersion > m_databaseVersion) || (m_codeVersion < m_minVersion)) + { + if (m_fatalOnMismatch) + { + FATAL(true,("This version of the server requires GOLD database version %i, but the GOLD database is version %i.\n",m_codeVersion,m_databaseVersion)); + } + else + { + WARNING(true,("This version of the server requires GOLD database version %i, but the GOLD database is version %i.\n",m_codeVersion,m_databaseVersion)); + } + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.h b/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.h new file mode 100644 index 00000000..4a6fc31c --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckGoldVersionNumber.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// TaskCheckGoldVersionNumber.h +// copyright (c) 2004 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskCheckGoldVersionNumber_H +#define INCLUDED_TaskCheckGoldVersionNumber_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" + +// ====================================================================== + +class TaskCheckGoldVersionNumber : public DB::TaskRequest +{ + public: + TaskCheckGoldVersionNumber(int codeVersion, bool fatalOnMismatch); + virtual ~TaskCheckGoldVersionNumber(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + int m_codeVersion; + int m_databaseVersion; + int m_minVersion; + bool m_fatalOnMismatch; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.cpp b/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.cpp new file mode 100644 index 00000000..685271b9 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.cpp @@ -0,0 +1,62 @@ +// ====================================================================== +// +// TaskCheckVersionNumber.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskCheckVersionNumber.h" + +#include "serverDatabase/GetVersionNumberQuery.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +TaskCheckVersionNumber::TaskCheckVersionNumber(int codeVersion, bool fatalOnMismatch) : + m_codeVersion(codeVersion), + m_databaseVersion(0), + m_minVersion(0), + m_fatalOnMismatch(fatalOnMismatch) +{ +} + +// ---------------------------------------------------------------------- + +TaskCheckVersionNumber::~TaskCheckVersionNumber() +{ +} + +// ---------------------------------------------------------------------- + +bool TaskCheckVersionNumber::process(DB::Session *session) +{ + int rowsFetched; + DBQuery::GetVersionNumberQuery qry; + + if (! (session->exec(&qry))) + return false; + rowsFetched = qry.fetch(); + m_databaseVersion=qry.getVersionNumber(); + m_minVersion=qry.getMinVersionNumber(); + return (rowsFetched >= 0); +} + +// ---------------------------------------------------------------------- + +void TaskCheckVersionNumber::onComplete() +{ + if ((m_codeVersion > m_databaseVersion) || (m_codeVersion < m_minVersion)) + { + if (m_fatalOnMismatch) + { + FATAL(true,("This version of the server requires database version %i, but the database is version %i.\n",m_codeVersion,m_databaseVersion)); + } + else + { + WARNING(true,("This version of the server requires database version %i, but the database is version %i.\n",m_codeVersion,m_databaseVersion)); + } + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.h b/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.h new file mode 100644 index 00000000..13c12e53 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskCheckVersionNumber.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// TaskCheckVersionNumber.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskCheckVersionNumber_H +#define INCLUDED_TaskCheckVersionNumber_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" + +// ====================================================================== + +class TaskCheckVersionNumber : public DB::TaskRequest +{ + public: + TaskCheckVersionNumber(int codeVersion, bool fatalOnMismatch); + virtual ~TaskCheckVersionNumber(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + int m_codeVersion; + int m_databaseVersion; + int m_minVersion; + bool m_fatalOnMismatch; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetBiography.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetBiography.cpp new file mode 100644 index 00000000..9c6cb243 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetBiography.cpp @@ -0,0 +1,69 @@ +// ====================================================================== +// +// TaskGetBiography.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskGetBiography.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/GetBiographyQuery.h" +#include "serverNetworkMessages/BiographyMessage.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +TaskGetBiography::TaskGetBiography(const NetworkId &owner, uint32 requestingProcess) : + m_owner(owner), + m_requestingProcess(requestingProcess), + m_bio(NULL) +{ +} + +// ---------------------------------------------------------------------- + +TaskGetBiography::~TaskGetBiography() +{ + delete m_bio; + m_bio=NULL; +} + +// ---------------------------------------------------------------------- + +bool TaskGetBiography::process(DB::Session *session) +{ + int rowsFetched; + DBQuery::GetBiographyQuery qry(m_owner); + if (! (session->exec(&qry))) + return false; + + m_bio = new Unicode::String(); + + if ((rowsFetched = qry.fetch()) > 0) + qry.getBio(*m_bio); + + qry.done(); + return (rowsFetched >= 0); +} + +// ---------------------------------------------------------------------- + +void TaskGetBiography::onComplete() +{ + WARNING_STRICT_FATAL(!m_bio,("In TaskGetBiography::onComplete, but m_bio is NULL\n")); + if (m_bio) + { + BiographyMessage msg(m_owner, *m_bio); + GameServerConnection *conn = DatabaseProcess::getInstance().getConnectionByProcess(m_requestingProcess); + if (conn) + conn->send(msg,true); + else + DEBUG_REPORT_LOG(true,("Discarded loaded biography because Game Server has disconnected.\n")); + } + +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetBiography.h b/engine/server/library/serverDatabase/src/shared/TaskGetBiography.h new file mode 100644 index 00000000..9648b0b2 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetBiography.h @@ -0,0 +1,35 @@ +// ====================================================================== +// +// TaskGetBiography.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskGetBiography_H +#define INCLUDED_TaskGetBiography_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +class TaskGetBiography : public DB::TaskRequest +{ + public: + TaskGetBiography(const NetworkId &owner, uint32 requestingProcess); + virtual ~TaskGetBiography(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + NetworkId m_owner; + uint32 m_requestingProcess; + Unicode::String *m_bio; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.cpp new file mode 100644 index 00000000..4efc86d7 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.cpp @@ -0,0 +1,77 @@ +// ====================================================================== +// +// TaskGetObjectIds.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskGetObjectIds.h" + +#include "serverNetworkMessages/AddObjectIdBlockMessage.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/GetObjectIdsQuery.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +TaskGetObjectIds::TaskGetObjectIds(int processId, int howMany, bool logRequest) : + m_processId(processId), + m_howMany(howMany), + m_logRequest(logRequest) +{ +} + +// ---------------------------------------------------------------------- + +bool TaskGetObjectIds::process(DB::Session *session) +{ + if (m_logRequest) + LOG("ObjectIdManager", ("TaskGetObjectIds::process() for %d more object ids for pid %d", m_howMany, m_processId)); + + int numLeft=m_howMany; + DBQuery::GetOIDsQuery qry; + + while (numLeft > 0) + { + qry.setHowMany(numLeft); + + if (! session->exec(&qry)) + return false; + + m_blockList.push_back(ObjectIdBlock(qry.getStartId(),qry.getEndId())); + + numLeft -= qry.getHowMany(); + } + return true; +} + +// ---------------------------------------------------------------------- +/** + * Send the object ID's to central. + * + * We send the block(s) of ID's to the central server. It is central's + * job to forward them to whatever game server needs them. + * In theory, we could send them directly to the game server. However, + * getting ID's happens during the startup process and it is simpler if + * we assume we don't have a connection to the game server yet. + */ +void TaskGetObjectIds::onComplete() +{ + if (m_logRequest) + LOG("ObjectIdManager", ("TaskGetObjectIds::onComplete() for %d more object ids for pid %d, returning %d blocks", m_howMany, m_processId, m_blockList.size())); + + bool logRequest = m_logRequest; + for (BlockListType::iterator i=m_blockList.begin(); i!=m_blockList.end(); ++i) + { + // Send one message for each block + AddOIDBlockMessage msg(m_processId,(*i).m_startId,(*i).m_endId, logRequest); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); + + // only need to do logging, if requested, for the first block sent + logRequest = false; + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.h b/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.h new file mode 100644 index 00000000..62f47532 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetObjectIds.h @@ -0,0 +1,55 @@ +// ====================================================================== +// +// TaskGetObjectIds.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskGetObjectIds_H +#define INCLUDED_TaskGetObjectIds_H + +// ====================================================================== + +#include + +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +class TaskGetObjectIds : public DB::TaskRequest +{ + public: + TaskGetObjectIds(int processId, int howMany, bool logRequest); + virtual ~TaskGetObjectIds() {} + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + int m_processId, m_howMany; + bool m_logRequest; + + class ObjectIdBlock + { + public: + NetworkId m_startId; + NetworkId m_endId; + ObjectIdBlock(const NetworkId &startId,const NetworkId &endId); + }; + + typedef std::vector BlockListType; + BlockListType m_blockList; +}; + +// ---------------------------------------------------------------------- + +inline TaskGetObjectIds::ObjectIdBlock::ObjectIdBlock(const NetworkId &startId,const NetworkId &endId) : + m_startId(startId), + m_endId(endId) +{ +} + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructures.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetStructures.cpp new file mode 100644 index 00000000..e55c0d1f --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructures.cpp @@ -0,0 +1,84 @@ +// TaskGetStructures.cpp +// copyright 2001 Verant Interactive +// Author: Calan Thurow + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.h" +#include "TaskGetStructures.h" + +#include "Unicode.h" +#include "serverDatabase/StructureQueries.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/StructureListMessage.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "unicodeArchive/UnicodeArchive.h" + +//----------------------------------------------------------------------- + +TaskGetStructures::TaskGetStructures(NetworkId & characterId, + uint32 toolId, + uint32 loginServerId) : + TaskRequest(), + m_characterId(characterId), + m_toolId(toolId), + m_loginServerId(loginServerId) +{ +} + +//----------------------------------------------------------------------- + +TaskGetStructures::~TaskGetStructures() +{ + for (StructuresType::iterator i=structures.begin(); i!=structures.end(); ++i) + { + delete *i; + } +} + +//----------------------------------------------------------------------- + +bool TaskGetStructures::process(DB::Session *session) +{ + int rowsFetched; + DBQuery::GetStructures qry; + + qry.setCharacterId(m_characterId); //lint !e713 //loss of precision ok //@todo check this + + if (! (session->exec(&qry))) + return false; + + while ((rowsFetched = qry.fetch()) > 0) + { + StructureRec *cr=new StructureRec; + + NOT_NULL(cr); + + cr->structureId = NetworkId(qry.getData().object_id.getValue()); + cr->location = Unicode::wideToNarrow(qry.getData().scene_id.getValue()); + cr->objectTemplate = Unicode::wideToNarrow(qry.getData().object_template.getValue()); + cr->x = static_cast(qry.getData().x.getValue()); + cr->y = static_cast(qry.getData().y.getValue()); + cr->z = static_cast(qry.getData().z.getValue()); + cr->deleted = qry.getData().deleted.getValue(); + structures.push_back(cr); + } + + qry.done(); + return (rowsFetched >= 0); +} + +//----------------------------------------------------------------------- + +void TaskGetStructures::onComplete() +{ + std::vector structurelist; + for(StructuresType::iterator i = structures.begin(); i != structures.end(); ++i) + { + structurelist.push_back(StructureListMessageData((*i)->objectTemplate, (*i)->structureId, (*i)->location, Vector((*i)->x,(*i)->y,(*i)->z),(*i)->deleted)); + } + StructureListMessage msg(m_toolId, m_loginServerId, m_characterId, structurelist); + DatabaseProcess::getInstance().sendToCentralServer(msg,true); +} + +//----------------------------------------------------------------------- diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructures.h b/engine/server/library/serverDatabase/src/shared/TaskGetStructures.h new file mode 100644 index 00000000..d63d0f69 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructures.h @@ -0,0 +1,58 @@ +// ====================================================================== +// +// TaskGetStructures.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskGetCharacters_H +#define INCLUDED_TaskGetCharacters_H + +// ====================================================================== + +#include + +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/NetworkId.h" +#include "Unicode.h" + +//----------------------------------------------------------------------- + +class TaskGetStructures:public DB::TaskRequest +{ + public: + struct StructureRec + { + std::string location; + std::string objectTemplate; + NetworkId structureId; + real x; + real y; + real z; + uint32 deleted; + }; + + typedef std::vector StructuresType; + + TaskGetStructures(NetworkId & characterId, uint32 toolId, uint32 loginServerId); + virtual ~TaskGetStructures(); + + virtual bool process (DB::Session *session); + virtual void onComplete (); + + protected: + StructuresType structures; + + private: + NetworkId m_characterId; + uint32 m_toolId; + uint32 m_loginServerId; + + TaskGetStructures(); + TaskGetStructures(const TaskGetStructures&); + TaskGetStructures& operator=(const TaskGetStructures& rhs); +}; + +//----------------------------------------------------------------------- + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp new file mode 100644 index 00000000..5ea2e6c8 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.cpp @@ -0,0 +1,261 @@ +// ====================================================================== +// +// TaskGetStructuresForPurge.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskGetStructuresForPurge.h" + +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/StructuresForPurgeMessage.h" +#include "sharedDatabaseInterface/Bindable.h" +#include "sharedDatabaseInterface/BindableNetworkId.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "unicodeArchive/UnicodeArchive.h" + +// ====================================================================== + + +namespace TaskGetStructuresForPurgeNamespace +{ + class GetStructuresForPurgeQuery : public DB::Query + { + public: + explicit GetStructuresForPurgeQuery(StationId stationId); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + NetworkId getStructureId() const; + NetworkId getOwnerId() const; + + private: + DB::BindableLong m_station_id; + DB::BindableNetworkId m_structure_id; + DB::BindableNetworkId m_owner_id; + + private: //disable + GetStructuresForPurgeQuery(const GetStructuresForPurgeQuery&); + GetStructuresForPurgeQuery& operator=(const GetStructuresForPurgeQuery&); + }; + + class GetVendorsForPurgeQuery : public DB::Query + { + public: + explicit GetVendorsForPurgeQuery(StationId stationId); + + virtual void getSQL(std::string &sql); + virtual bool bindParameters(); + virtual bool bindColumns(); + virtual QueryMode getExecutionMode() const; + + NetworkId getVendorId() const; + NetworkId getOwnerId() const; + Unicode::String getVendorName() const; + + private: + DB::BindableLong m_station_id; + DB::BindableNetworkId m_vendor_id; + DB::BindableNetworkId m_owner_id; + DB::BindableUnicode<128> m_vendor_name; + + private: //disable + GetVendorsForPurgeQuery(const GetVendorsForPurgeQuery&); + GetVendorsForPurgeQuery& operator=(const GetVendorsForPurgeQuery&); + }; +} +using namespace TaskGetStructuresForPurgeNamespace; + + +// ====================================================================== + +TaskGetStructuresForPurge::TaskGetStructuresForPurge(StationId account, bool warnOnly) : + DB::TaskRequest(), + m_account(account), + m_warnOnly(warnOnly), + m_structures(), + m_vendors() +{ +} + +// ---------------------------------------------------------------------- + +TaskGetStructuresForPurge::~TaskGetStructuresForPurge() +{ +} + +// ---------------------------------------------------------------------- + +bool TaskGetStructuresForPurge::process(DB::Session *session) +{ + int rowsFetched; + + { + GetStructuresForPurgeQuery qry(m_account); + if (! (session->exec(&qry))) + return false; + + do + { + rowsFetched = qry.fetch(); + if (rowsFetched > 0) + { + m_structures.push_back(std::make_pair(qry.getStructureId(),qry.getOwnerId())); + } + } while (rowsFetched > 0); + + qry.done(); + if (rowsFetched < 0) + return false; + } + + { + GetVendorsForPurgeQuery qry(m_account); + if (! (session->exec(&qry))) + return false; + + do + { + rowsFetched = qry.fetch(); + if (rowsFetched > 0) + { + m_vendors.push_back(std::make_pair(qry.getVendorId(),std::make_pair(qry.getOwnerId(),qry.getVendorName()))); + } + } while (rowsFetched > 0); + + qry.done(); + if (rowsFetched < 0) + return false; + } + + return true; +} + +// ---------------------------------------------------------------------- + +void TaskGetStructuresForPurge::onComplete() +{ + StructuresForPurgeMessage msg(m_account, m_structures, m_vendors, m_warnOnly); + DatabaseProcess::getInstance().sendToAnyGameServer(msg); // Any game server in the cluster can handle this. It will send messages to other game servers as needed +} + +// ====================================================================== + +GetStructuresForPurgeQuery::GetStructuresForPurgeQuery(StationId stationId) : + DB::Query(), + m_station_id(static_cast(stationId)) +{ +} + +// ---------------------------------------------------------------------- + +void GetStructuresForPurgeQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :result := ")+DatabaseProcess::getInstance().getSchemaQualifier()+"datalookup.get_structures_for_purge(:station_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetStructuresForPurgeQuery::bindParameters() +{ + if (!bindParameter(m_station_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetStructuresForPurgeQuery::bindColumns() +{ + if (!bindCol(m_structure_id)) return false; + if (!bindCol(m_owner_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +GetStructuresForPurgeQuery::QueryMode GetStructuresForPurgeQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ---------------------------------------------------------------------- + +NetworkId GetStructuresForPurgeQuery::getStructureId() const +{ + return m_structure_id.getValue(); +} + +// ---------------------------------------------------------------------- + +NetworkId GetStructuresForPurgeQuery::getOwnerId() const +{ + return m_owner_id.getValue(); +} + +// ====================================================================== + +GetVendorsForPurgeQuery::GetVendorsForPurgeQuery(StationId stationId) : + DB::Query(), + m_station_id(stationId) +{ +} + +// ---------------------------------------------------------------------- + +void GetVendorsForPurgeQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :result := ")+DatabaseProcess::getInstance().getSchemaQualifier()+"datalookup.get_vendors_for_purge(:station_id); end;"; +} + +// ---------------------------------------------------------------------- + +bool GetVendorsForPurgeQuery::bindParameters() +{ + if (!bindParameter(m_station_id)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool GetVendorsForPurgeQuery::bindColumns() +{ + if (!bindCol(m_vendor_id)) return false; + if (!bindCol(m_owner_id)) return false; + if (!bindCol(m_vendor_name)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +GetVendorsForPurgeQuery::QueryMode GetVendorsForPurgeQuery::getExecutionMode() const +{ + return MODE_PLSQL_REFCURSOR; +} + +// ---------------------------------------------------------------------- + +NetworkId GetVendorsForPurgeQuery::getVendorId() const +{ + return m_vendor_id.getValue(); +} + +// ---------------------------------------------------------------------- + +NetworkId GetVendorsForPurgeQuery::getOwnerId() const +{ + return m_owner_id.getValue(); +} + +// ---------------------------------------------------------------------- + +Unicode::String GetVendorsForPurgeQuery::getVendorName() const +{ + return m_vendor_name.getValue(); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.h b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.h new file mode 100644 index 00000000..251bce97 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskGetStructuresForPurge.h @@ -0,0 +1,39 @@ +// ====================================================================== +// +// TaskGetStructuresForPurge.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskGetStructuresForPurge_H +#define INCLUDED_TaskGetStructuresForPurge_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/NetworkId.h" +#include "sharedFoundation/StationId.h" +#include "Unicode.h" +#include + +// ====================================================================== + +class TaskGetStructuresForPurge : public DB::TaskRequest +{ + public: + explicit TaskGetStructuresForPurge(StationId account, bool warnOnly); + virtual ~TaskGetStructuresForPurge(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + StationId m_account; + bool m_warnOnly; + std::vector > m_structures; + std::vector > > m_vendors; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskLoadClock.cpp b/engine/server/library/serverDatabase/src/shared/TaskLoadClock.cpp new file mode 100644 index 00000000..53d40247 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskLoadClock.cpp @@ -0,0 +1,48 @@ +// ====================================================================== +// +// TaskLoadClock.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskLoadClock.h" + +#include "serverDatabase/GetTimestampQuery.h" +#include "serverDatabase/Loader.h" +#include "serverUtility/ServerClock.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +TaskLoadClock::TaskLoadClock() : + m_timestamp(-1) +{ +} + +// ====================================================================== + +bool TaskLoadClock::process(DB::Session *session) +{ + int rowsFetched; + DBQuery::GetTimestampQuery qry; + + if (! (session->exec(&qry))) + return false; + rowsFetched = qry.fetch(); + m_timestamp=qry.getTimestamp(); + return (rowsFetched >= 0); +} + +// ====================================================================== + +void TaskLoadClock::onComplete() +{ + DEBUG_REPORT_LOG(true,("Setting clock to %i\n",m_timestamp)); + DEBUG_FATAL(m_timestamp==-1,("Suspicious timestamp.\n")); + + ServerClock::getInstance().setGameTimeSeconds(m_timestamp); + Loader::getInstance().loadClockCompleted(); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskLoadClock.h b/engine/server/library/serverDatabase/src/shared/TaskLoadClock.h new file mode 100644 index 00000000..cc24b384 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskLoadClock.h @@ -0,0 +1,32 @@ +// ====================================================================== +// +// TaskLoadClock.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskLoadClock_H +#define INCLUDED_TaskLoadClock_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" + +// ====================================================================== + +/** + * Sets the clock based on the last timestamp saved in the database. + */ +class TaskLoadClock : public DB::TaskRequest +{ + public: + TaskLoadClock(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + int m_timestamp; +}; + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.cpp b/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.cpp new file mode 100644 index 00000000..88ab959d --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.cpp @@ -0,0 +1,46 @@ +// ====================================================================== +// +// TaskLoadSnapshots.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskLoadSnapshots.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/Loader.h" +#include "serverDatabase/LoaderSnapshotGroup.h" + +// ====================================================================== + +TaskLoadSnapshots::TaskLoadSnapshots(LoaderSnapshotGroup *snap) : + m_snapshotGroup(snap) +{ + DEBUG_REPORT_LOG(ConfigServerDatabase::getLogObjectLoading(),("Creating TaskLoadSnapshots with %i object locators attached.\n",m_snapshotGroup->getLocatorCount())); +} + +// ---------------------------------------------------------------------- + +TaskLoadSnapshots::~TaskLoadSnapshots() +{ + delete m_snapshotGroup; // normally loader takes custody, but delete it here in case the task is cancelled + m_snapshotGroup = 0; +} + +// ---------------------------------------------------------------------- + +bool TaskLoadSnapshots::process(DB::Session *session) +{ + return (m_snapshotGroup->load(session)); +} + +// ---------------------------------------------------------------------- + +void TaskLoadSnapshots::onComplete() +{ + Loader::getInstance().snapshotLoaded(m_snapshotGroup); + m_snapshotGroup = 0; // Loader takes custody +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.h b/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.h new file mode 100644 index 00000000..908d8b97 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskLoadSnapshots.h @@ -0,0 +1,34 @@ +// ====================================================================== +// +// TaskLoadSnapshots.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskLoadSnapshots_H +#define INCLUDED_TaskLoadSnapshots_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" + +class LoaderSnapshotGroup; + +// ====================================================================== + +class TaskLoadSnapshots : public DB::TaskRequest +{ + public: + TaskLoadSnapshots(LoaderSnapshotGroup *snap); + virtual ~TaskLoadSnapshots(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + LoaderSnapshotGroup *m_snapshotGroup; +}; + + +// ====================================================================== +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.cpp b/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.cpp new file mode 100644 index 00000000..30b7a19a --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.cpp @@ -0,0 +1,46 @@ +// TaskManagerConnection.cpp +// copyright 2000 Verant Interactive +// Author: Justin Randall + +//----------------------------------------------------------------------- + +#include "serverDatabase/FirstServerDatabase.h" +#include "ConfigServerDatabase.h" +#include "serverDatabase/TaskManagerConnection.h" +#include "serverNetworkMessages/TaskSpawnProcess.h" +#include "sharedNetwork/NetworkSetupData.h" + +//----------------------------------------------------------------------- + +TaskManagerConnection::TaskManagerConnection(const std::string & a, const unsigned short p) : +ServerConnection(a, p, NetworkSetupData()) +{ +} + +//----------------------------------------------------------------------- + +TaskManagerConnection::~TaskManagerConnection() +{ + DEBUG_REPORT_LOG(true, ("Deleting task server connection\n")); +} + +//----------------------------------------------------------------------- + +void TaskManagerConnection::onConnectionClosed() +{ + ServerConnection::onConnectionClosed(); + static MessageConnectionCallback m("TaskConnectionClosed"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + +void TaskManagerConnection::onConnectionOpened() +{ + ServerConnection::onConnectionClosed(); + static MessageConnectionCallback m("TaskConnectionOpened"); + emitMessage(m); +} + +//----------------------------------------------------------------------- + diff --git a/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.h b/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.h new file mode 100644 index 00000000..94d33a42 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskManagerConnection.h @@ -0,0 +1,29 @@ +// TaskManagerConnection.h +// copyright 2000 Verant Interactive +// Author: Justin Randall + +#ifndef _TaskManagerConnection_H +#define _TaskManagerConnection_H + +//----------------------------------------------------------------------- + +#include "serverUtility/ServerConnection.h" + +//----------------------------------------------------------------------- + +class TaskManagerConnection : public ServerConnection +{ +public: + TaskManagerConnection(const std::string & remoteAddress, const unsigned short remotePort); + ~TaskManagerConnection(); + void onConnectionClosed (); + void onConnectionOpened (); + +private: + TaskManagerConnection(TaskManagerConnection&); + TaskManagerConnection& operator=(TaskManagerConnection&); +}; + +//----------------------------------------------------------------------- + +#endif // _TaskManagerConnection_H diff --git a/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.cpp b/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.cpp new file mode 100644 index 00000000..4207b8b1 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.cpp @@ -0,0 +1,37 @@ +// ====================================================================== +// +// TaskSaveSnapshot.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskSaveSnapshot.h" + +#include "serverDatabase/Persister.h" +#include "serverDatabase/Snapshot.h" +#include "sharedFoundation/NetworkIdArchive.h" //TODO: Windows build breaks without this. Why? Makes no sense. + +// ====================================================================== + +TaskSaveSnapshot::TaskSaveSnapshot(Snapshot *snapshot) : + m_snapshot(snapshot) +{ +} + +// ---------------------------------------------------------------------- + +bool TaskSaveSnapshot::process(DB::Session *session) +{ + return (m_snapshot->saveToDB(session)); +} + +// ---------------------------------------------------------------------- + +void TaskSaveSnapshot::onComplete() +{ + m_snapshot->saveCompleted(); + Persister::getInstance().saveCompleted(m_snapshot); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.h b/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.h new file mode 100644 index 00000000..b87f532c --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskSaveSnapshot.h @@ -0,0 +1,32 @@ +// ====================================================================== +// +// TaskSaveSnapshot.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskSaveSnapshot_H +#define INCLUDED_TaskSaveSnapshot_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" + +class Snapshot; + +// ====================================================================== + +class TaskSaveSnapshot : public DB::TaskRequest +{ + public: + TaskSaveSnapshot(Snapshot *snapshot); + bool process(DB::Session *session); + void onComplete(); + + private: + Snapshot *m_snapshot; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/TaskSetBiography.cpp b/engine/server/library/serverDatabase/src/shared/TaskSetBiography.cpp new file mode 100644 index 00000000..d8a98958 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskSetBiography.cpp @@ -0,0 +1,47 @@ +// ====================================================================== +// +// TaskSetBiography.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/TaskSetBiography.h" + +#include "serverDatabase/SetBiographyQuery.h" +#include "sharedDatabaseInterface/DbSession.h" + +// ====================================================================== + +TaskSetBiography::TaskSetBiography(const NetworkId &owner, const Unicode::String &bio) : + m_owner(owner), + m_bio(new Unicode::String(bio)) +{ +} + +// ---------------------------------------------------------------------- + +TaskSetBiography::~TaskSetBiography() +{ + delete m_bio; + m_bio=NULL; +} + +// ---------------------------------------------------------------------- + +bool TaskSetBiography::process(DB::Session *session) +{ + NOT_NULL(m_bio); + DBQuery::SetBiographyQuery qry(m_owner, *m_bio); + bool rval = session->exec(&qry); + qry.done(); + return rval; +} + +// ---------------------------------------------------------------------- + +void TaskSetBiography::onComplete() +{ +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/TaskSetBiography.h b/engine/server/library/serverDatabase/src/shared/TaskSetBiography.h new file mode 100644 index 00000000..926eb8dd --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/TaskSetBiography.h @@ -0,0 +1,34 @@ +// ====================================================================== +// +// TaskSetBiography.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_TaskSetBiography_H +#define INCLUDED_TaskSetBiography_H + +// ====================================================================== + +#include "sharedDatabaseInterface/DbTaskRequest.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +class TaskSetBiography : public DB::TaskRequest +{ + public: + TaskSetBiography(const NetworkId &owner, const Unicode::String &bio); + virtual ~TaskSetBiography(); + + virtual bool process(DB::Session *session); + virtual void onComplete(); + + private: + NetworkId m_owner; + Unicode::String *m_bio; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp b/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp new file mode 100644 index 00000000..bad7a18c --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/UniverseLocator.cpp @@ -0,0 +1,47 @@ +// ====================================================================== +// +// UniverseLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/UniverseLocator.h" + +#include + +#include "serverDatabase/GameServerConnection.h" +#include "serverDatabase/GetUniverseQuery.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverNetworkMessages/SetUniverseAuthoritativeMessage.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedNetworkMessages/GenericValueTypeMessage.h" + +// ====================================================================== + +bool UniverseLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + DEBUG_REPORT_LOG(true,("Loading Universe Objects.\n")); + + DBQuery::GetUniverseQuery qry(schema); + bool rval = session->exec(&qry); + qry.done(); + + objectsLocated = 1; //TODO: Counts + return rval; +} + +// ---------------------------------------------------------------------- + +void UniverseLocator::sendPostBaselinesCustomData(GameServerConnection &conn) const +{ + DEBUG_REPORT_LOG(true,("Sending UniverseComplete.\n")); + GenericValueTypeMessage const universeCompleteMessage("UniverseCompleteMessage", DatabaseProcess::getInstance().getProcessId()); + conn.send(universeCompleteMessage, true); + + SetUniverseAuthoritativeMessage const setUniverseAuthoritativeMessage(conn.getProcessId()); + conn.send(setUniverseAuthoritativeMessage, true); +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/UniverseLocator.h b/engine/server/library/serverDatabase/src/shared/UniverseLocator.h new file mode 100644 index 00000000..07a53ade --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/UniverseLocator.h @@ -0,0 +1,24 @@ +// ====================================================================== +// +// UniverseLocator.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_UniverseLocator_H +#define INCLUDED_UniverseLocator_H + +#include "serverDatabase/ObjectLocator.h" + +// ====================================================================== + +class UniverseLocator:public ObjectLocator +{ + public: + virtual bool locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated); + virtual void sendPostBaselinesCustomData(GameServerConnection &conn) const; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.cpp b/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.cpp new file mode 100644 index 00000000..e44bf920 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.cpp @@ -0,0 +1,76 @@ +// ====================================================================== +// +// UnloadCharacterCustomPersistStep.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/UnloadCharacterCustomPersistStep.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "serverDatabase/Loader.h" +#include "serverDatabase/Persister.h" +#include "serverNetworkMessages/PersistedPlayerMessage.h" +#include "sharedLog/Log.h" + +// ====================================================================== + +UnloadCharacterCustomPersistStep::UnloadCharacterCustomPersistStep(const NetworkId &characterObject, uint32 serverId) : + m_characterObject(characterObject), + m_serverId(serverId) +{ + Loader::getInstance().addLoadLock(m_characterObject); +} + +// ---------------------------------------------------------------------- + +UnloadCharacterCustomPersistStep::~UnloadCharacterCustomPersistStep() +{ +} + +// ---------------------------------------------------------------------- + +bool UnloadCharacterCustomPersistStep::beforePersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +bool UnloadCharacterCustomPersistStep::afterPersist(DB::Session *session) +{ + UNREF(session); + return true; +} + +// ---------------------------------------------------------------------- + +void UnloadCharacterCustomPersistStep::onComplete() +{ + Loader::getInstance().removeLoadLock(m_characterObject); + + bool hasDataForObject = Persister::getInstance().hasDataForObject(m_characterObject); + + if (hasDataForObject) + LOG("UnloadCharacterCustomPersistStep::onComplete",("Unloaded character %s still has unsaved data",m_characterObject.getValueString().c_str())); + + if ((hasDataForObject) && (ConfigServerDatabase::getDelayUnloadIfObjectStillHasData())) + { + // the object still has unsaved data, so wait until + // the next save cycle to save/unload the object; + // otherwise, if we unload the object now, we could + // lose the unsaved data if the player logs in before + // the data has been saved + Persister::getInstance().unloadCharacter(m_characterObject, m_serverId); + } + else + { + PersistedPlayerMessage const persistedPlayerMessage(m_characterObject); + DatabaseProcess::getInstance().sendToGameServer(m_serverId, persistedPlayerMessage); + } +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.h b/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.h new file mode 100644 index 00000000..b566b1e8 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/UnloadCharacterCustomPersistStep.h @@ -0,0 +1,44 @@ +// ====================================================================== +// +// UnloadCharacterCustomPersistStep.h +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_UnloadCharacterCustomPersistStep_H +#define INCLUDED_UnloadCharacterCustomPersistStep_H + +// ====================================================================== + +#include "serverDatabase/CustomPersistStep.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * A custom persist step when a charcter logs out. + * Locks the object to prevent a reload until any pending persisted data + * has been saved. + */ +class UnloadCharacterCustomPersistStep : public CustomPersistStep +{ + public: + UnloadCharacterCustomPersistStep(const NetworkId &characterObject, uint32 serverId); + ~UnloadCharacterCustomPersistStep(); + + virtual bool beforePersist (DB::Session *session); + virtual bool afterPersist (DB::Session *session); + virtual void onComplete (); + + private: + NetworkId m_characterObject; + uint32 m_serverId; + + private: + UnloadCharacterCustomPersistStep &operator= (const UnloadCharacterCustomPersistStep&); //disable + UnloadCharacterCustomPersistStep(const UnloadCharacterCustomPersistStep&); //disable +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.cpp b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.cpp new file mode 100644 index 00000000..5a1ada28 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.cpp @@ -0,0 +1,166 @@ +// ====================================================================== +// +// WorldContainerLocator.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +#include "serverDatabase/WorldContainerLocator.h" + +#include "serverDatabase/ConfigServerDatabase.h" +#include "serverDatabase/DatabaseProcess.h" +#include "sharedDatabaseInterface/DbSession.h" +#include "sharedLog/Log.h" +#include + +// ====================================================================== + +namespace WorldContainerLocatorTablespace +{ + const int ms_maxItemsPerExec = 10000; +} + +using namespace WorldContainerLocatorTablespace; + +// ====================================================================== + +WorldContainerLocator::WorldContainerLocator(const std::vector &containers) : + ObjectLocator(), + m_containers(new std::vector(containers)) +{ +} + +// ---------------------------------------------------------------------- + +WorldContainerLocator::~WorldContainerLocator() +{ + delete m_containers; + m_containers=0; +} + +// ====================================================================== + +bool WorldContainerLocator::locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated) +{ + NOT_NULL(session); + int objectCount (0); + bool rval = true; + + WorldContainerQuery qry(schema); + if (!qry.setupData(session)) + return false; + for (std::vector::const_iterator i=m_containers->begin(); i!=m_containers->end(); ++i) + { + if (!qry.addContainer(*i)) + return false; + if (qry.getNumItems() > ms_maxItemsPerExec) + { + rval=qry.exec(); + if (! rval) + break; + objectCount += qry.getObjectCount(); + qry.clearData(); + } + } + if (! rval) + return false; + + if (qry.getNumItems() > 0) + { + rval = session->exec(&qry); + objectCount += qry.getObjectCount(); + } + + qry.freeData(); + qry.done(); + + objectsLocated = objectCount; + return rval; +} + +// ====================================================================== + +WorldContainerLocator::WorldContainerQuery::WorldContainerQuery(const std::string &schema) : + num_containers(0), + m_schema(schema) +{ +} + +// ---------------------------------------------------------------------- + +void WorldContainerLocator::WorldContainerQuery::getSQL(std::string &sql) +{ + sql=std::string("begin :object_count := ")+m_schema+"loader.locate_by_loadwith_batch(:loadwiths, :chunk_size); end;"; +} + +// ---------------------------------------------------------------------- + +bool WorldContainerLocator::WorldContainerQuery::bindParameters() +{ + if (!bindParameter(num_objects_found)) return false; + if (!bindParameter(container_ids)) return false; + if (!bindParameter(num_containers)) return false; + return true; +} + +// ---------------------------------------------------------------------- + +bool WorldContainerLocator::WorldContainerQuery::bindColumns() +{ + return true; +} + +// ---------------------------------------------------------------------- + +bool WorldContainerLocator::WorldContainerQuery::setupData(DB::Session *session) +{ + return container_ids.create(session, "VAOFSTRING", DatabaseProcess::getInstance().getSchema(),1000); +} + +// ---------------------------------------------------------------------- + +void WorldContainerLocator::WorldContainerQuery::clearData() +{ + container_ids.clear(); +} + +// ---------------------------------------------------------------------- + +void WorldContainerLocator::WorldContainerQuery::freeData() +{ + container_ids.free(); +} + +// ---------------------------------------------------------------------- + +bool WorldContainerLocator::WorldContainerQuery::addContainer(const NetworkId &containerId) +{ + if (!container_ids.push_back(containerId)) + return false; + num_containers = num_containers.getValue() + 1; + return true; +} + +// ---------------------------------------------------------------------- + +int WorldContainerLocator::WorldContainerQuery::getNumItems() const +{ + return num_containers.getValue(); +} + +// ---------------------------------------------------------------------- + +int WorldContainerLocator::WorldContainerQuery::getObjectCount() const +{ + return num_objects_found.getValue(); +} + +// ---------------------------------------------------------------------- + +DB::Query::QueryMode WorldContainerLocator::WorldContainerQuery::getExecutionMode() const +{ + return MODE_PROCEXEC; +} + +// ====================================================================== diff --git a/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h new file mode 100644 index 00000000..b3b70720 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/WorldContainerLocator.h @@ -0,0 +1,73 @@ +// ====================================================================== +// +// WorldContainerLocator.h +// copyright (c) 2003 Sony Online Entertainment +// +// ====================================================================== + +#ifndef INCLUDED_WorldContainerLocator_H +#define INCLUDED_WorldContainerLocator_H + +#include "serverDatabase/ObjectLocator.h" +#include "sharedDatabaseInterface/DbBindableVarray.h" +#include "sharedDatabaseInterface/DbQuery.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Locate all objects whose load_with matches objects in the list. + * This is intended to locate objects in the live database who are persisted + * inside objects in the gold database. + */ +class WorldContainerLocator : public ObjectLocator +{ + public: + WorldContainerLocator(const stdvector::fwd &containers); + virtual ~WorldContainerLocator(); + + public: + virtual bool locateObjects(DB::Session *session, const std::string &schema, int &objectsLocated); + + private: + stdvector::fwd * m_containers; + + private: + WorldContainerLocator &operator=(const WorldContainerLocator&); //disable + WorldContainerLocator(const WorldContainerLocator&); //disable + + private: + class WorldContainerQuery : public DB::Query + { + public: + WorldContainerQuery(const std::string &schema); + + virtual void getSQL (std::string &sql); + virtual bool bindParameters (); + virtual bool bindColumns (); + + bool setupData(DB::Session *session); + void clearData(); + void freeData(); + bool addContainer(const NetworkId &containerId); + int getNumItems() const; + int getObjectCount() const; + + private: + virtual DB::Query::QueryMode getExecutionMode() const; + + private: + DB::BindableVarrayString container_ids; + DB::BindableLong num_containers; + DB::BindableLong num_objects_found; + std::string m_schema; + + private: + WorldContainerQuery (const WorldContainerQuery&); // disable + WorldContainerQuery& operator= (const WorldContainerQuery&); //disable + }; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/dBAuctionRecord.h b/engine/server/library/serverDatabase/src/shared/dBAuctionRecord.h new file mode 100644 index 00000000..7aba1b7c --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/dBAuctionRecord.h @@ -0,0 +1,46 @@ +// ====================================================================== +// +// dBAuctionRecord.h +// copyright (c) 2004 Sony Online Entertainment +// Author: Doug Mellencamp +// +// ====================================================================== + + +#ifndef INCLUDED_dBAuctionRecord_H +#define INCLUDED_dBAuctionRecord_H + +// ====================================================================== + +#include "Unicode.h" +#include "sharedFoundation/NetworkId.h" + +#include + +// ====================================================================== + +/** + * Data structures for querying auctions. + */ +struct AuctionRecord +{ + NetworkId m_creatorId; + int m_minBid; + int m_auctionTimer; + int m_buyNowPrice; + Unicode::String m_userDescription; + std::string m_oob; + NetworkId m_locationId; + NetworkId m_itemId; + int m_category; + int m_itemTimer; + Unicode::String m_itemName; + NetworkId m_ownerId; + int m_active; + int m_itemSize; + int m_itemTemplateId; +}; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/dBBidRecord.h b/engine/server/library/serverDatabase/src/shared/dBBidRecord.h new file mode 100644 index 00000000..bd158ce1 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/dBBidRecord.h @@ -0,0 +1,36 @@ +// ====================================================================== +// +// dBBidRecord.h +// copyright (c) 2004 Sony Online Entertainment +// Author: Doug Mellencamp +// +// ====================================================================== + +#ifndef INCLUDED_dBBidRecord_H +#define INCLUDED_dBBidRecord_H + +// ====================================================================== + +#include "Unicode.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Data structures for querying bids. + */ +struct BidRecord +{ + NetworkId m_itemId; + NetworkId m_bidderId; + int m_bid; + int m_maxProxyBid; +}; + +// ====================================================================== + +typedef stdvector::fwd BidList; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/shared/dBLocationRecord.h b/engine/server/library/serverDatabase/src/shared/dBLocationRecord.h new file mode 100644 index 00000000..feec0939 --- /dev/null +++ b/engine/server/library/serverDatabase/src/shared/dBLocationRecord.h @@ -0,0 +1,43 @@ +// ====================================================================== +// +// dBLocationRecord.h +// copyright (c) 2004 Sony Online Entertainment +// Author: Doug Mellencamp +// +// ====================================================================== + +#ifndef INCLUDED_dBLocationRecord_H +#define INCLUDED_dBLocationRecord_H + +// ====================================================================== + +#include "Unicode.h" +#include "sharedFoundation/NetworkId.h" + +// ====================================================================== + +/** + * Data structures for querying Location. + */ +struct LocationRecord +{ + NetworkId m_locationId; + NetworkId m_ownerId; + std::string m_locationString; + int m_salesTax; + NetworkId m_salesTaxBankId; + int m_emptyDate; + int m_lastAccessDate; + int m_inactiveDate; + int m_status; + bool m_searchEnabled; + int m_entranceCharge; +}; + +// ====================================================================== + +typedef stdvector::fwd LocationList; + +// ====================================================================== + +#endif diff --git a/engine/server/library/serverDatabase/src/win32/FirstServerDatabase.cpp b/engine/server/library/serverDatabase/src/win32/FirstServerDatabase.cpp new file mode 100644 index 00000000..944e604d --- /dev/null +++ b/engine/server/library/serverDatabase/src/win32/FirstServerDatabase.cpp @@ -0,0 +1,9 @@ +// ====================================================================== +// +// FirstServerDatabase.cpp +// copyright (c) 2001 Sony Online Entertainment +// +// ====================================================================== + +#include "serverDatabase/FirstServerDatabase.h" +