Code cleanup
This commit is contained in:
parent
066b9fe269
commit
271a22f148
@ -8,31 +8,63 @@
|
||||
void ParsePacket(const std::vector<unsigned char>& packet)
|
||||
{
|
||||
assert(packet.size() <= NET_MAX_PAYLOAD);
|
||||
CBitRead bitBuf(packet.data(), packet.size());
|
||||
while (bitBuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS)
|
||||
CBitRead bitbuf(packet.data(), packet.size());
|
||||
while (bitbuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS)
|
||||
{
|
||||
uint32 typeId = bitBuf.ReadUBitLong(NETMSG_TYPE_BITS);
|
||||
uint32 typeId = bitbuf.ReadUBitLong(NETMSG_TYPE_BITS);
|
||||
printf("%i\n", typeId);
|
||||
ProcessNetMsg(typeId, bitBuf);
|
||||
ProcessNetMsg(typeId, bitbuf);
|
||||
}
|
||||
}
|
||||
|
||||
void ParseSignonData(const std::vector<unsigned char>& signonData)
|
||||
void ParseDemoSequence(const std::vector<unsigned char>& sequenceData)
|
||||
{
|
||||
CBitRead bitbuf(signonData.data(), signonData.size());
|
||||
const char cmd = bitbuf.ReadChar();
|
||||
assert(cmd == dem_signon);
|
||||
const int32 tick = bitbuf.ReadLong();
|
||||
bitbuf.SeekRelative(sizeof(democmdinfo_t) * 8);
|
||||
const int32 seq1 = bitbuf.ReadLong();
|
||||
const int32 seq2 = bitbuf.ReadLong();
|
||||
assert(seq1 == seq2);
|
||||
unsigned char cmd;
|
||||
int32 tick;
|
||||
int32 sequenceInfo1;
|
||||
int32 sequenceInfo2;
|
||||
democmdinfo_t cmdInfo;
|
||||
std::vector<unsigned char> buffer;
|
||||
|
||||
const int32 numBytes = bitbuf.ReadLong();
|
||||
std::vector<unsigned char> packet;
|
||||
packet.resize(numBytes);
|
||||
bitbuf.ReadBytes(&packet[0], numBytes);
|
||||
ParsePacket(packet);
|
||||
DemoSequenceReader reader(sequenceData);
|
||||
for (;;)
|
||||
{
|
||||
reader.ReadCmdHeader(cmd, tick);
|
||||
switch (cmd)
|
||||
{
|
||||
case dem_signon:
|
||||
case dem_packet:
|
||||
reader.ReadCmdInfo(cmdInfo);
|
||||
reader.ReadSequenceInfo(sequenceInfo1, sequenceInfo2);
|
||||
assert(sequenceInfo1 == sequenceInfo2);
|
||||
reader.ReadRawData(buffer);
|
||||
ParsePacket(buffer);
|
||||
break;
|
||||
case dem_synctick:
|
||||
// nothing
|
||||
break;
|
||||
case dem_consolecmd:
|
||||
break;
|
||||
case dem_usercmd:
|
||||
reader.ReadUserCmd(buffer);
|
||||
break;
|
||||
case dem_datatables:
|
||||
// TODO: datatables
|
||||
reader.ReadRawData(nullptr, 0);
|
||||
break;
|
||||
case dem_stop:
|
||||
// TODO assert frame and tick numbers
|
||||
break;
|
||||
case dem_customdata:
|
||||
reader.ReadRawData(nullptr, 0);
|
||||
break;
|
||||
case dem_stringtables:
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(const int argc, const char* argv[])
|
||||
@ -49,48 +81,8 @@ int main(const int argc, const char* argv[])
|
||||
}
|
||||
|
||||
auto demoHeader = demoFile.GetDemoHeader();
|
||||
|
||||
ParseSignonData(demoFile.GetSignOnData());
|
||||
|
||||
unsigned char cmd;
|
||||
int32 tick;
|
||||
int32 sequenceInfo1;
|
||||
int32 sequenceInfo2;
|
||||
democmdinfo_t cmdInfo;
|
||||
std::vector<unsigned char> packet;
|
||||
demoFile.ReadCmdHeader(cmd, tick);
|
||||
|
||||
assert(cmd == dem_synctick && tick == 0);
|
||||
|
||||
const int numFrames = demoHeader->playback_frames;
|
||||
const int numTicks = demoHeader->playback_ticks;
|
||||
for (int i = 0; i <= numFrames; ++i)
|
||||
{
|
||||
demoFile.ReadCmdHeader(cmd, tick);
|
||||
//printf("tick: %i\n", tick);
|
||||
switch (cmd)
|
||||
{
|
||||
case dem_packet:
|
||||
demoFile.ReadCmdInfo(cmdInfo);
|
||||
demoFile.ReadSequenceInfo(sequenceInfo1, sequenceInfo2);
|
||||
assert(sequenceInfo1 == sequenceInfo2);
|
||||
demoFile.ReadRawData(packet);
|
||||
ParsePacket(packet);
|
||||
break;
|
||||
case dem_stop:
|
||||
assert(i == numFrames && tick == numTicks);
|
||||
break;
|
||||
case dem_synctick:
|
||||
case dem_consolecmd:
|
||||
case dem_usercmd:
|
||||
case dem_datatables:
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ParseDemoSequence(demoFile.GetSignOnData());
|
||||
ParseDemoSequence(demoFile.GetDemoData());
|
||||
demoFile.Close();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -27,129 +27,169 @@
|
||||
#include <assert.h>
|
||||
#include "demofile.h"
|
||||
|
||||
CDemoFile::CDemoFile():
|
||||
m_DemoHeader(),
|
||||
m_fileBufferPos(0)
|
||||
DemoSequenceReader::DemoSequenceReader(const std::vector<unsigned char>& sequenceData):
|
||||
m_sequenceData(sequenceData),
|
||||
m_dataReadOffset(0)
|
||||
{
|
||||
}
|
||||
|
||||
CDemoFile::~CDemoFile()
|
||||
int32 DemoSequenceReader::ReadRawData(char *buffer, int32 length)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
void CDemoFile::ReadSequenceInfo( int32 &nSeqNrIn, int32 &nSeqNrOut )
|
||||
{
|
||||
if ( !m_fileBuffer.size() )
|
||||
return;
|
||||
|
||||
nSeqNrIn = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( int32 );
|
||||
nSeqNrOut = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( int32 );
|
||||
}
|
||||
|
||||
void CDemoFile::ReadCmdInfo( democmdinfo_t& info )
|
||||
{
|
||||
if ( !m_fileBuffer.size() )
|
||||
return;
|
||||
|
||||
memcpy( &info, &m_fileBuffer[ m_fileBufferPos ], sizeof( democmdinfo_t ) );
|
||||
m_fileBufferPos += sizeof( democmdinfo_t );
|
||||
}
|
||||
|
||||
void CDemoFile::ReadCmdHeader( unsigned char& cmd, int32& tick )
|
||||
{
|
||||
if ( !m_fileBuffer.size() )
|
||||
return;
|
||||
|
||||
// Read the command
|
||||
cmd = *( unsigned char * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( unsigned char );
|
||||
|
||||
if ( cmd <=0 )
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
fprintf( stderr, "CDemoFile::ReadCmdHeader: Missing end tag in demo file.\n");
|
||||
cmd = dem_stop;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
assert( cmd >= 1 && cmd <= dem_lastcmd );
|
||||
|
||||
// Read the timestamp
|
||||
tick = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( int32 );
|
||||
}
|
||||
|
||||
int32 CDemoFile::ReadUserCmd( char *buffer, int32 &size )
|
||||
{
|
||||
if ( !m_fileBuffer.size() )
|
||||
return 0;
|
||||
|
||||
int32 outgoing_sequence = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( int32 );
|
||||
|
||||
size = ReadRawData( buffer, size );
|
||||
|
||||
return outgoing_sequence;
|
||||
}
|
||||
|
||||
int32 CDemoFile::ReadRawData( char *buffer, int32 length )
|
||||
{
|
||||
if ( !m_fileBuffer.size() )
|
||||
return 0;
|
||||
const unsigned char* sequenceData = m_sequenceData.data();
|
||||
size_t currentReadOffset = m_dataReadOffset;
|
||||
|
||||
// read length of data block
|
||||
int32 size = *( int32 * )( &m_fileBuffer[ m_fileBufferPos ] );
|
||||
m_fileBufferPos += sizeof( int32 );
|
||||
|
||||
if ( buffer && (length < size) )
|
||||
const int32 size = *reinterpret_cast<const int32*>(sequenceData + currentReadOffset);
|
||||
currentReadOffset += sizeof(int32);
|
||||
|
||||
if (buffer && (length < size))
|
||||
{
|
||||
fprintf( stderr, "CDemoFile::ReadRawData: buffer overflow (%i).\n", size );
|
||||
fprintf(stderr, "CDemoFile::ReadRawData: buffer overflow (%i).\n", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( buffer )
|
||||
if (buffer)
|
||||
{
|
||||
// read data into buffer
|
||||
memcpy( buffer, &m_fileBuffer[ m_fileBufferPos ], size );
|
||||
m_fileBufferPos += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
// just skip it
|
||||
m_fileBufferPos += size;
|
||||
memcpy(buffer, sequenceData + currentReadOffset, size);
|
||||
}
|
||||
currentReadOffset += size;
|
||||
|
||||
m_dataReadOffset = currentReadOffset;
|
||||
return size;
|
||||
}
|
||||
|
||||
bool CDemoFile::ReadRawData(std::vector<unsigned char>& buf)
|
||||
bool DemoSequenceReader::ReadRawData(std::vector<unsigned char>& buf,
|
||||
const int32 maxReadSize /*= MAX_READ_SIZE*/)
|
||||
{
|
||||
if (!m_fileBuffer.size())
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const unsigned char* sequenceData = m_sequenceData.data();
|
||||
size_t currentReadOffset = m_dataReadOffset;
|
||||
|
||||
// read length of data block
|
||||
int32 size = *(int32 *)(&m_fileBuffer[m_fileBufferPos]);
|
||||
m_fileBufferPos += sizeof(int32);
|
||||
const int32 size = *reinterpret_cast<const int32*>(sequenceData + currentReadOffset);
|
||||
currentReadOffset += sizeof(int32);
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
fprintf(stderr, "CDemoFile::ReadRawData: invalid size (%i).\n", size);
|
||||
fprintf(stderr, "DemoSequenceReader::ReadRawData: invalid size (%i).\n", size);
|
||||
return false;
|
||||
}
|
||||
if (maxReadSize < 0 || size > maxReadSize)
|
||||
{
|
||||
fprintf(stderr, "DemoSequenceReader::ReadRawData: invalid size (%i) with max (%i).\n", size, maxReadSize);
|
||||
return false;
|
||||
}
|
||||
|
||||
buf.resize(size);
|
||||
|
||||
// read data into buffer
|
||||
memcpy(&buf[0], &m_fileBuffer[m_fileBufferPos], size);
|
||||
m_fileBufferPos += size;
|
||||
memcpy(buf.data(), sequenceData + currentReadOffset, size);
|
||||
currentReadOffset += size;
|
||||
|
||||
m_dataReadOffset = currentReadOffset;
|
||||
return true;
|
||||
}
|
||||
|
||||
void DemoSequenceReader::ReadSequenceInfo(int32 &nSeqNrIn, int32 &nSeqNrOut)
|
||||
{
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned char* sequenceData = m_sequenceData.data();
|
||||
size_t currentReadOffset = m_dataReadOffset;
|
||||
|
||||
nSeqNrIn = *reinterpret_cast<const int32*>(sequenceData + currentReadOffset);
|
||||
currentReadOffset += sizeof(int32);
|
||||
nSeqNrOut = *reinterpret_cast<const int32*>(sequenceData + currentReadOffset);
|
||||
currentReadOffset += sizeof(int32);
|
||||
|
||||
m_dataReadOffset = currentReadOffset;
|
||||
}
|
||||
|
||||
void DemoSequenceReader::ReadCmdInfo(democmdinfo_t& info)
|
||||
{
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
size_t currentReadOffset = m_dataReadOffset;
|
||||
|
||||
memcpy(&info, m_sequenceData.data() + currentReadOffset, sizeof(democmdinfo_t));
|
||||
currentReadOffset += sizeof(democmdinfo_t);
|
||||
|
||||
m_dataReadOffset = currentReadOffset;
|
||||
}
|
||||
|
||||
void DemoSequenceReader::ReadCmdHeader(unsigned char& cmd, int32& tick)
|
||||
{
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned char* sequenceData = m_sequenceData.data();
|
||||
size_t currentReadOffset = m_dataReadOffset;
|
||||
|
||||
// Read the command
|
||||
cmd = sequenceData[currentReadOffset];
|
||||
currentReadOffset += sizeof(unsigned char);
|
||||
|
||||
if (cmd > 0)
|
||||
{
|
||||
assert(cmd <= dem_lastcmd);
|
||||
|
||||
// Read the timestamp
|
||||
tick = *reinterpret_cast<const int32*>(sequenceData + currentReadOffset);
|
||||
currentReadOffset += sizeof(int32);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "CDemoFile::ReadCmdHeader: Missing end tag in demo file.\n");
|
||||
cmd = dem_stop;
|
||||
}
|
||||
m_dataReadOffset = currentReadOffset;
|
||||
}
|
||||
|
||||
int32 DemoSequenceReader::ReadUserCmd(std::vector<unsigned char>& buf)
|
||||
{
|
||||
if (m_sequenceData.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
const int32 outgoing_sequence = *reinterpret_cast<const int32*>(m_sequenceData.data() + m_dataReadOffset);
|
||||
m_dataReadOffset += sizeof(int32);
|
||||
|
||||
if (!ReadRawData(buf))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return outgoing_sequence;
|
||||
}
|
||||
|
||||
CDemoFile::CDemoFile():
|
||||
m_DemoHeader()
|
||||
{
|
||||
}
|
||||
|
||||
CDemoFile::~CDemoFile()
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
bool CDemoFile::Open( const char *name )
|
||||
{
|
||||
Close();
|
||||
@ -209,8 +249,6 @@ bool CDemoFile::Open( const char *name )
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_fileBufferPos = 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -218,6 +256,4 @@ void CDemoFile::Close()
|
||||
{
|
||||
m_signOnData.clear();
|
||||
m_fileBuffer.clear();
|
||||
|
||||
m_fileBufferPos = 0;
|
||||
}
|
||||
|
@ -218,6 +218,29 @@ struct democmdinfo_t
|
||||
Split_t u[ MAX_SPLITSCREEN_CLIENTS ];
|
||||
};
|
||||
|
||||
class DemoSequenceReader
|
||||
{
|
||||
static const int32 MAX_READ_SIZE = 1024 * 1024;
|
||||
public:
|
||||
DemoSequenceReader(const std::vector<unsigned char>& sequenceData);
|
||||
|
||||
int32 ReadRawData(char *buffer, int32 length);
|
||||
|
||||
bool ReadRawData(std::vector<unsigned char>& buf, const int32 maxReadSize = MAX_READ_SIZE);
|
||||
|
||||
void ReadSequenceInfo(int32 &nSeqNrIn, int32 &nSeqNrOutAck);
|
||||
|
||||
void ReadCmdInfo(democmdinfo_t& info);
|
||||
|
||||
void ReadCmdHeader(unsigned char &cmd, int32 &tick);
|
||||
|
||||
int32 ReadUserCmd(std::vector<unsigned char>& buf);
|
||||
|
||||
private:
|
||||
const std::vector<unsigned char>& m_sequenceData;
|
||||
size_t m_dataReadOffset;
|
||||
};
|
||||
|
||||
class CDemoFile
|
||||
{
|
||||
public:
|
||||
@ -227,29 +250,16 @@ public:
|
||||
bool Open( const char *name );
|
||||
void Close();
|
||||
|
||||
int32 ReadRawData( char *buffer, int32 length );
|
||||
|
||||
bool ReadRawData(std::vector<unsigned char>& buf);
|
||||
|
||||
void ReadSequenceInfo( int32 &nSeqNrIn, int32 &nSeqNrOutAck );
|
||||
|
||||
void ReadCmdInfo( democmdinfo_t& info );
|
||||
|
||||
void ReadCmdHeader( unsigned char &cmd, int32 &tick );
|
||||
|
||||
int32 ReadUserCmd( char *buffer, int32 &size );
|
||||
|
||||
const demoheader_t *GetDemoHeader() const;
|
||||
|
||||
const std::vector<unsigned char>& GetSignOnData() const;
|
||||
const std::vector<unsigned char>& GetDemoData() const;
|
||||
|
||||
private:
|
||||
demoheader_t m_DemoHeader; //general demo info
|
||||
|
||||
std::vector<unsigned char> m_signOnData;
|
||||
std::vector<unsigned char> m_fileBuffer;
|
||||
|
||||
size_t m_fileBufferPos;
|
||||
};
|
||||
|
||||
inline const demoheader_t *CDemoFile::GetDemoHeader() const
|
||||
@ -262,4 +272,9 @@ inline const std::vector<unsigned char>& CDemoFile::GetSignOnData() const
|
||||
return m_signOnData;
|
||||
}
|
||||
|
||||
inline const std::vector<unsigned char>& CDemoFile::GetDemoData() const
|
||||
{
|
||||
return m_fileBuffer;
|
||||
}
|
||||
|
||||
#endif // DEMOFILE_H
|
||||
|
Loading…
Reference in New Issue
Block a user