WIP game event parsing

This commit is contained in:
Jordan Cristiano 2016-04-27 22:31:33 -04:00
parent 9dcda5054c
commit 963fc1ae4c
15 changed files with 249 additions and 24 deletions

112
demboyz/game/gameevents.cpp Normal file
View File

@ -0,0 +1,112 @@
#include "gameevents.h"
#include "base/bitfile.h"
#include <stdio.h>
namespace GameEvents
{
EventDataMap ParseEventData(bf_read& bitbuf, const EventDescriptor& desc, std::vector<char>& stringMem)
{
stringMem.reserve(stringMem.size() + MAX_EVENT_BYTES);
EventDataMap data;
char tempStr[MAX_EVENT_BYTES];
for (const EventValue& value : desc.values)
{
EventData& eventData = data[value.name];
eventData.type = value.type;
switch(value.type)
{
case EventValueType::String:
{
int length = 0;
const bool ok = bitbuf.ReadString(tempStr, sizeof(tempStr), false, &length);
assert(ok);
length += 1; // for null terminator
eventData.strOffset = stringMem.size();
stringMem.insert(stringMem.end(), tempStr, tempStr + length + 1);
break;
}
case EventValueType::Float:
{
eventData.flValue = bitbuf.ReadFloat();
break;
}
case EventValueType::Long:
{
eventData.i32Value = bitbuf.ReadSBitLong(32);
break;
}
case EventValueType::Short:
{
eventData.i16Value = bitbuf.ReadSBitLong(16);
break;
}
case EventValueType::Byte:
{
eventData.u8Value = bitbuf.ReadUBitLong(8);
break;
}
case EventValueType::Bool:
{
eventData.bValue = bitbuf.ReadOneBit() != 0;
break;
}
case EventValueType::Local:
default:
assert(false);
break;
}
}
return data;
}
void PrintEventData(bf_read& bitbuf, const EventDescriptor& desc)
{
char tempStr[MAX_EVENT_BYTES];
printf("%s:\n", desc.name);
for (const EventValue& value : desc.values)
{
printf(" %s: ", value.name);
switch(value.type)
{
case EventValueType::String:
{
const bool ok = bitbuf.ReadString(tempStr, sizeof(tempStr), false, nullptr);
assert(ok);
printf("%s\n", tempStr);
break;
}
case EventValueType::Float:
{
printf("%f\n", bitbuf.ReadFloat());
break;
}
case EventValueType::Long:
{
printf("%i\n", bitbuf.ReadSBitLong(32));
break;
}
case EventValueType::Short:
{
printf("%i\n", bitbuf.ReadSBitLong(16));
break;
}
case EventValueType::Byte:
{
printf("%u\n", bitbuf.ReadUBitLong(8));
break;
}
case EventValueType::Bool:
{
printf("%s\n", (bitbuf.ReadOneBit() != 0) ? "true" : "false");
break;
}
case EventValueType::Local:
default:
assert(false);
break;
}
}
}
}

57
demboyz/game/gameevents.h Normal file
View File

@ -0,0 +1,57 @@
#pragma once
#include "netmessages/netcontants.h"
#include <cstdint>
#include <map>
#include <string>
#include <vector>
//#define WIP_GAMEEVENTS
class bf_read;
namespace GameEvents
{
enum EventValueType : uint8_t
{
Local = 0, // not networked
String = 1, // zero terminated ASCII string
Float = 2, // 32 bit float
Long = 3, // 32 bit signed int
Short = 4, // 16 bit signed int
Byte = 5, // 8 bit unsigned int
Bool = 6 // 1 bit unsigned int
};
struct EventValue
{
EventValueType type;
char name[MAX_EVENT_NAME_LENGTH];
};
struct EventDescriptor
{
uint16_t id;
char name[MAX_EVENT_NAME_LENGTH];
std::vector<EventValue> values;
};
struct EventData
{
EventValueType type;
union
{
ptrdiff_t strOffset;
float flValue;
int32_t i32Value;
int16_t i16Value;
uint8_t u8Value;
bool bValue;
};
};
using EventDataMap = std::map<std::string, EventData>;
EventDataMap ParseEventData(bf_read& bitbuf, const EventDescriptor& desc, std::vector<char>& stringMem);
void PrintEventData(bf_read& bitbuf, const EventDescriptor& desc);
}

View File

@ -0,0 +1,16 @@
#include "sourcecontext.h"
#include "netmessages/svc_gameeventlist.h"
SourceGameContext::SourceGameContext():
protocol(0),
gameEventList(nullptr)
{
}
SourceGameContext::~SourceGameContext()
{
protocol = 0;
delete gameEventList;
gameEventList = nullptr;
}

