OpenClonk
C4Record Class Reference

#include <C4Record.h>

Public Member Functions

 C4Record ()
 
 C4Record (const char *szPlaybackFile, const char *szRecordFile, const char *szTempRecFile)
 
 ~C4Record ()
 
bool IsRecording () const
 
unsigned int GetStreamingPos () const
 
const StdBufGetStreamingBuf () const
 
bool Start (bool fInitial)
 
bool Stop (StdStrBuf *pRecordName=nullptr, BYTE *pRecordSHA1=nullptr)
 
bool Rec (const C4Control &Ctrl, int iFrame)
 
bool Rec (C4PacketType eCtrlType, C4ControlPacket *pCtrl, int iFrame)
 
bool Rec (int iFrame, const StdBuf &sBuf, C4RecordChunkType eType)
 
bool AddFile (const char *szLocalFilename, const char *szAddAs, bool fDelete=false)
 
bool StartStreaming (bool fInitial)
 
void ClearStreamingBuf (unsigned int iAmount)
 
void StopStreaming ()
 
CStdFileGetLogFile ()
 

Public Attributes

int Index
 

Detailed Description

Definition at line 243 of file C4Record.h.

Constructor & Destructor Documentation

◆ C4Record() [1/2]

C4Record::C4Record ( )
default

◆ C4Record() [2/2]

C4Record::C4Record ( const char *  szPlaybackFile,
const char *  szRecordFile,
const char *  szTempRecFile 
)

◆ ~C4Record()

C4Record::~C4Record ( )
default

Member Function Documentation

◆ AddFile()

bool C4Record::AddFile ( const char *  szLocalFilename,
const char *  szAddAs,
bool  fDelete = false 
)

Definition at line 266 of file C4Record.cpp.

267 {
268  if (!fRecording) return false;
269 
270  // Streaming?
271  if (fStreaming)
272  {
273 
274  // Special stripping for streaming
275  StdCopyStrBuf szFile(szLocalFilename);
276  if (SEqualNoCase(GetExtension(szAddAs), "ocp"))
277  {
278  // Create a copy
279  MakeTempFilename(&szFile);
280  if (!CopyItem(szLocalFilename, szFile.getData()))
281  return false;
282  // Strip it
283  if (!C4Player::Strip(szFile.getData(), true))
284  return false;
285  }
286 
287  // Add to stream
288  if (!StreamFile(szFile.getData(), szAddAs))
289  return false;
290 
291  // Remove temporary file
292  if (szFile != szLocalFilename)
293  EraseItem(szFile.getData());
294  }
295 
296  // Add to record group
297  if (fDelete)
298  {
299  if (!RecordGrp.Move(szLocalFilename, szAddAs))
300  return false;
301  }
302  else
303  {
304  if (!RecordGrp.Add(szLocalFilename, szAddAs))
305  return false;
306  }
307 
308  return true;
309 }
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:213
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:833
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:118
void MakeTempFilename(char *szFilename)
Definition: StdFile.cpp:320
bool CopyItem(const char *szSource, const char *szTarget, bool fResetAttributes)
Definition: StdFile.cpp:855
bool Add(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1621
bool Move(const char *filename, const char *entry_name)
Definition: C4Group.cpp:1633
static bool Strip(const char *szFilename, bool fAggressive)
Definition: C4Player.cpp:957

References C4Group::Add(), CopyItem(), EraseItem(), StdStrBuf::getData(), GetExtension(), MakeTempFilename(), C4Group::Move(), SEqualNoCase(), and C4Player::Strip().

Referenced by C4ControlJoinPlayer::PreRec(), and C4GameControl::RecAddFile().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ClearStreamingBuf()

void C4Record::ClearStreamingBuf ( unsigned int  iAmount)

Definition at line 339 of file C4Record.cpp.

340 {
341  iStreamingPos += iAmount;
342  if (iAmount == StreamingData.getSize())
343  StreamingData.Clear();
344  else
345  {
346  StreamingData.Move(iAmount, StreamingData.getSize() - iAmount);
347  StreamingData.SetSize(StreamingData.getSize() - iAmount);
348  }
349 }
size_t getSize() const
Definition: StdBuf.h:101
void SetSize(size_t inSize)
Definition: StdBuf.h:204
void Clear()
Definition: StdBuf.h:190
void Move(size_t iFrom, size_t inSize, size_t iTo=0)
Definition: StdBuf.h:159

References StdBuf::Clear(), StdBuf::getSize(), StdBuf::Move(), and StdBuf::SetSize().

Referenced by C4Network2::StreamIn().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetLogFile()

CStdFile* C4Record::GetLogFile ( )
inline

Definition at line 278 of file C4Record.h.

278 { return &LogRec; }

Referenced by LogSilent().

Here is the caller graph for this function:

◆ GetStreamingBuf()

const StdBuf& C4Record::GetStreamingBuf ( ) const
inline

Definition at line 263 of file C4Record.h.

263 { return StreamingData; }

Referenced by C4Network2::DrawStatus(), and C4Network2::StreamIn().

Here is the caller graph for this function:

◆ GetStreamingPos()

unsigned int C4Record::GetStreamingPos ( ) const
inline

Definition at line 262 of file C4Record.h.

262 { return iStreamingPos; }

Referenced by C4Network2::DrawStatus().

Here is the caller graph for this function:

◆ IsRecording()

bool C4Record::IsRecording ( ) const
inline

Definition at line 261 of file C4Record.h.

261 { return fRecording; } // return whether Start() has been called

◆ Rec() [1/3]

bool C4Record::Rec ( C4PacketType  eCtrlType,
C4ControlPacket pCtrl,
int  iFrame 
)

Definition at line 224 of file C4Record.cpp.

225 {
226  if (!fRecording) return false;
227  // create copy
228  C4IDPacket Pkt = C4IDPacket(eCtrlType, pCtrl, false); if (!Pkt.getPkt()) return false;
229  C4ControlPacket *pCtrlCpy = static_cast<C4ControlPacket *>(Pkt.getPkt());
230  // prepare for recording
231  pCtrlCpy->PreRec(this);
232  // record it
233  return Rec(iFrame, DecompileToBuf<StdCompilerBinWrite>(Pkt), RCT_CtrlPkt);
234 }
@ RCT_CtrlPkt
Definition: C4Record.h:47
virtual void PreRec(C4Record *pRecord)
Definition: C4Control.h:50
C4PacketBase * getPkt() const
Definition: C4PacketBase.h:260
bool Rec(const C4Control &Ctrl, int iFrame)
Definition: C4Record.cpp:211

References C4IDPacket::getPkt(), C4ControlPacket::PreRec(), RCT_CtrlPkt, and Rec().

Here is the call graph for this function:

◆ Rec() [2/3]

bool C4Record::Rec ( const C4Control Ctrl,
int  iFrame 
)

Definition at line 211 of file C4Record.cpp.

212 {
213  if (!fRecording) return false;
214  // don't record empty control
215  if (!Ctrl.firstPkt()) return true;
216  // create copy
217  C4Control Cpy; Cpy.Copy(Ctrl);
218  // prepare it for record
219  Cpy.PreRec(this);
220  // record it
221  return Rec(iFrame, DecompileToBuf<StdCompilerBinWrite>(Cpy), RCT_Ctrl);
222 }
@ RCT_Ctrl
Definition: C4Record.h:46
void PreRec(C4Record *pRecord) const
Definition: C4Control.cpp:128
C4IDPacket * firstPkt() const
Definition: C4Control.h:78
void Copy(const C4Control &Ctrl)
Definition: C4Control.h:86

References C4Control::Copy(), C4Control::firstPkt(), C4Control::PreRec(), and RCT_Ctrl.

Referenced by C4GameControl::DbgRec(), C4GameControl::ExecControl(), C4GameControl::ExecControlPacket(), C4GameControl::Execute(), Rec(), and C4GameControl::StartRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Rec() [3/3]

bool C4Record::Rec ( int  iFrame,
const StdBuf sBuf,
C4RecordChunkType  eType 
)

Definition at line 236 of file C4Record.cpp.

237 {
238  // filler chunks (this should never be necessary, though)
239  while (iFrame > int(iLastFrame + 0xff))
240  Rec(iLastFrame + 0xff, StdBuf(), RCT_Frame);
241  // get frame difference
242  uint8_t iFrameDiff = std::max<uint8_t>(0, iFrame - iLastFrame);
243  iLastFrame += iFrameDiff;
244  // create head
245  C4RecordChunkHead Head = { iFrameDiff, uint8_t(eType) };
246  // pack
247  CtrlRec.Write(&Head, sizeof(Head));
248  CtrlRec.Write(sBuf.getData(), sBuf.getSize());
249 #ifdef IMMEDIATEREC
250  // immediate rec: always flush
251  CtrlRec.Flush();
252 #endif
253  // Stream
254  if (fStreaming)
255  Stream(Head, sBuf);
256  return true;
257 }
@ RCT_Frame
Definition: C4Record.h:48
bool Write(const void *pBuffer, int iSize)
Definition: CStdFile.cpp:240
bool Flush()
Definition: CStdFile.h:70
Definition: StdBuf.h:30
const void * getData() const
Definition: StdBuf.h:99

References CStdFile::Flush(), StdBuf::getData(), StdBuf::getSize(), RCT_Frame, Rec(), and CStdFile::Write().

Here is the call graph for this function:

◆ Start()

bool C4Record::Start ( bool  fInitial)

Definition at line 104 of file C4Record.cpp.

105 {
106  // no double record
107  if (fRecording) return false;
108 
109  // create demos folder
111  return false;
112 
113  // various infos
114  StdStrBuf sDemoFolder(C4CFN_Records);
116 
117  // remove trailing numbers from scenario name (e.g. from savegames) - could we perhaps use C4S.Head.Origin instead...?
118  char *pScenNameEnd = sScenName + SLen(sScenName);
119  while (Inside<char>(*--pScenNameEnd, '0', '9'))
120  if (pScenNameEnd == sScenName)
121  break;
122  pScenNameEnd[1] = 0;
123 
124  // determine index (by total number of records)
125  Index = 1;
128  Index++;
129 
130  // compose record filename
131  sFilename.Format("%s" DirSep "%03i-%s.ocs", Config.AtUserDataPath(sDemoFolder.getData()), Index, sScenName);
132 
133  // log
134  StdStrBuf sLog; sLog.Format(LoadResStr("IDS_PRC_RECORDINGTO"),sFilename.getData());
135  if (Game.FrameCounter) sLog.AppendFormat(" (Frame %d)", Game.FrameCounter);
136  Log(sLog.getData());
137 
138  // save game - this also saves player info list
139  C4GameSaveRecord saveRec(fInitial, Index, Game.Parameters.isLeague());
140  if (!saveRec.Save(sFilename.getData())) return false;
141  saveRec.Close();
142 
143  // unpack group, if neccessary
144  if ( !DirectoryExists(sFilename.getData()) &&
145  !C4Group_UnpackDirectory(sFilename.getData()) )
146  return false;
147 
148  // open control record file
149  char szCtrlRecFilename[_MAX_PATH_LEN + _MAX_FNAME];
150  sprintf(szCtrlRecFilename, "%s" DirSep C4CFN_CtrlRec, sFilename.getData());
151  if (!CtrlRec.Create(szCtrlRecFilename)) return false;
152 
153  // open log file in record
154  char szLogRecFilename[_MAX_PATH_LEN + _MAX_FNAME];
155  sprintf(szLogRecFilename, "%s" DirSep C4CFN_LogRec, sFilename.getData());
156  if (!LogRec.Create(szLogRecFilename)) return false;
157 
158  // open record group
159  if (!RecordGrp.Open(sFilename.getData()))
160  return false;
161 
162  // record go
163  fStreaming = false;
164  fRecording = true;
165  iLastFrame = 0;
166  return true;
167 }
#define C4CFN_Records
Definition: C4Components.h:36
#define C4CFN_LogRec
Definition: C4Components.h:79
#define C4CFN_CtrlRec
Definition: C4Components.h:77
#define C4CFN_ScenarioFiles
Definition: C4Components.h:175
C4Config Config
Definition: C4Config.cpp:930
C4Game Game
Definition: C4Globals.cpp:52
bool C4Group_UnpackDirectory(const char *filename)
Definition: C4Group.cpp:401
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
bool Log(const char *szMessage)
Definition: C4Log.cpp:204
#define _MAX_FNAME
#define _MAX_PATH_LEN
#define DirSep
#define _MAX_FNAME_LEN
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:152
#define sprintf
Definition: Standard.h:162
size_t SLen(const char *sptr)
Definition: Standard.h:74
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:708
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:396
const char * GetFilenameOnly(const char *strFilename)
Definition: StdFile.cpp:57
bool CreateSaveFolder(const char *directory, const char *language_title)
Definition: C4Config.cpp:636
C4ConfigGeneral General
Definition: C4Config.h:255
const char * AtUserDataPath(const char *filename)
Definition: C4Config.cpp:586
int32_t FrameCounter
Definition: C4Game.h:129
C4GameParameters & Parameters
Definition: C4Game.h:67
bool isLeague() const
const char * getFile() const
bool Open(const char *group_name, bool do_create=false)
Definition: C4Group.cpp:660
int Index
Definition: C4Record.h:259
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
Definition: CStdFile.cpp:49
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:190
const char * getData() const
Definition: StdBuf.h:442
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:174

References _MAX_FNAME, _MAX_FNAME_LEN, _MAX_PATH_LEN, StdStrBuf::AppendFormat(), C4Config::AtUserDataPath(), C4CFN_CtrlRec, C4CFN_LogRec, C4CFN_Records, C4CFN_ScenarioFiles, C4Group_UnpackDirectory(), C4GameSave::Close(), Config, CStdFile::Create(), C4ConfigGeneral::CreateSaveFolder(), DirectoryExists(), DirSep, StdStrBuf::Format(), C4Game::FrameCounter, Game, C4Config::General, StdStrBuf::getData(), C4GameRes::getFile(), GetFilenameOnly(), Index, C4GameParameters::isLeague(), LoadResStr(), Log(), C4Group::Open(), C4Game::Parameters, C4GameSave::Save(), C4GameParameters::Scenario, SCopy(), SLen(), sprintf, and WildcardMatch().

Referenced by C4GameControl::StartRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StartStreaming()

bool C4Record::StartStreaming ( bool  fInitial)

Definition at line 311 of file C4Record.cpp.

312 {
313  if (!fRecording) return false;
314  if (fStreaming) return false;
315 
316  // Get temporary file name
317  StdCopyStrBuf sTempFilename(sFilename);
318  MakeTempFilename(&sTempFilename);
319 
320  // Save start state (without copy of scenario!)
321  C4GameSaveRecord saveRec(fInitial, Index, Game.Parameters.isLeague(), false);
322  if (!saveRec.Save(sTempFilename.getData())) return false;
323  saveRec.Close();
324 
325  // Add file into stream, delete file
326  fStreaming = true;
327  if (!StreamFile(sTempFilename.getData(), sFilename.getData()))
328  {
329  fStreaming = false;
330  return false;
331  }
332 
333  // Okay
334  EraseFile(sTempFilename.getData());
335  iStreamingPos = 0;
336  return true;
337 }
bool EraseFile(const char *szFileName)

References C4GameSave::Close(), EraseFile(), Game, StdStrBuf::getData(), Index, C4GameParameters::isLeague(), MakeTempFilename(), C4Game::Parameters, and C4GameSave::Save().

Referenced by C4GameControl::StartRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Stop()

bool C4Record::Stop ( StdStrBuf pRecordName = nullptr,
BYTE pRecordSHA1 = nullptr 
)

Definition at line 169 of file C4Record.cpp.

170 {
171  // safety
172  if (!fRecording) return false;
173  if (!DirectoryExists(sFilename.getData())) return false;
174 
175  // streaming finished
176  StopStreaming();
177 
178  // save desc into record group
179  C4GameSaveRecord saveRec(false, Index, Game.Parameters.isLeague());
180  saveRec.SaveDesc(RecordGrp);
181 
182  // save end player infos into record group
184  RecordGrp.Close();
185 
186  // write last entry and close
187  C4RecordChunkHead Head;
188  Head.iFrm = 37;
189  Head.Type = RCT_End;
190  CtrlRec.Write(&Head, sizeof(Head));
191  CtrlRec.Close();
192 
193  LogRec.Close();
194 
195  // pack group
196  if (!Config.General.DebugRec)
197  if (!C4Group_PackDirectory(sFilename.getData())) return false;
198 
199  // return record data
200  if (pRecordName)
201  pRecordName->Copy(sFilename);
202  if (pRecordSHA1)
203  if (!GetFileSHA1(sFilename.getData(), pRecordSHA1))
204  return false;
205 
206  // ok
207  fRecording = false;
208  return true;
209 }
#define C4CFN_RecPlayerInfos
Definition: C4Components.h:126
bool C4Group_PackDirectory(const char *filename)
Definition: C4Group.cpp:371
@ RCT_End
Definition: C4Record.h:49
uint8_t iFrm
Definition: C4Record.h:99
bool GetFileSHA1(const char *szFilename, BYTE *pSHA1)
Definition: CStdFile.cpp:381
int32_t DebugRec
Definition: C4Config.h:63
C4PlayerInfoList & PlayerInfos
Definition: C4Game.h:71
bool Close()
Definition: C4Group.cpp:971
bool Save(C4Group &hGroup, const char *szToFile)
void StopStreaming()
Definition: C4Record.cpp:351
bool Close(StdBuf **ppMemory=nullptr)
Definition: CStdFile.cpp:151
void Copy()
Definition: StdBuf.h:467

References C4CFN_RecPlayerInfos, C4Group_PackDirectory(), C4Group::Close(), CStdFile::Close(), Config, StdStrBuf::Copy(), C4ConfigGeneral::DebugRec, DirectoryExists(), Game, C4Config::General, StdStrBuf::getData(), GetFileSHA1(), C4RecordChunkHead::iFrm, Index, C4GameParameters::isLeague(), C4Game::Parameters, C4Game::PlayerInfos, RCT_End, C4PlayerInfoList::Save(), C4GameSave::SaveDesc(), StopStreaming(), C4RecordChunkHead::Type, and CStdFile::Write().

Referenced by C4GameControl::StopRecord().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ StopStreaming()

void C4Record::StopStreaming ( )

Definition at line 351 of file C4Record.cpp.

352 {
353  fStreaming = false;
354 }

Referenced by Stop().

Here is the caller graph for this function:

Member Data Documentation

◆ Index

int C4Record::Index

Definition at line 259 of file C4Record.h.

Referenced by Start(), StartStreaming(), and Stop().


The documentation for this class was generated from the following files: