diff --git a/demboyz/demmessages/demhandlers.h b/demboyz/demmessages/demhandlers.h index 13fc2bb..ed03eae 100644 --- a/demboyz/demmessages/demhandlers.h +++ b/demboyz/demmessages/demhandlers.h @@ -3,12 +3,20 @@ #include +namespace base +{ + class JsonWriterFile; +} + class DemoFileReader; class DemoFileWriter; +class DemoFileReader2; +class DemoFileWriter2; + using FileRead = DemoFileReader; using FileWrite = DemoFileWriter; class JsonRead; -class JsonWrite; +using JsonWrite = base::JsonWriterFile; #define DECLARE_DEM_HANDLERS(msgname) \ namespace DemHandlers \ diff --git a/demboyz/demofile/demotypes.h b/demboyz/demofile/demotypes.h index 46a3448..c2374e8 100644 --- a/demboyz/demofile/demotypes.h +++ b/demboyz/demofile/demotypes.h @@ -61,6 +61,27 @@ enum dem_lastcmd = dem_stringtables }; +inline const char* DemoCmdToString(unsigned int cmd) +{ + static const char* cmdNames[] = + { + "dem_unknown", + "dem_signon", + "dem_packet", + "dem_synctick", + "dem_consolecmd", + "dem_usercmd", + "dem_datatables", + "dem_stop", + "dem_stringtables" + }; + if (cmd > (sizeof(cmdNames) / sizeof(const char*))) + { + return ""; + } + return cmdNames[cmd]; +} + struct demoheader_t { char demofilestamp[ 8 ]; // Should be HL2DEMO diff --git a/demboyz/io/jsonwriter.cpp b/demboyz/io/jsonwriter.cpp index 4ddf4ba..8ef3102 100644 --- a/demboyz/io/jsonwriter.cpp +++ b/demboyz/io/jsonwriter.cpp @@ -1,6 +1,12 @@ #include "idemowriter.h" +#include "demofile/demojson.h" +#include "demofile/demotypes.h" +#include "base/jsonfile.h" +#include "demmessages/demhandlers.h" +#include "netmessages/nethandlers.h" #include +#include class JsonWriter: public IDemoWriter { @@ -14,6 +20,11 @@ public: virtual void EndCommandPacket(const PacketTrailingBits& trailingBits) override final; virtual void WriteNetPacket(NetPacket& packet, SourceGameContext& context) override final; + +private: + base::JsonWriterFile m_jsonFile; + bool m_writingNetPackets; + char m_buffer[4096]; }; IDemoWriter* IDemoWriter::CreateJsonWriter(void* outputFp) @@ -21,26 +32,59 @@ IDemoWriter* IDemoWriter::CreateJsonWriter(void* outputFp) return new JsonWriter(reinterpret_cast(outputFp)); } -JsonWriter::JsonWriter(FILE* outputFp) +JsonWriter::JsonWriter(FILE* outputFp): + m_jsonFile(outputFp, m_buffer, sizeof(m_buffer)), + m_writingNetPackets(false) { } void JsonWriter::StartWriting(demoheader_t& header) { + auto& jsonFile = m_jsonFile; + jsonFile.StartObject(); + + DemoJsonWriter::WriteDemoHeader(jsonFile, header); + jsonFile.StartArray("demmessages"); } void JsonWriter::EndWriting() { + auto& jsonFile = m_jsonFile; + jsonFile.EndArray(); + jsonFile.EndObject(); + assert(jsonFile.IsComplete()); } void JsonWriter::StartCommandPacket(const CommandPacket& packet) { + auto& jsonFile = m_jsonFile; + jsonFile.StartObject(); + jsonFile.WriteInt32("tick", packet.tick); + jsonFile.StartObject(DemoCmdToString(packet.cmd)); + DemHandlers::DemMsg_JsonWrite(packet.cmd, jsonFile, packet.data); + if (packet.cmd == dem_packet || packet.cmd == dem_signon) + { + m_writingNetPackets = true; + jsonFile.StartArray("netpackets"); + } } void JsonWriter::EndCommandPacket(const PacketTrailingBits& trailingBits) { + auto& jsonFile = m_jsonFile; + if (m_writingNetPackets) + { + m_writingNetPackets = false; + jsonFile.EndArray(); + } + jsonFile.EndObject(); + jsonFile.EndObject(); } void JsonWriter::WriteNetPacket(NetPacket& packet, SourceGameContext& context) { + auto& jsonFile = m_jsonFile; + jsonFile.StartObject(); + NetHandlers::NetMsg_JsonWrite(packet.type, jsonFile, context, packet.data); + jsonFile.EndObject(); }