View File

@ -0,0 +1,18 @@
#pragma once
#include <cstdint>
namespace NetMsg
{
struct SVC_GameEventList;
}
struct SourceGameContext
{
SourceGameContext();
~SourceGameContext();
int16_t protocol;
NetMsg::SVC_GameEventList* gameEventList;
};

View File

@ -4,6 +4,7 @@
#include "demofile/demofile.h" #include "demofile/demofile.h"
#include "demofile/demotypes.h" #include "demofile/demotypes.h"
#include "game/sourcecontext.h"
#include "netmessages/nethandlers.h" #include "netmessages/nethandlers.h"
#include "netmessages/netcontants.h" #include "netmessages/netcontants.h"
#include "demmessages/demhandlers.h" #include "demmessages/demhandlers.h"

View File

@ -5,6 +5,7 @@
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "io/idemowriter.h" #include "io/idemowriter.h"
#include "game/sourcecontext.h"
#include "netmessages/nethandlers.h" #include "netmessages/nethandlers.h"
#include "demmessages/demhandlers.h" #include "demmessages/demhandlers.h"

View File

@ -25,10 +25,7 @@ namespace NetHandlers
using JsonWrite = base::JsonWriterFile; using JsonWrite = base::JsonWriterFile;
} }
struct SourceGameContext struct SourceGameContext;
{
int16_t protocol;
};
#if !defined(MAX_OSPATH) #if !defined(MAX_OSPATH)
#define MAX_OSPATH 260 // max length of a filesystem pathname #define MAX_OSPATH 260 // max length of a filesystem pathname

View File

@ -2,6 +2,7 @@
#include "svc_createstringtable.h" #include "svc_createstringtable.h"
#include "base/bitfile.h" #include "base/bitfile.h"
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "game/sourcecontext.h"
#include "netmath.h" #include "netmath.h"
#include "netcontants.h" #include "netcontants.h"

View File

@ -5,13 +5,32 @@
#include "netcontants.h" #include "netcontants.h"
#include "netmath.h" #include "netmath.h"
#ifdef WIP_GAMEEVENTS
#include "svc_gameeventlist.h"
#endif
namespace NetHandlers namespace NetHandlers
{ {
bool SVC_GameEvent_BitRead_Internal(BitRead& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data) bool SVC_GameEvent_BitRead_Internal(BitRead& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data)
{ {
data->dataLengthInBits = bitbuf.ReadUBitLong(11); const unsigned int numBits = bitbuf.ReadUBitLong(11);
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]); const size_t numBytes = math::BitsToBytes(numBits);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
data->dataLengthInBits = numBits;
data->data.reset(new uint8_t[numBytes]);
bitbuf.ReadBits(data->data.get(), numBits);
#ifdef WIP_GAMEEVENTS
{
BitRead bitbuf2(data->data.get(), numBytes, numBits);
const size_t id = bitbuf2.ReadUBitLong(9);
//std::vector<char> stringMem;
//GameEvents::ParseEventData(bitbuf2, context.gameEventList->eventDescriptors[id], stringMem);
GameEvents::PrintEventData(bitbuf2, context.gameEventList->eventDescriptors[id]);
printf("%i\n", id);
}
#endif // WIP_GAMEEVENTS
return !bitbuf.IsOverflowed(); return !bitbuf.IsOverflowed();
} }

View File

