OpenClonk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros
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::C4Record ( )

Definition at line 104 of file C4Record.cpp.

105  : fRecording(false), fStreaming(false)
106 {
107 }
C4Record::C4Record ( const char *  szPlaybackFile,
const char *  szRecordFile,
const char *  szTempRecFile 
)
C4Record::~C4Record ( )

Definition at line 109 of file C4Record.cpp.

110 {
111 }

Member Function Documentation

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

Definition at line 275 of file C4Record.cpp.

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

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

276 {
277  if (!fRecording) return false;
278 
279  // Streaming?
280  if (fStreaming)
281  {
282 
283  // Special stripping for streaming
284  StdCopyStrBuf szFile(szLocalFilename);
285  if (SEqualNoCase(GetExtension(szAddAs), "ocp"))
286  {
287  // Create a copy
288  MakeTempFilename(&szFile);
289  if (!CopyItem(szLocalFilename, szFile.getData()))
290  return false;
291  // Strip it
292  if (!C4Player::Strip(szFile.getData(), true))
293  return false;
294  }
295 
296  // Add to stream
297  if (!StreamFile(szFile.getData(), szAddAs))
298  return false;
299 
300  // Remove temporary file
301  if (szFile != szLocalFilename)
302  EraseItem(szFile.getData());
303  }
304 
305  // Add to record group
306  if (fDelete)
307  {
308  if (!RecordGrp.Move(szLocalFilename, szAddAs))
309  return false;
310  }
311  else
312  {
313  if (!RecordGrp.Add(szLocalFilename, szAddAs))
314  return false;
315  }
316 
317  return true;
318 }
bool CopyItem(const char *szSource, const char *szTarget, bool fResetAttributes)
Definition: StdFile.cpp:841
bool SEqualNoCase(const char *szStr1, const char *szStr2, int iLen)
Definition: Standard.cpp:184
static bool Strip(const char *szFilename, bool fAggressive)
Definition: C4Player.cpp:959
bool Move(const char *szFile, const char *szAddAs)
Definition: C4Group.cpp:1325
char * GetExtension(char *szFilename)
Definition: StdFile.cpp:131
bool EraseItem(const char *szItemName)
Definition: StdFile.cpp:819
bool Add(const char *szFile, const char *szAddAs)
Definition: C4Group.cpp:1316
void MakeTempFilename(char *szFilename)
Definition: StdFile.cpp:333

Here is the call graph for this function:

Here is the caller graph for this function:

void C4Record::ClearStreamingBuf ( unsigned int  iAmount)

Definition at line 348 of file C4Record.cpp.

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

Referenced by C4Network2::StreamIn().

349 {
350  iStreamingPos += iAmount;
351  if (iAmount == StreamingData.getSize())
352  StreamingData.Clear();
353  else
354  {
355  StreamingData.Move(iAmount, StreamingData.getSize() - iAmount);
356  StreamingData.SetSize(StreamingData.getSize() - iAmount);
357  }
358 }
void Clear()
Definition: StdBuf.h:198
size_t getSize() const
Definition: StdBuf.h:109
void SetSize(size_t inSize)
Definition: StdBuf.h:212
void Move(size_t iFrom, size_t inSize, size_t iTo=0)
Definition: StdBuf.h:167

Here is the call graph for this function:

Here is the caller graph for this function:

CStdFile* C4Record::GetLogFile ( )
inline

Definition at line 278 of file C4Record.h.

Referenced by LogSilent().

278 { return &LogRec; }

Here is the caller graph for this function:

const StdBuf& C4Record::GetStreamingBuf ( ) const
inline

Definition at line 263 of file C4Record.h.

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

263 { return StreamingData; }

Here is the caller graph for this function:

unsigned int C4Record::GetStreamingPos ( ) const
inline

Definition at line 262 of file C4Record.h.

Referenced by C4Network2::DrawStatus().

262 { return iStreamingPos; }

Here is the caller graph for this function:

bool C4Record::IsRecording ( ) const
inline

Definition at line 261 of file C4Record.h.

261 { return fRecording; } // return whether Start() has been called
bool C4Record::Rec ( const C4Control Ctrl,
int  iFrame 
)

Definition at line 220 of file C4Record.cpp.

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

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

