WIP game event parsing
This commit is contained in:
parent
9dcda5054c
commit
963fc1ae4c
112
demboyz/game/gameevents.cpp
Normal file
112
demboyz/game/gameevents.cpp
Normal 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
57
demboyz/game/gameevents.h
Normal 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);
|
||||
}
|
16
demboyz/game/sourcecontext.cpp
Normal file
16
demboyz/game/sourcecontext.cpp
Normal 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;
|
||||
}
|
18
demboyz/game/sourcecontext.h
Normal file
18
demboyz/game/sourcecontext.h
Normal 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;
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
#include "demofile/demofile.h"
|
||||
#include "demofile/demotypes.h"
|
||||
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netmessages/nethandlers.h"
|
||||
#include "netmessages/netcontants.h"
|
||||
#include "demmessages/demhandlers.h"
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "base/jsonfile.h"
|
||||
#include "io/idemowriter.h"
|
||||
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netmessages/nethandlers.h"
|
||||
#include "demmessages/demhandlers.h"
|
||||
|
||||
|
|
|
@ -25,10 +25,7 @@ namespace NetHandlers
|
|||
using JsonWrite = base::JsonWriterFile;
|
||||
}
|
||||
|
||||
struct SourceGameContext
|
||||
{
|
||||
int16_t protocol;
|
||||
};
|
||||
struct SourceGameContext;
|
||||
|
||||
#if !defined(MAX_OSPATH)
|
||||
#define MAX_OSPATH 260 // max length of a filesystem pathname
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "svc_createstringtable.h"
|
||||
#include "base/bitfile.h"
|
||||
#include "base/jsonfile.h"
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netmath.h"
|
||||
#include "netcontants.h"
|
||||
|
||||
|
|
|
@ -5,13 +5,32 @@
|
|||
#include "netcontants.h"
|
||||
#include "netmath.h"
|
||||
|
||||
#ifdef WIP_GAMEEVENTS
|
||||
#include "svc_gameeventlist.h"
|
||||
#endif
|
||||
|
||||
namespace NetHandlers
|
||||
{
|
||||
bool SVC_GameEvent_BitRead_Internal(BitRead& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data)
|
||||
{
|
||||
data->dataLengthInBits = bitbuf.ReadUBitLong(11);
|
||||
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
|
||||
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
|
||||
const unsigned int numBits = bitbuf.ReadUBitLong(11);
|
||||
const size_t numBytes = math::BitsToBytes(numBits);
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
|
|
@ -2,12 +2,14 @@
|
|||
#pragma once
|
||||
|
||||
#include "nethandlers.h"
|
||||
#include "game/gameevents.h"
|
||||
#include <memory>
|
||||
|
||||
namespace NetMsg
|
||||
{
|
||||
struct SVC_GameEvent
|
||||
{
|
||||
GameEvents::EventDataMap eventData;
|
||||
std::unique_ptr<uint8_t[]> data;
|
||||
uint16_t dataLengthInBits;
|
||||
};
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
#include "svc_gameeventlist.h"
|
||||
#include "base/bitfile.h"
|
||||
#include "base/jsonfile.h"
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netcontants.h"
|
||||
#include "netmath.h"
|
||||
|
||||
using EventDescriptor = NetMsg::SVC_GameEventList::EventDescriptor;
|
||||
using EventValue = NetMsg::SVC_GameEventList::EventValue;
|
||||
using EventDescriptor = GameEvents::EventDescriptor;
|
||||
using EventValue = GameEvents::EventValue;
|
||||
|
||||
uint32_t CalculateNumDataBits(const std::vector<EventDescriptor>& eventDescriptors)
|
||||
{
|
||||
|
@ -38,13 +39,20 @@ namespace NetHandlers
|
|||
event.id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
|
||||
bitbuf.ReadString(event.name, sizeof(event.name));
|
||||
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));
|
||||
event.values.push_back(value);
|
||||
}
|
||||
event.values.shrink_to_fit();
|
||||
}
|
||||
|
||||
#ifdef WIP_GAMEEVENTS
|
||||
if (!context.gameEventList)
|
||||
{
|
||||
context.gameEventList = new NetMsg::SVC_GameEventList(*data);
|
||||
}
|
||||
#endif
|
||||
return !bitbuf.IsOverflowed();
|
||||
}
|
||||
|
||||
|
@ -52,6 +60,7 @@ namespace NetHandlers
|
|||
{
|
||||
bitbuf.WriteUBitLong(data->eventDescriptors.size(), MAX_EVENT_BITS);
|
||||
bitbuf.WriteUBitLong(data->dataLengthInBits, 20);
|
||||
assert(data->dataLengthInBits == CalculateNumDataBits(data->eventDescriptors));
|
||||
for (EventDescriptor& event : data->eventDescriptors)
|
||||
{
|
||||
bitbuf.WriteUBitLong(event.id, MAX_EVENT_BITS);
|
||||
|
@ -79,7 +88,7 @@ namespace NetHandlers
|
|||
base::JsonReaderArray values = obj.ReadArray("values");
|
||||
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));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -3,26 +3,15 @@
|
|||
|
||||
#include "nethandlers.h"
|
||||
#include "netcontants.h"
|
||||
#include "game/gameevents.h"
|
||||
#include <vector>
|
||||
|
||||
namespace NetMsg
|
||||
{
|
||||
struct SVC_GameEventList
|
||||
{
|
||||
struct EventValue
|
||||
{
|
||||
uint8_t type;
|
||||
char name[MAX_EVENT_NAME_LENGTH];
|
||||
};
|
||||
struct EventDescriptor
|
||||
{
|
||||
uint16_t id;
|
||||
char name[MAX_EVENT_NAME_LENGTH];
|
||||
std::vector<EventValue> values;
|
||||
};
|
||||
|
||||
std::vector<GameEvents::EventDescriptor> eventDescriptors;
|
||||
uint32_t dataLengthInBits;
|
||||
std::vector<EventDescriptor> eventDescriptors;
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "svc_prefetch.h"
|
||||
#include "base/bitfile.h"
|
||||
#include "base/jsonfile.h"
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netcontants.h"
|
||||
|
||||
namespace NetHandlers
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "svc_serverinfo.h"
|
||||
#include "base/bitfile.h"
|
||||
#include "base/jsonfile.h"
|
||||
#include "game/sourcecontext.h"
|
||||
|
||||
namespace NetHandlers
|
||||
{
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include "svc_tempentities.h"
|
||||
#include "base/bitfile.h"
|
||||
#include "base/jsonfile.h"
|
||||
#include "game/sourcecontext.h"
|
||||
#include "netcontants.h"
|
||||
#include "netmath.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user