@ -2,12 +2,14 @@
#pragma once #pragma once
#include "nethandlers.h" #include "nethandlers.h"
#include "game/gameevents.h"
#include <memory> #include <memory>
namespace NetMsg namespace NetMsg
{ {
struct SVC_GameEvent struct SVC_GameEvent
{ {
GameEvents::EventDataMap eventData;
std::unique_ptr<uint8_t[]> data; std::unique_ptr<uint8_t[]> data;
uint16_t dataLengthInBits; uint16_t dataLengthInBits;
}; };

View File

@ -2,11 +2,12 @@
#include "svc_gameeventlist.h" #include "svc_gameeventlist.h"
#include "base/bitfile.h" #include "base/bitfile.h"
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "game/sourcecontext.h"
#include "netcontants.h" #include "netcontants.h"
#include "netmath.h" #include "netmath.h"
using EventDescriptor = NetMsg::SVC_GameEventList::EventDescriptor; using EventDescriptor = GameEvents::EventDescriptor;
using EventValue = NetMsg::SVC_GameEventList::EventValue; using EventValue = GameEvents::EventValue;
uint32_t CalculateNumDataBits(const std::vector<EventDescriptor>& eventDescriptors) uint32_t CalculateNumDataBits(const std::vector<EventDescriptor>& eventDescriptors)
{ {
@ -38,13 +39,20 @@ namespace NetHandlers
event.id = bitbuf.ReadUBitLong(MAX_EVENT_BITS); event.id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
bitbuf.ReadString(event.name, sizeof(event.name)); bitbuf.ReadString(event.name, sizeof(event.name));
EventValue value; EventValue value;
while ((value.type = bitbuf.ReadUBitLong(3)) > 0) while ((value.type = static_cast<GameEvents::EventValueType>(bitbuf.ReadUBitLong(3))) > 0)
{ {
bitbuf.ReadString(value.name, sizeof(value.name)); bitbuf.ReadString(value.name, sizeof(value.name));
event.values.push_back(value); event.values.push_back(value);
} }
event.values.shrink_to_fit(); event.values.shrink_to_fit();
} }
#ifdef WIP_GAMEEVENTS
if (!context.gameEventList)
{
context.gameEventList = new NetMsg::SVC_GameEventList(*data);
}
#endif
return !bitbuf.IsOverflowed(); return !bitbuf.IsOverflowed();
} }
@ -52,6 +60,7 @@ namespace NetHandlers
{ {
bitbuf.WriteUBitLong(data->eventDescriptors.size(), MAX_EVENT_BITS); bitbuf.WriteUBitLong(data->eventDescriptors.size(), MAX_EVENT_BITS);
bitbuf.WriteUBitLong(data->dataLengthInBits, 20); bitbuf.WriteUBitLong(data->dataLengthInBits, 20);
assert(data->dataLengthInBits == CalculateNumDataBits(data->eventDescriptors));
for (EventDescriptor& event : data->eventDescriptors) for (EventDescriptor& event : data->eventDescriptors)
{ {
bitbuf.WriteUBitLong(event.id, MAX_EVENT_BITS); bitbuf.WriteUBitLong(event.id, MAX_EVENT_BITS);
@ -79,7 +88,7 @@ namespace NetHandlers
base::JsonReaderArray values = obj.ReadArray("values"); base::JsonReaderArray values = obj.ReadArray("values");
values.TransformTo(event.values, [](base::JsonReaderObject& obj, EventValue& value) values.TransformTo(event.values, [](base::JsonReaderObject& obj, EventValue& value)
{ {
value.type = obj.ReadUInt32("type"); value.type = static_cast<GameEvents::EventValueType>(obj.ReadUInt32("type"));
obj.ReadString("name", value.name, sizeof(value.name)); obj.ReadString("name", value.name, sizeof(value.name));
}); });
}); });

View File

@ -3,26 +3,15 @@
#include "nethandlers.h" #include "nethandlers.h"
#include "netcontants.h" #include "netcontants.h"
#include "game/gameevents.h"
#include <vector> #include <vector>
namespace NetMsg namespace NetMsg
{ {
struct SVC_GameEventList struct SVC_GameEventList
{ {
struct EventValue std::vector<GameEvents::EventDescriptor> eventDescriptors;
{
uint8_t type;
char name[MAX_EVENT_NAME_LENGTH];
};
struct EventDescriptor
{
uint16_t id;
char name[MAX_EVENT_NAME_LENGTH];
std::vector<EventValue> values;
};
uint32_t dataLengthInBits; uint32_t dataLengthInBits;
std::vector<EventDescriptor> eventDescriptors;
}; };
} }

View File

@ -2,6 +2,7 @@
#include "svc_prefetch.h" #include "svc_prefetch.h"
#include "base/bitfile.h" #include "base/bitfile.h"
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "game/sourcecontext.h"
#include "netcontants.h" #include "netcontants.h"
namespace NetHandlers namespace NetHandlers

View File

@ -2,6 +2,7 @@
#include "svc_serverinfo.h" #include "svc_serverinfo.h"
#include "base/bitfile.h" #include "base/bitfile.h"
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "game/sourcecontext.h"
namespace NetHandlers namespace NetHandlers
{ {

View File

@ -2,6 +2,7 @@
#include "svc_tempentities.h" #include "svc_tempentities.h"
#include "base/bitfile.h" #include "base/bitfile.h"
#include "base/jsonfile.h" #include "base/jsonfile.h"
#include "game/sourcecontext.h"
#include "netcontants.h" #include "netcontants.h"
#include "netmath.h" #include "netmath.h"