Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

295 lines
7.2 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. //=============================================================================//
  6. #include <utlbuffer.h>
  7. #include "tooldemofile.h"
  8. #include "filesystem.h"
  9. #include "demofile/demoformat.h"
  10. extern IBaseFileSystem *g_pFileSystem;
  11. //////////////////////////////////////////////////////////////////////
  12. // Construction/Destruction
  13. //////////////////////////////////////////////////////////////////////
  14. CToolDemoFile::CToolDemoFile()
  15. {
  16. m_hDemoFile = FILESYSTEM_INVALID_HANDLE;
  17. }
  18. CToolDemoFile::~CToolDemoFile()
  19. {
  20. if ( IsOpen() )
  21. {
  22. Close();
  23. }
  24. }
  25. //-----------------------------------------------------------------------------
  26. // Purpose:
  27. //-----------------------------------------------------------------------------
  28. void CToolDemoFile::ReadSequenceInfo(int &nSeqNrIn, int &nSeqNrOut)
  29. {
  30. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  31. g_pFileSystem->Read( &nSeqNrIn, sizeof(int), m_hDemoFile );
  32. g_pFileSystem->Read( &nSeqNrOut, sizeof(int), m_hDemoFile );
  33. }
  34. //-----------------------------------------------------------------------------
  35. // Purpose:
  36. //-----------------------------------------------------------------------------
  37. void CToolDemoFile::ReadCmdInfo( democmdinfo_t& info )
  38. {
  39. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  40. g_pFileSystem->Read( &info, sizeof( democmdinfo_t ), m_hDemoFile );
  41. }
  42. //-----------------------------------------------------------------------------
  43. // Purpose:
  44. // Input : cmd -
  45. // dt -
  46. // frame -
  47. //-----------------------------------------------------------------------------
  48. void CToolDemoFile::ReadCmdHeader( unsigned char& cmd, int& tick )
  49. {
  50. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  51. // Read the command
  52. int r = g_pFileSystem->Read ( &cmd, sizeof(byte), m_hDemoFile );
  53. if ( r <=0 )
  54. {
  55. Warning("Missing end tag in demo file.\n");
  56. cmd = dem_stop;
  57. return;
  58. }
  59. Assert( cmd >= 1 && cmd <= dem_lastcmd );
  60. // Read the timestamp
  61. g_pFileSystem->Read ( &tick, sizeof(int), m_hDemoFile );
  62. tick = LittleDWord( tick );
  63. }
  64. const char *CToolDemoFile::ReadConsoleCommand()
  65. {
  66. static char cmdstring[1024];
  67. ReadRawData( cmdstring, sizeof(cmdstring) );
  68. return cmdstring;
  69. }
  70. unsigned int CToolDemoFile::GetCurPos()
  71. {
  72. if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE )
  73. return 0;
  74. return g_pFileSystem->Tell( m_hDemoFile );
  75. }
  76. //-----------------------------------------------------------------------------
  77. // Purpose:
  78. // Input : expected_length -
  79. // &demofile -
  80. //-----------------------------------------------------------------------------
  81. int CToolDemoFile::ReadNetworkDataTables( CUtlBuffer *buf )
  82. {
  83. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  84. char data[ 1024 ];
  85. int length;
  86. g_pFileSystem->Read( &length, sizeof( int ), m_hDemoFile );
  87. while( length > 0 )
  88. {
  89. int chunk = min( length, 1024 );
  90. g_pFileSystem->Read( data, chunk, m_hDemoFile );
  91. length -= chunk;
  92. if ( buf )
  93. {
  94. buf->Put( data, chunk );
  95. }
  96. }
  97. return length;
  98. }
  99. //-----------------------------------------------------------------------------
  100. // Purpose:
  101. // Input : discard -
  102. //-----------------------------------------------------------------------------
  103. int CToolDemoFile::ReadUserCmd( char *buffer, int &size )
  104. {
  105. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  106. int outgoing_sequence;
  107. g_pFileSystem->Read( &outgoing_sequence, sizeof( int ), m_hDemoFile );
  108. size = ReadRawData( buffer, size );
  109. return outgoing_sequence;
  110. }
  111. //-----------------------------------------------------------------------------
  112. // Purpose: Rewind from the current spot by the time stamp, byte code and frame counter offsets
  113. //-----------------------------------------------------------------------------
  114. void CToolDemoFile::SeekTo( int position )
  115. {
  116. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  117. g_pFileSystem->Seek( m_hDemoFile, position, FILESYSTEM_SEEK_HEAD );
  118. }
  119. //-----------------------------------------------------------------------------
  120. // Purpose:
  121. // Output : Returns true on success, false on failure.
  122. //-----------------------------------------------------------------------------
  123. int CToolDemoFile::ReadRawData( char *buffer, int length )
  124. {
  125. Assert( m_hDemoFile != FILESYSTEM_INVALID_HANDLE );
  126. int size;
  127. // read length of data block
  128. g_pFileSystem->Read( &size, sizeof( int ), m_hDemoFile );
  129. if ( buffer && (length < size) )
  130. {
  131. DevMsg("CToolDemoFile::ReadRawData: buffe overflow (%i).\n", size );
  132. return -1;
  133. }
  134. if ( buffer )
  135. {
  136. if ( length < size )
  137. {
  138. // given buffer is too small
  139. DevMsg("CToolDemoFile::ReadRawData: buffe overflow (%i).\n", size );
  140. g_pFileSystem->Seek( m_hDemoFile, size, FILESYSTEM_SEEK_CURRENT );
  141. size = -1;
  142. }
  143. else
  144. {
  145. // read data into buffer
  146. int r = g_pFileSystem->Read( buffer, size, m_hDemoFile );
  147. if ( r != size )
  148. {
  149. Warning( "Error reading demo message data.\n");
  150. return -1;
  151. }
  152. }
  153. }
  154. else
  155. {
  156. // just skip it
  157. g_pFileSystem->Seek( m_hDemoFile, size, FILESYSTEM_SEEK_CURRENT );
  158. }
  159. return size;
  160. }
  161. demoheader_t *CToolDemoFile::ReadDemoHeader()
  162. {
  163. if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE )
  164. return NULL; // file not open
  165. // goto file start
  166. g_pFileSystem->Seek(m_hDemoFile, 0, FILESYSTEM_SEEK_HEAD);
  167. Q_memset( &m_DemoHeader, 0, sizeof(m_DemoHeader) );
  168. int r = g_pFileSystem->Read( &m_DemoHeader, sizeof(demoheader_t), m_hDemoFile );
  169. if ( r != sizeof(demoheader_t) )
  170. return NULL; // reading failed
  171. if ( Q_strcmp ( m_DemoHeader.demofilestamp, DEMO_HEADER_ID ) )
  172. {
  173. Warning( "%s has invalid demo header ID.\n", m_szFileName );
  174. return NULL;
  175. }
  176. /*
  177. // The current network protocol version. Changing this makes clients and servers incompatible
  178. #define PROTOCOL_VERSION 7
  179. if ( m_DemoHeader.networkprotocol != PROTOCOL_VERSION )
  180. {
  181. Warning ("ERROR: demo network protocol %i outdated, engine version is %i \n",
  182. m_DemoHeader.networkprotocol, PROTOCOL_VERSION );
  183. return NULL;
  184. }
  185. */
  186. if ( m_DemoHeader.demoprotocol != DEMO_PROTOCOL )
  187. {
  188. Warning ("ERROR: demo file protocol %i outdated, engine version is %i \n",
  189. m_DemoHeader.demoprotocol, DEMO_PROTOCOL );
  190. return NULL;
  191. }
  192. return &m_DemoHeader;
  193. }
  194. bool CToolDemoFile::Open(const char *name, bool bReadOnly)
  195. {
  196. if ( m_hDemoFile != FILESYSTEM_INVALID_HANDLE )
  197. {
  198. Warning ("CToolDemoFile::Open: file already open.\n");
  199. return false;
  200. }
  201. m_szFileName[0] = 0; // clear name
  202. Q_memset( &m_DemoHeader, 0, sizeof(m_DemoHeader) ); // and demo header
  203. if ( bReadOnly )
  204. {
  205. // open existing file for reading only
  206. m_hDemoFile = g_pFileSystem->Open (name, "rb", "GAME" );
  207. }
  208. else
  209. {
  210. // create new file for writing only
  211. m_hDemoFile = g_pFileSystem->Open (name, "wb", "GAME" );
  212. }
  213. if ( m_hDemoFile == FILESYSTEM_INVALID_HANDLE )
  214. {
  215. Warning ("CToolDemoFile::Open: couldn't open file %s for %s.\n",
  216. name, bReadOnly?"reading":"writing" );
  217. return false;
  218. }
  219. Q_strncpy( m_szFileName, name, sizeof(m_szFileName) );
  220. return true;
  221. }
  222. bool CToolDemoFile::IsOpen()
  223. {
  224. return m_hDemoFile != FILESYSTEM_INVALID_HANDLE;
  225. }
  226. void CToolDemoFile::Close()
  227. {
  228. if ( m_hDemoFile != FILESYSTEM_INVALID_HANDLE )
  229. {
  230. g_pFileSystem->Close(m_hDemoFile);
  231. m_hDemoFile = FILESYSTEM_INVALID_HANDLE;
  232. }
  233. }
  234. int CToolDemoFile::GetSize()
  235. {
  236. return g_pFileSystem->Size( m_hDemoFile );
  237. }