/*==LICENSE==* CyanWorlds.com Engine - MMOG client, server and tools Copyright (C) 2011 Cyan Worlds, Inc. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . You can contact Cyan Worlds, Inc. by email legal@cyan.com or by snail mail at: Cyan Worlds, Inc. 14617 N Newport Hwy Mead, WA 99021 *==LICENSE==*/ #ifndef plNetClientRecorder_h_inc #define plNetClientRecorder_h_inc #include "hsTypes.h" class hsStream; class plNetMessage; class plStatusLog; class plLinkToAgeMsg; class plAgeLoadedMsg; class hsResMgr; class plNetClientRecorder { public: class TimeWrapper { public: virtual double GetWrappedTime() = 0; }; protected: TimeWrapper *fTimeWrapper; // Puts the full path to recName in path virtual void IMakeFilename(const char* recName, char* path); public: plNetClientRecorder(TimeWrapper* timeWrapper); virtual ~plNetClientRecorder(); virtual bool BeginRecording(const char* recName) = 0;; virtual bool BeginPlayback(const char* recName) { hsAssert(false,"plNetClientRecording: Playback not supported"); return false; } // Recording functions virtual bool IsRecordableMsg(plNetMessage* msg) const; virtual void RecordMsg(plNetMessage* msg, double secs) = 0; virtual void RecordLinkMsg(plLinkToAgeMsg* linkMsg, double secs) = 0; virtual void RecordAgeLoadedMsg(plAgeLoadedMsg* ageLoadedMsg) = 0; // Playback functions double GetTime(); virtual bool IsQueueEmpty() { hsAssert(false,"plNetClientRecording: Playback not supported"); return true; } virtual plNetMessage* GetNextMessage() { hsAssert(false,"plNetClientRecording: Playback not supported"); return nil; } virtual double GetNextMessageTimeDelta() { hsAssert(false,"plNetClientRecording: Playback not supported"); return 0; } }; class plNetClientLoggingRecorder : public plNetClientRecorder { protected: double fPlaybackTimeOffset; double fNextPlaybackTime; plStatusLog* fLog; // We don't send messages when between ages bool fBetweenAges; virtual void ILogMsg(plNetMessage* msg, const char* preText="") = 0; bool IProcessRecordMsg(plNetMessage* msg, double secs); public: plNetClientLoggingRecorder(TimeWrapper* timeWrapper); ~plNetClientLoggingRecorder(); void RecordLinkMsg(plLinkToAgeMsg* linkMsg, double secs); virtual void RecordAgeLoadedMsg(plAgeLoadedMsg* ageLoadedMsg) = 0; }; // // Record the net client msgs to a file // class plNetClientStreamRecorder : public plNetClientLoggingRecorder { protected: hsStream* fRecordStream; hsResMgr* fResMgr; plNetMessage* IGetNextMessage(); virtual bool IIsValidMsg(plNetMessage* msg); void ILogMsg(plNetMessage* msg, const char* preText=""); public: plNetClientStreamRecorder(TimeWrapper* timeWrapper = nil); ~plNetClientStreamRecorder(); bool BeginRecording(const char* recName); bool BeginPlayback(const char* recName); // Recording functions void RecordMsg(plNetMessage* msg, double secs); void RecordAgeLoadedMsg(plAgeLoadedMsg* ageLoadedMsg); // Playback functions void SetResMgr(hsResMgr* resmgr) { fResMgr = resmgr; } hsResMgr* GetResMgr(); bool IsQueueEmpty(); plNetMessage* GetNextMessage(); double GetNextMessageTimeDelta(); }; class plNetClientStatsRecorder : public plNetClientLoggingRecorder { protected: void ILogMsg(plNetMessage* msg, const char* preText=""); public: plNetClientStatsRecorder(TimeWrapper* timeWrapper = nil); ~plNetClientStatsRecorder(); bool BeginRecording(const char* recName); // Recording functions void RecordMsg(plNetMessage* msg, double secs); void RecordAgeLoadedMsg(plAgeLoadedMsg* ageLoadedMsg) { }; }; class plNetClientStreamAndStatsRecorder : public plNetClientRecorder { protected: plNetClientStreamRecorder* fStreamRecorder; plNetClientStatsRecorder* fStatsRecorder; public: plNetClientStreamAndStatsRecorder(plNetClientStreamRecorder* streamrec, plNetClientStatsRecorder* statrec) : plNetClientRecorder(nil),fStreamRecorder(streamrec), fStatsRecorder(statrec) {} ~plNetClientStreamAndStatsRecorder() { delete fStreamRecorder; delete fStatsRecorder; } bool BeginRecording(const char* recName) { return fStreamRecorder->BeginRecording(recName) && fStatsRecorder->BeginRecording(recName); } bool BeginPlayback(const char* recName) { return fStreamRecorder->BeginPlayback(recName); } // Recording functions bool IsRecordableMsg(plNetMessage* msg) const { return fStreamRecorder->IsRecordableMsg(msg) || fStatsRecorder->IsRecordableMsg(msg); } void RecordMsg(plNetMessage* msg, double secs) { fStreamRecorder->RecordMsg(msg,secs); fStatsRecorder->RecordMsg(msg,secs); } void RecordLinkMsg(plLinkToAgeMsg* linkMsg, double secs) { fStreamRecorder->RecordLinkMsg(linkMsg,secs); fStatsRecorder->RecordLinkMsg(linkMsg,secs); } void RecordAgeLoadedMsg(plAgeLoadedMsg* ageLoadedMsg) { fStreamRecorder->RecordAgeLoadedMsg(ageLoadedMsg); fStatsRecorder->RecordAgeLoadedMsg(ageLoadedMsg); } // Playback functions bool IsQueueEmpty() { return fStreamRecorder->IsQueueEmpty(); } plNetMessage* GetNextMessage() { return fStreamRecorder->GetNextMessage(); } double GetNextMessageTimeDelta() { return fStreamRecorder->GetNextMessageTimeDelta(); } }; class plNetClientStressStreamRecorder : public plNetClientStreamRecorder { public: plNetClientStressStreamRecorder(TimeWrapper* timeWrapper = nil) : plNetClientStreamRecorder(timeWrapper) {} bool IsRecordableMsg(plNetMessage* msg) const; }; #endif // plNetClientRecorder_h_inc