221 {
222  if (!fRecording) return false;
223  // don't record empty control
224  if (!Ctrl.firstPkt()) return true;
225  // create copy
226  C4Control Cpy; Cpy.Copy(Ctrl);
227  // prepare it for record
228  Cpy.PreRec(this);
229  // record it
230  return Rec(iFrame, DecompileToBuf<StdCompilerBinWrite>(Cpy), RCT_Ctrl);
231 }
C4IDPacket * firstPkt() const
Definition: C4Control.h:78
void PreRec(C4Record *pRecord) const
Definition: C4Control.cpp:138
bool Rec(const C4Control &Ctrl, int iFrame)
Definition: C4Record.cpp:220
void Copy(const C4Control &Ctrl)
Definition: C4Control.h:86

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 233 of file C4Record.cpp.

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

234 {
235  if (!fRecording) return false;
236  // create copy
237  C4IDPacket Pkt = C4IDPacket(eCtrlType, pCtrl, false); if (!Pkt.getPkt()) return false;
238  C4ControlPacket *pCtrlCpy = static_cast<C4ControlPacket *>(Pkt.getPkt());
239  // prepare for recording
240  pCtrlCpy->PreRec(this);
241  // record it
242  return Rec(iFrame, DecompileToBuf<StdCompilerBinWrite>(Pkt), RCT_CtrlPkt);
243 }
bool Rec(const C4Control &Ctrl, int iFrame)
Definition: C4Record.cpp:220
virtual void PreRec(C4Record *pRecord)
Definition: C4Control.h:50
C4PacketBase * getPkt() const
Definition: C4PacketBase.h:255

Here is the call graph for this function:

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

Definition at line 245 of file C4Record.cpp.

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

246 {
247  // filler chunks (this should never be necessary, though)
248  while (iFrame > int(iLastFrame + 0xff))
249  Rec(iLastFrame + 0xff, StdBuf(), RCT_Frame);
250  // get frame difference
251  uint8_t iFrameDiff = std::max<uint8_t>(0, iFrame - iLastFrame);
252  iLastFrame += iFrameDiff;
253  // create head
254  C4RecordChunkHead Head = { iFrameDiff, uint8_t(eType) };
255  // pack
256  CtrlRec.Write(&Head, sizeof(Head));
257  CtrlRec.Write(sBuf.getData(), sBuf.getSize());
258 #ifdef IMMEDIATEREC
259  // immediate rec: always flush
260  CtrlRec.Flush();
261 #endif
262  // Stream
263  if (fStreaming)
264  Stream(Head, sBuf);
265  return true;
266 }
const void * getData() const
Definition: StdBuf.h:107
Definition: StdBuf.h:37
bool Rec(const C4Control &Ctrl, int iFrame)
Definition: C4Record.cpp:220
size_t getSize() const
Definition: StdBuf.h:109
bool Write(const void *pBuffer, int iSize)
Definition: CStdFile.cpp:244
bool Flush()
Definition: CStdFile.h:71

Here is the call graph for this function:

bool C4Record::Start ( bool  fInitial)

Definition at line 113 of file C4Record.cpp.

References _MAX_FNAME, _MAX_PATH, 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, C4GameParameters::Scenario, SCopy(), SLen(), sprintf, and WildcardMatch().

Referenced by C4GameControl::StartRecord().

