Improvements to Network Commands/Buffers

Fixed a memory leak in DNetworkBuffer. Added native function support to FNetworkCommand and DNetworkBuffer. Exposed EndOfStream() for FNetworkCommand.
This commit is contained in:
Boondorl 2024-02-21 17:06:32 -05:00 committed by Rachael Alexanderson
parent e37c19b5b4
commit 49cac88c12
3 changed files with 266 additions and 145 deletions

View file

@ -131,7 +131,7 @@ void DNetworkBuffer::OnDestroy()
{ {
Super::OnDestroy(); Super::OnDestroy();
_buffer.Clear(); _buffer.Reset();
} }
void DNetworkBuffer::Serialize(FSerializer& arc) void DNetworkBuffer::Serialize(FSerializer& arc)
@ -1043,164 +1043,201 @@ DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacee)
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacement) DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, Replacement)
DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, IsFinal) DEFINE_FIELD_X(ReplacedEvent, FReplacedEvent, IsFinal)
DEFINE_FIELD_X(NetworkCommand, FNetworkCommand, Player) DEFINE_FIELD(FNetworkCommand, Player)
DEFINE_FIELD_X(NetworkCommand, FNetworkCommand, Command) DEFINE_FIELD(FNetworkCommand, Command)
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadInt8) static int NativeReadInt8(FNetworkCommand* const self) { return self->ReadInt8(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadInt8, NativeReadInt8)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_INT(self->ReadInt8()); ACTION_RETURN_INT(self->ReadInt8());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadInt16) static int NativeReadInt16(FNetworkCommand* const self) { return self->ReadInt16(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadInt16, NativeReadInt16)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_INT(self->ReadInt16()); ACTION_RETURN_INT(self->ReadInt16());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadInt) static int NativeReadInt(FNetworkCommand* const self) { return self->ReadInt(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadInt, NativeReadInt)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_INT(self->ReadInt()); ACTION_RETURN_INT(self->ReadInt());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadFloat) static double NativeReadFloat(FNetworkCommand* const self) { return self->ReadFloat(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadFloat, NativeReadFloat)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_FLOAT(self->ReadFloat()); ACTION_RETURN_FLOAT(self->ReadFloat());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadDouble) static double NativeReadDouble(FNetworkCommand* const self) { return self->ReadDouble(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadDouble, NativeReadDouble)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_FLOAT(self->ReadDouble()); ACTION_RETURN_FLOAT(self->ReadDouble());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadString) static void NativeReadString(FNetworkCommand* const self, FString* const result)
{
const auto str = self->ReadString();
if (str != nullptr)
*result = str;
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadString, NativeReadString)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
FString res = {}; FString res = {};
auto str = self->ReadString(); NativeReadString(self, &res);
if (str != nullptr)
res = str;
ACTION_RETURN_STRING(res); ACTION_RETURN_STRING(res);
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadName) static int NativeReadName(FNetworkCommand* const self)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
FName res = NAME_None; FName res = NAME_None;
auto str = self->ReadString(); const auto str = self->ReadString();
if (str != nullptr) if (str != nullptr)
res = str; res = str;
ACTION_RETURN_INT(res.GetIndex()); return res.GetIndex();
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadMapUnit) DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadName, NativeReadName)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_INT(NativeReadName(self));
}
static double NativeReadMapUnit(FNetworkCommand* const self)
{
constexpr double FixedToFloat = 1.0 / (1 << 16); constexpr double FixedToFloat = 1.0 / (1 << 16);
ACTION_RETURN_FLOAT(self->ReadInt() * FixedToFloat); return self->ReadInt() * FixedToFloat;
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadAngle) DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadMapUnit, NativeReadMapUnit)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
const DAngle bam = DAngle::fromBam(self->ReadInt()); ACTION_RETURN_FLOAT(NativeReadMapUnit(self));
ACTION_RETURN_FLOAT(bam.Degrees());
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector2) static double NativeReadAngle(FNetworkCommand* const self) { return DAngle::fromBam(self->ReadInt()).Degrees(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadAngle, NativeReadAngle)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
DVector2 vec = {}; ACTION_RETURN_FLOAT(DAngle::fromBam(self->ReadInt()).Degrees());
vec.X = self->ReadDouble();
vec.Y = self->ReadDouble();
ACTION_RETURN_VEC2(vec);
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector3) static void NativeReadVector2(FNetworkCommand* const self, DVector2* const result)
{
result->X = self->ReadDouble();
result->Y = self->ReadDouble();
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadVector2, NativeReadVector2)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
DVector3 vec = {}; ACTION_RETURN_VEC2(DVector2(self->ReadDouble(), self->ReadDouble()));
vec.X = self->ReadDouble();
vec.Y = self->ReadDouble();
vec.Z = self->ReadDouble();
ACTION_RETURN_VEC3(vec);
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector4) static void NativeReadVector3(FNetworkCommand* const self, DVector3* const result)
{
result->X = self->ReadDouble();
result->Y = self->ReadDouble();
result->Z = self->ReadDouble();
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadVector3, NativeReadVector3)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
DVector4 vec = {}; ACTION_RETURN_VEC3(DVector3(self->ReadDouble(), self->ReadDouble(), self->ReadDouble()));
vec.X = self->ReadDouble();
vec.Y = self->ReadDouble();
vec.Z = self->ReadDouble();
vec.W = self->ReadDouble();
ACTION_RETURN_VEC4(vec);
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadQuat) static void NativeReadVector4(FNetworkCommand* const self, DVector4* const result)
{
result->X = self->ReadDouble();
result->Y = self->ReadDouble();
result->Z = self->ReadDouble();
result->W = self->ReadDouble();
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadVector4, NativeReadVector4)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
DQuaternion quat = {}; ACTION_RETURN_VEC4(DVector4(self->ReadDouble(), self->ReadDouble(), self->ReadDouble(), self->ReadDouble()));
quat.X = self->ReadDouble();
quat.Y = self->ReadDouble();
quat.Z = self->ReadDouble();
quat.W = self->ReadDouble();
ACTION_RETURN_QUAT(quat);
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadIntArray) static void NativeReadQuat(FNetworkCommand* const self, DQuaternion* const result)
{
result->X = self->ReadDouble();
result->Y = self->ReadDouble();
result->Z = self->ReadDouble();
result->W = self->ReadDouble();
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadQuat, NativeReadQuat)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
PARAM_OUTPOINTER(values, TArray<int>);
PARAM_INT(type)
unsigned int size = self->ReadInt(); ACTION_RETURN_QUAT(DQuaternion(self->ReadDouble(), self->ReadDouble(), self->ReadDouble(), self->ReadDouble()));
}
static void NativeReadIntArray(FNetworkCommand* const self, TArray<int>* const values, const int type)
{
const unsigned int size = self->ReadInt();
for (unsigned int i = 0u; i < size; ++i) for (unsigned int i = 0u; i < size; ++i)
{ {
switch (type) switch (type)
{ {
case NET_INT8: case NET_INT8:
values->Push(self->ReadInt8()); values->Push(self->ReadInt8());
break; break;
case NET_INT16: case NET_INT16:
values->Push(self->ReadInt16()); values->Push(self->ReadInt16());
break; break;
default: default:
values->Push(self->ReadInt()); values->Push(self->ReadInt());
break; break;
} }
} }
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadIntArray, NativeReadIntArray)
{
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
PARAM_OUTPOINTER(values, TArray<int>);
PARAM_INT(type);
NativeReadIntArray(self, values, type);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadDoubleArray) static void NativeReadDoubleArray(FNetworkCommand* const self, TArray<double>* const values, const bool doublePrecision)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); const unsigned int size = self->ReadInt();
PARAM_OUTPOINTER(values, TArray<double>);
PARAM_BOOL(doublePrecision);
unsigned int size = self->ReadInt();
for (unsigned int i = 0u; i < size; ++i) for (unsigned int i = 0u; i < size; ++i)
{ {
if (doublePrecision) if (doublePrecision)
@ -1208,32 +1245,55 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadDoubleArray)
else else
values->Push(self->ReadFloat()); values->Push(self->ReadFloat());
} }
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadDoubleArray, NativeReadDoubleArray)
{
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
PARAM_OUTPOINTER(values, TArray<double>);
PARAM_BOOL(doublePrecision);
NativeReadDoubleArray(self, values, doublePrecision);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadStringArray) static void NativeReadStringArray(FNetworkCommand* const self, TArray<FString>* const values, const bool skipEmpty)
{ {
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand); const unsigned int size = self->ReadInt();
PARAM_OUTPOINTER(values, TArray<FString>);
PARAM_BOOL(skipEmpty);
unsigned int size = self->ReadInt();
for (unsigned int i = 0u; i < size; ++i) for (unsigned int i = 0u; i < size; ++i)
{ {
FString res = {}; FString res = {};
auto str = self->ReadString(); const auto str = self->ReadString();
if (str != nullptr) if (str != nullptr)
res = str; res = str;
if (!skipEmpty || !res.IsEmpty()) if (!skipEmpty || !res.IsEmpty())
values->Push(res); values->Push(res);
} }
}
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, ReadStringArray, NativeReadStringArray)
{
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
PARAM_OUTPOINTER(values, TArray<FString>);
PARAM_BOOL(skipEmpty);
NativeReadStringArray(self, values, skipEmpty);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt8) static int EndOfStream(FNetworkCommand* const self) { return self->EndOfStream(); }
DEFINE_ACTION_FUNCTION_NATIVE(FNetworkCommand, EndOfStream, EndOfStream)
{
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
ACTION_RETURN_BOOL(self->EndOfStream());
}
static void AddInt8(DNetworkBuffer* const self, const int value) { self->AddInt8(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddInt8, AddInt8)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_INT(value); PARAM_INT(value);
@ -1241,7 +1301,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt8)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt16) static void AddInt16(DNetworkBuffer* const self, const int value) { self->AddInt16(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddInt16, AddInt16)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_INT(value); PARAM_INT(value);
@ -1249,7 +1311,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt16)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt) static void AddInt(DNetworkBuffer* const self, const int value) { self->AddInt(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddInt, AddInt)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_INT(value); PARAM_INT(value);
@ -1257,7 +1321,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddInt)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddFloat) static void AddFloat(DNetworkBuffer* const self, const double value) { self->AddFloat(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddFloat, AddFloat)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(value); PARAM_FLOAT(value);
@ -1265,7 +1331,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddFloat)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDouble) static void AddDouble(DNetworkBuffer* const self, const double value) { self->AddDouble(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddDouble, AddDouble)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(value); PARAM_FLOAT(value);
@ -1273,7 +1341,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDouble)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddString) static void AddString(DNetworkBuffer* const self, const FString& value) { self->AddString(value); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddString, AddString)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_STRING(value); PARAM_STRING(value);
@ -1281,7 +1351,9 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddString)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddName) static void AddName(DNetworkBuffer* const self, const int value) { FName x = ENamedName(value); self->AddString(x.GetChars()); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddName, AddName)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_NAME(value); PARAM_NAME(value);
@ -1289,17 +1361,24 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddName)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddMapUnit) static void AddMapUnit(DNetworkBuffer* const self, const double value)
{
constexpr int FloatToFixed = 1 << 16;
self->AddInt(static_cast<int>(value * FloatToFixed));
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddMapUnit, AddMapUnit)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(value); PARAM_FLOAT(value);
constexpr int FloatToFixed = 1 << 16; AddMapUnit(self, value);
self->AddInt(static_cast<int>(value * FloatToFixed));
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddAngle) static void AddAngle(DNetworkBuffer* const self, const double value) { self->AddInt(DAngle::fromDeg(value).BAMs()); }
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddAngle, AddAngle)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_ANGLE(value); PARAM_ANGLE(value);
@ -1307,7 +1386,13 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddAngle)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector2) static void AddVector2(DNetworkBuffer* const self, const double x, const double y)
{
self->AddDouble(x);
self->AddDouble(y);
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddVector2, AddVector2)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(x); PARAM_FLOAT(x);
@ -1317,7 +1402,14 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector2)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector3) static void AddVector3(DNetworkBuffer* const self, const double x, const double y, const double z)
{
self->AddDouble(x);
self->AddDouble(y);
self->AddDouble(z);
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddVector3, AddVector3)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(x); PARAM_FLOAT(x);
@ -1329,7 +1421,15 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector3)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector4) static void AddVector4(DNetworkBuffer* const self, const double x, const double y, const double z, const double w)
{
self->AddDouble(x);
self->AddDouble(y);
self->AddDouble(z);
self->AddDouble(w);
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddVector4, AddVector4)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(x); PARAM_FLOAT(x);
@ -1343,7 +1443,15 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddVector4)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddQuat) static void AddQuat(DNetworkBuffer* const self, const double x, const double y, const double z, const double w)
{
self->AddDouble(x);
self->AddDouble(y);
self->AddDouble(z);
self->AddDouble(w);
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddQuat, AddQuat)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_FLOAT(x); PARAM_FLOAT(x);
@ -1357,42 +1465,42 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddQuat)
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddIntArray) static void AddIntArray(DNetworkBuffer* const self, TArray<int>* const values, const int type)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); const unsigned int size = values->Size();
PARAM_POINTER(values, TArray<int>);
PARAM_INT(type);
unsigned int size = values->Size();
self->AddInt(size); self->AddInt(size);
for (unsigned int i = 0u; i < size; ++i) for (unsigned int i = 0u; i < size; ++i)
{ {
switch (type) switch (type)
{ {
case NET_INT8: case NET_INT8:
self->AddInt8((*values)[i]); self->AddInt8((*values)[i]);
break; break;
case NET_INT16: case NET_INT16:
self->AddInt16((*values)[i]); self->AddInt16((*values)[i]);
break; break;
default: default:
self->AddInt((*values)[i]); self->AddInt((*values)[i]);
break; break;
} }
} }
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddIntArray, AddIntArray)
{
PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_POINTER(values, TArray<int>);
PARAM_INT(type);
AddIntArray(self, values, type);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDoubleArray) static void AddDoubleArray(DNetworkBuffer* const self, TArray<double>* const values, const bool doublePrecision)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); const unsigned int size = values->Size();
PARAM_POINTER(values, TArray<double>);
PARAM_BOOL(doublePrecision);
unsigned int size = values->Size();
self->AddInt(size); self->AddInt(size);
for (unsigned int i = 0u; i < size; ++i) for (unsigned int i = 0u; i < size; ++i)
{ {
@ -1401,20 +1509,32 @@ DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddDoubleArray)
else else
self->AddFloat((*values)[i]); self->AddFloat((*values)[i]);
} }
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddDoubleArray, AddDoubleArray)
{
PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_POINTER(values, TArray<double>);
PARAM_BOOL(doublePrecision);
AddDoubleArray(self, values, doublePrecision);
return 0; return 0;
} }
DEFINE_ACTION_FUNCTION(DNetworkBuffer, AddStringArray) static void AddStringArray(DNetworkBuffer* const self, TArray<FString>* const values)
{
const unsigned int size = values->Size();
self->AddInt(size);
for (unsigned int i = 0u; i < size; ++i)
self->AddString((*values)[i]);
}
DEFINE_ACTION_FUNCTION_NATIVE(DNetworkBuffer, AddStringArray, AddStringArray)
{ {
PARAM_SELF_PROLOGUE(DNetworkBuffer); PARAM_SELF_PROLOGUE(DNetworkBuffer);
PARAM_POINTER(values, TArray<FString>); PARAM_POINTER(values, TArray<FString>);
unsigned int size = values->Size(); AddStringArray(self, values);
self->AddInt(size);
for (unsigned int i = 0u; i < size; ++i)
self->AddString((*values)[i]);
return 0; return 0;
} }

View file

@ -36,11 +36,6 @@ private:
size_t _index = 0; size_t _index = 0;
TArray<uint8_t> _stream; TArray<uint8_t> _stream;
inline bool IsValid() const
{
return _index < _stream.Size();
}
public: public:
int Player; int Player;
FName Command; FName Command;
@ -50,6 +45,11 @@ public:
_stream.Swap(stream); _stream.Swap(stream);
} }
inline bool EndOfStream() const
{
return _index >= _stream.Size();
}
inline void Reset() inline void Reset()
{ {
_index = 0; _index = 0;
@ -57,7 +57,7 @@ public:
int ReadInt8() int ReadInt8()
{ {
if (!IsValid()) if (EndOfStream())
return 0; return 0;
return _stream[_index++]; return _stream[_index++];
@ -66,11 +66,11 @@ public:
// If a value has to cut off early, just treat the previous value as the full one. // If a value has to cut off early, just treat the previous value as the full one.
int ReadInt16() int ReadInt16()
{ {
if (!IsValid()) if (EndOfStream())
return 0; return 0;
int value = _stream[_index++]; int value = _stream[_index++];
if (IsValid()) if (!EndOfStream())
value = (value << 8) | _stream[_index++]; value = (value << 8) | _stream[_index++];
return value; return value;
@ -78,17 +78,17 @@ public:
int ReadInt() int ReadInt()
{ {
if (!IsValid()) if (EndOfStream())
return 0; return 0;
int value = _stream[_index++]; int value = _stream[_index++];
if (IsValid()) if (!EndOfStream())
{ {
value = (value << 8) | _stream[_index++]; value = (value << 8) | _stream[_index++];
if (IsValid()) if (!EndOfStream())
{ {
value = (value << 8) | _stream[_index++]; value = (value << 8) | _stream[_index++];
if (IsValid()) if (!EndOfStream())
value = (value << 8) | _stream[_index++]; value = (value << 8) | _stream[_index++];
} }
} }
@ -99,17 +99,17 @@ public:
// Floats without their first bits are pretty meaningless so those are done first. // Floats without their first bits are pretty meaningless so those are done first.
double ReadFloat() double ReadFloat()
{ {
if (!IsValid()) if (EndOfStream())
return 0.0; return 0.0;
int value = _stream[_index++] << 24; int value = _stream[_index++] << 24;
if (IsValid()) if (!EndOfStream())
{ {
value |= _stream[_index++] << 16; value |= _stream[_index++] << 16;
if (IsValid()) if (!EndOfStream())
{ {
value |= _stream[_index++] << 8; value |= _stream[_index++] << 8;
if (IsValid()) if (!EndOfStream())
value |= _stream[_index++]; value |= _stream[_index++];
} }
} }
@ -125,29 +125,29 @@ public:
double ReadDouble() double ReadDouble()
{ {
if (!IsValid()) if (EndOfStream())
return 0.0; return 0.0;
int64_t value = int64_t(_stream[_index++]) << 56; int64_t value = int64_t(_stream[_index++]) << 56;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 48; value |= int64_t(_stream[_index++]) << 48;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 40; value |= int64_t(_stream[_index++]) << 40;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 32; value |= int64_t(_stream[_index++]) << 32;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 24; value |= int64_t(_stream[_index++]) << 24;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 16; value |= int64_t(_stream[_index++]) << 16;
if (IsValid()) if (!EndOfStream())
{ {
value |= int64_t(_stream[_index++]) << 8; value |= int64_t(_stream[_index++]) << 8;
if (IsValid()) if (!EndOfStream())
value |= int64_t(_stream[_index++]); value |= int64_t(_stream[_index++]);
} }
} }
@ -167,7 +167,7 @@ public:
const char* ReadString() const char* ReadString()
{ {
if (!IsValid()) if (EndOfStream())
return nullptr; return nullptr;
const char* str = reinterpret_cast<const char*>(&_stream[_index]); const char* str = reinterpret_cast<const char*>(&_stream[_index]);

View file

@ -19,11 +19,12 @@ struct NetworkCommand native play version("4.12")
native double ReadFloat(); native double ReadFloat();
native double ReadDouble(); native double ReadDouble();
native string ReadString(); native string ReadString();
native bool EndOfStream();
// Wrappers // Wrappers
native Name ReadName(); native Name ReadName();
native double ReadMapUnit(); // 16.16 long -> double native double ReadMapUnit(); // 16.16 int -> double
native double ReadAngle(); // BAM long -> double native double ReadAngle(); // BAM int -> double
native Vector2 ReadVector2(); native Vector2 ReadVector2();
native Vector3 ReadVector3(); native Vector3 ReadVector3();
native Vector4 ReadVector4(); native Vector4 ReadVector4();
@ -44,8 +45,8 @@ class NetworkBuffer native version("4.12")
// Wrappers // Wrappers
native void AddName(Name value); native void AddName(Name value);
native void AddMapUnit(double value); // double -> 16.16 long native void AddMapUnit(double value); // double -> 16.16 int
native void AddAngle(double value); // double -> BAM long native void AddAngle(double value); // double -> BAM int
native void AddVector2(Vector2 value); native void AddVector2(Vector2 value);
native void AddVector3(Vector3 value); native void AddVector3(Vector3 value);
native void AddVector4(Vector4 value); native void AddVector4(Vector4 value);