Added the SwgDatabaseServer project, still need to handle generated files

This commit is contained in:
Anonymous
2014-01-17 07:02:57 -07:00
parent 63ccf4eb43
commit 84d3709fdc
220 changed files with 21265 additions and 0 deletions
+1
View File
@@ -1,2 +1,3 @@
add_subdirectory(SwgDatabaseServer)
add_subdirectory(SwgGameServer)
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 2.8)
project(SwgDatabaseServer)
if(WIN32)
add_definitions(/D_CRT_SECURE_NO_WARNINGS)
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/public)
add_subdirectory(src)
@@ -0,0 +1 @@
#include "../../../src/shared/buffers/AuctionLocationsBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/BattlefieldParticipantBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/BattlefieldParticipantQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/BountyHunterTargetBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/BountyHunterTargetQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CMLoader.h"
@@ -0,0 +1 @@
#include "../../../src/shared/queries/CommoditiesQuery.h"
@@ -0,0 +1 @@
#include "../../../src/shared/queries/CommoditiesSchema.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/CommoditiesSnapshot.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/CreatureObjectBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/DataCleanupManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/DeleteDemandLoadedContainerQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ExperienceBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/ExperienceQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/FirstSwgDatabaseServer.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/IndexedNetworkTableBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/IndexedTableBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/LocationBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/LocationQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ManufactureSchematicAttributeBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/ManufactureSchematicAttributeQuery.h"
@@ -0,0 +1 @@
#include "../../../src/shared/buffers/MarketAuctionBidsBuffer.h"
@@ -0,0 +1 @@
#include "../../../src/shared/buffers/MarketAuctionsBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/MessageBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/MessageQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/generated/ObjectQueries.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ObjectTableBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/ObjectVariableQueries.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/ObjectsTableQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ObjvarBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/ObjvarNameManager.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/OfflineMoneyCustomPersistStep.h"
@@ -0,0 +1 @@
#include "../../src/shared/persistable/PersistableWaypoint.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/PropertyListBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/PropertyListQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ResourceTypeBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/ResourceTypeQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/generated/Schema.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/ScriptBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/SkillQuery.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SwgDatabaseServer.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SwgLoader.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SwgLoaderSnapshotGroup.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SwgPersister.h"
@@ -0,0 +1 @@
#include "../../src/shared/core/SwgSnapshot.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskAnySQL.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskBrokenObjectCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskConsolidateExperience.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskDailyCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskFixBadCells.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskGetCharacters.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskLoadObjvarNames.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskLocateStructure.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskMarketAttributesCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskMessagesCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskMoveToPlayer.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskObjectTemplateListUpdater.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskObjvarNameCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskOrphanedObjectCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskRestoreCharacter.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskRestoreHouse.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskSaveObjvarNames.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskUndeleteItem.h"
@@ -0,0 +1 @@
#include "../../src/shared/cleanup/TaskVendorObjectCleanup.h"
@@ -0,0 +1 @@
#include "../../src/shared/tasks/TaskVerifyCharacter.h"
@@ -0,0 +1 @@
#include "../../src/shared/buffers/WaypointBuffer.h"
@@ -0,0 +1 @@
#include "../../src/shared/queries/WaypointQuery.h"
@@ -0,0 +1,265 @@
set(SHARED_SOURCES
shared/buffers/AuctionLocationsBuffer.cpp
shared/buffers/AuctionLocationsBuffer.h
shared/buffers/BattlefieldParticipantBuffer.cpp
shared/buffers/BattlefieldParticipantBuffer.h
shared/buffers/BountyHunterTargetBuffer.cpp
shared/buffers/BountyHunterTargetBuffer.h
shared/buffers/CreatureObjectBuffer.cpp
shared/buffers/CreatureObjectBuffer.h
shared/buffers/ExperienceBuffer.cpp
shared/buffers/ExperienceBuffer.h
shared/buffers/IndexedNetworkTableBuffer.cpp
shared/buffers/IndexedNetworkTableBuffer.h
shared/buffers/IndexedTableBuffer.h
shared/buffers/LocationBuffer.cpp
shared/buffers/LocationBuffer.h
shared/buffers/ManufactureSchematicAttributeBuffer.cpp
shared/buffers/ManufactureSchematicAttributeBuffer.h
shared/buffers/MarketAuctionBidsBuffer.cpp
shared/buffers/MarketAuctionBidsBuffer.h
shared/buffers/MarketAuctionsBuffer.cpp
shared/buffers/MarketAuctionsBuffer.h
shared/buffers/MessageBuffer.cpp
shared/buffers/MessageBuffer.h
shared/buffers/ObjectTableBuffer.cpp
shared/buffers/ObjectTableBuffer.h
shared/buffers/ObjvarBuffer.cpp
shared/buffers/ObjvarBuffer.h
shared/buffers/PropertyListBuffer.cpp
shared/buffers/PropertyListBuffer.h
shared/buffers/ResourceTypeBuffer.cpp
shared/buffers/ResourceTypeBuffer.h
shared/buffers/ScriptBuffer.cpp
shared/buffers/ScriptBuffer.h
shared/buffers/WaypointBuffer.cpp
shared/buffers/WaypointBuffer.h
shared/cleanup/DataCleanupManager.cpp
shared/cleanup/DataCleanupManager.h
shared/cleanup/TaskConsolidateExperience.cpp
shared/cleanup/TaskConsolidateExperience.h
shared/cleanup/TaskDailyCleanup.cpp
shared/cleanup/TaskDailyCleanup.h
shared/cleanup/TaskAnySQL.cpp
shared/cleanup/TaskAnySQL.h
shared/cleanup/TaskObjvarNameCleanup.cpp
shared/cleanup/TaskObjvarNameCleanup.h
shared/cleanup/TaskOrphanedObjectCleanup.cpp
shared/cleanup/TaskOrphanedObjectCleanup.h
shared/cleanup/TaskMarketAttributesCleanup.cpp
shared/cleanup/TaskMarketAttributesCleanup.h
shared/cleanup/TaskMessagesCleanup.cpp
shared/cleanup/TaskMessagesCleanup.h
shared/cleanup/TaskBrokenObjectCleanup.cpp
shared/cleanup/TaskBrokenObjectCleanup.h
shared/cleanup/TaskVendorObjectCleanup.cpp
shared/cleanup/TaskVendorObjectCleanup.h
shared/cleanup/TaskFixBadCells.cpp
shared/cleanup/TaskFixBadCells.h
shared/cleanup/TaskObjectTemplateListUpdater.cpp
shared/cleanup/TaskObjectTemplateListUpdater.h
shared/core/CMLoader.cpp
shared/core/CMLoader.h
shared/core/FirstSwgDatabaseServer.h
shared/core/MiscPack.cpp
shared/core/ObjvarNameManager.cpp
shared/core/ObjvarNameManager.h
shared/core/CommoditiesSnapshot.cpp
shared/core/CommoditiesSnapshot.h
shared/core/SwgDatabaseServer.cpp
shared/core/SwgDatabaseServer.h
shared/core/SwgLoader.cpp
shared/core/SwgLoader.h
shared/core/SwgLoaderSnapshotGroup.cpp
shared/core/SwgLoaderSnapshotGroup.h
shared/core/SwgPersister.cpp
shared/core/SwgPersister.h
shared/core/SwgSnapshot.cpp
shared/core/SwgSnapshot.h
shared/persistable/PersistableWaypoint.cpp
shared/persistable/PersistableWaypoint.h
shared/queries/BattlefieldParticipantQuery.cpp
shared/queries/BattlefieldParticipantQuery.h
shared/queries/BountyHunterTargetQuery.cpp
shared/queries/BountyHunterTargetQuery.h
shared/queries/CommoditiesQuery.cpp
shared/queries/CommoditiesQuery.h
shared/queries/DeleteDemandLoadedContainerQuery.cpp
shared/queries/DeleteDemandLoadedContainerQuery.h
shared/queries/ExperienceQuery.cpp
shared/queries/ExperienceQuery.h
shared/queries/LocationQuery.cpp
shared/queries/LocationQuery.h
shared/queries/ManufactureSchematicAttributeQuery.cpp
shared/queries/ManufactureSchematicAttributeQuery.h
shared/queries/MessageQuery.cpp
shared/queries/MessageQuery.h
shared/queries/ObjectVariableQueries.cpp
shared/queries/ObjectVariableQueries.h
shared/queries/ObjectsTableQuery.cpp
shared/queries/ObjectsTableQuery.h
shared/queries/OfflineMoneyCustomPersistStep.cpp
shared/queries/OfflineMoneyCustomPersistStep.h
shared/queries/PropertyListQuery.cpp
shared/queries/PropertyListQuery.h
shared/queries/ResourceTypeQuery.cpp
shared/queries/ResourceTypeQuery.h
shared/queries/SkillQuery.cpp
shared/queries/SkillQuery.h
shared/queries/WaypointQuery.cpp
shared/queries/WaypointQuery.h
shared/tasks/TaskGetAuctionAttributeList.cpp
shared/tasks/TaskGetAuctionAttributeList.h
shared/tasks/TaskGetAuctionList.cpp
shared/tasks/TaskGetAuctionList.h
shared/tasks/TaskGetBidList.cpp
shared/tasks/TaskGetBidList.h
shared/tasks/TaskGetCharacters.cpp
shared/tasks/TaskGetCharacters.h
shared/tasks/TaskGetLocationList.cpp
shared/tasks/TaskGetLocationList.h
shared/tasks/TaskLoadObjvarNames.cpp
shared/tasks/TaskLoadObjvarNames.h
shared/tasks/TaskLocateStructure.cpp
shared/tasks/TaskLocateStructure.h
shared/tasks/TaskMoveToPlayer.cpp
shared/tasks/TaskMoveToPlayer.h
shared/tasks/TaskRestoreCharacter.cpp
shared/tasks/TaskRestoreCharacter.h
shared/tasks/TaskRestoreHouse.cpp
shared/tasks/TaskRestoreHouse.h
shared/tasks/TaskSaveObjvarNames.cpp
shared/tasks/TaskSaveObjvarNames.h
shared/tasks/TaskUndeleteItem.cpp
shared/tasks/TaskUndeleteItem.h
shared/tasks/TaskVerifyCharacter.cpp
shared/tasks/TaskVerifyCharacter.h
)
if(WIN32)
set(PLATFORM_SOURCES
win32/FirstSwgDatabaseServer.cpp
win32/WinMain.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/win32)
else()
set(PLATFORM_SOURCES
linux/main.cpp
)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/linux)
endif()
include_directories(
#${CMAKE_CURRENT_SOURCE_DIR}/shared/combat
#${CMAKE_CURRENT_SOURCE_DIR}/shared/core
#${CMAKE_CURRENT_SOURCE_DIR}/shared/lint
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCollision/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedCommandParser/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedDebug/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFile/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundation/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedFoundationTypes/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedGame/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedImage/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/sharedObject/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedPathfinding/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRandom/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRegex/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedRemoteDebugServer/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedSkillSystem/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedTerrain/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedThread/include/public
#${SWG_ENGINE_SOURCE_DIR}/shared/library/sharedUtility/include/public
#${SWG_ENGINE_SOURCE_DIR}/server/library/serverGame/include/public
#${SWG_ENGINE_SOURCE_DIR}/server/library/serverNetworkMessages/include/public
#${SWG_ENGINE_SOURCE_DIR}/server/library/serverPathfinding/include/public
#${SWG_ENGINE_SOURCE_DIR}/server/library/serverScript/include/public
#${SWG_ENGINE_SOURCE_DIR}/server/library/serverUtility/include/public
#${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedNetworkMessages/include/public
#${SWG_GAME_SOURCE_DIR}/shared/library/swgSharedUtility/include/public
#${SWG_GAME_SOURCE_DIR}/server/library/swgServerNetworkMessages/include/public
#${SWG_EXTERNALS_SOURCE_DIR}/ours/library/archive/include
#${SWG_EXTERNALS_SOURCE_DIR}/ours/library/fileInterface/include/public
#${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
#${Boost_INCLUDE_DIR}
#${JNI_INCLUDE_DIRS}
)
link_directories(${STLPORT_LIBDIR})
add_executable(SwgDatabaseServer
${SHARED_SOURCES}
${PLATFORM_SOURCES}
)
target_link_libraries(SwgDatabaseServer
#sharedCollision
#sharedCommandParser
#sharedCompression
#sharedDebug
#sharedFile
#sharedFractal
#sharedFoundation
#sharedGame
#sharedImage
#sharedLog
#sharedMath
#sharedMemoryManager
#sharedMessageDispatch
#sharedNetwork
#sharedNetworkMessages
#sharedObject
#sharedPathfinding
#sharedRandom
#sharedRegex
#sharedRemoteDebugServer
#sharedSkillSystem
#sharedSynchronization
#sharedTerrain
#sharedThread
#sharedUtility
#sharedXml
#serverGame
#serverMetrics
#serverNetworkMessages
#serverPathfinding
#serverScript
#serverUtility
#swgSharedNetworkMessages
#swgSharedUtility
#swgServerNetworkMessages
#archive
#fileInterface
#localization
#localizationArchive
#unicode
#unicodeArchive
#Base
#udplibrary
#${PCRE_LIBRARY}
#${LIBXML2_LIBRARY}
#${ZLIB_LIBRARY}
)
if(WIN32)
target_link_libraries(SwgDatabaseServer mswsock ws2_32)
endif()
@@ -0,0 +1,76 @@
#include "FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/SwgDatabaseServer.h"
#include "serverDatabase/ConfigServerDatabase.h"
#include "sharedDebug/SetupSharedDebug.h"
#include "sharedFile/SetupSharedFile.h"
#include "sharedFile/TreeFile.h"
#include "sharedFoundation/Os.h"
#include "sharedFoundation/SetupSharedFoundation.h"
#include "sharedLog/LogManager.h"
#include "sharedLog/SetupSharedLog.h"
#include "sharedNetwork/NetworkHandler.h"
#include "sharedNetwork/SetupSharedNetwork.h"
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
#include "sharedRandom/SetupSharedRandom.h"
#include "sharedThread/SetupSharedThread.h"
#include "sharedNetworkMessages/SetupSharedNetworkMessages.h"
#include "swgSharedNetworkMessages/SetupSwgSharedNetworkMessages.h"
#include "swgServerNetworkMessages/SetupSwgServerNetworkMessages.h"
// ======================================================================
void dumpPid(const char * argv)
{
pid_t p = getpid();
char fileName[1024];
sprintf(fileName, "%s.%d", argv, p);
FILE * f = fopen(fileName, "w+");
fclose(f);
}
int main(int argc, char ** argv)
{
// dumpPid(argv[0]);
SetupSharedThread::install();
SetupSharedDebug::install(1024);
//-- setup foundation
SetupSharedFoundation::Data setupFoundationData(SetupSharedFoundation::Data::D_game);
setupFoundationData.lpCmdLine = ConvertCommandLine(argc,argv);
SetupSharedFoundation::install (setupFoundationData);
SetupSharedFile::install(false);
SetupSharedRandom::install(time(NULL));
SetupSharedNetwork::SetupData networkSetupData;
SetupSharedNetwork::getDefaultServerSetupData(networkSetupData);
SetupSharedNetwork::install(networkSetupData);
SetupSharedNetworkMessages::install();
SetupSwgSharedNetworkMessages::install();
SetupSwgServerNetworkMessages::install();
SetupSharedLog::install("SwgDatabaseServer");
TreeFile::addSearchAbsolute(0);
TreeFile::addSearchPath(".",0);
//-- setup server
ConfigServerDatabase::install ();
NetworkHandler::install();
Os::setProgramName("SwgDatabaseServer");
SwgDatabaseServer::install();
//-- run server
SwgDatabaseServer::getInstance().run();
NetworkHandler::remove();
SetupSharedLog::remove();
SetupSharedFoundation::remove();
SetupSharedThread::remove();
return 0;
}
@@ -0,0 +1,180 @@
// ======================================================================
//
// AuctionLocationsBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/AuctionLocationsBuffer.h"
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverGame/ServerPlayerObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include <vector>
// ======================================================================
AuctionLocationsBuffer::AuctionLocationsBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_mode(mode),
m_rows()
{
}
// ----------------------------------------------------------------------
AuctionLocationsBuffer::~AuctionLocationsBuffer(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
bool AuctionLocationsBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
return true;
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::removeObject(const NetworkId &object)
{
removeAuctionLocations(object);
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::removeAuctionLocations(const NetworkId &locationId)
{
IndexType::iterator i=m_rows.find(locationId);
if (i!=m_rows.end())
{
delete i->second;
i->second=NULL;
m_rows.erase(i);
}
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::setAuctionLocations(const NetworkId &locationId)
{
DBSchema::AuctionLocationsRow *row=findRowByIndex(locationId);
if (!row)
{
row=new DBSchema::AuctionLocationsRow;
addRowToIndex(locationId, row);
}
row->location_id = locationId;
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::setAuctionLocations(const NetworkId &locationId, const std::string &locationName, const int salesTax, const NetworkId &salesTaxBankId, const int emptyDate, const int lastAccessDate, const int inactiveDate, const int status, const bool searchEnabled, const int entranceCharge)
{
DBSchema::AuctionLocationsRow *row=findRowByIndex(locationId);
if (!row)
{
row=new DBSchema::AuctionLocationsRow;
addRowToIndex(locationId, row);
}
row->location_id = locationId;
row->location_name = locationName;
row->sales_tax = salesTax;
row->sales_tax_bank_id = salesTaxBankId;
row->empty_date = emptyDate;
row->last_access_date = lastAccessDate;
row->inactive_date = inactiveDate;
row->status = status;
row->search_enabled = searchEnabled;
row->entrance_charge = entranceCharge;
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::setAuctionLocations(const NetworkId &locationId, const std::string &locationName, const NetworkId &ownerId, const int salesTax, const NetworkId &salesTaxBankId, const int emptyDate, const int lastAccessDate, const int inactiveDate, const int status, const bool searchEnabled, const int entranceCharge)
{
DBSchema::AuctionLocationsRow *row=findRowByIndex(locationId);
if (!row)
{
row=new DBSchema::AuctionLocationsRow;
addRowToIndex(locationId, row);
}
row->location_id = locationId;
row->location_name = locationName;
row->owner_id = ownerId;
row->sales_tax = salesTax;
row->sales_tax_bank_id = salesTaxBankId;
row->empty_date = emptyDate;
row->last_access_date = lastAccessDate;
row->inactive_date = inactiveDate;
row->status = status;
row->search_enabled = searchEnabled;
row->entrance_charge = entranceCharge;
}
// ----------------------------------------------------------------------
DBSchema::AuctionLocationsRow * AuctionLocationsBuffer::findRowByIndex(const NetworkId &locationId)
{
IndexType::iterator i=m_rows.find(locationId);
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void AuctionLocationsBuffer::addRowToIndex (const NetworkId &locationId, DBSchema::AuctionLocationsRow *row)
{
m_rows[locationId]=row;
}
// ----------------------------------------------------------------------
bool AuctionLocationsBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("AuctionLocations: %i saved to db",m_rows.size()));
DEBUG_REPORT_LOG(true, ("Saving Auctions Locations Buffer. mode:%d rowcount:%d\n", m_mode, m_rows.size()));
DBQuery::AuctionLocationsQuery qry;
if (m_mode==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else if (m_mode == DB::ModeQuery::mode_UPDATE)
qry.updateMode();
else
qry.deleteMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData(i->second))
return false;
if (qry.getNumItems() >= AuctionLocationsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
return true;
}
// ======================================================================
@@ -0,0 +1,65 @@
// ======================================================================
//
// AuctionLocationsBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_AuctionLocationsBuffer_H
#define INCLUDED_AuctionLocationsBuffer_H
// ======================================================================
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverDatabase/AbstractTableBuffer.h"
#include <map>
#include <string>
// ======================================================================
namespace AuctionLocationsTableBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace AuctionLocationsTableBufferNamespace;
// ======================================================================
class AuctionLocationsBuffer : public AbstractTableBuffer
{
public:
explicit AuctionLocationsBuffer (DB::ModeQuery::Mode mode);
virtual ~AuctionLocationsBuffer ();
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
DBSchema::AuctionLocationsRow * findRowByIndex (const NetworkId &locationId);
void setAuctionLocations (const NetworkId &locationId);
void setAuctionLocations (const NetworkId &locationId, const std::string &locationName, const int salesTax, const NetworkId &salesTaxBankId, const int emptyDate, const int lastAccessDate, const int inactiveDate, const int status, const bool searchEnabled, const int entranceCharge);
void setAuctionLocations (const NetworkId &locationId, const std::string &locationName, const NetworkId &ownerId, const int salesTax, const NetworkId &salesTaxBankId, const int emptyDate, const int lastAccessDate, const int inactiveDate, const int status, const bool searchEnabled, const int entranceCharge);
void removeAuctionLocations (const NetworkId &locationId);
virtual void removeObject (const NetworkId &object);
private:
void addRowToIndex (const NetworkId &locationId, DBSchema::AuctionLocationsRow *row);
private:
typedef std::map<NetworkId, DBSchema::AuctionLocationsRow*> IndexType;
DB::ModeQuery::Mode m_mode;
IndexType m_rows;
private:
AuctionLocationsBuffer(); //disable
AuctionLocationsBuffer(const AuctionLocationsBuffer&); //disable
AuctionLocationsBuffer & operator=(const AuctionLocationsBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
#endif
@@ -0,0 +1,165 @@
// ======================================================================
//
// BattlefieldParticipantBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/BattlefieldParticipantBuffer.h"
#include "SwgDatabaseServer/BattlefieldParticipantQuery.h"
#include "SwgDatabaseServer/Schema.h"
#include "serverGame/ServerBattlefieldMarkerObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
// ======================================================================
BattlefieldParticipantBuffer::BattlefieldParticipantBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_rows(),
m_mode(mode)
{
}
// ----------------------------------------------------------------------
BattlefieldParticipantBuffer::~BattlefieldParticipantBuffer(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
void BattlefieldParticipantBuffer::setParticipantForRegion(const NetworkId &regionObjectId, const NetworkId &characterObjectId, uint32 factionId)
{
DBSchema::BattlefieldParticipantRow *row=findRowByIndex(regionObjectId,characterObjectId);
if (!row)
{
row=new DBSchema::BattlefieldParticipantRow;
addRowToIndex(regionObjectId,characterObjectId,row);
}
row->region_object_id = regionObjectId;
row->character_object_id = characterObjectId;
row->faction_id = static_cast<int>(factionId);
}
// ----------------------------------------------------------------------
bool BattlefieldParticipantBuffer::getParticipantsForRegion(const NetworkId &objectId, std::vector<std::pair<NetworkId, uint32> > &values) const
{
DEBUG_FATAL(values.size()!=0,("Values vector should be empty on call to getBattlefieldParticipantForRegion()\n"));
IndexType::const_iterator i ( m_rows.lower_bound(IndexKey(objectId,NetworkId::cms_invalid)) );
if (i==m_rows.end())
return false;
for (; (i!=m_rows.end()) && (((*i).second)->region_object_id.getValue()==objectId); ++i)
{
NetworkId temp;
(*i).second->character_object_id.getValue(temp);
values.push_back(std::pair<NetworkId, uint32>(temp, static_cast<uint32>((*i).second->faction_id.getValue())));
}
return true;
}
// ----------------------------------------------------------------------
DBSchema::BattlefieldParticipantRow * BattlefieldParticipantBuffer::findRowByIndex(const NetworkId &regionObjectId, const NetworkId &characterObjectId)
{
IndexType::iterator i=m_rows.find(IndexKey(regionObjectId,characterObjectId));
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void BattlefieldParticipantBuffer::addRowToIndex (const NetworkId &regionObjectId, const NetworkId &characterObjectId, DBSchema::BattlefieldParticipantRow *row)
{
m_rows[IndexKey(regionObjectId,characterObjectId)]=row;
}
// ----------------------------------------------------------------------
/**
* Load the attributes for all the remembered objectId's.
*/
bool BattlefieldParticipantBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched = 0;
if (tags.find(static_cast<Tag>(ServerBattlefieldMarkerObjectTemplate::ServerBattlefieldMarkerObjectTemplate_tag)) != tags.end())
{
DBQuery::GetAllBattlefieldParticipant qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::BattlefieldParticipantRow> &data = qry.getData();
for (std::vector<DBSchema::BattlefieldParticipantRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
DBSchema::BattlefieldParticipantRow *row=new DBSchema::BattlefieldParticipantRow(*i);
NOT_NULL(row);
NetworkId temp;
row->character_object_id.getValue(temp);
addRowToIndex(row->region_object_id.getValue(),temp,row);
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
bool BattlefieldParticipantBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("BattlefieldParticipants: %i saved to db",m_rows.size()));
DBQuery::BattlefieldParticipantQuery qry;
if (m_mode==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else
qry.updateMode();
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
qry.setData(*(i->second));
if (! (session->exec(&qry)))
return false;
}
qry.done();
return true;
}
// ----------------------------------------------------------------------
void BattlefieldParticipantBuffer::removeObject(const NetworkId &object)
{
IndexType::iterator i=m_rows.lower_bound(IndexKey(object,NetworkId::cms_invalid));
while (i!=m_rows.end() && i->first.m_regionObjectId==object)
{
IndexType::iterator next=i;
++next;
delete i->second;
i->second=NULL;
m_rows.erase(i);
i=next;
}
}
// ======================================================================
@@ -0,0 +1,102 @@
// ======================================================================
//
// BattlefieldParticipantBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_BattlefieldParticipantBuffer_H
#define INCLUDED_BattlefieldParticipantBuffer_H
// ======================================================================
#include <map>
#include <string>
#include "serverDatabase/TableBuffer.h"
#include "SwgDatabaseServer/BattlefieldParticipantQuery.h"
#include "SwgDatabaseServer/Schema.h"
// ======================================================================
class BattlefieldParticipantBuffer : public AbstractTableBuffer
{
public:
explicit BattlefieldParticipantBuffer (DB::ModeQuery::Mode mode);
virtual ~BattlefieldParticipantBuffer ();
virtual bool load (DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save (DB::Session *session);
virtual void removeObject (const NetworkId &object);
DBSchema::BattlefieldParticipantRow * findRowByIndex (const NetworkId &regionObjectId, const NetworkId &characterObjectId);
void setParticipantForRegion (const NetworkId &regionObjectId, const NetworkId &characterObjectId, uint32 factionId);
void removeParticipantForRegion (const NetworkId &regionObjectId, const NetworkId &characterObjectId);
bool getParticipantsForRegion (const NetworkId &regionObjectId, std::vector<std::pair<NetworkId, uint32> > &values) const;
private:
void addRowToIndex (const NetworkId &regionObjectId, const NetworkId &characterObjectId, DBSchema::BattlefieldParticipantRow *row);
private:
struct IndexKey
{
NetworkId m_regionObjectId;
NetworkId m_characterObjectId;
IndexKey(const NetworkId &regionObjectId, const NetworkId &characterObjectId);
bool operator==(const IndexKey &rhs) const;
};
struct IndexSorter
{
bool operator() (const IndexKey &left, const IndexKey &right) const;
};
typedef std::map<IndexKey,DBSchema::BattlefieldParticipantRow*,IndexSorter> IndexType;
IndexType m_rows;
DB::ModeQuery::Mode m_mode;
private:
BattlefieldParticipantBuffer(); //disable
BattlefieldParticipantBuffer(const BattlefieldParticipantBuffer&); //disable
BattlefieldParticipantBuffer & operator=(const BattlefieldParticipantBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
inline BattlefieldParticipantBuffer::IndexKey::IndexKey(const NetworkId &regionObjectId, const NetworkId &characterObjectId) :
m_regionObjectId(regionObjectId),
m_characterObjectId(characterObjectId)
{
}
// ----------------------------------------------------------------------
inline bool BattlefieldParticipantBuffer::IndexKey::operator==(const IndexKey &rhs) const
{
return ((m_regionObjectId == rhs.m_regionObjectId) && (m_characterObjectId == rhs.m_characterObjectId));
}
// ----------------------------------------------------------------------
inline bool BattlefieldParticipantBuffer::IndexSorter::operator() (const IndexKey &left, const IndexKey &right) const
{
if (left.m_regionObjectId == right.m_regionObjectId)
return (left.m_characterObjectId < right.m_characterObjectId);
else
return (left.m_regionObjectId < right.m_regionObjectId);
}
// ----------------------------------------------------------------------
/**
* Removing a battlefield participant is the same as setting it to 0. (The database package
* will delete the row if faction_id == 0.)
*/
inline void BattlefieldParticipantBuffer::removeParticipantForRegion(const NetworkId &regionObjectId, const NetworkId &characterObjectId)
{
setParticipantForRegion(regionObjectId,characterObjectId,0);
}
// ======================================================================
#endif
@@ -0,0 +1,184 @@
// ======================================================================
//
// BountyHunterTargetBuffer.cpp
// copyright (c) 2004 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/BountyHunterTargetBuffer.h"
#include "SwgDatabaseServer/BountyHunterTargetQuery.h"
#include "SwgDatabaseServer/Schema.h"
#include "serverDatabase/ConfigServerDatabase.h"
#include "serverDatabase/GameServerConnection.h"
#include "serverGame/ServerPlanetObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
// ======================================================================
BountyHunterTargetBuffer::BountyHunterTargetBuffer() :
AbstractTableBuffer(),
m_data()
{
}
// ----------------------------------------------------------------------
BountyHunterTargetBuffer::~BountyHunterTargetBuffer()
{
for (DataType::iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
void BountyHunterTargetBuffer::setBountyHunterTarget(const NetworkId &objectId, const NetworkId &targetId)
{
DBSchema::BountyHunterTargetRow *row=findRowByIndex(objectId);
if (!row)
{
row=new DBSchema::BountyHunterTargetRow;
addRowToIndex(objectId, row);
}
row->object_id = objectId;
row->target_id = targetId;
}
// ----------------------------------------------------------------------
void BountyHunterTargetBuffer::sendBountyHunterTargetMessage(GameServerConnection & conn) const
{
if (m_data.empty())
return;
std::vector< std::pair< NetworkId, NetworkId > > targetList;
for (DataType::const_iterator row = m_data.begin(); row != m_data.end(); ++row)
{
NOT_NULL(row->second);
NetworkId objectId;
NetworkId targetId;
row->second->object_id.getValue(objectId);
row->second->target_id.getValue(targetId);
targetList.push_back(std::make_pair(objectId, targetId));
}
DEBUG_REPORT_LOG(true,("Sending BountyHunterTargetsList\n"));
BountyHunterTargetListMessage msg(targetList);
conn.send(msg,true);
}
// ----------------------------------------------------------------------
DBSchema::BountyHunterTargetRow * BountyHunterTargetBuffer::findRowByIndex(const NetworkId &objectId)
{
DataType::iterator i=m_data.find(objectId);
if (i==m_data.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void BountyHunterTargetBuffer::addRowToIndex (const NetworkId &objectId, DBSchema::BountyHunterTargetRow *row)
{
m_data[objectId]=row;
}
// ----------------------------------------------------------------------
bool BountyHunterTargetBuffer::save(DB::Session *session)
{
bool rval = true;
if (m_data.empty())
return true;
int actualSaves=0;
DBQuery::BountyHunterTargetQuery qry;
if (!qry.setupData(session))
return false;
for (DataType::const_iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
++actualSaves;
NOT_NULL(i->second);
if (!qry.addData(*(i->second)))
return false;
if (qry.getNumItems() == ConfigServerDatabase::getDefaultMessageBulkBindSize())
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
rval = session->exec(&qry);
qry.done();
qry.freeData();
LOG("SaveCounts",("BountyHunterTargets: %i saved in db",actualSaves));
return rval;
}
// ----------------------------------------------------------------------
bool BountyHunterTargetBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
int rowsFetched = 0;
// Only load Bounty Hunter Target data if the planets are being loaded
if (tags.find(ServerPlanetObjectTemplate::ServerPlanetObjectTemplate_tag)!=tags.end())
{
DEBUG_REPORT_LOG(true,("Loading BountyHunterTargets\n"));
DBQuery::BountyHunterTargetQuerySelect qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t const numRows = qry.getNumRowsFetched();
size_t count = 0;
std::vector<DBSchema::BountyHunterTargetRow> const & data = qry.getData();
for (std::vector<DBSchema::BountyHunterTargetRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
DBSchema::BountyHunterTargetRow *row=new DBSchema::BountyHunterTargetRow(*i);
NOT_NULL(row);
NetworkId temp;
row->object_id.getValue(temp);
m_data.insert(std::make_pair(row->object_id.getValue(), row));
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
void BountyHunterTargetBuffer::removeObject(const NetworkId &object)
{
DBSchema::BountyHunterTargetRow *row=findRowByIndex(object);
if (row)
{
const NetworkId zeroNetworkId(static_cast<NetworkId::NetworkIdType>(0));
row->object_id = object;
row->target_id = zeroNetworkId;
}
}
// ======================================================================
@@ -0,0 +1,59 @@
// ======================================================================
//
// BountyHunterTargetBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_BountyHunterTargetBuffer_H
#define INCLUDED_BountyHunterTargetBuffer_H
// ======================================================================
#include "serverDatabase/AbstractTableBuffer.h"
#include "serverNetworkMessages/BountyHunterTargetListMessage.h"
#include "serverNetworkMessages/BountyHunterTargetMessage.h"
// ======================================================================
namespace DB
{
class Session;
}
namespace DBSchema
{
struct BountyHunterTargetRow;
}
class GameServerConnection;
// ======================================================================
/**
* A buffer to hold bounty hunter target data.
*/
class BountyHunterTargetBuffer : public AbstractTableBuffer
{
public:
void setBountyHunterTarget (const NetworkId &objectId, const NetworkId &targetId);
void sendBountyHunterTargetMessage (GameServerConnection & conn) const;
virtual bool save(DB::Session *session);
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual void removeObject(const NetworkId &object);
DBSchema::BountyHunterTargetRow * findRowByIndex (const NetworkId &objectId);
public:
BountyHunterTargetBuffer();
virtual ~BountyHunterTargetBuffer();
private:
void addRowToIndex (const NetworkId &objectId, DBSchema::BountyHunterTargetRow *row);
typedef std::map<NetworkId, DBSchema::BountyHunterTargetRow*> DataType;
DataType m_data;
};
// ======================================================================
#endif
@@ -0,0 +1,249 @@
// ======================================================================
//
// CreatureObjectBuffer.cpp
// copyright (c) 2003 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/CreatureObjectBuffer.h"
#include "serverNetworkMessages/UpdateObjectPositionMessage.h"
#include "sharedLog/Log.h"
// ======================================================================
CreatureObjectBuffer::CreatureObjectBuffer(DB::ModeQuery::Mode mode) :
IndexedNetworkTableBuffer<DBSchema::CreatureObjectBufferRow, DBSchema::CreatureObjectRow, DBQuery::CreatureObjectQuery, DBQuery::CreatureObjectQuerySelect>(mode)
{
}
// ----------------------------------------------------------------------
bool CreatureObjectBuffer::handleUpdateObjectPosition(const UpdateObjectPositionMessage &message)
{
DBSchema::CreatureObjectBufferRow *row=dynamic_cast<DBSchema::CreatureObjectBufferRow*>(findRowByIndex(message.getNetworkId()));
if (row==0)
{
row=addEmptyRow(message.getNetworkId());
}
Vector v = message.getWorldspaceTransform().getPosition_p();
row->ws_x = static_cast<double>(v.x);
row->ws_y = static_cast<double>(v.y);
row->ws_z = static_cast<double>(v.z);
return true;
}
// ----------------------------------------------------------------------
void CreatureObjectBuffer::setAttribute(const NetworkId &objectId, Attributes::Enumerator type, Attributes::Value value)
{
DBSchema::CreatureObjectBufferRow *row=dynamic_cast<DBSchema::CreatureObjectBufferRow*>(findRowByIndex(objectId));
if (row==0)
{
row=addEmptyRow(objectId);
}
switch (type)
{
case 0:
row->attribute_0=value;
break;
case 1:
row->attribute_1=value;
break;
case 2:
row->attribute_2=value;
break;
case 3:
row->attribute_3=value;
break;
case 4:
row->attribute_4=value;
break;
case 5:
row->attribute_5=value;
break;
case 6:
row->attribute_6=value;
break;
case 7:
row->attribute_7=value;
break;
case 8:
row->attribute_8=value;
break;
case 9:
row->attribute_9=value;
break;
case 10:
row->attribute_10=value;
break;
case 11:
row->attribute_11=value;
break;
case 12:
row->attribute_12=value;
break;
case 13:
row->attribute_13=value;
break;
case 14:
row->attribute_14=value;
break;
case 15:
row->attribute_15=value;
break;
case 16:
row->attribute_16=value;
break;
case 17:
row->attribute_17=value;
break;
case 18:
row->attribute_18=value;
break;
case 19:
row->attribute_19=value;
break;
case 20:
row->attribute_20=value;
break;
case 21:
row->attribute_21=value;
break;
case 22:
row->attribute_22=value;
break;
case 23:
row->attribute_23=value;
break;
case 24:
row->attribute_24=value;
break;
case 25:
row->attribute_25=value;
break;
case 26:
row->attribute_26=value;
break;
default:
WARNING_STRICT_FATAL(true,("Programmer bug: setAttribute(%s, %i, %i): %i is not a valid attribute identifier",objectId.getValueString().c_str(), type, value, type));
}
}
// ----------------------------------------------------------------------
/**
* Retreive a range of attributes for an object
*/
void CreatureObjectBuffer::getAttributesForObject(const NetworkId &objectId, std::vector<Attributes::Value> &values, int offset, int howMany) const
{
const DBSchema::CreatureObjectBufferRow *row=dynamic_cast<const DBSchema::CreatureObjectBufferRow*>(findConstRowByIndex(objectId));
for (int position=offset; position<offset+howMany; ++position)
{
int value=0;
switch(position)
{
case 0:
row->attribute_0.getValue(value);
break;
case 1:
row->attribute_1.getValue(value);
break;
case 2:
row->attribute_2.getValue(value);
break;
case 3:
row->attribute_3.getValue(value);
break;
case 4:
row->attribute_4.getValue(value);
break;
case 5:
row->attribute_5.getValue(value);
break;
case 6:
row->attribute_6.getValue(value);
break;
case 7:
row->attribute_7.getValue(value);
break;
case 8:
row->attribute_8.getValue(value);
break;
case 9:
row->attribute_9.getValue(value);
break;
case 10:
row->attribute_10.getValue(value);
break;
case 11:
row->attribute_11.getValue(value);
break;
case 12:
row->attribute_12.getValue(value);
break;
case 13:
row->attribute_13.getValue(value);
break;
case 14:
row->attribute_14.getValue(value);
break;
case 15:
row->attribute_15.getValue(value);
break;
case 16:
row->attribute_16.getValue(value);
break;
case 17:
row->attribute_17.getValue(value);
break;
case 18:
row->attribute_18.getValue(value);
break;
case 19:
row->attribute_19.getValue(value);
break;
case 20:
row->attribute_20.getValue(value);
break;
case 21:
row->attribute_21.getValue(value);
break;
case 22:
row->attribute_22.getValue(value);
break;
case 23:
row->attribute_23.getValue(value);
break;
case 24:
row->attribute_24.getValue(value);
break;
case 25:
row->attribute_25.getValue(value);
break;
case 26:
row->attribute_26.getValue(value);
break;
default:
FATAL(true,("Programmer bug: getAttributesForObject(%s, &values, %i, %i): attempted to read attribute %i, which is out of range",objectId.getValueString().c_str(),offset, howMany, position));
}
if (value == -999)
{
WARNING(true,("Object %s had null attribute %i, defaulting to 100",objectId.getValueString().c_str(), position));
value = 100;
}
values.push_back(static_cast<Attributes::Value>(value));
}
}
// ======================================================================
@@ -0,0 +1,35 @@
// ======================================================================
//
// CreatureObjectBuffer.h
// copyright (c) 2003 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_CreatureObjectBuffer_H
#define INCLUDED_CreatureObjectBuffer_H
// ======================================================================
#include "SwgDatabaseServer/IndexedNetworkTableBuffer.h"
#include "SwgDatabaseServer/ObjectQueries.h"
#include "SwgDatabaseServer/Schema.h"
#include "swgSharedUtility/Attributes.def"
class UpdateObjectPositionMessage;
// ======================================================================
class CreatureObjectBuffer : public IndexedNetworkTableBuffer<DBSchema::CreatureObjectBufferRow, DBSchema::CreatureObjectRow, DBQuery::CreatureObjectQuery, DBQuery::CreatureObjectQuerySelect>
{
public:
CreatureObjectBuffer(DB::ModeQuery::Mode mode);
void setAttribute(const NetworkId &objectId, Attributes::Enumerator type, Attributes::Value value);
void getAttributesForObject (const NetworkId &objectId, std::vector<Attributes::Value> &values, int offset, int howMany) const;
virtual bool handleUpdateObjectPosition(const UpdateObjectPositionMessage &message);
};
// ======================================================================
#endif
@@ -0,0 +1,166 @@
// ======================================================================
//
// ExperienceBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/ExperienceBuffer.h"
#include "SwgDatabaseServer/ExperienceQuery.h"
#include "SwgDatabaseServer/Schema.h"
#include "serverGame/ServerPlayerObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include <vector>
// ======================================================================
ExperienceBuffer::ExperienceBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_mode(mode),
m_rows()
{
}
// ----------------------------------------------------------------------
ExperienceBuffer::~ExperienceBuffer(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
void ExperienceBuffer::setExperience(const NetworkId &objectId, const std::string &experienceType, int value)
{
DBSchema::ExperiencePointRow *row=findRowByIndex(objectId,experienceType);
if (!row)
{
row=new DBSchema::ExperiencePointRow;
addRowToIndex(objectId,experienceType,row);
}
row->object_id = objectId;
row->experience_type=experienceType;
row->points = value;
}
// ----------------------------------------------------------------------
bool ExperienceBuffer::getExperienceForObject(const NetworkId &objectId, std::vector<std::pair<std::string, int> > &values) const
{
DEBUG_FATAL(values.size()!=0,("Values vector should be empty on call to getExperienceForObject()\n"));
IndexType::const_iterator i ( m_rows.lower_bound(IndexKey(objectId,"")) );
if (i==m_rows.end())
return false;
for (; (i!=m_rows.end()) && (((*i).second)->object_id.getValue()==objectId); ++i)
{
std::string temp;
(*i).second->experience_type.getValue(temp);
values.push_back(std::pair<std::string, int>(temp, (*i).second->points.getValue()));
}
return true;
}
// ----------------------------------------------------------------------
DBSchema::ExperiencePointRow * ExperienceBuffer::findRowByIndex(const NetworkId &objectId, const std::string &experienceType)
{
IndexType::iterator i=m_rows.find(IndexKey(objectId,experienceType));
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void ExperienceBuffer::addRowToIndex (const NetworkId &objectId, const std::string &experienceType, DBSchema::ExperiencePointRow *row)
{
m_rows[IndexKey(objectId,experienceType)]=row;
}
// ----------------------------------------------------------------------
/**
* Load the attributes for all the remembered objectId's.
*/
bool ExperienceBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched = 0;
if (tags.find(static_cast<Tag>(ServerPlayerObjectTemplate::ServerPlayerObjectTemplate_tag)) != tags.end())
{
DBQuery::GetAllExperience qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::ExperiencePointRow> &data = qry.getData();
for (std::vector<DBSchema::ExperiencePointRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
DBSchema::ExperiencePointRow *row=new DBSchema::ExperiencePointRow(*i);
NOT_NULL(row);
std::string temp;
row->experience_type.getValue(temp);
addRowToIndex(row->object_id.getValue(),temp,row);
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
bool ExperienceBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("Experience: %i saved to db",m_rows.size()));
DBQuery::ExperienceQuery qry;
if (m_mode==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else
qry.updateMode();
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
qry.setData(*(i->second));
if (! (session->exec(&qry)))
return false;
}
qry.done();
return true;
}
// ----------------------------------------------------------------------
void ExperienceBuffer::removeObject(const NetworkId &object)
{
IndexType::iterator i=m_rows.lower_bound(IndexKey(object,""));
while (i!=m_rows.end() && i->first.m_objectId==object)
{
IndexType::iterator next=i;
++next;
delete i->second;
i->second=NULL;
m_rows.erase(i);
i=next;
}
}
// ======================================================================
@@ -0,0 +1,102 @@
// ======================================================================
//
// ExperienceBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ExperienceBuffer_H
#define INCLUDED_ExperienceBuffer_H
// ======================================================================
#include "SwgDatabaseServer/ExperienceQuery.h"
#include "SwgDatabaseServer/Schema.h"
#include "serverDatabase/AbstractTableBuffer.h"
#include <map>
#include <string>
// ======================================================================
class ExperienceBuffer : public AbstractTableBuffer
{
public:
explicit ExperienceBuffer (DB::ModeQuery::Mode mode);
virtual ~ExperienceBuffer ();
virtual bool load (DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save (DB::Session *session);
virtual void removeObject (const NetworkId &object);
DBSchema::ExperiencePointRow * findRowByIndex (const NetworkId &objectId, const std::string &experienceType);
void setExperience (const NetworkId &objectId, const std::string &experienceType, int value);
void removeExperience (const NetworkId &objectId, std::string experienceType);
bool getExperienceForObject (const NetworkId &objectId, stdvector<std::pair<std::string, int> >::fwd &values) const;
private:
void addRowToIndex (const NetworkId &objectId, const std::string &experienceType, DBSchema::ExperiencePointRow *row);
private:
struct IndexKey
{
NetworkId m_objectId;
std::string m_experienceType;
IndexKey(NetworkId objectId, std::string experienceType);
bool operator==(const IndexKey &rhs) const;
};
struct IndexSorter
{
bool operator() (const IndexKey &left, const IndexKey &right) const;
};
typedef std::map<IndexKey,DBSchema::ExperiencePointRow*,IndexSorter> IndexType;
DB::ModeQuery::Mode m_mode;
IndexType m_rows;
private:
ExperienceBuffer(); //disable
ExperienceBuffer(const ExperienceBuffer&); //disable
ExperienceBuffer & operator=(const ExperienceBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
inline ExperienceBuffer::IndexKey::IndexKey(NetworkId objectId, std::string experienceType) :
m_objectId(objectId),
m_experienceType(experienceType)
{
}
// ----------------------------------------------------------------------
inline bool ExperienceBuffer::IndexKey::operator==(const IndexKey &rhs) const
{
return ((m_objectId == rhs.m_objectId) && (m_experienceType == rhs.m_experienceType));
}
// ----------------------------------------------------------------------
inline bool ExperienceBuffer::IndexSorter::operator() (const IndexKey &left, const IndexKey &right) const
{
if (left.m_objectId == right.m_objectId)
return (left.m_experienceType < right.m_experienceType);
else
return (left.m_objectId < right.m_objectId);
}
// ----------------------------------------------------------------------
/**
* Removing experience is the same as setting it to 0. (The database package
* will delete the row if points == 0.)
*/
inline void ExperienceBuffer::removeExperience(const NetworkId &objectId, std::string experienceType)
{
setExperience(objectId,experienceType,0);
}
// ======================================================================
#endif
@@ -0,0 +1,11 @@
// ======================================================================
//
// IndexedNetworkTableBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "IndexedNetworkTableBuffer.h"
// ======================================================================
@@ -0,0 +1,270 @@
// ======================================================================
//
// IndexedNetworkTableBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_IndexedNetworkTableBuffer_H
#define INCLUDED_IndexedNetworkTableBuffer_H
// ======================================================================
#include "serverDatabase/AbstractTableBuffer.h"
#include "sharedDatabaseInterface/DbModeQuery.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedFoundation/NetworkId.h"
#include <map>
#include <set>
#include <vector>
// ======================================================================
namespace IndexedNetworkTableBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace IndexedNetworkTableBufferNamespace;
/**
* A TableBuffer organized to track data by objects, one row per object.
*
* @todo: Rename the class. Name makes no sense anymore. Un-templatize.
*/
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
class IndexedNetworkTableBuffer : public AbstractTableBuffer
{
public:
explicit IndexedNetworkTableBuffer(DB::ModeQuery::Mode mode);
~IndexedNetworkTableBuffer();
public:
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
BUFFERROW *findRowByIndex(const NetworkId &indexValue);
const BUFFERROW *findConstRowByIndex(const NetworkId &indexValue) const;
BUFFERROW *addEmptyRow(const NetworkId &indexValue);
virtual void removeObject(const NetworkId &object);
DB::ModeQuery::Mode getMode(void) const;
void addTag(Tag tag);
static int getRowsCreated() { return m_sRowsCreated; }
static int getRowsDeleted() { return m_sRowsDeleted; }
static int getRowsActive()
{
int i_retval = m_sRowsCreated - m_sRowsDeleted;
if ( i_retval < 0 )
return 0;
return i_retval;
}
protected:
typedef std::map<NetworkId, BUFFERROW*> IndexType;
IndexType m_rows;
private:
DB::ModeQuery::Mode m_mode;
DB::TagSet m_relevantTags;
private:
void addRow(const NetworkId &indexValue,BUFFERROW *row);
static volatile int m_sRowsCreated;
static volatile int m_sRowsDeleted;
private:
IndexedNetworkTableBuffer(); // disable
};
template <class B, class R, class Q, class S> volatile int IndexedNetworkTableBuffer<B,R,Q,S>::m_sRowsCreated = 0;
template <class B, class R, class Q, class S> volatile int IndexedNetworkTableBuffer<B,R,Q,S>::m_sRowsDeleted = 0;
// ======================================================================
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::IndexedNetworkTableBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_rows(),
m_mode(mode)
{
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::~IndexedNetworkTableBuffer()
{
for (typename IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
++m_sRowsDeleted;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
void IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::addRow(const NetworkId &indexValue,BUFFERROW *row)
{
m_rows[indexValue]=row;
++m_sRowsCreated;
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
BUFFERROW *IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::findRowByIndex(const NetworkId &indexValue)
{
typename IndexType::iterator i=m_rows.find(indexValue);
if (i==m_rows.end())
return 0;
else
return i->second;
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
const BUFFERROW *IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::findConstRowByIndex(const NetworkId &indexValue) const
{
typename IndexType::const_iterator i=m_rows.find(indexValue);
if (i==m_rows.end())
return 0;
else
return i->second;
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
BUFFERROW *IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::addEmptyRow(const NetworkId &indexValue)
{
BUFFERROW *row=new BUFFERROW;
row->setPrimaryKey(indexValue);
addRow(indexValue,row);
return row;
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
void IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::removeObject(const NetworkId &object)
{
typename IndexType::iterator i=m_rows.find(object);
if (i!=m_rows.end())
{
delete i->second;
++m_sRowsDeleted;
i->second=NULL;
m_rows.erase(i);
}
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
DB::ModeQuery::Mode IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::getMode(void) const
{
return m_mode;
}
// ----------------------------------------------------------------------
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
bool IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::save(DB::Session *session)
{
QUERY qry;
if (getMode()==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else
qry.updateMode();
if (!qry.setupData(session))
return false;
for (typename IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData((i->second)))
return false;
if (qry.getNumItems() == IndexedNetworkTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
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 <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
bool IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched = 0;
if (m_relevantTags.empty() || hasCommonTags(m_relevantTags, tags))
{
SELECTQUERY qry(schema);
FATAL (getMode()!=DB::ModeQuery::mode_SELECT,("load() was invoked on a TableBuffer that was not in tbm_select mode."));
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
int numRows = qry.getNumRowsFetched();
int count = 0;
const std::vector<ROW> &data = qry.getData();
for (typename std::vector<ROW>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
BUFFERROW *newRow=new BUFFERROW(*i);
addRow(newRow->getPrimaryKey(),newRow);
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
/**
* Add a tag to the list we are interested in. If the current snapshot
* contains no objects with tags in this list, this buffer will skip its
* load. (Exception: If no tags are registered at all, the load will
* always happen.)
*/
template <class BUFFERROW, class ROW, class QUERY, class SELECTQUERY>
void IndexedNetworkTableBuffer<BUFFERROW,ROW,QUERY,SELECTQUERY>::addTag(Tag tag)
{
m_relevantTags.insert(tag);
}
// ======================================================================
#endif
@@ -0,0 +1,54 @@
#if 0 //@todo code reorg
// ======================================================================
//
// IndexedNetworkTableBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_IndexedNetworkTableBuffer_H
#define INCLUDED_IndexedNetworkTableBuffer_H
// ======================================================================
#include <hash_map>
#include "serverDatabase/TableBuffer.h"
// ======================================================================
/**
* Adds to NetworkTableBuffer the ability to retrieve rows based on an
* integer index.
* @todo Remove "Network" from the name because it no longer has anything to
* do with the network.
* @todo If we have time someday :) Play with the idea of making this be a
* class that's attached to a TableBuffer, much the same way a real DB index
* is attached to a table. The TableBuffer could have a list of pointers
* to indexes, and it would invoke addRow, etc., as needed.
*/
class IndexedNetworkTableBuffer : public TableBuffer
{
public:
void addRowToIndex(int indexValue, DB::Row *row);
DB::Row *findRowByIndex(int indexValue);
protected:
IndexedNetworkTableBuffer(TableBufferMode mode, DB::ModeQuery *query);
private:
typedef std::hash_map<int, DB::Row*> IndexType;
/**
* Index to locate rows.
*
* Note that the rows are owned by the TableBuffer base class. This
* is just an index to find a specific row quickly. Therefore, this
* class does not create or delete the rows.
*/
IndexType m_index;
};
// ======================================================================
#endif
#endif
@@ -0,0 +1,165 @@
// ======================================================================
//
// LocationBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "LocationBuffer.h"
#include "SwgDatabaseServer/LocationQuery.h"
#include "serverGame/ServerCreatureObjectTemplate.h"
#include "sharedLog/Log.h"
// ======================================================================
LocationBuffer::LocationBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer()
{
UNREF(mode);
}
// ----------------------------------------------------------------------
LocationBuffer::~LocationBuffer()
{
}
// ----------------------------------------------------------------------
bool LocationBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("Locations: %i saved to db",m_saveData.size()));
DBQuery::SaveLocationQuery qry;
for (SaveDataType::const_iterator i=m_saveData.begin(); i!=m_saveData.end(); ++i)
{
NetworkId networkId=i->first;
const std::vector<BufferEntry> &data=i->second;
for (std::vector<BufferEntry>::const_iterator j=data.begin(); j!=data.end(); ++j)
{
qry.setData(networkId, j->m_listId, j->m_action, j->m_index, j->m_data);
if (! (session->exec(&qry)))
return false;
}
}
qry.done();
return true;
}
// ----------------------------------------------------------------------
bool LocationBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched = 0;
if (tags.find(static_cast<Tag>(ServerCreatureObjectTemplate::ServerCreatureObjectTemplate_tag)) != tags.end())
{
DBQuery::LoadLocationQuery qry(schema);
LocationData temp;
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBQuery::LoadLocationQuery::LocationRow> &data = qry.getData();
for (std::vector<DBQuery::LoadLocationQuery::LocationRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
i->name.getValue(temp.name);
i->scene.getValue(temp.scene);
temp.location.setCenter(static_cast<float>(i->x.getValue()),static_cast<float>(i->y.getValue()),static_cast<float>(i->z.getValue()));
temp.location.setRadius(static_cast<float>(i->radius.getValue()));
m_loadData[IndexKey(i->object_id.getValue(),i->list_id.getValue(),i->index.getValue())]=temp;
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
void LocationBuffer::removeObject(const NetworkId &object)
{
m_saveData.erase(object);
}
// ----------------------------------------------------------------------
void LocationBuffer::addAction(BufferEntry::Action action, const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value)
{
m_saveData[objectId].push_back(BufferEntry(listId, action, sequenceNumber, value));
}
// ----------------------------------------------------------------------
void LocationBuffer::getLocationList(const NetworkId &objectId, size_t listId, std::vector<LocationData> &values) const
{
#ifdef _DEBUG
size_t expectedIndex = 0;
#endif
for (LoadDataType::const_iterator i=m_loadData.find(IndexKey(objectId, listId, 0)); (i!=m_loadData.end()) && (i->first.m_objectId == objectId) && (i->first.m_listId == listId); ++i)
{
DEBUG_FATAL(i->first.m_index != expectedIndex++,("Programmer bug: location list was not sorted or had gaps in the sequence. Object id %s, list id %i, sequence %i\n",objectId.getValueString().c_str(), listId, i->first.m_index));
values.push_back(i->second);
}
}
// ======================================================================
LocationBuffer::BufferEntry::BufferEntry(size_t listId, Action action, size_t index, const LocationData &data) :
m_listId(listId),
m_action(action),
m_index(index),
m_data(data)
{
}
// ======================================================================
LocationBuffer::IndexKey::IndexKey()
{
}
// ----------------------------------------------------------------------
LocationBuffer::IndexKey::IndexKey(const NetworkId &objectId, size_t listId, size_t index) :
m_objectId(objectId),
m_listId(listId),
m_index(index)
{
}
// ----------------------------------------------------------------------
LocationBuffer::IndexKey::IndexKey(const IndexKey &rhs) :
m_objectId(rhs.m_objectId),
m_listId(rhs.m_listId),
m_index(rhs.m_index)
{
}
// ----------------------------------------------------------------------
bool LocationBuffer::IndexKey::operator<(const IndexKey &rhs) const
{
if (m_objectId == rhs.m_objectId)
if (m_listId == rhs.m_listId)
return (m_index < rhs.m_index);
else
return (m_listId < rhs.m_listId);
else
return (m_objectId < rhs.m_objectId);
}
// ======================================================================
@@ -0,0 +1,114 @@
// ======================================================================
//
// LocationBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_LocationBuffer_H
#define INCLUDED_LocationBuffer_H
// ======================================================================
#include <map>
#include <vector>
#include "serverDatabase/TableBuffer.h"
#include "serverUtility/LocationData.h"
#include "sharedFoundation/NetworkId.h"
namespace DBSchema
{
struct LocationRow;
}
// ======================================================================
/**
* LocationBuffer is a table buffer customized to the job of loading and
* saving locations for OnArrivedAt() targets, etc.
*
* Locations are keyed by object id, a list number, and a sequence number. (Thus
* each object can have multiple lists of locations.)
*
* Unlike most other buffer classes, this class does not maintain a list of rows.
* Instead, it has a map of vectors of actions to be applied in the database.
*/
class LocationBuffer : public AbstractTableBuffer
{
public:
explicit LocationBuffer(DB::ModeQuery::Mode mode);
virtual ~LocationBuffer(void);
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
virtual void removeObject(const NetworkId &object);
void set (const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value);
void insert (const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value);
void erase (const NetworkId &objectId, size_t listId, size_t sequenceNumber);
void getLocationList(const NetworkId &objectId, size_t listId, std::vector<LocationData> &values) const;
private:
struct BufferEntry
{
enum Action {be_INSERT, be_ERASE, be_SET};
size_t m_listId;
Action m_action;
size_t m_index;
LocationData m_data;
BufferEntry(size_t listId, Action action, size_t index, const LocationData &data);
};
struct IndexKey
{
NetworkId m_objectId;
size_t m_listId;
size_t m_index;
IndexKey();
IndexKey(const NetworkId &objectId, size_t listId, size_t index);
IndexKey(const IndexKey &rhs);
bool operator < (const IndexKey &rhs) const;
};
typedef std::map<NetworkId, std::vector<BufferEntry> > SaveDataType;
SaveDataType m_saveData;
typedef std::map<IndexKey, LocationData> LoadDataType;
LoadDataType m_loadData;
private:
void addAction(BufferEntry::Action action, const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value);
private:
LocationBuffer(); //disable
LocationBuffer(const LocationBuffer&); //disable
LocationBuffer & operator=(const LocationBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
inline void LocationBuffer::set(const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value)
{
addAction(BufferEntry::be_SET, objectId, listId, sequenceNumber, value);
}
// ----------------------------------------------------------------------
inline void LocationBuffer::insert(const NetworkId &objectId, size_t listId, size_t sequenceNumber, const LocationData &value)
{
addAction(BufferEntry::be_INSERT, objectId, listId, sequenceNumber, value);
}
// ----------------------------------------------------------------------
inline void LocationBuffer::erase(const NetworkId &objectId, size_t listId, size_t sequenceNumber)
{
addAction(BufferEntry::be_ERASE, objectId, listId, sequenceNumber, LocationData());
}
// ======================================================================
#endif
@@ -0,0 +1,183 @@
// ======================================================================
//
// ManufactureSchematicAttributeBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/ManufactureSchematicAttributeBuffer.h"
#include "SwgDatabaseServer/ManufactureSchematicAttributeQuery.h"
#include "serverGame/ServerManufactureSchematicObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include<vector>
// ======================================================================
ManufactureSchematicAttributeBuffer::ManufactureSchematicAttributeBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_mode(mode),
m_rows()
{
}
// ----------------------------------------------------------------------
ManufactureSchematicAttributeBuffer::~ManufactureSchematicAttributeBuffer(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
void ManufactureSchematicAttributeBuffer::setManufactureSchematicAttribute(const NetworkId &objectId, std::string attributeType, float value)
{
DBSchema::ManufactureSchematicAttributeRow *row=findRowByIndex(objectId,attributeType);
if (!row)
{
row=new DBSchema::ManufactureSchematicAttributeRow;
addRowToIndex(objectId,attributeType,row);
}
row->action = 1; //TODO: enum somewhere
row->object_id = objectId;
row->attribute_type=attributeType;
row->value = value;
}
// ----------------------------------------------------------------------
void ManufactureSchematicAttributeBuffer::removeManufactureSchematicAttribute(const NetworkId &objectId, std::string attributeType)
{
DBSchema::ManufactureSchematicAttributeRow *row=findRowByIndex(objectId,attributeType);
if (!row)
{
row=new DBSchema::ManufactureSchematicAttributeRow;
addRowToIndex(objectId,attributeType,row);
}
row->action = 0; //TODO: enum somewhere
}
// ----------------------------------------------------------------------
bool ManufactureSchematicAttributeBuffer::getDataForObject(const NetworkId &objectId, std::vector<std::pair<std::string, float> > &values) const
{
DEBUG_FATAL(values.size()!=0,("Values vector should be empty on call to getExperienceForObject()\n"));
IndexType::const_iterator i ( m_rows.lower_bound(IndexKey(objectId,"")) );
if (i==m_rows.end())
return false;
for (; (i!=m_rows.end()) && (((*i).second)->object_id.getValue()==objectId); ++i)
{
std::string temp;
(*i).second->attribute_type.getValue(temp);
values.push_back(std::pair<std::string, float>(temp, static_cast<float>((*i).second->value.getValue())));
}
return true;
}
// ----------------------------------------------------------------------
DBSchema::ManufactureSchematicAttributeRow * ManufactureSchematicAttributeBuffer::findRowByIndex(NetworkId objectId, std::string experienceType)
{
IndexType::iterator i=m_rows.find(IndexKey(objectId,experienceType));
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void ManufactureSchematicAttributeBuffer::addRowToIndex(NetworkId objectId, std::string attributeType, DBSchema::ManufactureSchematicAttributeRow *row)
{
m_rows[IndexKey(objectId,attributeType)]=row;
}
// ----------------------------------------------------------------------
/**
* Load the attributes for all the remembered objectId's.
*/
bool ManufactureSchematicAttributeBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched = 0;
if (tags.find(static_cast<Tag>(ServerManufactureSchematicObjectTemplate::ServerManufactureSchematicObjectTemplate_tag)) != tags.end())
{
DBQuery::GetAllManufactureSchematicAttributes qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::ManufactureSchematicAttributeRow> &data = qry.getData();
for (std::vector<DBSchema::ManufactureSchematicAttributeRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
DBSchema::ManufactureSchematicAttributeRow *row=new DBSchema::ManufactureSchematicAttributeRow(*i);
NOT_NULL(row);
std::string temp;
row->attribute_type.getValue(temp);
addRowToIndex(row->object_id.getValue(),temp,row);
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
bool ManufactureSchematicAttributeBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("ManufactureSchematicAttributeBuffer: %i saved to db",m_rows.size()));
DBQuery::ManufactureSchematicAttributeQuery qry;
if (m_mode==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else
qry.updateMode();
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
qry.setData(*(i->second));
if (! (session->exec(&qry)))
return false;
}
qry.done();
return true;
}
// ----------------------------------------------------------------------
void ManufactureSchematicAttributeBuffer::removeObject(const NetworkId &object)
{
IndexType::iterator i=m_rows.lower_bound(IndexKey(object,""));
while (i!=m_rows.end() && i->first.m_objectId==object)
{
IndexType::iterator next=i;
++next;
delete i->second;
i->second=NULL;
m_rows.erase(i);
i=next;
}
}
// ======================================================================
@@ -0,0 +1,97 @@
// ======================================================================
//
// ManufactureSchematicAttributeBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ManufactureSchematicAttributeBuffer_H
#define INCLUDED_ManufactureSchematicAttributeBuffer_H
// ======================================================================
#include <map>
#include <string>
#include "serverDatabase/AbstractTableBuffer.h"
#include "SwgDatabaseServer/ManufactureSchematicAttributeQuery.h"
namespace DBSchema
{
struct ManufactureSchematicAttributeRow;
}
// ======================================================================
class ManufactureSchematicAttributeBuffer : public AbstractTableBuffer // <DBSchema::ManufactureSchematicAttributeRow, DBQuery::ManufactureSchematicAttributeQuery>
{
public:
explicit ManufactureSchematicAttributeBuffer (DB::ModeQuery::Mode mode);
virtual ~ManufactureSchematicAttributeBuffer ();
virtual bool load (DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save (DB::Session *session);
virtual void removeObject (const NetworkId &object);
DBSchema::ManufactureSchematicAttributeRow * findRowByIndex (NetworkId objectId, std::string attributeType);
void setManufactureSchematicAttribute (const NetworkId &objectId, std::string attributeType, float value);
void removeManufactureSchematicAttribute (const NetworkId &objectId, std::string attributeType);
bool getDataForObject (const NetworkId &objectId, stdvector<std::pair<std::string, float> >::fwd &values) const;
private:
void addRowToIndex (NetworkId objectId, std::string attributeType, DBSchema::ManufactureSchematicAttributeRow *row);
private:
struct IndexKey
{
NetworkId m_objectId;
std::string m_attributeType;
IndexKey(NetworkId objectId, std::string attributeType);
bool operator==(const IndexKey &rhs) const;
};
struct IndexSorter
{
bool operator() (const IndexKey &left, const IndexKey &right) const;
};
typedef std::map<IndexKey,DBSchema::ManufactureSchematicAttributeRow*,IndexSorter> IndexType;
DB::ModeQuery::Mode m_mode;
IndexType m_rows;
private:
ManufactureSchematicAttributeBuffer(); //disable
ManufactureSchematicAttributeBuffer(const ManufactureSchematicAttributeBuffer&); //disable
ManufactureSchematicAttributeBuffer & operator=(const ManufactureSchematicAttributeBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
inline ManufactureSchematicAttributeBuffer::IndexKey::IndexKey(NetworkId objectId, std::string attributeType) :
m_objectId(objectId),
m_attributeType(attributeType)
{
}
// ----------------------------------------------------------------------
inline bool ManufactureSchematicAttributeBuffer::IndexKey::operator==(const IndexKey &rhs) const
{
return ((m_objectId == rhs.m_objectId) && (m_attributeType == rhs.m_attributeType));
}
// ----------------------------------------------------------------------
inline bool ManufactureSchematicAttributeBuffer::IndexSorter::operator() (const IndexKey &left, const IndexKey &right) const
{
if (left.m_objectId == right.m_objectId)
return (left.m_attributeType < right.m_attributeType);
else
return (left.m_objectId < right.m_objectId);
}
// ======================================================================
#endif
@@ -0,0 +1,138 @@
// ======================================================================
//
// MarketAuctionBidsBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/MarketAuctionBidsBuffer.h"
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverGame/ServerPlayerObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include <vector>
// ======================================================================
MarketAuctionBidsBuffer::MarketAuctionBidsBuffer(DB::ModeQuery::Mode mode) :
AbstractTableBuffer(),
m_mode(mode),
m_rows()
{
}
// ----------------------------------------------------------------------
MarketAuctionBidsBuffer::~MarketAuctionBidsBuffer(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
bool MarketAuctionBidsBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
return true;
}
// ----------------------------------------------------------------------
void MarketAuctionBidsBuffer::removeObject(const NetworkId &object)
{
removeMarketAuctionBids(object);
}
// ----------------------------------------------------------------------
void MarketAuctionBidsBuffer::removeMarketAuctionBids(const NetworkId &itemId)
{
IndexType::iterator i=m_rows.find(itemId);
if (i!=m_rows.end())
{
delete i->second;
i->second=NULL;
m_rows.erase(i);
}
}
// ----------------------------------------------------------------------
void MarketAuctionBidsBuffer::setMarketAuctionBids(const NetworkId &itemId, const NetworkId &bidderId, const int bid, const int maxProxyBid)
{
DBSchema::MarketAuctionBidsRow *row=findRowByIndex(itemId);
if (!row)
{
row=new DBSchema::MarketAuctionBidsRow;
addRowToIndex(itemId, row);
}
row->item_id = itemId;
row->bidder_id = bidderId;
row->bid = bid;
row->max_proxy_bid = maxProxyBid;
}
// ----------------------------------------------------------------------
DBSchema::MarketAuctionBidsRow * MarketAuctionBidsBuffer::findRowByIndex(const NetworkId &itemId)
{
IndexType::iterator i=m_rows.find(itemId);
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void MarketAuctionBidsBuffer::addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionBidsRow *row)
{
m_rows[itemId]=row;
}
// ----------------------------------------------------------------------
bool MarketAuctionBidsBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("MarketAuctionBids: %i saved to db",m_rows.size()));
DEBUG_REPORT_LOG(true, ("Saving Market Auction Bids Buffer. mode:%d rowcount:%d\n", m_mode, m_rows.size()));
DBQuery::MarketAuctionBidsQuery qry;
if (m_mode==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else if (m_mode == DB::ModeQuery::mode_UPDATE)
qry.updateMode();
else
qry.deleteMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData(i->second))
return false;
if (qry.getNumItems() >= MarketAuctionBidsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
return true;
}
// ======================================================================
@@ -0,0 +1,63 @@
// ======================================================================
//
// MarketAuctionBidsBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_MarketAuctionBidsBuffer_H
#define INCLUDED_MarketAuctionBidsBuffer_H
// ======================================================================
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverDatabase/AbstractTableBuffer.h"
#include <map>
#include <string>
// ======================================================================
namespace MarketAuctionBidsTableBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace MarketAuctionBidsTableBufferNamespace;
// ======================================================================
class MarketAuctionBidsBuffer : public AbstractTableBuffer
{
public:
explicit MarketAuctionBidsBuffer (DB::ModeQuery::Mode mode);
virtual ~MarketAuctionBidsBuffer ();
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
DBSchema::MarketAuctionBidsRow * findRowByIndex (const NetworkId &itemId);
void setMarketAuctionBids (const NetworkId &itemId, const NetworkId &bidderId, const int bid, const int maxProxyBid);
void removeMarketAuctionBids(const NetworkId &itemId);
virtual void removeObject (const NetworkId &object);
private:
void addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionBidsRow *row);
private:
typedef std::map<NetworkId, DBSchema::MarketAuctionBidsRow*> IndexType;
DB::ModeQuery::Mode m_mode;
IndexType m_rows;
private:
MarketAuctionBidsBuffer(); //disable
MarketAuctionBidsBuffer(const MarketAuctionBidsBuffer&); //disable
MarketAuctionBidsBuffer & operator=(const MarketAuctionBidsBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
#endif
@@ -0,0 +1,433 @@
// ======================================================================
//
// MarketAuctionsBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/MarketAuctionsBuffer.h"
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverGame/ServerPlayerObjectTemplate.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include <vector>
// ======================================================================
MarketAuctionsBufferCreate::MarketAuctionsBufferCreate() :
AbstractTableBuffer(),
m_rows(),
m_attributes()
{
}
// ----------------------------------------------------------------------
MarketAuctionsBufferCreate::~MarketAuctionsBufferCreate(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferCreate::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
return true;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferCreate::removeObject(const NetworkId &object)
{
removeMarketAuctions(object);
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferCreate::removeMarketAuctions(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferCreate Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
DBSchema::MarketAuctionsRow *row=findRowByIndex(itemId);
if (row)
{
delete row;
IGNORE_RETURN(m_rows.erase(itemId));
IGNORE_RETURN(m_attributes.erase(itemId));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferCreate Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
}
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferCreate::setMarketAuctions(const NetworkId &itemId, const NetworkId &ownerId, const int active)
{
DBSchema::MarketAuctionsRow *row=findRowByIndex(itemId);
if (!row)
{
row=new DBSchema::MarketAuctionsRow;
addRowToIndex(itemId, row);
}
row->item_id = itemId;
row->owner_id = ownerId;
row->active = active;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferCreate::setMarketAuctions(const NetworkId &itemId, const NetworkId &ownerId, const NetworkId &creatorId, const NetworkId &locationId, const int minBid, const int buyNowPrice, const int auctionTimer, std::vector<std::pair<std::string, Unicode::String> > const & attributes, const Unicode::String userDescription, const int category, const int itemTemplateId, const Unicode::String itemName, const int itemTimer, const int active, const int itemSize)
{
DBSchema::MarketAuctionsRow *row=findRowByIndex(itemId);
if (!row)
{
row=new DBSchema::MarketAuctionsRow;
addRowToIndex(itemId, row);
}
row->item_id = itemId;
row->owner_id = ownerId;
row->creator_id = creatorId;
row->location_id = locationId;
row->min_bid = minBid;
row->buy_now_price = buyNowPrice;
row->auction_timer = auctionTimer;
// row->oob = oob;
row->user_description = userDescription;
row->category = category;
row->item_name = itemName;
row->item_timer = itemTimer;
row->active = active;
row->item_size = itemSize;
row->object_template_id = itemTemplateId;
LOG("CommoditiesServer", ("MarketAuctionsBufferCreate Added MarketAuctionsBuffer row for item %s", row->item_id.getValueASCII().c_str()));
m_attributes[itemId] = attributes;
}
// ----------------------------------------------------------------------
DBSchema::MarketAuctionsRow * MarketAuctionsBufferCreate::findRowByIndex(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferCreate Finding row by Index. ItemId : %s.\n", itemId.getValueString().c_str()));
IndexType::iterator i=m_rows.find(itemId);
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferCreate::addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRow *row)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferCreate Adding row to Index. ItemId : %s.\n", itemId.getValueString().c_str()));
m_rows[itemId]=row;
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferCreate::save(DB::Session *session)
{
{
// count how many attributes we're saving
size_t numAttributes = 0;
for (AttributesType::const_iterator i=m_attributes.begin(); i!=m_attributes.end(); ++i)
numAttributes += i->second.size();
LOG("SaveCounts",("MarketAuctionsBufferCreate: %i auctions, %i auction attributes saved to db",m_rows.size(), numAttributes));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferCreate Saving Market Auctions Buffer. rowcount:%d auctions, %d auction attributes\n", m_rows.size(), numAttributes));
}
{
DBQuery::MarketAuctionsQuery qry;
qry.insertMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData(i->second))
return false;
LOG("CommoditiesServer", ("MarketAuctionsBufferCreate Added row to MarketAuctionsQuery VARRAY for item %s", (i->second)->item_id.getValueASCII().c_str()));
if (qry.getNumItems() >= MarketAuctionsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
}
{
DBQuery::MarketAuctionsAttributesQuery qry;
qry.insertMode();
if (!qry.setupData(session))
return false;
for (AttributesType::const_iterator i=m_attributes.begin(); i!=m_attributes.end(); ++i)
{
for (std::vector<std::pair<std::string, Unicode::String> >::const_iterator j=i->second.begin(); j!=i->second.end(); ++j)
{
if (!qry.addData(i->first, j->first, j->second))
return false;
if (qry.getNumItems() >= MarketAuctionsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
}
return true;
}
// ======================================================================
MarketAuctionsBufferDelete::MarketAuctionsBufferDelete() :
AbstractTableBuffer(),
m_rows()
{
}
// ----------------------------------------------------------------------
MarketAuctionsBufferDelete::~MarketAuctionsBufferDelete(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferDelete::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
return true;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferDelete::removeObject(const NetworkId &object)
{
removeMarketAuctions(object);
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferDelete::removeMarketAuctions(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferDelete Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
DBSchema::MarketAuctionsRowDelete *row=findRowByIndex(itemId);
if (row)
{
delete row;
IGNORE_RETURN(m_rows.erase(itemId));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferDelete Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
}
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferDelete::setMarketAuctions(const NetworkId &itemId)
{
DBSchema::MarketAuctionsRowDelete *row=findRowByIndex(itemId);
if (!row)
{
row=new DBSchema::MarketAuctionsRowDelete;
addRowToIndex(itemId, row);
}
row->item_id = itemId;
}
// ----------------------------------------------------------------------
DBSchema::MarketAuctionsRowDelete * MarketAuctionsBufferDelete::findRowByIndex(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferDelete Finding row by Index. ItemId : %s.\n", itemId.getValueString().c_str()));
IndexType::iterator i=m_rows.find(itemId);
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferDelete::addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRowDelete *row)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferDelete Adding row to Index. ItemId : %s.\n", itemId.getValueString().c_str()));
m_rows[itemId]=row;
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferDelete::save(DB::Session *session)
{
LOG("SaveCounts",("MarketAuctionsBufferDelete: %i saved to db",m_rows.size()));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferDelete Saving Market Auctions Buffer. rowcount:%d\n", m_rows.size()));
DBQuery::MarketAuctionsQuery qry;
qry.deleteMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData(i->second))
return false;
LOG("CommoditiesServer", ("MarketAuctionsBufferDelete Added row to MarketAuctionsQuery VARRAY for item %s", (i->second)->item_id.getValueASCII().c_str()));
if (qry.getNumItems() >= MarketAuctionsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
return true;
}
// ======================================================================
MarketAuctionsBufferUpdate::MarketAuctionsBufferUpdate() :
AbstractTableBuffer(),
m_rows()
{
}
// ----------------------------------------------------------------------
MarketAuctionsBufferUpdate::~MarketAuctionsBufferUpdate(void)
{
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
delete i->second;
i->second=NULL;
}
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferUpdate::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
return true;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferUpdate::removeObject(const NetworkId &object)
{
removeMarketAuctions(object);
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferUpdate::removeMarketAuctions(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
DBSchema::MarketAuctionsRowUpdate *row=findRowByIndex(itemId);
if (row)
{
delete row;
IGNORE_RETURN(m_rows.erase(itemId));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Removing Market Auctions Buffer Row. rowcount:%d\n", m_rows.size()));
}
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferUpdate::setMarketAuctions(const NetworkId &itemId, const NetworkId &ownerId, const int active)
{
DBSchema::MarketAuctionsRowUpdate *row=findRowByIndex(itemId);
if (!row)
{
row=new DBSchema::MarketAuctionsRowUpdate;
addRowToIndex(itemId, row);
}
row->item_id = itemId;
row->owner_id = ownerId;
row->active = active;
}
// ----------------------------------------------------------------------
DBSchema::MarketAuctionsRowUpdate * MarketAuctionsBufferUpdate::findRowByIndex(const NetworkId &itemId)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Finding row by Index. ItemId : %s.\n", itemId.getValueString().c_str()));
IndexType::iterator i=m_rows.find(itemId);
if (i==m_rows.end())
return 0;
else
return (*i).second;
}
// ----------------------------------------------------------------------
void MarketAuctionsBufferUpdate::addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRowUpdate *row)
{
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Adding row to Index. ItemId : %s.\n", itemId.getValueString().c_str()));
m_rows[itemId]=row;
}
// ----------------------------------------------------------------------
bool MarketAuctionsBufferUpdate::save(DB::Session *session)
{
LOG("SaveCounts",("MarketAuctionsBufferUpdate: %i saved to db",m_rows.size()));
DEBUG_REPORT_LOG(true, ("MarketAuctionsBufferUpdate Saving Market Auctions Buffer. rowcount:%d\n", m_rows.size()));
DBQuery::MarketAuctionsQuery qry;
qry.updateMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (!qry.addData(i->second))
return false;
LOG("CommoditiesServer", ("MarketAuctionsBufferUpdate Added row to MarketAuctionsQuery VARRAY for item %s", (i->second)->item_id.getValueASCII().c_str()));
if (qry.getNumItems() >= MarketAuctionsTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
return true;
}
// ======================================================================
@@ -0,0 +1,121 @@
// ======================================================================
//
// MarketAuctionsBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_MarketAuctionsBuffer_H
#define INCLUDED_MarketAuctionsBuffer_H
// ======================================================================
#include "SwgDatabaseServer/CommoditiesQuery.h"
#include "SwgDatabaseServer/CommoditiesSchema.h"
#include "serverDatabase/AbstractTableBuffer.h"
#include <hash_map>
#include <string>
// ======================================================================
namespace MarketAuctionsTableBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace MarketAuctionsTableBufferNamespace;
// ======================================================================
class MarketAuctionsBufferCreate : public AbstractTableBuffer
{
public:
MarketAuctionsBufferCreate();
virtual ~MarketAuctionsBufferCreate();
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
DBSchema::MarketAuctionsRow * findRowByIndex (const NetworkId &itemId);
void setMarketAuctions (const NetworkId &itemId, const NetworkId &ownerId, const int active);
void setMarketAuctions (const NetworkId &itemId, const NetworkId &ownerId, const NetworkId &creatorId, const NetworkId &locationId, const int minBid, const int buyNowPrice, const int auctionTimer, std::vector<std::pair<std::string, Unicode::String> > const & attributes, const Unicode::String userDescription, const int category, const int itemTemplateId, const Unicode::String itemName, const int itemTimer, const int active, const int itemSize);
void removeMarketAuctions (const NetworkId &itemId);
virtual void removeObject (const NetworkId &object);
private:
void addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRow *row);
private:
typedef std::hash_map<NetworkId, DBSchema::MarketAuctionsRow*> IndexType;
IndexType m_rows;
typedef std::hash_map<NetworkId, std::vector<std::pair<std::string, Unicode::String> > > AttributesType;
AttributesType m_attributes;
private:
MarketAuctionsBufferCreate(const MarketAuctionsBufferCreate&); //disable
MarketAuctionsBufferCreate & operator=(const MarketAuctionsBufferCreate&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
class MarketAuctionsBufferDelete : public AbstractTableBuffer
{
public:
explicit MarketAuctionsBufferDelete();
virtual ~MarketAuctionsBufferDelete();
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
DBSchema::MarketAuctionsRowDelete * findRowByIndex(const NetworkId &itemId);
void setMarketAuctions (const NetworkId &itemId);
void removeMarketAuctions (const NetworkId &itemId);
virtual void removeObject (const NetworkId &object);
private:
void addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRowDelete *row);
private:
typedef std::hash_map<NetworkId, DBSchema::MarketAuctionsRowDelete*> IndexType;
IndexType m_rows;
private:
MarketAuctionsBufferDelete(const MarketAuctionsBufferDelete&); //disable
MarketAuctionsBufferDelete & operator=(const MarketAuctionsBufferDelete&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
class MarketAuctionsBufferUpdate : public AbstractTableBuffer
{
public:
explicit MarketAuctionsBufferUpdate();
virtual ~MarketAuctionsBufferUpdate();
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
DBSchema::MarketAuctionsRowUpdate * findRowByIndex(const NetworkId &itemId);
void setMarketAuctions (const NetworkId &itemId, const NetworkId &ownerId, const int active);
void removeMarketAuctions (const NetworkId &itemId);
virtual void removeObject (const NetworkId &object);
private:
void addRowToIndex (const NetworkId &itemId, DBSchema::MarketAuctionsRowUpdate *row);
private:
typedef std::hash_map<NetworkId, DBSchema::MarketAuctionsRowUpdate*> IndexType;
IndexType m_rows;
private:
MarketAuctionsBufferUpdate(const MarketAuctionsBufferUpdate&); //disable
MarketAuctionsBufferUpdate & operator=(const MarketAuctionsBufferUpdate&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
#endif
@@ -0,0 +1,205 @@
// ======================================================================
//
// MessageBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "SwgDatabaseServer/MessageBuffer.h"
#include "SwgDatabaseServer/MessageQuery.h"
#include "serverDatabase/ConfigServerDatabase.h"
#include "serverDatabase/DatabaseProcess.h"
#include "serverDatabase/GameServerConnection.h"
#include "serverDatabase/Loader.h"
#include "serverDatabase/MessageToManager.h"
#include "serverNetworkMessages/MessageToMessage.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
// ======================================================================
MessageBuffer::~MessageBuffer()
{
}
// ----------------------------------------------------------------------
void MessageBuffer::handleMessageTo(const MessageToPayload &message)
{
DEBUG_FATAL(m_data.find(message.getMessageId())!=m_data.end(),("Received duplicate messageTo, id %s.\n",message.getMessageId().getValueString().c_str()));
if (message.getNetworkId().getValue() <= static_cast<NetworkId::NetworkIdType>(0))
DEBUG_WARNING(true,("Ignored persisted messageTo sent to invalid object id %s, method %s",message.getNetworkId().getValueString().c_str(), message.getMethod().c_str()));
else
m_data[message.getMessageId()]=message;
}
// ----------------------------------------------------------------------
void MessageBuffer::handleMessageToAck(const MessageToId &messageId)
{
MessageMap::iterator i=m_data.find(messageId);
if (i!=m_data.end())
{
// we have the message in the buffer, so we can just delete it without involving the database
m_data.erase(i);
}
else
{
// we don't have the message, so it must have already been persisted to the database
// set a flag to remove it from the DB
m_ackedMessages.push_back(messageId);
}
}
// ----------------------------------------------------------------------
bool MessageBuffer::save(DB::Session *session)
{
int actualSaves=0;
DBQuery::SaveMessageQuery qry;
if (!qry.setupData(session))
return false;
for (MessageMap::const_iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
if (m_cancelledObjects.find(i->second.getNetworkId())==m_cancelledObjects.end())
{
++actualSaves;
if (!qry.addData((*i).second))
return false;
if (qry.getNumItems() == ConfigServerDatabase::getDefaultMessageBulkBindSize())
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
DBQuery::AckMessageQuery ackqry;
if (!ackqry.setupData(session))
return false;
for (AckedMessagesType::const_iterator j=m_ackedMessages.begin(); j!=m_ackedMessages.end(); ++j)
{
if (!ackqry.addData(*j))
return false;
if (ackqry.getNumItems() == ConfigServerDatabase::getDefaultMessageBulkBindSize())
{
if (! (session->exec(&ackqry)))
return false;
ackqry.clearData();
}
}
if (ackqry.getNumItems() != 0)
if (! (session->exec(&ackqry)))
return false;;
ackqry.done();
ackqry.freeData();
LOG("SaveCounts",("Messages: %i out of %i saved in db, %i acks sent to db",actualSaves,m_data.size(),m_ackedMessages.size()));
return true;
}
// ----------------------------------------------------------------------
bool MessageBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched;
UNREF(tags); // any object can have messages
DBQuery::LoadMessagesQuery qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBQuery::LoadMessagesQuery::MessageRow> &data =qry.getData();
for (std::vector<DBQuery::LoadMessagesQuery::MessageRow>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
std::string utf8data;
i->packed_data.getValue(utf8data);
std::vector<int8> packedDataVector;
qry.convertUTF8ToMessage(utf8data, packedDataVector);
MessageToPayload messageData(i->object_id.getValue(),
i->message_id.getValue(),
Unicode::wideToNarrow(i->method.getValue()),
packedDataVector,
i->call_time.getValue(),
i->guaranteed.getValue(),
static_cast<MessageToPayload::DeliveryType>(i->delivery_type.getValue()),
NetworkId::cms_invalid,
std::string(),
0);
messageData.setPersisted(true);
m_data[i->message_id.getValue()]=messageData;
}
}
qry.done();
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
/**
* Send all the messages in the buffer to the GameServer, which will enqueue
* them and handle them when their timers expire.
* Note: This requires that all the objects loaded have already been
* sent to the game server.
*/
void MessageBuffer::sendMessages(GameServerConnection &conn) const
{
for (MessageMap::const_iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
if (!MessageToManager::getInstance().hasMessage(i->second.getMessageId()))
{
MessageToMessage const msg((*i).second, DatabaseProcess::getInstance().getProcessId());
conn.send(msg, true);
}
}
}
// ----------------------------------------------------------------------
void MessageBuffer::removeObject(const NetworkId &object)
{
// Too slow to hunt down all the messages & acks for this object, so easier to make
// a set of objects and skip any new messages for these objects
m_cancelledObjects.insert(object);
}
// ----------------------------------------------------------------------
/**
* Called by the main thread after persistence is complete.
* Remove all the saved messages from the MessageToManager, since
* they will be reloaded from the DB if needed.
*/
void MessageBuffer::removeSavedMessagesFromMemory () const
{
for (MessageMap::const_iterator i=m_data.begin(); i!=m_data.end(); ++i)
MessageToManager::getInstance().onMessagePersisted(i->second.getMessageId());
}
// ======================================================================
@@ -0,0 +1,62 @@
// ======================================================================
//
// MessageBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_MessageBuffer_H
#define INCLUDED_MessageBuffer_H
// ======================================================================
#include "serverDatabase/AbstractTableBuffer.h"
#include "serverNetworkMessages/MessageToPayload.h"
#include <map>
#include <vector>
#include <set>
// ======================================================================
namespace DB
{
class Session;
}
class GameServerConnection;
// ======================================================================
/**
* A buffer to hold messageTo commands.
*/
class MessageBuffer : public AbstractTableBuffer
{
public:
void handleMessageTo (const MessageToPayload &message);
void handleMessageToAck (const MessageToId &messageId);
void sendMessages (GameServerConnection &conn) const;
void removeSavedMessagesFromMemory () const;
virtual bool save(DB::Session *session);
virtual bool load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual void removeObject(const NetworkId &object);
public:
virtual ~MessageBuffer();
private:
typedef std::map<MessageToId,MessageToPayload> MessageMap;
typedef std::vector<MessageToId> AckedMessagesType;
typedef std::set<NetworkId> OIDList;
private:
MessageMap m_data;
AckedMessagesType m_ackedMessages;
OIDList m_cancelledObjects;
};
// ======================================================================
#endif
@@ -0,0 +1,819 @@
// ======================================================================
//
// ObjectTableBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "ObjectTableBuffer.h"
#include <vector>
#include <map>
#include <set>
#include "SwgDatabaseServer/DeleteDemandLoadedContainerQuery.h"
#include "SwgDatabaseServer/Schema.h"
#include "serverDatabase/DatabaseProcess.h"
#include "serverDatabase/GetContentsList.h"
#include "serverNetworkMessages/GetMoneyFromOfflineObjectMessage.h"
#include "serverNetworkMessages/UpdateObjectPositionMessage.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
#include "sharedMath/Quaternion.h"
#include "sharedNetworkMessages/MessageQueueDataTransform.h"
#include "sharedNetworkMessages/ObjectChannelMessages.h"
// ======================================================================
namespace ObjectTableBufferNamespace
{
static const int s_numPositions = 20;
static const int s_positionMasks[20] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288};
static const int s_allPositionsSet = 1048575;
}
using namespace ObjectTableBufferNamespace;
// ======================================================================
ObjectTableBuffer::ObjectTableBuffer(DB::ModeQuery::Mode mode) :
IndexedNetworkTableBuffer<DBSchema::ObjectBufferRow, DBSchema::ObjectRow, DBQuery::ObjectsTableQuery, DBQuery::ObjectsTableQuerySelect>(mode)
{
}
// ======================================================================
ObjectTableBuffer::~ObjectTableBuffer()
{
}
// ----------------------------------------------------------------------
/**
* Called when a new object is created.
*
* Sets up the data for the object in the Objects table.
*/
void ObjectTableBuffer::newObject(const NetworkId &objectId, int templateId, Tag typeId)
{
DBSchema::ObjectBufferRow *row=addEmptyRow(objectId);
row->object_template_id.setValue(templateId);
row->type_id.setValue(static_cast<long>(typeId)); // cast because tags are unsigned
row->deleted.setValue(0);
row->controller_type.setValue(0);
}
// ----------------------------------------------------------------------
bool ObjectTableBuffer::handleUpdateObjectPosition(const UpdateObjectPositionMessage &message)
{
DBSchema::ObjectBufferRow *row=dynamic_cast<DBSchema::ObjectBufferRow*>(findRowByIndex(message.getNetworkId()));
if (row==0)
{
row=addEmptyRow(message.getNetworkId());
}
Vector v = message.getTransform().getPosition_p();
row->x = static_cast<double>(v.x);
row->y = static_cast<double>(v.y);
row->z = static_cast<double>(v.z);
Quaternion q(message.getTransform());
Transform t;
q.getTransform(&t);
row->quaternion_w = static_cast<double>(q.w);
row->quaternion_x = static_cast<double>(q.x);
row->quaternion_y = static_cast<double>(q.y);
row->quaternion_z = static_cast<double>(q.z);
row->node_x=roundToNode(v.x);
row->node_y=roundToNode(v.y);
row->node_z=roundToNode(v.z);
row->contained_by = message.getContainerId();
row->slot_arrangement = message.getSlotArrangement();
row->load_with = message.getLoadWith();
return true;
}
// ----------------------------------------------------------------------
/**
* Process a delete message for an object.
*
* Sets the "deleted" column to "true".
*
* Note: even if the object is a new object, leaves it in the buffer
* (but filters it out in save().) This is to avoid a possible bug
* where some delta comes to the object after it is deleted, and we end
* up creating a new row that doesn't have "deleted" set.
*/
void ObjectTableBuffer::handleDeleteMessage(const NetworkId &objectId, int reasonCode, bool demandLoadedContainer, bool cascadeDeleteReason)
{
DEBUG_FATAL(reasonCode==0,("Programmer bug: The gameserver sent 0 as the reason code when deleting object %s, but 0 indicates the object is not deleted.\n",objectId.getValueString().c_str()));
DBSchema::ObjectBufferRow *row=dynamic_cast<DBSchema::ObjectBufferRow*>(findRowByIndex(objectId));
if (row==0)
row=addEmptyRow(objectId);
row->deleted.setValue(reasonCode);
if (demandLoadedContainer)
{
if (cascadeDeleteReason)
m_demandLoadedContainersToDelete.push_back(std::make_pair(objectId, reasonCode));
else
m_demandLoadedContainersToDelete.push_back(std::make_pair(objectId, 0));
}
}
// ----------------------------------------------------------------------
int ObjectTableBuffer::roundToNode(real coordinate)
{
int c=static_cast<int>(coordinate);
// (c/chunksize)*chunksize : ... blah
return (c >= 0) ? (c/100)*100 : (((c-100)+1)/100)*100;
}
// ----------------------------------------------------------------------
// Topological sort
struct DFSNode
{
NetworkId m_oid;
NetworkId m_containedBy;
bool m_visited;
};
// ----------------------------------------------------------------------
void ObjectTableBuffer::getTags(DB::TagSet &tags) const
{
for (IndexType::const_iterator r=m_rows.begin(); r!=m_rows.end(); ++r)
tags.insert(r->second->type_id.getValue());
}
// ----------------------------------------------------------------------
void ObjectTableBuffer::getObjectList(stdvector<NetworkId>::fwd &theList) const
{
typedef std::map <NetworkId, DFSNode> NodesType;
NodesType nodes;
std::vector <DFSNode*> nodeStack;
// Copy the rows to our temporary space for sorting
for (IndexType::const_iterator r=m_rows.begin(); r!=m_rows.end(); ++r)
{
DFSNode &newNode = nodes[r->second->object_id.getValue()];
newNode.m_oid = r->second->object_id.getValue();
newNode.m_containedBy = r->second->contained_by.getValue();
newNode.m_visited = false;
}
// Depth-first search, outputting the nodes as we recurse *out* of them
for (NodesType::iterator i=nodes.begin(); i!=nodes.end(); ++i)
{
if (!i->second.m_visited)
{
nodeStack.push_back(&i->second);
i->second.m_visited = true;
while (!nodeStack.empty())
{
DFSNode *theNode = nodeStack.back();
bool noContainer = true;
if (theNode->m_containedBy!=NetworkId::cms_invalid)
{
NodesType::iterator j=nodes.find(theNode->m_containedBy);
if (j!=nodes.end() && !(j->second.m_visited))
{
nodeStack.push_back(&(j->second));
j->second.m_visited = true;
noContainer=false;
}
}
if (noContainer)
{
nodeStack.pop_back();
theList.push_back(theNode->m_oid);
}
}
}
}
}
// ----------------------------------------------------------------------
bool ObjectTableBuffer::save(DB::Session *session)
{
int updates=0;
int deletes=0;
int onlyPositionOrDeletes=0;
DBQuery::ObjectsTableQuery qry;
if (getMode()==DB::ModeQuery::mode_INSERT)
qry.insertMode();
else
qry.updateMode();
if (!qry.setupData(session))
return false;
for (IndexType::iterator i=m_rows.begin(); i!=m_rows.end(); ++i)
{
if (i->second->object_template_id.isNull() &&
i->second->type_id.isNull() &&
i->second->scene_id.isNull() &&
i->second->controller_type.isNull() &&
i->second->object_name.isNull() &&
i->second->volume.isNull() &&
i->second->slot_arrangement.isNull() &&
i->second->player_controlled.isNull() &&
i->second->cache_version.isNull() &&
i->second->load_contents.isNull() &&
i->second->cash_balance.isNull() &&
i->second->bank_balance.isNull() &&
i->second->complexity.isNull() &&
i->second->name_string_table.isNull() &&
i->second->name_string_text.isNull())
{
++onlyPositionOrDeletes;
}
if (!i->second->deleted.isNull() && i->second->deleted.getValue()!=0)
++deletes;
if (getMode()==DB::ModeQuery::mode_INSERT && !i->second->deleted.isNull() && i->second->deleted.getValue()!=0)
{
// DEBUG_REPORT_LOG(true,("Skipped saving deleted object %s\n",i->second->object_id.getValue().getValueString().c_str()));
}
else
{
++updates;
qry.setData(*(i->second));
#if 0 // Enable this to debug load_with problems
DEBUG_REPORT_LOG(true,("Save object %s ",i->second->object_id.getValue().getValueString().c_str()));
if (i->second->contained_by.isNull())
DEBUG_REPORT_LOG(true, ("contained_by NULL "));
else
DEBUG_REPORT_LOG(true, ("contained_by %s ",i->second->contained_by.getValue().getValueString().c_str()));
if (i->second->load_with.isNull())
DEBUG_REPORT_LOG(true,("load_with NULL\n"));
else
DEBUG_REPORT_LOG(true,("load_with %s\n",i->second->load_with.getValue().getValueString().c_str()));
#endif
if (!qry.addData((i->second)))
return false;
if (qry.getNumItems() == ObjectTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry)))
return false;
qry.clearData();
}
}
}
if (qry.getNumItems() != 0)
if (! (session->exec(&qry)))
return false;
qry.done();
qry.freeData();
if (!m_demandLoadedContainersToDelete.empty())
{
DBQuery::DeleteDemandLoadedContainerQuery ddlcq;
if (!ddlcq.setupData(*session))
return false;
for (std::vector<std::pair<NetworkId, int> >::const_iterator i=m_demandLoadedContainersToDelete.begin(); i!=m_demandLoadedContainersToDelete.end(); ++i)
{
if (!ddlcq.addData(i->first, i->second))
return false;
if (ddlcq.getCount() == ObjectTableBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&ddlcq)))
return false;
ddlcq.clearData();
}
}
if (ddlcq.getCount() != 0)
{
if (! (session->exec(&ddlcq)))
return false;
ddlcq.clearData();
}
ddlcq.done();
ddlcq.freeData();
}
if (getMode()==DB::ModeQuery::mode_INSERT)
LOG("SaveCounts",("Object table new objects: %i (out of %i) total, %i only position or delete, %i delete\n",updates,m_rows.size(),onlyPositionOrDeletes,deletes));
else
LOG("SaveCounts",("Object table updates: %i total, %i only position or delete, %i delete\n",updates,onlyPositionOrDeletes,deletes));
return true;
}
// ----------------------------------------------------------------------
void ObjectTableBuffer::decodeObjVarFreeFlags(const NetworkId &objectId, int freePositions)
{
// DEBUG_REPORT_LOG(true,("OBJVAR_DEBUG: decodeObjVarFreeFlags(%s,%i)\n",objectId.getValueString().c_str(),freePositions));
DBSchema::ObjectBufferRow *row=dynamic_cast<DBSchema::ObjectBufferRow*>(findRowByIndex(objectId));
if (row==0)
row=addEmptyRow(objectId);
for (int i=0; i<s_numPositions; ++i)
{
bool set=((s_positionMasks[i] & freePositions)!=0);
if (set)
{
switch (i)
{
case 0:
row->objvar_0_type = -1;
break;
case 1:
row->objvar_1_type = -1;
break;
case 2:
row->objvar_2_type = -1;
break;
case 3:
row->objvar_3_type = -1;
break;
case 4:
row->objvar_4_type = -1;
break;
case 5:
row->objvar_5_type = -1;
break;
case 6:
row->objvar_6_type = -1;
break;
case 7:
row->objvar_7_type = -1;
break;
case 8:
row->objvar_8_type = -1;
break;
case 9:
row->objvar_9_type = -1;
break;
case 10:
row->objvar_10_type = -1;
break;
case 11:
row->objvar_11_type = -1;
break;
case 12:
row->objvar_12_type = -1;
break;
case 13:
row->objvar_13_type = -1;
break;
case 14:
row->objvar_14_type = -1;
break;
case 15:
row->objvar_15_type = -1;
break;
case 16:
row->objvar_16_type = -1;
break;
case 17:
row->objvar_17_type = -1;
break;
case 18:
row->objvar_18_type = -1;
break;
case 19:
row->objvar_19_type = -1;
break;
default:
DEBUG_FATAL(true,("ObjectId %s had freePositions flag %i, which is not valid.",objectId.getValueString().c_str(),freePositions));
}
}
}
}
// ----------------------------------------------------------------------
void ObjectTableBuffer::handlePackedObjvar(const NetworkId &objectId, int position, const std::string &objvarName, int typeId, const std::string &packedValue)
{
// DEBUG_REPORT_LOG(true,("OBJVAR_DEBUG: handlePackedObjvar(%s,%i,%s,%i,%s)\n",objectId.getValueString().c_str(),position,objvarName.c_str(), typeId, packedValue.c_str()));
DBSchema::ObjectBufferRow *row=dynamic_cast<DBSchema::ObjectBufferRow*>(findRowByIndex(objectId));
if (row==0)
row=addEmptyRow(objectId);
switch(position)
{
case 0:
row->objvar_0_name = objvarName;
row->objvar_0_type = typeId;
row->objvar_0_value = packedValue;
break;
case 1:
row->objvar_1_name = objvarName;
row->objvar_1_type = typeId;
row->objvar_1_value = packedValue;
break;
case 2:
row->objvar_2_name = objvarName;
row->objvar_2_type = typeId;
row->objvar_2_value = packedValue;
break;
case 3:
row->objvar_3_name = objvarName;
row->objvar_3_type = typeId;
row->objvar_3_value = packedValue;
break;
case 4:
row->objvar_4_name = objvarName;
row->objvar_4_type = typeId;
row->objvar_4_value = packedValue;
break;
case 5:
row->objvar_5_name = objvarName;
row->objvar_5_type = typeId;
row->objvar_5_value = packedValue;
break;
case 6:
row->objvar_6_name = objvarName;
row->objvar_6_type = typeId;
row->objvar_6_value = packedValue;
break;
case 7:
row->objvar_7_name = objvarName;
row->objvar_7_type = typeId;
row->objvar_7_value = packedValue;
break;
case 8:
row->objvar_8_name = objvarName;
row->objvar_8_type = typeId;
row->objvar_8_value = packedValue;
break;
case 9:
row->objvar_9_name = objvarName;
row->objvar_9_type = typeId;
row->objvar_9_value = packedValue;
break;
case 10:
row->objvar_10_name = objvarName;
row->objvar_10_type = typeId;
row->objvar_10_value = packedValue;
break;
case 11:
row->objvar_11_name = objvarName;
row->objvar_11_type = typeId;
row->objvar_11_value = packedValue;
break;
case 12:
row->objvar_12_name = objvarName;
row->objvar_12_type = typeId;
row->objvar_12_value = packedValue;
break;
case 13:
row->objvar_13_name = objvarName;
row->objvar_13_type = typeId;
row->objvar_13_value = packedValue;
break;
case 14:
row->objvar_14_name = objvarName;
row->objvar_14_type = typeId;
row->objvar_14_value = packedValue;
break;
case 15:
row->objvar_15_name = objvarName;
row->objvar_15_type = typeId;
row->objvar_15_value = packedValue;
break;
case 16:
row->objvar_16_name = objvarName;
row->objvar_16_type = typeId;
row->objvar_16_value = packedValue;
break;
case 17:
row->objvar_17_name = objvarName;
row->objvar_17_type = typeId;
row->objvar_17_value = packedValue;
break;
case 18:
row->objvar_18_name = objvarName;
row->objvar_18_type = typeId;
row->objvar_18_value = packedValue;
break;
case 19:
row->objvar_19_name = objvarName;
row->objvar_19_type = typeId;
row->objvar_19_value = packedValue;
break;
default:
WARNING_STRICT_FATAL(true,("ObjectId %s had objvar %s with postion %i, which is not a valid position.",objectId.getValueString().c_str(),objvarName.c_str(), position));
}
}
// ----------------------------------------------------------------------
void ObjectTableBuffer::getObjvarsForObject(const NetworkId &objectId, std::vector<DynamicVariableList::MapType::Command> &commands) const
{
const DBSchema::ObjectBufferRow *row=safe_cast<const DBSchema::ObjectBufferRow*>(findConstRowByIndex(objectId));
if (row==0)
{
WARNING_STRICT_FATAL(true,("Loaded OBJECT_VARIABLES for %s, but had no OBJECTS row.",objectId.getValueString().c_str()));
return;
}
DynamicVariableList::MapType::Command c;
c.cmd = DynamicVariableList::MapType::Command::ADD;
if (row->objvar_0_type.getValue() >= 0)
{
row->objvar_0_name.getValue(c.key);
c.value.load(0, row->objvar_0_type.getValue(), row->objvar_0_value.getValue());
commands.push_back(c);
}
if (row->objvar_1_type.getValue() >= 0)
{
row->objvar_1_name.getValue(c.key);
c.value.load(1, row->objvar_1_type.getValue(), row->objvar_1_value.getValue());
commands.push_back(c);
}
if (row->objvar_2_type.getValue() >= 0)
{
row->objvar_2_name.getValue(c.key);
c.value.load(2, row->objvar_2_type.getValue(), row->objvar_2_value.getValue());
commands.push_back(c);
}
if (row->objvar_3_type.getValue() >= 0)
{
row->objvar_3_name.getValue(c.key);
c.value.load(3, row->objvar_3_type.getValue(), row->objvar_3_value.getValue());
commands.push_back(c);
}
if (row->objvar_4_type.getValue() >= 0)
{
row->objvar_4_name.getValue(c.key);
c.value.load(4, row->objvar_4_type.getValue(), row->objvar_4_value.getValue());
commands.push_back(c);
}
if (row->objvar_5_type.getValue() >= 0)
{
row->objvar_5_name.getValue(c.key);
c.value.load(5, row->objvar_5_type.getValue(), row->objvar_5_value.getValue());
commands.push_back(c);
}
if (row->objvar_6_type.getValue() >= 0)
{
row->objvar_6_name.getValue(c.key);
c.value.load(6, row->objvar_6_type.getValue(), row->objvar_6_value.getValue());
commands.push_back(c);
}
if (row->objvar_7_type.getValue() >= 0)
{
row->objvar_7_name.getValue(c.key);
c.value.load(7, row->objvar_7_type.getValue(), row->objvar_7_value.getValue());
commands.push_back(c);
}
if (row->objvar_8_type.getValue() >= 0)
{
row->objvar_8_name.getValue(c.key);
c.value.load(8, row->objvar_8_type.getValue(), row->objvar_8_value.getValue());
commands.push_back(c);
}
if (row->objvar_9_type.getValue() >= 0)
{
row->objvar_9_name.getValue(c.key);
c.value.load(9, row->objvar_9_type.getValue(), row->objvar_9_value.getValue());
commands.push_back(c);
}
if (row->objvar_10_type.getValue() >= 0)
{
row->objvar_10_name.getValue(c.key);
c.value.load(10, row->objvar_10_type.getValue(), row->objvar_10_value.getValue());
commands.push_back(c);
}
if (row->objvar_11_type.getValue() >= 0)
{
row->objvar_11_name.getValue(c.key);
c.value.load(11, row->objvar_11_type.getValue(), row->objvar_11_value.getValue());
commands.push_back(c);
}
if (row->objvar_12_type.getValue() >= 0)
{
row->objvar_12_name.getValue(c.key);
c.value.load(12, row->objvar_12_type.getValue(), row->objvar_12_value.getValue());
commands.push_back(c);
}
if (row->objvar_13_type.getValue() >= 0)
{
row->objvar_13_name.getValue(c.key);
c.value.load(13, row->objvar_13_type.getValue(), row->objvar_13_value.getValue());
commands.push_back(c);
}
if (row->objvar_14_type.getValue() >= 0)
{
row->objvar_14_name.getValue(c.key);
c.value.load(14, row->objvar_14_type.getValue(), row->objvar_14_value.getValue());
commands.push_back(c);
}
if (row->objvar_15_type.getValue() >= 0)
{
row->objvar_15_name.getValue(c.key);
c.value.load(15, row->objvar_15_type.getValue(), row->objvar_15_value.getValue());
commands.push_back(c);
}
if (row->objvar_16_type.getValue() >= 0)
{
row->objvar_16_name.getValue(c.key);
c.value.load(16, row->objvar_16_type.getValue(), row->objvar_16_value.getValue());
commands.push_back(c);
}
if (row->objvar_17_type.getValue() >= 0)
{
row->objvar_17_name.getValue(c.key);
c.value.load(17, row->objvar_17_type.getValue(), row->objvar_17_value.getValue());
commands.push_back(c);
}
if (row->objvar_18_type.getValue() >= 0)
{
row->objvar_18_name.getValue(c.key);
c.value.load(18, row->objvar_18_type.getValue(), row->objvar_18_value.getValue());
commands.push_back(c);
}
if (row->objvar_19_type.getValue() >= 0)
{
row->objvar_19_name.getValue(c.key);
c.value.load(19, row->objvar_19_type.getValue(), row->objvar_19_value.getValue());
commands.push_back(c);
}
}
// ----------------------------------------------------------------------
int ObjectTableBuffer::encodeObjVarFreeFlags(const NetworkId & objectId) const
{
const DBSchema::ObjectBufferRow *row=findConstRowByIndex(objectId);
WARNING_STRICT_FATAL(row==NULL,("Loading object %s, no ObjectRow in the buffer\n",objectId.getValueString().c_str()));
if (!row)
return 0;
int positionFlags=0;
for (int i=0; i<s_numPositions; ++i)
{
bool free = false;
switch(i)
{
case 0:
free = (row->objvar_0_type.getValue() < 0);
break;
case 1:
free = (row->objvar_1_type.getValue() < 0);
break;
case 2:
free = (row->objvar_2_type.getValue() < 0);
break;
case 3:
free = (row->objvar_3_type.getValue() < 0);
break;
case 4:
free = (row->objvar_4_type.getValue() < 0);
break;
case 5:
free = (row->objvar_5_type.getValue() < 0);
break;
case 6:
free = (row->objvar_6_type.getValue() < 0);
break;
case 7:
free = (row->objvar_7_type.getValue() < 0);
break;
case 8:
free = (row->objvar_8_type.getValue() < 0);
break;
case 9:
free = (row->objvar_9_type.getValue() < 0);
break;
case 10:
free = (row->objvar_10_type.getValue() < 0);
break;
case 11:
free = (row->objvar_11_type.getValue() < 0);
break;
case 12:
free = (row->objvar_12_type.getValue() < 0);
break;
case 13:
free = (row->objvar_13_type.getValue() < 0);
break;
case 14:
free = (row->objvar_14_type.getValue() < 0);
break;
case 15:
free = (row->objvar_15_type.getValue() < 0);
break;
case 16:
free = (row->objvar_16_type.getValue() < 0);
break;
case 17:
free = (row->objvar_17_type.getValue() < 0);
break;
case 18:
free = (row->objvar_18_type.getValue() < 0);
break;
case 19:
free = (row->objvar_19_type.getValue() < 0);
break;
default:
DEBUG_FATAL(true,("Iterated through too many positions. WTF?"));
}
if (free)
positionFlags += s_positionMasks[i];
}
return positionFlags;
}
// ----------------------------------------------------------------------
void ObjectTableBuffer::getWorldContainers(std::vector<NetworkId> &containers) const
{
for (IndexType::const_iterator r=m_rows.begin(); r!=m_rows.end(); ++r)
{
if ((r->second->contained_by.getValue()==NetworkId::cms_invalid) && (r->second->load_contents.getValue()))
containers.push_back(r->second->object_id.getValue());
}
}
// ----------------------------------------------------------------------
bool ObjectTableBuffer::getMoneyFromOfflineObject(uint32 replyServer, NetworkId const & sourceObject, int amount, NetworkId const & replyTo, std::string const & successCallback, std::string const & failCallback, stdvector<int8>::fwd const & packedDictionary)
{
DBSchema::ObjectBufferRow * const row=findRowByIndex(sourceObject);
if (!row)
return false;
// We might have buffered values for bank balance, cash balance, both, or neither
// We can only change the ones for which we have a value.
bool const definiteBankBalance = !row->bank_balance.isNull();
bool const definiteCashBalance = !row->cash_balance.isNull();
int const previousBankBalance = definiteBankBalance ? row->bank_balance.getValue() : 0;
int const previousCashBalance = definiteCashBalance ? row->cash_balance.getValue() : 0;
if (previousBankBalance + previousCashBalance < amount)
{
if (definiteBankBalance && definiteCashBalance)
{
// send failure message
GetMoneyFromOfflineObjectMessage replyMessage(sourceObject, amount, replyTo, successCallback, failCallback, packedDictionary, false);
DatabaseProcess::getInstance().sendToGameServer(replyServer, replyMessage);
}
else
return false; // can't be handled in memory, but there's a possibility it could be handled in the DB
}
// Has enough money to handle this in memory
int newBankBalance = previousBankBalance - amount;
int newCashBalance = previousCashBalance;
if (newBankBalance < 0)
{
int const remainingAmount = -newBankBalance;
newBankBalance = 0;
newCashBalance -= remainingAmount;
DEBUG_FATAL(newCashBalance < 0,("Programmer bug: newCashBalance ended up negative, which should not be possible. Indicates bad logic in getMoneyFromOfflineObject()"));
}
if (definiteBankBalance)
row->bank_balance=newBankBalance;
if (definiteCashBalance)
row->cash_balance=newCashBalance;
// Send success message
GetMoneyFromOfflineObjectMessage replyMessage(sourceObject, amount, replyTo, successCallback, failCallback, packedDictionary, true);
DatabaseProcess::getInstance().sendToGameServer(replyServer, replyMessage);
return true;
}
// ======================================================================
@@ -0,0 +1,78 @@
// ======================================================================
//
// ObjectTableBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ObjectTableBuffer_H
#define INCLUDED_ObjectTableBuffer_H
// ======================================================================
#include "IndexedNetworkTableBuffer.h"
#include "SwgDatabaseServer/ObjectsTableQuery.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedFoundation/Tag.h"
// ======================================================================
class NetworkId;
class UpdateObjectPositionMessage;
namespace DB
{
class Session;
}
namespace DBSchema
{
struct ObjectRow;
}
namespace ObjectTableBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace ObjectTableBufferNamespace;
// ======================================================================
class ObjectTableBuffer : public IndexedNetworkTableBuffer<DBSchema::ObjectBufferRow, DBSchema::ObjectRow, DBQuery::ObjectsTableQuery, DBQuery::ObjectsTableQuerySelect>
{
public:
explicit ObjectTableBuffer(DB::ModeQuery::Mode mode);
virtual ~ObjectTableBuffer();
// virtual void loadRow(DB::Session *session, const NetworkId &primaryKey);
virtual bool handleUpdateObjectPosition(const UpdateObjectPositionMessage &message);
void handleDeleteMessage(const NetworkId &objectId, int reasonCode, bool demandLoadedContainer, bool cascadeDeleteReason);
void decodeObjVarFreeFlags(const NetworkId &objectId, int freePositions);
int encodeObjVarFreeFlags(const NetworkId & objectId) const;
void handlePackedObjvar(const NetworkId &objectId, int position, const std::string &objvarName, int typeId, const std::string &packedValue);
void getObjvarsForObject(const NetworkId &objectId, std::vector<DynamicVariableList::MapType::Command> &commands) const;
bool getMoneyFromOfflineObject(uint32 replyServer,NetworkId const & sourceObject, int amount, NetworkId const & replyTo, std::string const & successCallback, std::string const & failCallback, stdvector<int8>::fwd const & packedDictionary);
void newObject(const NetworkId &objectId, int templateId, Tag typeId);
// std::vector<NetworkId> queueForLoadWithContents(const stdvector<NetworkId>::fwd &oidList, DB::Session *session);
void getObjectList(stdvector<NetworkId>::fwd &theList) const;
void getWorldContainers(stdvector<NetworkId>::fwd &containers) const;
void getTags(DB::TagSet &tags) const;
virtual bool save(DB::Session *session);
private:
static int roundToNode(real coordinate);
std::vector<std::pair<NetworkId,int> > m_demandLoadedContainersToDelete;
private:
ObjectTableBuffer(); // disable
};
// ======================================================================
#endif
@@ -0,0 +1,348 @@
// ======================================================================
//
// ObjvarBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "ObjvarBuffer.h"
#include "SwgDatabaseServer/ObjvarNameManager.h"
#include "serverDatabase/ConfigServerDatabase.h"
#include "serverDatabase/DatabaseProcess.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
// ======================================================================
namespace ObjvarBufferNamespace
{
const int ms_maxItemsPerExec = 10000;
}
using namespace ObjvarBufferNamespace;
// ======================================================================
ObjvarBuffer::ObjvarBuffer(DB::ModeQuery::Mode mode, ObjectTableBuffer *objectTableBuffer, bool useGoldNames) :
AbstractTableBuffer(),
m_mode(mode),
m_data(),
m_objectTableBuffer(objectTableBuffer),
m_useGoldNames(useGoldNames)
{
}
// ----------------------------------------------------------------------
ObjvarBuffer::~ObjvarBuffer()
{
}
// ----------------------------------------------------------------------
/**
* Loads all the object variables for the remembered objectId's
*/
bool ObjvarBuffer::load(DB::Session *session,const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase)
{
int rowsFetched;
UNREF(tags); // all objects have objvars
DBQuery::GetAllObjectVariables qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::ObjectVariableRow> &data = qry.getData();
for (std::vector<DBSchema::ObjectVariableRow>::const_iterator row=data.begin(); row!=data.end(); ++row)
{
if (++count > numRows)
{
break;
}
IndexKey key(row->object_id.getValue(), row->name_id.getValue());
ObjvarValue value;
value.m_type=row->type.getValue();
// The string is stored in the database as utf8, so a wide-to-narrow is appropriate
value.m_value=Unicode::wideToNarrow(row->value.getValue());
value.m_detached=false;
m_data.insert(std::make_pair(key,value));
}
}
qry.done();
if (rowsFetched < 0)
return false;
if (usingGoldDatabase)
{
// Check for local overrides to the gold data
DBQuery::GetObjectVariableOverrides qry(DatabaseProcess::getInstance().getSchemaQualifier(), schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::ObjectVariableRow> &data = qry.getData();
for (std::vector<DBSchema::ObjectVariableRow>::const_iterator row=data.begin(); row!=data.end(); ++row)
{
if (++count > numRows)
{
break;
}
IndexKey key(row->object_id.getValue(), row->name_id.getValue());
ObjvarValue value;
value.m_type=row->type.getValue();
// The string is stored in the database as utf8, so a wide-to-narrow is appropriate
value.m_value=Unicode::wideToNarrow(row->value.getValue());
value.m_detached=false;
m_overrides.insert(std::make_pair(key,value));
}
}
qry.done();
}
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
bool ObjvarBuffer::save(DB::Session *session)
{
LOG("SaveCounts",("Objvars: %i saved to db",m_data.size()));
{
DBQuery::AddObjectVariableQuery addQuery;
if (!addQuery.setupData(session))
return false;
for (DataType::iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
if (!i->second.m_detached && !i->second.m_inDatabase)
if (!addQuery.addData(i->first.m_objectId, i->first.m_nameId, i->second.m_type, i->second.m_value))
return false;
if (addQuery.getNumItems() == ObjvarBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&addQuery)))
return false;
addQuery.clearData();
}
}
if (addQuery.getNumItems() != 0)
if (! (session->exec(&addQuery)))
return false;
addQuery.done();
addQuery.freeData();
}
{
DBQuery::UpdateObjectVariableQuery updateQuery;
if (!updateQuery.setupData(session))
return false;
for (DataType::iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
if (!i->second.m_detached && i->second.m_inDatabase)
if (!updateQuery.addData(i->first.m_objectId, i->first.m_nameId, i->second.m_type, i->second.m_value))
return false;
if (updateQuery.getNumItems() == ObjvarBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&updateQuery)))
return false;
updateQuery.clearData();
}
}
if (updateQuery.getNumItems() != 0)
if (! (session->exec(&updateQuery)))
return false;
updateQuery.done();
updateQuery.freeData();
}
{
DBQuery::RemoveObjectVariableQuery removeQuery;
if (!removeQuery.setupData(session))
return false;
for (DataType::iterator i=m_data.begin(); i!=m_data.end(); ++i)
{
if (i->second.m_detached && i->second.m_inDatabase)
if (!removeQuery.addData(i->first.m_objectId, i->first.m_nameId))
return false;
if (removeQuery.getNumItems() == ObjvarBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&removeQuery)))
return false;
removeQuery.clearData();
}
}
if (removeQuery.getNumItems() != 0)
if (! (session->exec(&removeQuery)))
return false;
removeQuery.done();
removeQuery.freeData();
}
return true;
}
// ----------------------------------------------------------------------
void ObjvarBuffer::getObjvarsForObject(const NetworkId &objectId, std::vector<DynamicVariableList::MapType::Command> &commands) const
{
DynamicVariableList::MapType::Command c;
// unpacked object variables
{
for (DataType::const_iterator i= m_data.lower_bound(IndexKey(objectId,0)); (i!=m_data.end()) && (i->first.m_objectId==objectId); ++i)
{
std::string name;
bool foundName = false;
if (m_useGoldNames)
foundName=ObjvarNameManager::getGoldInstance().getName(i->first.m_nameId, name);
else
foundName=ObjvarNameManager::getInstance().getName(i->first.m_nameId, name);
if (foundName)
{
c.cmd = DynamicVariableList::MapType::Command::ADD;
c.key = name;
c.value.load(-1, i->second.m_type, Unicode::utf8ToWide(i->second.m_value));
commands.push_back(c);
}
else
WARNING_STRICT_FATAL(true,("Object %s has an objvar with name_id %i, which was not in the list of names.",objectId.getValueString().c_str(), i->first.m_nameId));
}
}
//packed object variables
m_objectTableBuffer->getObjvarsForObject(objectId, commands);
// Apply overrides, if any.
// The last objvar sent to the game takes precedence, so we want to send the overrides after the values read in through the regular process
{
for (DataType::const_iterator i= m_overrides.lower_bound(IndexKey(objectId,0)); (i!=m_overrides.end()) && (i->first.m_objectId==objectId); ++i)
{
std::string name;
bool foundName = false;
foundName=ObjvarNameManager::getInstance().getName(i->first.m_nameId, name); // overrides always use the live names, not the gold names.
if (foundName)
{
c.cmd = DynamicVariableList::MapType::Command::ADD;
c.key = name;
c.value.load(-1, i->second.m_type, Unicode::utf8ToWide(i->second.m_value));
commands.push_back(c);
}
else
WARNING_STRICT_FATAL(true,("Object %s has an objvar with name_id %i, which was not in the list of names.",objectId.getValueString().c_str(), i->first.m_nameId));
}
}
}
// ----------------------------------------------------------------------
void ObjvarBuffer::updateObjvars(const NetworkId &objectId, const std::vector<DynamicVariableList::MapType::Command> &commands)
{
bool override=false; // flag that we're dealing with the gold data override case (storing an objvar change in the live database, on an object that came from the gold database)
if (ConfigServerDatabase::getEnableGoldDatabase() && objectId < ConfigServerDatabase::getMaxGoldNetworkId())
override=true;
for (std::vector<DynamicVariableList::MapType::Command>::const_iterator i=commands.begin(); i!=commands.end(); ++i)
{
switch(i->cmd)
{
case DynamicVariableList::MapType::Command::ADD :
case DynamicVariableList::MapType::Command::SET :
{
std::string packedValue(Unicode::wideToUTF8(i->value.getPackedValueString()));
if (i->value.getPosition() !=-1 && ConfigServerDatabase::getEnableObjvarPacking() && !override)
{
m_objectTableBuffer->handlePackedObjvar(objectId, i->value.getPosition(), i->key, i->value.getType(), packedValue);
}
else
{
int nameId = ObjvarNameManager::getInstance().getOrAddNameId(i->key);
DataType::iterator row=m_data.find(IndexKey(objectId, nameId));
if (row==m_data.end())
{
row=m_data.insert(std::make_pair(IndexKey(objectId, nameId),ObjvarValue())).first;
if (i->cmd==DynamicVariableList::MapType::Command::ADD || override)
row->second.m_inDatabase=false; // new variable
else
row->second.m_inDatabase=true; // update to existing variable
}
row->second.m_type = i->value.getType();
row->second.m_value = packedValue;
row->second.m_detached = false;
}
break;
}
case DynamicVariableList::MapType::Command::ERASE :
{
int nameId = ObjvarNameManager::getInstance().getNameId(i->key);
if (nameId != 0) // It's possible to get an ERASE for a packed objvar where the name was never used in the OBJECT_VARIABLES table. We can safely ignore these.
{
DataType::iterator row=m_data.find(IndexKey(objectId, nameId));
if (row==m_data.end())
{
if (i->value.getPosition() == -1 || override)
{
row=m_data.insert(std::make_pair(IndexKey(objectId, nameId),ObjvarValue())).first;
row->second.m_inDatabase=true; // deleting existing variable
}
// else it was a packed objvar, and no update is necessary
}
row->second.m_type = i->value.getType();
row->second.m_detached = true;
}
break;
}
default:
WARNING_STRICT_FATAL(true,("Unknown command %i unpacked in object variables for object %s.",i->cmd,objectId.getValueString().c_str()));
}
}
DEBUG_WARNING(commands.size() > 100,("Object %s has a suspicious number of objvar updates (%i updates).",objectId.getValueString().c_str(),commands.size()));
}
// ----------------------------------------------------------------------
void ObjvarBuffer::removeObject(const NetworkId &object)
{
DataType::iterator i=m_data.lower_bound(IndexKey(object,0));
while (i!=m_data.end() && i->first.m_objectId==object)
{
DataType::iterator next=i;
++next;
m_data.erase(i);
i=next;
}
}
// ======================================================================
@@ -0,0 +1,122 @@
// ======================================================================
//
// ObjvarBuffer.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_ObjvarBuffer_H
#define INCLUDED_ObjvarBuffer_H
// ======================================================================
#include "SwgDatabaseServer/ObjectTableBuffer.h"
#include "SwgDatabaseServer/ObjectVariableQueries.h"
#include "serverDatabase/AbstractTableBuffer.h"
#include "sharedFoundation/DynamicVariableList.h"
#include <map>
#include <string>
// ======================================================================
class ObjectTableBuffer;
namespace DBSchema
{
struct ObjvarRow;
}
// ======================================================================
/**
* ObjvarBuffer is a table buffer customized to the job of loading and
* saving object variables.
*
* Differences from standard table buffers:
*
* 1) Objvars are keyed by object_id and name
*
* 2) When loading, only the object_id is specified, and all objvars
* are loaded for that object.
*/
class ObjvarBuffer : public AbstractTableBuffer
{
public:
explicit ObjvarBuffer(DB::ModeQuery::Mode mode, ObjectTableBuffer *objectTableBuffer, bool useGoldNames);
virtual ~ObjvarBuffer(void);
virtual bool load(DB::Session *session,const DB::TagSet &tags, const std::string &schema, bool usingGoldDatabase);
virtual bool save(DB::Session *session);
virtual void removeObject(const NetworkId &object);
DBSchema::ObjectVariableRow *findRowByIndex(const NetworkId &objectId, const std::string &name);
void updateObjvars(const NetworkId &objectId, const std::vector<DynamicVariableList::MapType::Command> &commands);
void getObjvarsForObject(const NetworkId &objectId, std::vector<DynamicVariableList::MapType::Command> &commands) const;
private:
struct IndexKey
{
NetworkId m_objectId;
int m_nameId;
IndexKey(const NetworkId &objectId, int nameId);
bool operator==(const IndexKey &rhs) const;
bool operator<(const IndexKey &rhs) const;
};
struct ObjvarValue
{
int m_type;
std::string m_value;
bool m_detached;
bool m_inDatabase;
};
typedef std::map<IndexKey,ObjvarValue> DataType;
DB::ModeQuery::Mode m_mode;
DataType m_data;
DataType m_overrides;
ObjectTableBuffer *m_objectTableBuffer;
bool m_useGoldNames;
// typedef std::map<NetworkId,std::vector<DBSchema::ObjectVariableRow*> > LoadIndexType;
// LoadIndexType m_loadIndex;
private:
ObjvarBuffer(); //disable
ObjvarBuffer(const ObjvarBuffer&); //disable
ObjvarBuffer & operator=(const ObjvarBuffer&); //disable
}; //lint !e1712 // IndexKey has no default constructor
// ======================================================================
inline ObjvarBuffer::IndexKey::IndexKey(const NetworkId &objectId, int nameId) :
m_objectId(objectId),
m_nameId(nameId)
{
}
// ----------------------------------------------------------------------
inline bool ObjvarBuffer::IndexKey::operator==(const IndexKey &rhs) const
{
return ((m_objectId == rhs.m_objectId) && (m_nameId == rhs.m_nameId));
}
// ----------------------------------------------------------------------
inline bool ObjvarBuffer::IndexKey::operator<(const IndexKey &rhs) const
{
if (m_objectId < rhs.m_objectId)
return true;
else if (m_objectId == rhs.m_objectId)
return (m_nameId < rhs.m_nameId);
else
return false;
}
// ======================================================================
#endif
@@ -0,0 +1,263 @@
// ======================================================================
//
// PropertyListBuffer.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "SwgDatabaseServer/FirstSwgDatabaseServer.h"
#include "PropertyListBuffer.h"
#include "SwgDatabaseServer/PropertyListQuery.h"
#include "sharedDatabaseInterface/DbSession.h"
#include "sharedLog/Log.h"
// ======================================================================
using namespace PropertyListBufferNamespace;
// ======================================================================
PropertyListBuffer::PropertyListBuffer(DB::ModeQuery::Mode mode) :
TableBuffer<DBSchema::PropertyListQueryData, DBQuery::PropertyListQuery>(mode),
m_loadData()
{
}
// ----------------------------------------------------------------------
PropertyListBuffer::~PropertyListBuffer(void)
{
}
// ----------------------------------------------------------------------
void PropertyListBuffer::insertProperty(const NetworkId &objectId, int listId, const std::string &value)
{
PropertyListEntry entry(objectId, listId, value);
m_adds.insert(entry);
m_deletes.erase(entry); // if this add cancels out a previous delete, don't save the delete
}
// ----------------------------------------------------------------------
void PropertyListBuffer::deleteProperty(const NetworkId &objectId, int listId, const std::string &value)
{
PropertyListEntry entry(objectId, listId, value);
m_deletes.insert(entry);
m_adds.erase(entry); // if this delete cancels out a previous add, don't save the add
}
// ----------------------------------------------------------------------
void PropertyListBuffer::clearProperties(const NetworkId &objectId, int listId)
{
static const std::string emptyString;
PropertyListEntry entry(objectId, listId, emptyString);
// erase any changes we saved for this object & list previously. For each set, find the range
// of entries corresponding to this object & list, then erase them
PropertyListSet::iterator startOfRange = m_deletes.lower_bound(entry);
PropertyListSet::iterator endOfRange;
for (endOfRange = startOfRange;
endOfRange!=m_deletes.end() && endOfRange->m_objectId == objectId && endOfRange->m_listId == listId;
++endOfRange)
;
m_deletes.erase(startOfRange, endOfRange);
startOfRange = m_adds.lower_bound(entry);
for (endOfRange = startOfRange;
endOfRange!=m_adds.end() && endOfRange->m_objectId == objectId && endOfRange->m_listId == listId;
++endOfRange)
;
m_adds.erase(startOfRange, endOfRange);
m_clears.insert(entry);
}
// ----------------------------------------------------------------------
/**
* Get all the commands for a particular object and value type.
*/
bool PropertyListBuffer::getPropertyListForObject(const NetworkId &objectId, int listId, std::set<std::string> &values) const
{
static const std::string emptyString;
DEBUG_FATAL(!values.empty(),("Values vector should be empty on call to getPropertyListsForObject()\n"));
// The data is ordered by object id then by list id, so start with the first entry matching the object id and list id.
// Return all the entries in sequence until we move to the next list or the next object
for (PropertyListSet::const_iterator i = m_loadData.lower_bound(PropertyListEntry(objectId, listId, emptyString));
i!=m_loadData.end() && i->m_objectId == objectId && i->m_listId == listId;
++i)
{
values.insert(i->m_value);
}
return true;
}
// ----------------------------------------------------------------------
bool PropertyListBuffer::load(DB::Session *session, const DB::TagSet &tags, const std::string &schema, bool)
{
int rowsFetched;
UNREF(tags);
DBQuery::GetAllPropertyLists qry(schema);
if (! (session->exec(&qry)))
return false;
while ((rowsFetched = qry.fetch()) > 0)
{
size_t numRows = qry.getNumRowsFetched();
size_t count = 0;
const std::vector<DBSchema::PropertyListQueryData> &data = qry.getData();
for (std::vector<DBSchema::PropertyListQueryData>::const_iterator i=data.begin(); i!=data.end(); ++i)
{
if (++count > numRows)
break;
const DBSchema::PropertyListQueryData &row=*i;
m_loadData.insert(PropertyListEntry(row.object_id.getValue(), row.list_id.getValue(), row.value.getValueASCII()));
}
}
qry.done();
return (rowsFetched >= 0);
}
// ----------------------------------------------------------------------
bool PropertyListBuffer::save(DB::Session *session)
{
DBQuery::PropertyListQuery qry_ot_CLEAR;
DBQuery::PropertyListQuery qry_ot_DELETE;
DBQuery::PropertyListQuery qry_ot_INSERT;
int actualSaves=0;
if (!qry_ot_DELETE.setupData(session)) return false;
if (!qry_ot_INSERT.setupData(session)) return false;
if (!qry_ot_CLEAR.setupData(session)) return false;
// Clears must be done first, so that we don't clear something we were trying to add
{
for (PropertyListSet::const_iterator i=m_clears.begin(); i!=m_clears.end(); ++i)
{
if (m_cancelledObjects.find(i->m_objectId) == m_cancelledObjects.end())
{
++actualSaves;
if (!qry_ot_CLEAR.addData(i->m_objectId, i->m_listId, i->m_value, DBSchema::PropertyListQueryData::ot_CLEAR))
return false;
if (qry_ot_CLEAR.getNumItems() == PropertyListBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry_ot_CLEAR)))
return false;
qry_ot_CLEAR.clearData();
}
}
}
if (qry_ot_CLEAR.getNumItems() != 0)
{
if (! (session->exec(&qry_ot_CLEAR)))
return false;
}
qry_ot_CLEAR.done();
qry_ot_CLEAR.freeData();
}
{
for (PropertyListSet::const_iterator i=m_adds.begin(); i!=m_adds.end(); ++i)
{
if (m_cancelledObjects.find(i->m_objectId) == m_cancelledObjects.end())
{
++actualSaves;
if (!qry_ot_INSERT.addData(i->m_objectId, i->m_listId, i->m_value, DBSchema::PropertyListQueryData::ot_INSERT))
return false;
if (qry_ot_INSERT.getNumItems() == PropertyListBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry_ot_INSERT)))
return false;
qry_ot_INSERT.clearData();
}
}
}
if (qry_ot_INSERT.getNumItems() != 0)
{
if (! (session->exec(&qry_ot_INSERT)))
return false;
}
qry_ot_INSERT.done();
qry_ot_INSERT.freeData();
}
{
for (PropertyListSet::const_iterator i=m_deletes.begin(); i!=m_deletes.end(); ++i)
{
if (m_cancelledObjects.find(i->m_objectId) == m_cancelledObjects.end())
{
++actualSaves;
if (!qry_ot_DELETE.addData(i->m_objectId, i->m_listId, i->m_value, DBSchema::PropertyListQueryData::ot_DELETE))
return false;
if (qry_ot_DELETE.getNumItems() == PropertyListBufferNamespace::ms_maxItemsPerExec)
{
if (! (session->exec(&qry_ot_DELETE)))
return false;
qry_ot_DELETE.clearData();
}
}
}
if (qry_ot_DELETE.getNumItems() != 0)
{
if (! (session->exec(&qry_ot_DELETE)))
return false;
}
qry_ot_DELETE.done();
qry_ot_DELETE.freeData();
}
LOG("SaveCounts",("PropertyList updates: %i (out of %i) saved to db",actualSaves, m_rows.size()));
return true;
}
// ----------------------------------------------------------------------
void PropertyListBuffer::removeObject(const NetworkId &object)
{
m_cancelledObjects.insert(object);
}
// ======================================================================
PropertyListBuffer::PropertyListEntry::PropertyListEntry() :
m_objectId(),
m_listId(0),
m_value()
{
}
// ----------------------------------------------------------------------
PropertyListBuffer::PropertyListEntry::PropertyListEntry(const PropertyListBuffer::PropertyListEntry & rhs) :
m_objectId(rhs.m_objectId),
m_listId(rhs.m_listId),
m_value(rhs.m_value)
{
}
// ----------------------------------------------------------------------
PropertyListBuffer::PropertyListEntry & PropertyListBuffer::PropertyListEntry::operator=(const PropertyListBuffer::PropertyListEntry & rhs)
{
m_objectId=rhs.m_objectId;
m_listId=rhs.m_listId;
m_value=rhs.m_value;
return *this;
}
// ======================================================================

Some files were not shown because too many files have changed in this diff Show More