| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts 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 <http://www.gnu.org/licenses/>.
- */
- ////////////////////////////////////////////////////////////////////////////////
- // //
- // (c) 2001-2003 Electronic Arts Inc. //
- // //
- ////////////////////////////////////////////////////////////////////////////////
- #pragma once
- #include "Common/MessageStream.h"
- #include "GameNetwork/GameInfo.h"
- /**
- * The ReplayGameInfo class holds information about the replay game and
- * the contents of its slot list for reconstructing multiplayer games.
- */
- class ReplayGameInfo : public GameInfo
- {
- private:
- GameSlot m_ReplaySlot[MAX_SLOTS];
- public:
- ReplayGameInfo()
- {
- for (Int i = 0; i< MAX_SLOTS; ++i)
- setSlotPointer(i, &m_ReplaySlot[i]);
- }
- };
- enum RecorderModeType {
- RECORDERMODETYPE_RECORD,
- RECORDERMODETYPE_PLAYBACK,
- RECORDERMODETYPE_NONE // this is a valid state to be in on the shell map, or in saved games
- };
- class CRCInfo;
- class RecorderClass : public SubsystemInterface {
- public:
- RecorderClass(); ///< Constructor.
- virtual ~RecorderClass(); ///< Destructor.
- void init(); ///< Initialize TheRecorder.
- void reset(); ///< Reset the state of TheRecorder.
- void update(); ///< General purpose update function.
- // Methods dealing with recording.
- void updateRecord(); ///< The update function for recording.
- // Methods dealing with playback.
- void updatePlayback(); ///< The update function for playing back a file.
- Bool playbackFile(AsciiString filename); ///< Starts playback of the specified file.
- Bool testVersionPlayback(AsciiString filename); ///< Returns if the playback is a valid playback file for this version or not.
- AsciiString getCurrentReplayFilename( void ); ///< valid during playback only
- void stopPlayback(); ///< Stops playback. Its fine to call this even if not playing back a file.
- #if defined _DEBUG || defined _INTERNAL
- Bool analyzeReplay( AsciiString filename );
- Bool isAnalysisInProgress( void );
- #endif
- public:
- void handleCRCMessage(UnsignedInt newCRC, Int playerIndex, Bool fromPlayback);
- protected:
- CRCInfo *m_crcInfo;
- public:
- // read in info relating to a replay, conditionally setting up m_file for playback
- struct ReplayHeader
- {
- AsciiString filename;
- Bool forPlayback;
- UnicodeString replayName;
- SYSTEMTIME timeVal;
- UnicodeString versionString;
- UnicodeString versionTimeString;
- UnsignedInt versionNumber;
- UnsignedInt exeCRC;
- UnsignedInt iniCRC;
- time_t startTime;
- time_t endTime;
- UnsignedInt frameDuration;
- Bool quitEarly;
- Bool desyncGame;
- Bool playerDiscons[MAX_SLOTS];
- AsciiString gameOptions;
- Int localPlayerIndex;
- };
- Bool readReplayHeader( ReplayHeader& header );
- RecorderModeType getMode(); ///< Returns the current operating mode.
- void initControls(); ///< Show or Hide the Replay controls
- AsciiString getReplayDir(); ///< Returns the directory that holds the replay files.
- AsciiString getReplayExtention(); ///< Returns the file extention for replay files.
- AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay.
- GameInfo *getGameInfo( void ) { return &m_gameInfo; } ///< Returns the slot list for playback game start
- Bool isMultiplayer( void ); ///< is this a multiplayer game (record OR playback)?
- Int getGameMode( void ) { return m_originalGameMode; }
- void logPlayerDisconnect(UnicodeString player, Int slot);
- void logCRCMismatch( void );
- void cleanUpReplayFile( void ); ///< after a crash, send replay/debug info to a central repository
- void stopRecording(); ///< Stop recording and close m_file.
- protected:
- void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file.
- void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file.
- void logGameStart(AsciiString options);
- void logGameEnd( void );
- AsciiString readAsciiString(); ///< Read the next string from m_file using ascii characters.
- UnicodeString readUnicodeString(); ///< Read the next string from m_file using unicode characters.
- void readNextFrame(); ///< Read the next frame number to execute a command on.
- void appendNextCommand(); ///< Read the next GameMessage and append it to TheCommandList.
- void writeArgument(GameMessageArgumentDataType type, const GameMessageArgumentType arg);
- void readArgument(GameMessageArgumentDataType type, GameMessage *msg);
- void cullBadCommands(); ///< prevent the user from giving mouse commands that he shouldn't be able to do during playback.
- FILE *m_file;
- AsciiString m_fileName;
- Int m_currentFilePosition;
- RecorderModeType m_mode;
- AsciiString m_currentReplayFilename; ///< valid during playback only
- ReplayGameInfo m_gameInfo;
- Bool m_wasDesync;
- Bool m_doingAnalysis;
- Int m_originalGameMode; // valid in replays
- UnsignedInt m_nextFrame; ///< The Frame that the next message is to be executed on. This can be -1.
- };
- extern RecorderClass *TheRecorder;
- RecorderClass *createRecorder();
|