Skip to content

Commit f966d34

Browse files
committed
feat: Add replay archive feature
1 parent 9ba92fa commit f966d34

File tree

12 files changed

+120
-0
lines changed

12 files changed

+120
-0
lines changed

Generals/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -392,6 +392,7 @@ class GlobalData : public SubsystemInterface
392392
smaller area within the rectangle to order the gather. */
393393

394394
Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu
395+
Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording
395396
Bool m_languageFilterPref; ///< Bool if user wants to filter language
396397
Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie
397398
Bool m_disableRender; ///< if true, no rendering!

Generals/Code/GameEngine/Include/Common/Recorder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class RecorderClass : public SubsystemInterface {
119119
void initControls(); ///< Show or Hide the Replay controls
120120

121121
AsciiString getReplayDir(); ///< Returns the directory that holds the replay files.
122+
AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files.
122123
static AsciiString getReplayExtention(); ///< Returns the file extention for replay files.
123124
AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay.
124125

@@ -137,6 +138,7 @@ class RecorderClass : public SubsystemInterface {
137138
protected:
138139
void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file.
139140
void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file.
141+
void archiveReplay(AsciiString fileName); ///< Move the specified replay file to the archive directory.
140142

141143
void logGameStart(AsciiString options);
142144
void logGameEnd( void );

Generals/Code/GameEngine/Include/Common/UserPreferences.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class OptionPreferences : public UserPreferences
9191
void setOnlineIPAddress(AsciiString IP); // convenience function
9292
void setLANIPAddress(UnsignedInt IP); // convenience function
9393
void setOnlineIPAddress(UnsignedInt IP); // convenience function
94+
Bool getArchiveReplaysEnabled(); // convenience function
9495
Bool getAlternateMouseModeEnabled(void); // convenience function
9596
Real getScrollFactor(void); // convenience function
9697
Bool getDrawScrollAnchor(void);

Generals/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,7 @@ GlobalData::GlobalData()
920920
m_standardPublicBones.clear();
921921

922922
m_antiAliasBoxValue = 0;
923+
m_archiveReplays = false;
923924

924925
// m_languageFilterPref = false;
925926
m_languageFilterPref = true;
@@ -1173,6 +1174,7 @@ void GlobalData::parseGameDataDefinition( INI* ini )
11731174

11741175
// override INI values with user preferences
11751176
OptionPreferences optionPref;
1177+
TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled();
11761178
TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled();
11771179
TheWritableGlobalData->m_keyboardScrollFactor = optionPref.getScrollFactor();
11781180
TheWritableGlobalData->m_drawScrollAnchor = optionPref.getDrawScrollAnchor();

Generals/Code/GameEngine/Source/Common/Recorder.cpp

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -726,10 +726,40 @@ void RecorderClass::stopRecording() {
726726
if (m_file != NULL) {
727727
m_file->close();
728728
m_file = NULL;
729+
730+
if (TheGlobalData->m_archiveReplays)
731+
archiveReplay(m_fileName);
729732
}
730733
m_fileName.clear();
731734
}
732735

736+
/**
737+
* Copy the replay file to the archive directory and rename it using the current timestamp.
738+
*/
739+
void RecorderClass::archiveReplay(AsciiString fileName)
740+
{
741+
SYSTEMTIME st;
742+
GetLocalTime(&st);
743+
744+
AsciiString archiveFileName;
745+
// Use a standard YYYYMMDD_HHMMSS format for simplicity and to avoid conflicts.
746+
archiveFileName.format("%04d%02d%02d_%02d%02d%02d", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
747+
748+
AsciiString sourcePath = getReplayDir();
749+
sourcePath.concat(fileName);
750+
751+
if (!sourcePath.endsWith(getReplayExtention()))
752+
sourcePath.concat(getReplayExtention());
753+
754+
AsciiString destPath = getReplayArchiveDir();
755+
destPath.concat(archiveFileName);
756+
destPath.concat(getReplayExtention());
757+
758+
TheFileSystem->createDirectory(getReplayArchiveDir().str());
759+
if (!CopyFile(sourcePath.str(), destPath.str(), FALSE))
760+
DEBUG_LOG(("RecorderClass::archiveReplay: Failed to copy %s to %s", sourcePath.str(), destPath.str()));
761+
}
762+
733763
/**
734764
* Write this game message to the record file. This also writes the game message's execution frame.
735765
*/
@@ -1602,6 +1632,18 @@ AsciiString RecorderClass::getReplayDir()
16021632
return tmp;
16031633
}
16041634

1635+
/**
1636+
* returns the directory that holds the archived replay files.
1637+
*/
1638+
AsciiString RecorderClass::getReplayArchiveDir()
1639+
{
1640+
const char* replayDir = "ArchivedReplays\\";
1641+
1642+
AsciiString tmp = TheGlobalData->getPath_UserData();
1643+
tmp.concat(replayDir);
1644+
return tmp;
1645+
}
1646+
16051647
/**
16061648
* returns the file extention for the replay files.
16071649
*/

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/OptionsMenu.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,6 +310,18 @@ void OptionPreferences::setOnlineIPAddress( UnsignedInt IP )
310310
(*this)["GameSpyIPAddress"] = tmp;
311311
}
312312

313+
Bool OptionPreferences::getArchiveReplaysEnabled()
314+
{
315+
OptionPreferences::const_iterator it = find("ArchiveReplays");
316+
if (it == end())
317+
return TheGlobalData->m_archiveReplays;
318+
319+
if (stricmp(it->second.str(), "yes") == 0) {
320+
return TRUE;
321+
}
322+
return FALSE;
323+
}
324+
313325
Bool OptionPreferences::getAlternateMouseModeEnabled(void)
314326
{
315327
OptionPreferences::const_iterator it = find("UseAlternateMouse");

GeneralsMD/Code/GameEngine/Include/Common/GlobalData.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,7 @@ class GlobalData : public SubsystemInterface
400400
smaller area within the rectangle to order the gather. */
401401

402402
Int m_antiAliasBoxValue; ///< value of selected antialias from combo box in options menu
403+
Bool m_archiveReplays; ///< if true, each replay is archived to the replay archive folder after recording
403404
Bool m_languageFilterPref; ///< Bool if user wants to filter language
404405
Bool m_loadScreenDemo; ///< Bool if true, run the loadscreen demo movie
405406
Bool m_disableRender; ///< if true, no rendering!

GeneralsMD/Code/GameEngine/Include/Common/Recorder.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class RecorderClass : public SubsystemInterface {
119119
void initControls(); ///< Show or Hide the Replay controls
120120

121121
AsciiString getReplayDir(); ///< Returns the directory that holds the replay files.
122+
AsciiString getReplayArchiveDir(); ///< Returns the directory that holds the archived replay files.
122123
static AsciiString getReplayExtention(); ///< Returns the file extention for replay files.
123124
AsciiString getLastReplayFileName(); ///< Returns the filename used for the default replay.
124125

@@ -137,6 +138,7 @@ class RecorderClass : public SubsystemInterface {
137138
protected:
138139
void startRecording(GameDifficulty diff, Int originalGameMode, Int rankPoints, Int maxFPS); ///< Start recording to m_file.
139140
void writeToFile(GameMessage *msg); ///< Write this GameMessage to m_file.
141+
void archiveReplay(AsciiString fileName); ///< Move the specified replay file to the archive directory.
140142

141143
void logGameStart(AsciiString options);
142144
void logGameEnd( void );

GeneralsMD/Code/GameEngine/Include/Common/UserPreferences.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ class OptionPreferences : public UserPreferences
9292
void setOnlineIPAddress(AsciiString IP); // convenience function
9393
void setLANIPAddress(UnsignedInt IP); // convenience function
9494
void setOnlineIPAddress(UnsignedInt IP); // convenience function
95+
Bool getArchiveReplaysEnabled(); // convenience function
9596
Bool getAlternateMouseModeEnabled(void); // convenience function
9697
Bool getRetaliationModeEnabled(); // convenience function
9798
Bool getDoubleClickAttackMoveEnabled(void); // convenience function

GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -929,6 +929,7 @@ GlobalData::GlobalData()
929929
m_standardPublicBones.clear();
930930

931931
m_antiAliasBoxValue = 0;
932+
m_archiveReplays = false;
932933

933934
// m_languageFilterPref = false;
934935
m_languageFilterPref = true;
@@ -1199,6 +1200,7 @@ void GlobalData::parseGameDataDefinition( INI* ini )
11991200

12001201
// override INI values with user preferences
12011202
OptionPreferences optionPref;
1203+
TheWritableGlobalData->m_archiveReplays = optionPref.getArchiveReplaysEnabled();
12021204
TheWritableGlobalData->m_useAlternateMouse = optionPref.getAlternateMouseModeEnabled();
12031205
TheWritableGlobalData->m_clientRetaliationModeEnabled = optionPref.getRetaliationModeEnabled();
12041206
TheWritableGlobalData->m_doubleClickAttackMove = optionPref.getDoubleClickAttackMoveEnabled();

0 commit comments

Comments
 (0)