Files
src-1.2/engine/server/library/serverDatabase/src/shared/Persister.h
T

241 lines
9.0 KiB
C++
Executable File

// ======================================================================
//
// Persister.h
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#ifndef INCLUDED_Persister_H
#define INCLUDED_Persister_H
// ======================================================================
#include <map>
#include <string>
#include <unordered_map>
#include <vector>
#include <set> //TODO: remove when we clean up newCharacterLock hack
#include "Unicode.h"
#include "serverNetworkMessages/MessageToPayload.h"
#include "sharedDatabaseInterface/DbModeQuery.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedFoundation/StationId.h"
#include "sharedFoundation/Tag.h"
#include "sharedMessageDispatch/Receiver.h"
class AddResourceTypeMessage;
class BaselinesMessage;
class BountyHunterTargetMessage;
class DeltasMessage;
class Snapshot;
class TransferAccountData;
class TransferCharacterData;
class DBCSRequestMessage;
namespace DB
{
class TaskQueue;
}
// ======================================================================
/**
* Singleton that organizes messages to be persisted to the database.
*
* For now, directs all changes to a "snapshot" object. For the future,
* may want to have a snapshot for each server so that we can do more in
* parallel. This might be implemented by having multiple instances
* of Persister.
*
* This is an abstract base class. A game-specific Persister should
* be derived from it.
*/
class Persister : public MessageDispatch::Receiver
{
public:
static Persister &getInstance();
void handleDeleteMessage (uint32 serverId, const NetworkId &objectId, int reasonCode, bool immediate, bool demandLoadedContainer, bool cascadeReason);
void handleMessageTo (uint32 sourceServer, const MessageToPayload &data);
void handleMessageToAck (uint32 sourceServer, const MessageToId &messageId);
void update(real updateTime);
void onFrameBarrierReached();
bool isIdle();
bool isSaveInProgress();
void newObject(uint32 serverId, const NetworkId &objectId, int templateId, Tag typeId, const NetworkId &container);
void beginBaselines(const NetworkId &newObject) const;
void endBaselines(const NetworkId &newObject, uint32 serverId);
void saveCompleted (Snapshot *completedSnapshot);
void onNewCharacterSaved (uint32 stationId, const NetworkId &characterObject, const Unicode::String &characterName, const int templateId, bool special) const;
void receiveMessage(const MessageDispatch::Emitter & source, const MessageDispatch::MessageBase & message);
void shutdown();
int getTimeSinceLastSave();
int getLastSaveTime();
int getLastSaveTotalObjectCount();
int getLastSaveNewObjectCount();
std::string getLastSaveCompletionTime();
void unloadCharacter(const NetworkId &characterId, uint32 sourceServer);
bool hasDataForObject(const NetworkId &objectId) const;
void renameCharacter(uint32 sourceServer, int8 renameCharacterMessageSource, uint32 stationId, const NetworkId &characterId, const Unicode::String &newName, const Unicode::String &oldName, bool lastNameChangeOnly, const NetworkId &requestedBy, const TransferCharacterData * renameRequest);
void changeStationId(const TransferAccountData * transferRequest);
void handleCSRequest( const DBCSRequestMessage & msg );
void handleCSMovePlayer( const DBCSRequestMessage & msg );
void handleCsUndelete(const NetworkId & character, const NetworkId & item, const std::string & message, bool move);
virtual void startLoadCommodities() =0;
protected:
DB::TaskQueue *taskQueue;
DB::TaskQueue *m_newCharacterTaskQueue;
private:
struct PendingCharacter
{
uint32 stationId;
Unicode::String name;
bool special;
};
typedef std::map<uint32,Snapshot*> ServerSnapshotMap;
typedef std::unordered_map<NetworkId,Snapshot*> ObjectSnapshotMap;
typedef std::map<NetworkId,PendingCharacter> PendingCharactersType;
typedef std::vector<Snapshot*> SnapshotListType;
typedef std::set<uint32> NewCharacterLockType;
typedef std::vector<std::pair<StationId, NetworkId> > CharactersToDeleteType;
ServerSnapshotMap m_currentSnapshots;
ServerSnapshotMap m_newObjectSnapshots;
ServerSnapshotMap m_newCharacterSnapshots;
ObjectSnapshotMap m_objectSnapshotMap;
PendingCharactersType m_pendingCharacters;
SnapshotListType m_savingSnapshots;
SnapshotListType m_savingCharacterSnapshots;
NewCharacterLockType m_newCharacterLock;
CharactersToDeleteType * m_charactersToDeleteThisSaveCycle;
CharactersToDeleteType * m_charactersToDeleteNextSaveCycle;
real m_timeSinceLastSave;
Snapshot * m_messageSnapshot;
Snapshot * m_commoditiesSnapshot;
Snapshot * m_arbitraryGameDataSnapshot;
int m_saveStartTime;
int m_totalSaveTime;
int m_maxSaveTime;
int m_saveCount;
int m_newObjectCount;
int m_lastSaveTime;
int m_lastSaveTotalObjectCount;
int m_lastSaveNewObjectCount;
std::string m_lastSaveCompletionTime;
int m_saveCounter;
bool m_startSaveWhenPossible;
bool m_inMagicMinute;
bool m_clusterShuttingDown;
protected:
virtual void startSave() = 0;
Snapshot *getSnapshotForObject(const NetworkId &networkId, uint32 serverId);
Snapshot *getSnapshotForServer(uint32 serverId);
private:
void handleDeltasMessage (uint32 serverId, const DeltasMessage &msg);
void handleBaselinesMessage (uint32 serverId, const BaselinesMessage &msg);
void handleAddResourceTypeMessage(uint32 const serverId, AddResourceTypeMessage const & message);
void handlePurgeCompleteMessage(uint32 const serverId, StationId stationId);
void addCharacter (uint32 stationId, const NetworkId &characterObject, uint32 creationGameServer, const Unicode::String &name, bool special);
void deleteCharacter (StationId stationId, const NetworkId &characterId);
void recordMoneyTransaction (uint32 sourceServer, const NetworkId &transactionId, const int transactionType, const NetworkId &sourceId, const std::string &sourceString, const NetworkId &targetId, const std::string &targetString, int amount);
void moveToPlayer (uint32 sourceServer, const NetworkId &objectId, const NetworkId &targetPlayer, int maxDepth, bool useBank, bool useDatapad);
void fixLoadWith (uint32 sourceServer, const NetworkId &topmostObject, const NetworkId &startingLoadWith, int maxDepth);
void moveToContainer (uint32 sourceServer, NetworkId const & objectId, NetworkId const & targetContainer);
void userRequestedSave (uint32 sourceGameServer, const NetworkId &whoRequested);
void centralRequestedSave ();
void planetRequestedSave ();
Snapshot *getCommoditiesSnapshot(uint32 serverId);
/**
* Derived class should override this to make a game-specific derived Snapshot.
*/
virtual Snapshot *makeSnapshot(DB::ModeQuery::Mode mode) const =0;
virtual Snapshot *makeCommoditiesSnapshot(DB::ModeQuery::Mode mode) const =0;
/**
* Admin functions
*/
virtual void restoreHouse(const NetworkId &houseId, const std::string &whoRequested)=0;
virtual void restoreCharacter(const NetworkId &characterId, const std::string &whoRequested)=0;
virtual void undeleteItem(const NetworkId &itemId, const std::string &whoRequested)=0;
virtual void moveToPlayer(const NetworkId &oid, const NetworkId &player, const std::string &whoRequested)=0;
/**
* Misc game-specific persistence steps
*/
virtual void getMoneyFromOfflineObject(uint32 replyServer, NetworkId const & sourceObject, int amount, NetworkId const & replyTo, std::string const & successCallback, std::string const & failCallback, std::vector<int8> const & packedDictionary)=0;
protected:
Persister();
virtual ~Persister();
static void installDerived(Persister *derivedInstance);
private:
Persister(const Persister&); //disable
Persister &operator=(const Persister&); //disable
private:
static void remove();
static Persister *ms_instance;
};
// ----------------------------------------------------------------------
inline Persister &Persister::getInstance()
{
NOT_NULL(ms_instance);
return *ms_instance;
}
// ----------------------------------------------------------------------
inline int Persister::getTimeSinceLastSave()
{
return static_cast<int>(m_timeSinceLastSave);
}
// ----------------------------------------------------------------------
inline int Persister::getLastSaveTime()
{
return m_lastSaveTime;
}
// ----------------------------------------------------------------------
inline int Persister::getLastSaveTotalObjectCount()
{
return m_lastSaveTotalObjectCount;
}
// ----------------------------------------------------------------------
inline int Persister::getLastSaveNewObjectCount()
{
return m_lastSaveNewObjectCount;
}
// ======================================================================
#endif