Recorder.h 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /*
  2. ** Command & Conquer Generals(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. ////////////////////////////////////////////////////////////////////////////////
  19. // //
  20. // (c) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. #pragma once
  24. #include "Common/MessageStream.h"
  25. #include "GameNetwork/GameInfo.h"
  26. /**
  27. * The ReplayGameInfo class holds information about the replay game and
  28. * the contents of its slot list for reconstructing multiplayer games.
  29. */
  30. class ReplayGameInfo : public GameInfo
  31. {
  32. private:
  33. GameSlot m_ReplaySlot[MAX_SLOTS];
  34. public:
  35. ReplayGameInfo()
  36. {
  37. for (Int i = 0; i< MAX_SLOTS; ++i)
  38. setSlotPointer(i, &m_ReplaySlot[i]);
  39. }
  40. };
  41. enum RecorderModeType {
  42. RECORDERMODETYPE_RECORD,
  43. RECORDERMODETYPE_PLAYBACK,
  44. RECORDERMODETYPE_NONE // this is a valid state to be in on the shell map, or in saved games
  45. };
  46. class CRCInfo;
  47. class RecorderClass : public SubsystemInterface {
  48. public:
  49. RecorderClass(); ///< Constructor.
  50. virtual ~RecorderClass(); ///< Destructor.
  51. void init(); ///< Initialize TheRecorder.
  52. void reset(); ///< Reset the state of TheRecorder.
  53. void update(); ///< General purpose update function.
  54. // Methods dealing with recording.
  55. void updateRecord(); ///< The update function for recording.
  56. // Methods dealing with playback.
  57. void updatePlayback(); ///< The update function for playing back a file.
  58. Bool playbackFile(AsciiString filename); ///< Starts playback of the specified file.
  59. Bool testVersionPlayback(AsciiString filename); ///< Returns if the playback is a valid playback file for this version or not.
  60. AsciiString getCurrentReplayFilename( void ); ///< valid during playback only
  61. void stopPlayback(); ///< Stops playback. Its fine to call this even if not playing back a file.
  62. #if defined _DEBUG || defined _INTERNAL
  63. Bool analyzeReplay( AsciiString filename );
  64. Bool isAnalysisInProgress( void );
  65. #endif
  66. public:
  67. void handleCRCMessage(UnsignedInt newCRC, Int playerIndex, Bool fromPlayback);
  68. protected:
  69. CRCInfo *m_crcInfo;
  70. public:
  71. // read in info relating to a replay, conditionally setting up m_file for playback
  72. struct ReplayHeader
  73. {
  74. AsciiString filename;
  75. Bool forPlayback;
  76. UnicodeString replayName;
  77. SYSTEMTIME timeVal;
  78. UnicodeString versionString;
  79. UnicodeString versionTimeString;
  80. UnsignedInt versionNumber;
  81. UnsignedInt exeCRC;
  82. UnsignedInt iniCRC;
  83. time_t startTime;
  84. time_t endTime;
  85. UnsignedInt frameDuration;
  86. Bool quitEarly;
  87. Bool desyncGame;
  88. Bool playerDiscons[MAX_SLOTS];
  89. AsciiString gameOptions;
  90. Int localPlayerIndex;
  91. };
  92. Bool readReplayHeader( ReplayHeader& header );
  93. RecorderModeType getMode(); ///< Returns the current operating mode.
  94. void initControls(); ///< Show or Hide the Replay controls
  95. AsciiString getReplayDir(); ///< Returns the directory that holds the replay files.
  96. AsciiString getReplayExtention(); ///< Returns the file extention for replay files.
  97. AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay.
  98. GameInfo *getGameInfo( void ) { return &m_gameInfo; } ///< Returns the slot list for playback game start
  99. Bool isMultiplayer( void ); ///< is this a multiplayer game (record OR playback)?
  100. Int getGameMode( void ) { return m_originalGameMode; }
  101. void logPlayerDisconnect(UnicodeString player, Int slot);
  102. void logCRCMismatch( void );
  103. void cleanUpReplayFile( void ); ///< after a crash, send replay/debug info to a central repository
  104. void stopRecording(); ///< Stop recording and close m_file.
  105. protected:
  106. void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file.
  107. void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file.
  108. void logGameStart(AsciiString options);
  109. void logGameEnd( void );
  110. AsciiString readAsciiString(); ///< Read the next string from m_file using ascii characters.
  111. UnicodeString readUnicodeString(); ///< Read the next string from m_file using unicode characters.
  112. void readNextFrame(); ///< Read the next frame number to execute a command on.
  113. void appendNextCommand(); ///< Read the next GameMessage and append it to TheCommandList.
  114. void writeArgument(GameMessageArgumentDataType type, const GameMessageArgumentType arg);
  115. void readArgument(GameMessageArgumentDataType type, GameMessage *msg);
  116. void cullBadCommands(); ///< prevent the user from giving mouse commands that he shouldn't be able to do during playback.
  117. FILE *m_file;
  118. AsciiString m_fileName;
  119. Int m_currentFilePosition;
  120. RecorderModeType m_mode;
  121. AsciiString m_currentReplayFilename; ///< valid during playback only
  122. ReplayGameInfo m_gameInfo;
  123. Bool m_wasDesync;
  124. Bool m_doingAnalysis;
  125. Int m_originalGameMode; // valid in replays
  126. UnsignedInt m_nextFrame; ///< The Frame that the next message is to be executed on. This can be -1.
  127. };
  128. extern RecorderClass *TheRecorder;
  129. RecorderClass *createRecorder();