114 {
115  // no double record
116  if (fRecording) return false;
117 
118  // create demos folder
120  return false;
121 
122  // various infos
123  StdStrBuf sDemoFolder(C4CFN_Records);
124  char sScenName[_MAX_FNAME+ 1]; SCopy(GetFilenameOnly(Game.Parameters.Scenario.getFile()), sScenName, _MAX_FNAME);
125 
126  // remove trailing numbers from scenario name (e.g. from savegames) - could we perhaps use C4S.Head.Origin instead...?
127  char *pScenNameEnd = sScenName + SLen(sScenName);
128  while (Inside<char>(*--pScenNameEnd, '0', '9'))
129  if (pScenNameEnd == sScenName)
130  break;
131  pScenNameEnd[1] = 0;
132 
133  // determine index (by total number of records)
134  Index = 1;
137  Index++;
138 
139  // compose record filename
140  sFilename.Format("%s" DirSep "%03i-%s.ocs", Config.AtUserDataPath(sDemoFolder.getData()), Index, sScenName);
141 
142  // log
143  StdStrBuf sLog; sLog.Format(LoadResStr("IDS_PRC_RECORDINGTO"),sFilename.getData());
144  if (Game.FrameCounter) sLog.AppendFormat(" (Frame %d)", Game.FrameCounter);
145  Log(sLog.getData());
146 
147  // save game - this also saves player info list
148  C4GameSaveRecord saveRec(fInitial, Index, Game.Parameters.isLeague());
149  if (!saveRec.Save(sFilename.getData())) return false;
150  saveRec.Close();
151 
152  // unpack group, if neccessary
153  if ( !DirectoryExists(sFilename.getData()) &&
154  !C4Group_UnpackDirectory(sFilename.getData()) )
155  return false;
156 
157  // open control record file
158  char szCtrlRecFilename[_MAX_PATH+1 + _MAX_FNAME];
159  sprintf(szCtrlRecFilename, "%s" DirSep C4CFN_CtrlRec, sFilename.getData());
160  if (!CtrlRec.Create(szCtrlRecFilename)) return false;
161 
162  // open log file in record
163  char szLogRecFilename[_MAX_PATH+1 + _MAX_FNAME];
164  sprintf(szLogRecFilename, "%s" DirSep C4CFN_LogRec, sFilename.getData());
165  if (!LogRec.Create(szLogRecFilename)) return false;
166 
167  // open record group
168  if (!RecordGrp.Open(sFilename.getData()))
169  return false;
170 
171  // record go
172  fStreaming = false;
173  fRecording = true;
174  iLastFrame = 0;
175  return true;
176 }
const char * getData() const
Definition: StdBuf.h:450
C4Config Config
Definition: C4Config.cpp:837
void SCopy(const char *szSource, char *sTarget, size_t iMaxL)
Definition: Standard.cpp:129
C4Game Game
Definition: C4Globals.cpp:52
bool Create(const char *szFileName, bool fCompressed=false, bool fExecutable=false, bool fMemory=false)
Definition: CStdFile.cpp:53
C4ConfigGeneral General
Definition: C4Config.h:252
#define sprintf
Definition: Standard.h:171
bool CreateSaveFolder(const char *strDirectory, const char *strLanguageTitle)
Definition: C4Config.cpp:576
void Format(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:181
bool C4Group_UnpackDirectory(const char *szFilename)
Definition: C4Group.cpp:306
#define _MAX_PATH
const char * GetFilenameOnly(const char *strFilename)
Definition: StdFile.cpp:70
size_t SLen(const char *sptr)
Definition: Standard.h:78
C4GameParameters & Parameters
Definition: C4Game.h:69
const char * LoadResStr(const char *id)
Definition: C4Language.h:83
void AppendFormat(const char *szFmt,...) GNUC_FORMAT_ATTRIBUTE_O
Definition: StdBuf.cpp:197
int32_t FrameCounter
Definition: C4Game.h:130
bool Close()
Definition: C4GameSave.cpp:449
bool Open(const char *szGroupName, bool fCreate=false)
Definition: C4Group.cpp:514
#define _MAX_FNAME
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:694
const char * AtUserDataPath(const char *szFilename)
Definition: C4Config.cpp:530
bool WildcardMatch(const char *szWildcard, const char *szString)
Definition: StdFile.cpp:384
const char * getFile() const
bool Log(const char *szMessage)
Definition: C4Log.cpp:195
bool isLeague() const
int Index
Definition: C4Record.h:259
#define C4CFN_ScenarioFiles
Definition: C4Components.h:174
#define C4CFN_Records
Definition: C4Components.h:36
#define C4CFN_CtrlRec
Definition: C4Components.h:77
#define DirSep
#define C4CFN_LogRec
Definition: C4Components.h:79

Here is the call graph for this function:

Here is the caller graph for this function:

bool C4Record::StartStreaming ( bool  fInitial)

Definition at line 320 of file C4Record.cpp.

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

Referenced by C4GameControl::StartRecord().

321 {
322  if (!fRecording) return false;
323  if (fStreaming) return false;
324 
325  // Get temporary file name
326  StdCopyStrBuf sTempFilename(sFilename);
327  MakeTempFilename(&sTempFilename);
328 
329  // Save start state (without copy of scenario!)
330  C4GameSaveRecord saveRec(fInitial, Index, Game.Parameters.isLeague(), false);
331  if (!saveRec.Save(sTempFilename.getData())) return false;
332  saveRec.Close();
333 
334  // Add file into stream, delete file
335  fStreaming = true;
336  if (!StreamFile(sTempFilename.getData(), sFilename.getData()))
337  {
338  fStreaming = false;
339  return false;
340  }
341 
342  // Okay
343  EraseFile(sTempFilename.getData());
344  iStreamingPos = 0;
345  return true;
346 }
const char * getData() const
Definition: StdBuf.h:450
C4Game Game
Definition: C4Globals.cpp:52
bool EraseFile(const char *szFilename)
Definition: StdFile.cpp:495
C4GameParameters & Parameters
Definition: C4Game.h:69
bool Close()
Definition: C4GameSave.cpp:449
bool isLeague() const
int Index
Definition: C4Record.h:259
void MakeTempFilename(char *szFilename)
Definition: StdFile.cpp:333

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 178 of file C4Record.cpp.

References C4CFN_RecPlayerInfos, C4Group_PackDirectory(), CStdFile::Close(), C4Group::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().

179 {
180  // safety
181  if (!fRecording) return false;
182  if (!DirectoryExists(sFilename.getData())) return false;
183 
184  // streaming finished
185  StopStreaming();
186 
187  // save desc into record group
188  C4GameSaveRecord saveRec(false, Index, Game.Parameters.isLeague());
189  saveRec.SaveDesc(RecordGrp);
190 
191  // save end player infos into record group
193  RecordGrp.Close();
194 
195  // write last entry and close
196  C4RecordChunkHead Head;
197  Head.iFrm = 37;
198  Head.Type = RCT_End;
199  CtrlRec.Write(&Head, sizeof(Head));
200  CtrlRec.Close();
201 
202  LogRec.Close();
203 
204  // pack group
205  if (!Config.General.DebugRec)
206  if (!C4Group_PackDirectory(sFilename.getData())) return false;
207 
208  // return record data
209  if (pRecordName)
210  pRecordName->Copy(sFilename);
211  if (pRecordSHA1)
212  if (!GetFileSHA1(sFilename.getData(), pRecordSHA1))
213  return false;
214 
215  // ok
216  fRecording = false;
217  return true;
218 }
const char * getData() const
Definition: StdBuf.h:450
bool Close(StdBuf **ppMemory=nullptr)
Definition: CStdFile.cpp:155
C4Config Config
Definition: C4Config.cpp:837
C4Game Game
Definition: C4Globals.cpp:52
C4ConfigGeneral General
Definition: C4Config.h:252
bool GetFileSHA1(const char *szFilename, BYTE *pSHA1)
Definition: CStdFile.cpp:385
void StopStreaming()
Definition: C4Record.cpp:360
C4GameParameters & Parameters
Definition: C4Game.h:69
bool Save(C4Group &hGroup, const char *szToFile)
bool Write(const void *pBuffer, int iSize)
Definition: CStdFile.cpp:244
bool SaveDesc(C4Group &hToGroup)
Definition: C4GameSave.cpp:237
bool Close()
Definition: C4Group.cpp:755
#define C4CFN_RecPlayerInfos
Definition: C4Components.h:126
bool DirectoryExists(const char *szFilename)
Definition: StdFile.cpp:694
C4PlayerInfoList & PlayerInfos
Definition: C4Game.h:73
bool isLeague() const
int Index
Definition: C4Record.h:259
int32_t DebugRec
Definition: C4Config.h:61
void Copy()
Definition: StdBuf.h:475
bool C4Group_PackDirectory(const char *szFilename)
Definition: C4Group.cpp:284
uint8_t iFrm
Definition: C4Record.h:99

Here is the call graph for this function:

Here is the caller graph for this function:

void C4Record::StopStreaming ( )

Definition at line 360 of file C4Record.cpp.

Referenced by Stop().

361 {
362  fStreaming = false;
363 }

Here is the caller graph for this function:

Member Data Documentation

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: