mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 23:52:02 +00:00
Added NetworkBuffer
Allows for a command to be built before sending it off. Added wrapper functions for certain data types. Changed command from a number to a Name.
This commit is contained in:
parent
9565c94cd2
commit
202d0d747f
6 changed files with 293 additions and 16 deletions
|
@ -2708,13 +2708,16 @@ void Net_DoCommand (int type, uint8_t **stream, int player)
|
|||
|
||||
case DEM_ZSC_CMD:
|
||||
{
|
||||
int cmd = ReadLong(stream);
|
||||
FName cmd = ReadStringConst(stream);
|
||||
unsigned int size = ReadWord(stream);
|
||||
|
||||
TArray<uint8_t> buffer = {};
|
||||
buffer.Grow(size);
|
||||
for (unsigned int i = 0u; i < size; ++i)
|
||||
buffer.Push(ReadByte(stream));
|
||||
if (size)
|
||||
{
|
||||
buffer.Grow(size);
|
||||
for (unsigned int i = 0u; i < size; ++i)
|
||||
buffer.Push(ReadByte(stream));
|
||||
}
|
||||
|
||||
FNetworkCommand netCmd = { player, cmd, buffer };
|
||||
primaryLevel->localEventManager->NetCommand(netCmd);
|
||||
|
@ -2779,7 +2782,8 @@ void Net_SkipCommand (int type, uint8_t **stream)
|
|||
break;
|
||||
|
||||
case DEM_ZSC_CMD:
|
||||
skip = 6 + (((*stream)[4] << 8) | (*stream)[5]);
|
||||
skip = strlen((char*)(*stream)) + 1;
|
||||
skip += (((*stream)[skip] << 8) | (*stream)[skip + 1]) + 2;
|
||||
break;
|
||||
|
||||
case DEM_SUMMON2:
|
||||
|
|
|
@ -163,7 +163,7 @@ enum EDemoCommand
|
|||
DEM_MDK, // 71 String: Damage type
|
||||
DEM_SETINV, // 72 SetInventory
|
||||
DEM_ENDSCREENJOB,
|
||||
DEM_ZSC_CMD, // 74 Long: Command id, Word: Byte size of command
|
||||
DEM_ZSC_CMD, // 74 String: Command, Word: Byte size of command
|
||||
};
|
||||
|
||||
// The following are implemented by cht_DoCheat in m_cheat.cpp
|
||||
|
|
164
src/events.cpp
164
src/events.cpp
|
@ -221,7 +221,7 @@ bool EventManager::SendNetworkEvent(FString name, int arg1, int arg2, int arg3,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EventManager::SendNetworkCommand(int cmd, VMVa_List args)
|
||||
bool EventManager::SendNetworkCommand(const FName& cmd, VMVa_List& args)
|
||||
{
|
||||
if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL)
|
||||
return false;
|
||||
|
@ -247,11 +247,13 @@ bool EventManager::SendNetworkCommand(int cmd, VMVa_List args)
|
|||
break;
|
||||
|
||||
case NET_STRING:
|
||||
{
|
||||
++bytes; // Strings will always consume at least one byte.
|
||||
const FString* str = ListGetString(args);
|
||||
if (str != nullptr)
|
||||
bytes += str->Len();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (tag != NET_STRING)
|
||||
|
@ -261,7 +263,7 @@ bool EventManager::SendNetworkCommand(int cmd, VMVa_List args)
|
|||
}
|
||||
|
||||
Net_WriteByte(DEM_ZSC_CMD);
|
||||
Net_WriteLong(cmd); // Using a full int here to allow better prevention of overlapping command ids.
|
||||
Net_WriteString(cmd.GetChars());
|
||||
Net_WriteWord(bytes);
|
||||
|
||||
constexpr char Default[] = "";
|
||||
|
@ -293,12 +295,14 @@ bool EventManager::SendNetworkCommand(int cmd, VMVa_List args)
|
|||
break;
|
||||
|
||||
case NET_STRING:
|
||||
{
|
||||
const FString* str = ListGetString(args);
|
||||
if (str != nullptr)
|
||||
Net_WriteString(str->GetChars());
|
||||
else
|
||||
Net_WriteString(Default); // Still have to send something here to be read correctly.
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
tag = ListGetInt(args);
|
||||
|
@ -307,6 +311,48 @@ bool EventManager::SendNetworkCommand(int cmd, VMVa_List args)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool EventManager::SendNetworkBuffer(const FName& cmd, const FNetworkBuffer* buffer)
|
||||
{
|
||||
if (gamestate != GS_LEVEL && gamestate != GS_TITLELEVEL)
|
||||
return false;
|
||||
|
||||
Net_WriteByte(DEM_ZSC_CMD);
|
||||
Net_WriteString(cmd.GetChars());
|
||||
Net_WriteWord(buffer != nullptr ? buffer->GetBytes() : 0);
|
||||
|
||||
if (buffer != nullptr)
|
||||
{
|
||||
for (unsigned int i = 0u; i < buffer->GetBufferSize(); ++i)
|
||||
{
|
||||
const auto& pair = buffer->GetPair(i);
|
||||
switch (pair.GetType())
|
||||
{
|
||||
case NET_BYTE:
|
||||
Net_WriteByte(pair.GetInt());
|
||||
break;
|
||||
|
||||
case NET_WORD:
|
||||
Net_WriteWord(pair.GetInt());
|
||||
break;
|
||||
|
||||
case NET_LONG:
|
||||
Net_WriteLong(pair.GetInt());
|
||||
break;
|
||||
|
||||
case NET_FLOAT:
|
||||
Net_WriteFloat(pair.GetFloat());
|
||||
break;
|
||||
|
||||
case NET_STRING:
|
||||
Net_WriteString(pair.GetString());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EventManager::CheckHandler(DStaticEventHandler* handler)
|
||||
{
|
||||
for (DStaticEventHandler* lhandler = FirstEventHandler; lhandler; lhandler = lhandler->next)
|
||||
|
@ -855,6 +901,109 @@ DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadString)
|
|||
ACTION_RETURN_STRING(res);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadName)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
|
||||
|
||||
FName res = NAME_None;
|
||||
auto str = self->ReadString();
|
||||
if (str != nullptr)
|
||||
res = str;
|
||||
|
||||
ACTION_RETURN_INT(res.GetIndex());
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector2)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
|
||||
|
||||
DVector2 vec = {};
|
||||
vec.X = self->ReadFloat();
|
||||
vec.Y = self->ReadFloat();
|
||||
ACTION_RETURN_VEC2(vec);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkCommand, ReadVector3)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkCommand);
|
||||
|
||||
DVector3 vec = {};
|
||||
vec.X = self->ReadFloat();
|
||||
vec.Y = self->ReadFloat();
|
||||
vec.Z = self->ReadFloat();
|
||||
ACTION_RETURN_VEC3(vec);
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddByte)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_INT(value);
|
||||
self->AddByte(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddWord)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_INT(value);
|
||||
self->AddWord(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddLong)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_INT(value);
|
||||
self->AddLong(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddFloat)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_FLOAT(value);
|
||||
self->AddFloat(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddString)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_STRING(value);
|
||||
self->AddString(value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddName)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_NAME(value);
|
||||
self->AddString(value.GetChars());
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddVector2)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
self->AddFloat(x);
|
||||
self->AddFloat(y);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(FNetworkBuffer, AddVector3)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(FNetworkBuffer);
|
||||
PARAM_FLOAT(x);
|
||||
PARAM_FLOAT(y);
|
||||
PARAM_FLOAT(z);
|
||||
self->AddFloat(x);
|
||||
self->AddFloat(y);
|
||||
self->AddFloat(z);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DStaticEventHandler);
|
||||
|
@ -867,13 +1016,22 @@ DEFINE_ACTION_FUNCTION(DStaticEventHandler, SetOrder)
|
|||
DEFINE_ACTION_FUNCTION(DEventHandler, SendNetworkCommand)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_INT(cmd);
|
||||
PARAM_NAME(cmd);
|
||||
PARAM_VA_POINTER(va_reginfo);
|
||||
|
||||
VMVa_List args = { param + 1, 0, numparam - 2, va_reginfo + 1 };
|
||||
ACTION_RETURN_BOOL(currentVMLevel->localEventManager->SendNetworkCommand(cmd, args));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DEventHandler, SendNetworkBuffer)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
PARAM_NAME(cmd);
|
||||
PARAM_POINTER(buffer, FNetworkBuffer);
|
||||
|
||||
ACTION_RETURN_BOOL(currentVMLevel->localEventManager->SendNetworkBuffer(cmd, buffer));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DEventHandler, SendNetworkEvent)
|
||||
{
|
||||
PARAM_PROLOGUE;
|
||||
|
|
101
src/events.h
101
src/events.h
|
@ -5,6 +5,7 @@
|
|||
#include "d_event.h"
|
||||
#include "sbar.h"
|
||||
#include "info.h"
|
||||
#include "vm.h"
|
||||
|
||||
class DStaticEventHandler;
|
||||
struct EventManager;
|
||||
|
@ -31,7 +32,7 @@ struct FNetworkCommand
|
|||
{
|
||||
private:
|
||||
size_t _index = 0;
|
||||
TArray<uint8_t> _stream = {};
|
||||
TArray<uint8_t> _stream;
|
||||
|
||||
inline bool IsValid() const
|
||||
{
|
||||
|
@ -39,10 +40,10 @@ private:
|
|||
}
|
||||
|
||||
public:
|
||||
int Player = 0;
|
||||
int Command = 0;
|
||||
int Player;
|
||||
FName Command;
|
||||
|
||||
FNetworkCommand(const int player, const int command, TArray<uint8_t>& stream) : Player(player), Command(command)
|
||||
FNetworkCommand(const int player, const FName& command, TArray<uint8_t>& stream) : Player(player), Command(command)
|
||||
{
|
||||
_stream.Swap(stream);
|
||||
}
|
||||
|
@ -131,6 +132,94 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
struct FNetworkBuffer
|
||||
{
|
||||
public:
|
||||
struct BufferPair
|
||||
{
|
||||
private:
|
||||
ENetCmd _type;
|
||||
VMValue _message;
|
||||
|
||||
public:
|
||||
BufferPair(const ENetCmd type, const int message) : _type(type), _message(message) {}
|
||||
BufferPair(const ENetCmd type, const double message) : _type(type), _message(message) {}
|
||||
BufferPair(const ENetCmd type, const FString* message) : _type(type), _message(message) {}
|
||||
|
||||
inline ENetCmd GetType() const
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
inline int GetInt() const
|
||||
{
|
||||
return _message.i;
|
||||
}
|
||||
|
||||
inline double GetFloat() const
|
||||
{
|
||||
return _message.f;
|
||||
}
|
||||
|
||||
inline const char* GetString() const
|
||||
{
|
||||
return _message.s().GetChars();
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
unsigned int _size;
|
||||
TArray<BufferPair> _buffer;
|
||||
TArray<FString> _strings; // Local copies of these need to be stored since VMValues store pointers to strings.
|
||||
|
||||
public:
|
||||
inline unsigned int GetBytes() const
|
||||
{
|
||||
return _size;
|
||||
}
|
||||
|
||||
inline unsigned int GetBufferSize() const
|
||||
{
|
||||
return _buffer.Size();
|
||||
}
|
||||
|
||||
inline const BufferPair& GetPair(unsigned int i) const
|
||||
{
|
||||
return _buffer[i];
|
||||
}
|
||||
|
||||
void AddByte(int byte)
|
||||
{
|
||||
++_size;
|
||||
_buffer.Push({ NET_BYTE, byte });
|
||||
}
|
||||
|
||||
void AddWord(int word)
|
||||
{
|
||||
_size += 2u;
|
||||
_buffer.Push({ NET_WORD, word });
|
||||
}
|
||||
|
||||
void AddLong(int msg)
|
||||
{
|
||||
_size += 4u;
|
||||
_buffer.Push({ NET_LONG, msg });
|
||||
}
|
||||
|
||||
void AddFloat(double msg)
|
||||
{
|
||||
_size += 4u;
|
||||
_buffer.Push({ NET_FLOAT, msg });
|
||||
}
|
||||
|
||||
void AddString(const FString& msg)
|
||||
{
|
||||
_size += msg.Len() + 1u;
|
||||
unsigned int index = _strings.Push(msg);
|
||||
_buffer.Push({ NET_STRING, &_strings[index] });
|
||||
}
|
||||
};
|
||||
|
||||
// ==============================================
|
||||
//
|
||||
// EventHandler - base class
|
||||
|
@ -413,7 +502,9 @@ struct EventManager
|
|||
// send networked event. unified function.
|
||||
bool SendNetworkEvent(FString name, int arg1, int arg2, int arg3, bool manual);
|
||||
// Send a custom network command from ZScript.
|
||||
bool SendNetworkCommand(int cmd, VMVa_List args);
|
||||
bool SendNetworkCommand(const FName& cmd, VMVa_List& args);
|
||||
// Send a pre-built command buffer over.
|
||||
bool SendNetworkBuffer(const FName& cmd, const FNetworkBuffer* buffer);
|
||||
|
||||
// check if there is anything that should receive GUI events
|
||||
bool CheckUiProcessors();
|
||||
|
|
|
@ -812,6 +812,10 @@ void InitThingdef()
|
|||
netcmdstruct->Size = sizeof(FNetworkCommand);
|
||||
netcmdstruct->Align = alignof(FNetworkCommand);
|
||||
|
||||
auto netbuffstruct = NewStruct("NetworkBuffer", nullptr);
|
||||
netbuffstruct->Size = sizeof(FNetworkBuffer);
|
||||
netbuffstruct->Align = alignof(FNetworkBuffer);
|
||||
|
||||
auto fltd = NewStruct("FLineTraceData", nullptr);
|
||||
fltd->Size = sizeof(FLineTraceData);
|
||||
fltd->Align = alignof(FLineTraceData);
|
||||
|
|
|
@ -10,13 +10,32 @@ enum ENetCmd
|
|||
struct NetworkCommand native play version("4.12")
|
||||
{
|
||||
native readonly int Player;
|
||||
native readonly int Command;
|
||||
native readonly Name Command;
|
||||
|
||||
native int ReadByte();
|
||||
native int ReadWord();
|
||||
native int ReadLong();
|
||||
native double ReadFloat();
|
||||
native string ReadString();
|
||||
|
||||
// Wrappers
|
||||
native Name ReadName();
|
||||
native Vector2 ReadVector2();
|
||||
native Vector3 ReadVector3();
|
||||
}
|
||||
|
||||
struct NetworkBuffer native version("4.12")
|
||||
{
|
||||
native void AddByte(int value);
|
||||
native void AddWord(int value);
|
||||
native void AddLong(int value);
|
||||
native void AddFloat(double value);
|
||||
native void AddString(string value);
|
||||
|
||||
// Wrappers
|
||||
native void AddName(Name value);
|
||||
native void AddVector2(Vector2 value);
|
||||
native void AddVector3(Vector3 value);
|
||||
}
|
||||
|
||||
struct RenderEvent native ui version("2.4")
|
||||
|
@ -171,6 +190,7 @@ class EventHandler : StaticEventHandler native version("2.4")
|
|||
{
|
||||
clearscope static native StaticEventHandler Find(class<StaticEventHandler> type);
|
||||
clearscope static native void SendNetworkEvent(String name, int arg1 = 0, int arg2 = 0, int arg3 = 0);
|
||||
version("4.12") clearscope static native vararg bool SendNetworkCommand(int cmd, ...);
|
||||
version("4.12") clearscope static native vararg bool SendNetworkCommand(Name cmd, ...);
|
||||
version("4.12") clearscope static native bool SendNetworkBuffer(Name cmd, NetworkBuffer buffer);
|
||||
clearscope static native void SendInterfaceEvent(int playerNum, string name, int arg1 = 0, int arg2 = 0, int arg3 = 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue