Moved netmsg implementations, restructure

This commit is contained in:
Jordan Cristiano 2015-05-14 21:36:57 -04:00
parent 78de8690ab
commit 90d39bc498
75 changed files with 2421 additions and 201 deletions

View File

@ -26,3 +26,23 @@ IDemoWriter* IDemoWriter::CreateDemoWriter(void* outputFp)
DemoWriter::DemoWriter(FILE* outputFp)
{
}
void DemoWriter::StartWriting(demoheader_t& header)
{
}
void DemoWriter::EndWriting()
{
}
void DemoWriter::StartCommandPacket(CommandPacket& packet)
{
}
void DemoWriter::EndCommandPacket()
{
}
void DemoWriter::WriteNetPacket(NetPacket& packet)
{
}

View File

@ -2,36 +2,51 @@
#include "demoreader.h"
#include "idemowriter.h"
#include "demofile.h"
#include "demotypes.h"
/*void ParsePacket(const std::vector<unsigned char>& packet)
#include "netmessages/netmessages.h"
#include "netmessages/netcontants.h"
#include "bitbuf.h"
#include <vector>
#include <cstdint>
typedef bool (*NetMsgReadFn)(bf_read& bitbuf, SourceGameContext& context, void* data);
static const NetMsgReadFn netHandlers[] = DECLARE_NET_HANDLER_ARRAY(BitRead);
//static const void* netDataStructs[] = DECLARE_NET_DATA_ARRAY;
void ParsePacket(uint8_t* packet, size_t length, IDemoWriter* writer)
{
assert(packet.size() <= NET_MAX_PAYLOAD);
bf_read bitbuf(packet.data(), packet.size());
assert(length <= NET_MAX_PAYLOAD);
bf_read bitbuf(packet, length);
NetPacket netPacket;
while (bitbuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS)
{
uint32 typeId = bitbuf.ReadUBitLong(NETMSG_TYPE_BITS);
printf("%i\n", typeId);
//ProcessNetMsg(typeId, bitbuf);
netPacket.type = bitbuf.ReadUBitLong(NETMSG_TYPE_BITS);
//netPacket.data = netDataStructs[netPacket.type];
//netHandlers[netPacket.type](bitbuf, context, );
}
}
void ParseDemoSequence(const std::vector<unsigned char>& sequenceData)
void ParseDemo(DemoFileReader& reader, IDemoWriter* writer)
{
democmdinfo_t cmdInfo;
CommandPacket packet;
packet.cmdInfo = &cmdInfo;
std::vector<uint8_t> buffer;
buffer.resize(NET_MAX_PAYLOAD);
DemoSequenceReader reader(sequenceData);
for (; reader.ReadCmdHeader(packet.cmd, packet.tick);)
do
{
reader.ReadCmdHeader(packet.cmd, packet.tick);
switch (packet.cmd)
{
case dem_signon:
case dem_packet:
reader.ReadCmdInfo(packet.cmdInfo);
reader.ReadCmdInfo(*packet.cmdInfo);
reader.ReadSequenceInfo(packet.sequenceInfo1, packet.sequenceInfo2);
assert(packet.sequenceInfo1 == packet.sequenceInfo2);
reader.ReadRawData(buffer);
ParsePacket(buffer);
reader.ReadRawData(buffer.data(), buffer.size());
break;
case dem_synctick:
// nothing
@ -40,7 +55,7 @@ void ParseDemoSequence(const std::vector<unsigned char>& sequenceData)
reader.ReadRawData(nullptr, 1024);
break;
case dem_usercmd:
reader.ReadUserCmd(buffer, 256);
reader.ReadUserCmd(buffer.data(), 256);
break;
case dem_datatables:
// TODO: datatables
@ -59,14 +74,23 @@ void ParseDemoSequence(const std::vector<unsigned char>& sequenceData)
assert(false);
break;
}
}
}*/
writer->StartCommandPacket(packet);
if (packet.cmd == dem_packet || packet.cmd == dem_signon)
{
ParsePacket(buffer.data(), buffer.size(), writer);
}
writer->EndCommandPacket();
} while (packet.cmd != dem_stop);
}
void DemoReader::ProcessDem(void* inputFp, IDemoWriter* writer)
{
DemoFileReader demoFile(reinterpret_cast<FILE*>(inputFp));
//auto demoHeader = demoFile.GetDemoHeader();
//ParseDemoSequence(demoFile.GetSignOnData());
//ParseDemoSequence(demoFile.GetDemoData());
{
demoheader_t header;
demoFile.ReadDemoHeader(header);
writer->StartWriting(header);
}
ParseDemo(demoFile, writer);
writer->EndWriting();
}

View File

@ -22,3 +22,27 @@ IDemoWriter* IDemoWriter::CreateJsonWriter(void* outputFp)
{
return new JsonWriter(reinterpret_cast<FILE*>(outputFp));
}
JsonWriter::JsonWriter(FILE* outputFp)
{
}
void JsonWriter::StartWriting(demoheader_t& header)
{
}
void JsonWriter::EndWriting()
{
}
void JsonWriter::StartCommandPacket(CommandPacket& packet)
{
}
void JsonWriter::EndCommandPacket()
{
}
void JsonWriter::WriteNetPacket(NetPacket& packet)
{
}

View File

@ -1,23 +1,9 @@
/*
#include "netmessages.h"
#include "demofilebitbuf.h"
#include "sourcenetcontants.h"
#include <cassert>
namespace math
{
unsigned int log2(unsigned int value)
{
unsigned int res = 0;
while (value >>= 1)
++res;
return res;
}
unsigned int Bits2Bytes(unsigned int bits)
{
return ((bits + 7) >> 3);
}
}
#include "netmath.h"
void Net_NOP(CBitRead& bitbuf)
{
@ -81,6 +67,7 @@ void Net_SignonState(CBitRead& bitbuf)
const int spawnCount = bitbuf.ReadLong();
}
// verified
void SVC_Print(CBitRead& bitbuf)
{
char textBuffer[2048];
@ -127,6 +114,7 @@ void SVC_ServerInfo(CBitRead& bitbuf)
// }
}
// verified
void SVC_SendTable(CBitRead& bitbuf)
{
const bool needsDecoder = bitbuf.ReadOneBit() != 0;
@ -160,6 +148,7 @@ void SVC_ClassInfo(CBitRead& bitbuf)
}
}
// verified
void SVC_SetPause(CBitRead& bitbuf)
{
const bool paused = bitbuf.ReadOneBit() != 0;
@ -191,7 +180,7 @@ void SVC_CreateStringTable(CBitRead& bitbuf)
// }
// else
// {
// const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS + 1);
// const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PAYLOAD_BITS + 1);
// }
const bool userDataFixedSize = bitbuf.ReadOneBit() != 0;
@ -234,6 +223,7 @@ void SVC_VoiceInit(CBitRead& bitbuf)
const int quality = bitbuf.ReadByte(); // custom quality setting
}
// verified
void SVC_VoiceData(CBitRead& bitbuf)
{
const int fromClientIndex = bitbuf.ReadByte();
@ -266,6 +256,7 @@ void SVC_Sounds(CBitRead& bitbuf)
bitbuf.SeekRelative(lengthInBits);
}
// verified
void SVC_SetView(CBitRead& bitbuf)
{
const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
@ -309,6 +300,7 @@ void SVC_TerrainMod(CBitRead& bitbuf)
assert(false);
}
// verified
void SVC_UserMessage(CBitRead& bitbuf)
{
const int msgType = bitbuf.ReadByte();
@ -318,6 +310,7 @@ void SVC_UserMessage(CBitRead& bitbuf)
bitbuf.SeekRelative(lengthInBits);
}
// verified
void SVC_EntityMessage(CBitRead& bitbuf)
{
const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
@ -328,6 +321,7 @@ void SVC_EntityMessage(CBitRead& bitbuf)
bitbuf.SeekRelative(lengthInBits);
}
// verified
void SVC_GameEvent(CBitRead& bitbuf)
{
const int lengthInBits = bitbuf.ReadUBitLong(11);
@ -335,6 +329,7 @@ void SVC_GameEvent(CBitRead& bitbuf)
bitbuf.SeekRelative(lengthInBits);
}
// verified
void SVC_PacketEntities(CBitRead& bitbuf)
{
const int maxEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
@ -357,7 +352,7 @@ void SVC_PacketEntities(CBitRead& bitbuf)
void SVC_TempEntities(CBitRead& bitbuf)
{
const int numEntries = bitbuf.ReadUBitLong(EVENT_INDEX_BITS);
const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS);
const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PAYLOAD_BITS);
bitbuf.SeekRelative(lengthInBits);
}
@ -391,17 +386,20 @@ void SVC_Menu(CBitRead& bitbuf)
void SVC_GameEventList(CBitRead& bitbuf)
{
const int numEvents = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
const int lengthInBits = bitbuf.ReadUBitLong(20);
for (int i = 0; i < numEvents; ++i)
{
const int id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
char name[MAX_EVENT_NAME_LENGTH];
bitbuf.ReadString(name, sizeof(name));
printf("%s\n", name);
assert(false);
while (bitbuf.ReadUBitLong(3) > 0)
{
bitbuf.ReadString(name, sizeof(name));
}
// gameeventmanager.cpp ParseEventList
}
const int lengthInBits = bitbuf.ReadUBitLong(20);
bitbuf.SeekRelative(lengthInBits);
//bitbuf.SeekRelative(lengthInBits);
}
void SVC_GetCvarValue(CBitRead& bitbuf)
@ -411,48 +409,4 @@ void SVC_GetCvarValue(CBitRead& bitbuf)
char cvarName[256];
bitbuf.ReadString(cvarName, sizeof(cvarName));
}
static const int NUM_MESSAGES = static_cast<uint8_t>(NetMsg::SVC_LASTMSG) + 1;
void ProcessNetMsg(const std::uint32_t msgType, CBitRead& bitbuf)
{
static NetMsgFn netMsgHandler[NUM_MESSAGES] =
{
&Net_NOP,
&Net_Disconnect,
&Net_File,
&Net_Tick,
&Net_StringCmd,
&Net_SetConVar,
&Net_SignonState,
&SVC_Print,
&SVC_ServerInfo,
&SVC_SendTable,
&SVC_ClassInfo,
&SVC_SetPause,
&SVC_CreateStringTable,
&SVC_UpdateStringTable,
&SVC_VoiceInit,
&SVC_VoiceData,
&SVC_HLTV,
&SVC_Sounds,
&SVC_SetView,
&SVC_FixAngle,
&SVC_CrosshairAngle,
&SVC_BSPDecal,
&SVC_TerrainMod,
&SVC_UserMessage,
&SVC_EntityMessage,
&SVC_GameEvent,
&SVC_PacketEntities,
&SVC_TempEntities,
&SVC_Prefetch,
&SVC_Menu,
&SVC_GameEventList,
&SVC_GetCvarValue
};
assert(msgType < NUM_MESSAGES);
netMsgHandler[msgType](bitbuf);
}
*/

View File

@ -1,114 +0,0 @@
#pragma once
#include <cstdint>
class CBitRead;
typedef void(*NetMsgFn)(CBitRead& bitbuf);
enum constants
{
// was 5
NETMSG_TYPE_BITS = 6, // 2^NETMSG_TYPE_BITS > SVC_LASTMSG
// was 96000
NET_MAX_PAYLOAD = 288000, // largest message size in bytes
// was 17
NET_MAX_PALYLOAD_BITS = 19, // 2^NET_MAX_PALYLOAD_BITS > NET_MAX_PAYLOAD
// table index is sent in log2(MAX_TABLES) bits
MAX_TABLES = 32, // Table id is 4 bits
// How many bits to use to encode an edict.
MAX_EDICT_BITS = 11, // # of bits needed to represent max edicts
// Max # of edicts in a level
MAX_EDICTS = (1<<MAX_EDICT_BITS),
MAX_DECAL_INDEX_BITS = 9,
SP_MODEL_INDEX_BITS = 11,
MAX_SERVER_CLASS_BITS = 9,
MAX_EVENT_NAME_LENGTH = 32,
MAX_EVENT_BITS = 9,
MAX_EVENT_NUMBER = (1 << MAX_EVENT_BITS),
MAX_EVENT_BYTES = 1024,
DELTASIZE_BITS = 20, // must be: 2^DELTASIZE_BITS > (NET_MAX_PAYLOAD * 8)
EVENT_INDEX_BITS = 8,
MAX_SOUND_INDEX_BITS = 13,
SIGNONSTATE_NONE = 0, // no state yet, about to connect
SIGNONSTATE_CHALLENGE = 1, // client challenging server, all OOB packets
SIGNONSTATE_CONNECTED = 2, // client is connected to server, netchans ready
SIGNONSTATE_NEW = 3, // just got serverinfo and string tables
SIGNONSTATE_PRESPAWN = 4, // received signon buffers
SIGNONSTATE_SPAWN = 5, // ready to receive entity packets
SIGNONSTATE_FULL = 6, // we are fully connected, first non-delta packet received
SIGNONSTATE_CHANGELEVEL = 7 // server is changing level, please wait
};
enum class NetMsg: std::uint8_t
{
net_NOP = 0, // nop command used for padding
net_Disconnect = 1, // disconnect, last message in connection
net_File = 2, // file transmission message request/deny
net_Tick = 3, // send last world tick
net_StringCmd = 4, // a string command
net_SetConVar = 5, // sends one/multiple convar settings
net_SignonState = 6, // signals current signon state
//
// server to client
//
svc_Print = 7, // print text to console
svc_ServerInfo = 8, // first message from server about game, map etc
svc_SendTable = 9, // sends a sendtable description for a game class
svc_ClassInfo = 10, // Info about classes (first byte is a CLASSINFO_ define).
svc_SetPause = 11, // tells client if server paused or unpaused
svc_CreateStringTable = 12, // inits shared string tables
svc_UpdateStringTable = 13, // updates a string table
svc_VoiceInit = 14, // inits used voice codecs & quality
svc_VoiceData = 15, // Voicestream data from the server
//svc_HLTV = 16, // HLTV control messages
svc_Sounds = 17, // starts playing sound
svc_SetView = 18, // sets entity as point of view
svc_FixAngle = 19, // sets/corrects players viewangle
svc_CrosshairAngle = 20, // adjusts crosshair in auto aim mode to lock on traget
svc_BSPDecal = 21, // add a static decal to the worl BSP
// NOTE: This is now unused!
// svc_TerrainMod = 22, // modification to the terrain/displacement
// Message from server side to client side entity
svc_UserMessage = 23, // a game specific message
svc_EntityMessage = 24, // a message for an entity
svc_GameEvent = 25, // global game event fired
svc_PacketEntities = 26, // non-delta compressed entities
svc_TempEntities = 27, // non-reliable event object
svc_Prefetch = 28, // only sound indices for now
svc_Menu = 29, // display a menu from a plugin
svc_GameEventList = 30, // list of known games events and fields
svc_GetCvarValue = 31, // Server wants to know the value of a cvar on the client.
SVC_LASTMSG = 31 // last known server messages
};
void ProcessNetMsg(const std::uint32_t msgType, CBitRead& bitbuf);

View File

@ -0,0 +1,33 @@
#include "net_disconnect.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool Net_Disconnect_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_Disconnect* data)
{
bitbuf.ReadString(data->message, sizeof(data->message));
return !bitbuf.IsOverflowed();
}
bool Net_Disconnect_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_Disconnect* data)
{
bitbuf.WriteString(data->message);
return !bitbuf.IsOverflowed();
}
bool Net_Disconnect_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_Disconnect* data)
{
return true;
}
bool Net_Disconnect_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_Disconnect* data)
{
return true;
}
void Net_Disconnect_ToString_Internal(std::ostringstream& out, NetMsg::Net_Disconnect* data)
{
// nothing
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_Disconnect
{
char message[1024];
};
}
DECLARE_NET_HANDLERS(Net_Disconnect);

View File

@ -0,0 +1,37 @@
#include "net_file.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool Net_File_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_File* data)
{
data->transferID = bitbuf.ReadUBitLong(32);
bitbuf.ReadString(data->filename, sizeof(data->filename));
data->isRequest = bitbuf.ReadOneBit() != 0;
return !bitbuf.IsOverflowed();
}
bool Net_File_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_File* data)
{
bitbuf.WriteUBitLong(data->transferID, 32);
bitbuf.WriteString(data->filename);
bitbuf.WriteOneBit(data->isRequest);
return !bitbuf.IsOverflowed();
}
bool Net_File_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_File* data)
{
return true;
}
bool Net_File_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_File* data)
{
return true;
}
void Net_File_ToString_Internal(std::ostringstream& out, NetMsg::Net_File* data)
{
// nothing
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_File
{
std::uint32_t transferID;
bool isRequest;
char filename[1024];
};
}
DECLARE_NET_HANDLERS(Net_File);

View File

@ -0,0 +1,29 @@
#include "net_nop.h"
namespace NetHandlers
{
bool Net_NOP_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_NOP* data)
{
return true;
}
bool Net_NOP_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_NOP* data)
{
return true;
}
bool Net_NOP_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_NOP* data)
{
return true;
}
bool Net_NOP_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_NOP* data)
{
return true;
}
void Net_NOP_ToString_Internal(std::ostringstream& out, NetMsg::Net_NOP* data)
{
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_NOP
{
};
}
DECLARE_NET_HANDLERS(Net_NOP);

View File

@ -0,0 +1,46 @@
#include "net_setconvar.h"
#include "bitbuf.h"
namespace NetHandlers
{
using cvar_t = NetMsg::Net_SetConVar::cvar_t;
bool Net_SetConVar_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_SetConVar* data)
{
data->cvars.resize(bitbuf.ReadUBitLong(8));
for (cvar_t& cvar : data->cvars)
{
bitbuf.ReadString(cvar.name, sizeof(cvar.name));
bitbuf.ReadString(cvar.value, sizeof(cvar.value));
}
return !bitbuf.IsOverflowed();
}
bool Net_SetConVar_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_SetConVar* data)
{
bitbuf.WriteUBitLong(data->cvars.size(), 8);
for (cvar_t& cvar : data->cvars)
{
bitbuf.WriteString(cvar.name);
bitbuf.WriteString(cvar.value);
}
return !bitbuf.IsOverflowed();
}
bool Net_SetConVar_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_SetConVar* data)
{
return true;
}
bool Net_SetConVar_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_SetConVar* data)
{
return true;
}
void Net_SetConVar_ToString_Internal(std::ostringstream& out, NetMsg::Net_SetConVar* data)
{
cvar_t cvar = data->cvars[0];
out << "net_SetConVar: " << data->cvars.size() << " cvars, \"" << cvar.name << "\"=\"" << cvar.value << '"';
}
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "nethandlers.h"
#include <vector>
namespace NetMsg
{
struct Net_SetConVar
{
typedef struct cvar_s
{
char name[MAX_OSPATH];
char value[MAX_OSPATH];
} cvar_t;
std::vector<cvar_t> cvars;
};
}
DECLARE_NET_HANDLERS(Net_SetConVar);

View File

@ -0,0 +1,36 @@
#include "net_signonstate.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool Net_SignonState_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_SignonState* data)
{
data->signonState = bitbuf.ReadUBitLong(8);
data->spawnCount = bitbuf.ReadUBitLong(32);
//assert(signonState >= SIGNONSTATE_NONE && signonState <= SIGNONSTATE_CHANGELEVEL);
return !bitbuf.IsOverflowed();
}
bool Net_SignonState_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_SignonState* data)
{
bitbuf.WriteUBitLong(data->signonState, 8);
bitbuf.WriteUBitLong(data->spawnCount, 32);
return !bitbuf.IsOverflowed();
}
bool Net_SignonState_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_SignonState* data)
{
return true;
}
bool Net_SignonState_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_SignonState* data)
{
return true;
}
void Net_SignonState_ToString_Internal(std::ostringstream& out, NetMsg::Net_SignonState* data)
{
out << "net_SignonState: state " << data->signonState << ", count " << data->spawnCount;
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_SignonState
{
std::uint32_t spawnCount;
std::uint8_t signonState;
};
}
DECLARE_NET_HANDLERS(Net_SignonState);

View File

@ -0,0 +1,33 @@
#include "net_stringcmd.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool Net_StringCmd_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_StringCmd* data)
{
bitbuf.ReadString(data->command, sizeof(data->command));
return !bitbuf.IsOverflowed();
}
bool Net_StringCmd_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_StringCmd* data)
{
bitbuf.WriteString(data->command);
return !bitbuf.IsOverflowed();
}
bool Net_StringCmd_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_StringCmd* data)
{
return true;
}
bool Net_StringCmd_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_StringCmd* data)
{
return true;
}
void Net_StringCmd_ToString_Internal(std::ostringstream& out, NetMsg::Net_StringCmd* data)
{
out << "net_StringCmd: \"" << data->command << '"';
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_StringCmd
{
char command[1024];
};
}
DECLARE_NET_HANDLERS(Net_StringCmd);

View File

@ -0,0 +1,37 @@
#include "net_tick.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool Net_Tick_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::Net_Tick* data)
{
data->tick = bitbuf.ReadUBitLong(32);
data->hostFrameTime = bitbuf.ReadUBitLong(16);
data->hostFrameTimeStdDev = bitbuf.ReadUBitLong(16);
return !bitbuf.IsOverflowed();
}
bool Net_Tick_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::Net_Tick* data)
{
bitbuf.WriteUBitLong(data->tick, 32);
bitbuf.WriteUBitLong(data->hostFrameTime, 16);
bitbuf.WriteUBitLong(data->hostFrameTimeStdDev, 16);
return !bitbuf.IsOverflowed();
}
bool Net_Tick_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::Net_Tick* data)
{
return true;
}
bool Net_Tick_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::Net_Tick* data)
{
return true;
}
void Net_Tick_ToString_Internal(std::ostringstream& out, NetMsg::Net_Tick* data)
{
out << "net_Tick: tick " << data->tick;
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct Net_Tick
{
static const std::uint32_t NET_TICK_SCALEUP = 100000;
std::int32_t tick;
std::uint16_t hostFrameTime;
std::uint16_t hostFrameTimeStdDev;
};
}
DECLARE_NET_HANDLERS(Net_Tick);

View File

@ -0,0 +1,46 @@
#pragma once
enum constants
{
// was 5
NETMSG_TYPE_BITS = 6, // 2^NETMSG_TYPE_BITS > SVC_LASTMSG
// was 96000
NET_MAX_PAYLOAD = 288000, // largest message size in bytes
// was 17
NET_MAX_PAYLOAD_BITS = 19, // 2^NET_MAX_PAYLOAD_BITS > NET_MAX_PAYLOAD
// table index is sent in log2(MAX_TABLES) bits
MAX_TABLES = 32, // Table id is 4 bits
// How many bits to use to encode an edict.
MAX_EDICT_BITS = 11, // # of bits needed to represent max edicts
// Max # of edicts in a level
MAX_EDICTS = (1 << MAX_EDICT_BITS),
MAX_DECAL_INDEX_BITS = 9,
SP_MODEL_INDEX_BITS = 11,
MAX_SERVER_CLASS_BITS = 9,
MAX_EVENT_NAME_LENGTH = 32,
MAX_EVENT_BITS = 9,
MAX_EVENT_NUMBER = (1 << MAX_EVENT_BITS),
MAX_EVENT_BYTES = 1024,
DELTASIZE_BITS = 20, // must be: 2^DELTASIZE_BITS > (NET_MAX_PAYLOAD * 8)
EVENT_INDEX_BITS = 8,
MAX_SOUND_INDEX_BITS = 13,
MAX_USER_MSG_DATA = 255,
SIGNONSTATE_NONE = 0, // no state yet, about to connect
SIGNONSTATE_CHALLENGE = 1, // client challenging server, all OOB packets
SIGNONSTATE_CONNECTED = 2, // client is connected to server, netchans ready
SIGNONSTATE_NEW = 3, // just got serverinfo and string tables
SIGNONSTATE_PRESPAWN = 4, // received signon buffers
SIGNONSTATE_SPAWN = 5, // ready to receive entity packets
SIGNONSTATE_FULL = 6, // we are fully connected, first non-delta packet received
SIGNONSTATE_CHANGELEVEL = 7 // server is changing level, please wait
};

View File

@ -0,0 +1,88 @@
#pragma once
#include <cstdint>
#include <sstream>
class bf_read;
class bf_write;
class JsonRead;
class JsonWrite;
struct SourceGameContext
{
int16_t protocol;
};
#if !defined(MAX_OSPATH)
#define MAX_OSPATH 260 // max length of a filesystem pathname
#endif
#define DECLARE_NET_HANDLERS(msgname) \
namespace NetHandlers \
{ \
namespace \
{ \
bool msgname##_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::##msgname* data); \
bool msgname##_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::##msgname* data); \
bool msgname##_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::##msgname* data); \
bool msgname##_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::##msgname* data); \
void msgname##_ToString_Internal(std::ostringstream& out, NetMsg::##msgname* data); \
} \
inline bool msgname##_BitRead(bf_read& bitbuf, SourceGameContext& context, void* data) \
{ \
return msgname##_BitRead_Internal(bitbuf, context, reinterpret_cast<NetMsg::##msgname*>(data)); \
} \
inline bool msgname##_BitWrite(bf_write& bitbuf, SourceGameContext& context, void* data) \
{ \
return msgname##_BitWrite_Internal(bitbuf, context, reinterpret_cast<NetMsg::##msgname*>(data)); \
} \
inline bool msgname##_JsonRead(JsonRead& jsonbuf, SourceGameContext& context, void* data) \
{ \
return msgname##_JsonRead_Internal(jsonbuf, context, reinterpret_cast<NetMsg::##msgname*>(data)); \
} \
inline bool msgname##_JsonWrite(JsonWrite& jsonbuf, SourceGameContext& context, void* data) \
{ \
return msgname##_JsonWrite_Internal(jsonbuf, context, reinterpret_cast<NetMsg::##msgname*>(data)); \
} \
inline void msgname##_ToString(std::ostringstream& out, void* data) \
{ \
msgname##_ToString_Internal(out, reinterpret_cast<NetMsg::##msgname*>(data)); \
} \
}
#define DECLARE_NET_HANDLER_ARRAY(funcname) \
{ \
&NetHandlers::Net_NOP_##funcname, \
&NetHandlers::Net_Disconnect_##funcname, \
&NetHandlers::Net_File_##funcname, \
&NetHandlers::Net_Tick_##funcname, \
&NetHandlers::Net_StringCmd_##funcname, \
&NetHandlers::Net_SetConVar_##funcname, \
&NetHandlers::Net_SignonState_##funcname, \
&NetHandlers::SVC_Print_##funcname, \
&NetHandlers::SVC_ServerInfo_##funcname, \
&NetHandlers::SVC_SendTable_##funcname, \
&NetHandlers::SVC_ClassInfo_##funcname, \
&NetHandlers::SVC_SetPause_##funcname, \
&NetHandlers::SVC_CreateStringTable_##funcname, \
&NetHandlers::SVC_UpdateStringTable_##funcname, \
&NetHandlers::SVC_VoiceInit_##funcname, \
&NetHandlers::SVC_VoiceData_##funcname, \
&NetHandlers::SVC_HLTV_##funcname, \
&NetHandlers::SVC_Sounds_##funcname, \
&NetHandlers::SVC_SetView_##funcname, \
&NetHandlers::SVC_FixAngle_##funcname, \
&NetHandlers::SVC_CrosshairAngle_##funcname, \
&NetHandlers::SVC_BSPDecal_##funcname, \
&NetHandlers::SVC_TerrainMod_##funcname, \
&NetHandlers::SVC_UserMessage_##funcname, \
&NetHandlers::SVC_EntityMessage_##funcname, \
&NetHandlers::SVC_GameEvent_##funcname, \
&NetHandlers::SVC_PacketEntities_##funcname, \
&NetHandlers::SVC_TempEntities_##funcname, \
&NetHandlers::SVC_Prefetch_##funcname, \
&NetHandlers::SVC_Menu_##funcname, \
&NetHandlers::SVC_GameEventList_##funcname, \
&NetHandlers::SVC_GetCvarValue_##funcname \
}

View File

@ -0,0 +1,20 @@
#pragma once
#include <cstddef>
namespace math
{
static size_t log2(size_t value)
{
size_t res = 0;
while (value >>= 1)
++res;
return res;
}
static size_t BitsToBytes(size_t bits)
{
return ((bits + 7) >> 3);
}
}

View File

@ -0,0 +1,105 @@
#pragma once
#include <cstdint>
#if !defined( MAX_OSPATH )
#define MAX_OSPATH 260 // max length of a filesystem pathname
#endif
#include "net_nop.h"
#include "net_disconnect.h"
#include "net_file.h"
#include "net_tick.h"
#include "net_stringcmd.h"
#include "net_setconvar.h"
#include "net_signonstate.h"
#include "svc_print.h"
#include "svc_serverinfo.h"
#include "svc_sendtable.h"
#include "svc_classinfo.h"
#include "svc_setpause.h"
#include "svc_createstringtable.h"
#include "svc_updatestringtable.h"
#include "svc_voiceinit.h"
#include "svc_voicedata.h"
#include "svc_hltv.h"
#include "svc_sounds.h"
#include "svc_setview.h"
#include "svc_fixangle.h"
#include "svc_crosshairangle.h"
#include "svc_bspdecal.h"
#include "svc_terrainmod.h"
#include "svc_usermessage.h"
#include "svc_entitymessage.h"
#include "svc_gameevent.h"
#include "svc_packetentities.h"
#include "svc_tempentities.h"
#include "svc_prefetch.h"
#include "svc_menu.h"
#include "svc_gameeventlist.h"
#include "svc_getcvarvalue.h"
namespace NetMsg
{
enum
{
net_NOP = 0, // nop command used for padding
net_Disconnect = 1, // disconnect, last message in connection
net_File = 2, // file transmission message request/deny
net_Tick = 3, // send last world tick
net_StringCmd = 4, // a string command
net_SetConVar = 5, // sends one/multiple convar settings
net_SignonState = 6, // signals current signon state
//
// server to client
//
svc_Print = 7, // print text to console
svc_ServerInfo = 8, // first message from server about game, map etc
svc_SendTable = 9, // sends a sendtable description for a game class
svc_ClassInfo = 10, // Info about classes (first byte is a CLASSINFO_ define).
svc_SetPause = 11, // tells client if server paused or unpaused
svc_CreateStringTable = 12, // inits shared string tables
svc_UpdateStringTable = 13, // updates a string table
svc_VoiceInit = 14, // inits used voice codecs & quality
svc_VoiceData = 15, // Voicestream data from the server
//svc_HLTV = 16, // HLTV control messages
svc_Sounds = 17, // starts playing sound
svc_SetView = 18, // sets entity as point of view
svc_FixAngle = 19, // sets/corrects players viewangle
svc_CrosshairAngle = 20, // adjusts crosshair in auto aim mode to lock on traget
svc_BSPDecal = 21, // add a static decal to the world BSP
// NOTE: This is now unused!
// svc_TerrainMod = 22, // modification to the terrain/displacement
// Message from server side to client side entity
svc_UserMessage = 23, // a game specific message
svc_EntityMessage = 24, // a message for an entity
svc_GameEvent = 25, // global game event fired
svc_PacketEntities = 26, // non-delta compressed entities
svc_TempEntities = 27, // non-reliable event object
svc_Prefetch = 28, // only sound indices for now
svc_Menu = 29, // display a menu from a plugin
svc_GameEventList = 30, // list of known games events and fields
svc_GetCvarValue = 31, // Server wants to know the value of a cvar on the client.
SVC_LASTMSG = 31 // last known server messages
};
}

View File

@ -0,0 +1,61 @@
#include "svc_bspdecal.h"
#include "bitbuf.h"
#include "netcontants.h"
namespace NetHandlers
{
bool SVC_BSPDecal_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_BSPDecal* data)
{
bitbuf.ReadBitVec3Coord(data->position);
data->decalTextureIndex = bitbuf.ReadUBitLong(MAX_DECAL_INDEX_BITS);
if (bitbuf.ReadOneBit() != 0)
{
data->entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
data->modelIndex = bitbuf.ReadUBitLong(SP_MODEL_INDEX_BITS);
}
else
{
data->entIndex = 0;
data->modelIndex = 0;
}
data->lowPriority = bitbuf.ReadOneBit() != 0;
return !bitbuf.IsOverflowed();
}
bool SVC_BSPDecal_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_BSPDecal* data)
{
bitbuf.WriteBitVec3Coord(data->position);
bitbuf.WriteUBitLong(data->decalTextureIndex, MAX_DECAL_INDEX_BITS);
if (data->entIndex != 0)
{
bitbuf.WriteOneBit(1);
bitbuf.WriteUBitLong(data->entIndex, MAX_EDICT_BITS);
bitbuf.WriteUBitLong(data->modelIndex, SP_MODEL_INDEX_BITS);
}
else
{
bitbuf.WriteOneBit(0);
}
bitbuf.WriteOneBit(data->lowPriority);
return !bitbuf.IsOverflowed();
}
bool SVC_BSPDecal_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_BSPDecal* data)
{
return true;
}
bool SVC_BSPDecal_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_BSPDecal* data)
{
return true;
}
void SVC_BSPDecal_ToString_Internal(std::ostringstream& out, NetMsg::SVC_BSPDecal* data)
{
out << "svc_BSPDecal: tex " << data->decalTextureIndex
<< ", ent " << data->entIndex
<< ", mod " << data->modelIndex
<< " lowpriority " << data->lowPriority;
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "nethandlers.h"
#include "vector.h"
namespace NetMsg
{
struct SVC_BSPDecal
{
Vector position;
uint16_t decalTextureIndex;
uint16_t entIndex;
uint16_t modelIndex;
bool lowPriority;
};
}
DECLARE_NET_HANDLERS(SVC_BSPDecal);

View File

@ -0,0 +1,62 @@
#include "svc_classinfo.h"
#include "bitbuf.h"
#include "netmath.h"
using class_t = NetMsg::SVC_ClassInfo::class_t;
namespace NetHandlers
{
bool SVC_ClassInfo_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_ClassInfo* data)
{
const int16_t numServerClasses = bitbuf.ReadShort();
const bool createOnClient = bitbuf.ReadOneBit() != 0;
data->numServerClasses = numServerClasses;
data->createOnClient = createOnClient;
if (!createOnClient)
{
const int numServerClassBits = math::log2(numServerClasses) + 1;
data->serverClasses.resize(numServerClasses);
for (class_t& serverClass : data->serverClasses)
{
serverClass.classID = bitbuf.ReadUBitLong(numServerClassBits);
bitbuf.ReadString(serverClass.className, sizeof(serverClass.className));
bitbuf.ReadString(serverClass.dataTableName, sizeof(serverClass.dataTableName));
}
}
return !bitbuf.IsOverflowed();
}
bool SVC_ClassInfo_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_ClassInfo* data)
{
bitbuf.WriteShort(data->numServerClasses);
bitbuf.WriteOneBit(data->createOnClient);
if (!data->createOnClient)
{
const int numServerClassBits = math::log2(data->numServerClasses) + 1;
for (class_t& serverClass : data->serverClasses)
{
bitbuf.WriteUBitLong(serverClass.classID, numServerClassBits);
bitbuf.WriteString(serverClass.className);
bitbuf.WriteString(serverClass.dataTableName);
}
}
return !bitbuf.IsOverflowed();
}
bool SVC_ClassInfo_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_ClassInfo* data)
{
return true;
}
bool SVC_ClassInfo_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_ClassInfo* data)
{
return true;
}
void SVC_ClassInfo_ToString_Internal(std::ostringstream& out, NetMsg::SVC_ClassInfo* data)
{
out << "svc_ClassInfo: num " << data->numServerClasses
<< ", " << (data->createOnClient ? "use client classes" : "full update");
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "nethandlers.h"
#include <vector>
namespace NetMsg
{
struct SVC_ClassInfo
{
typedef struct class_s
{
uint32_t classID;
char className[256];
char dataTableName[256];
} class_t;
int16_t numServerClasses;
bool createOnClient;
std::vector<class_t> serverClasses;
};
}
DECLARE_NET_HANDLERS(SVC_ClassInfo);

View File

@ -0,0 +1,104 @@
#include "svc_createstringtable.h"
#include "bitbuf.h"
#include "netmath.h"
#include "netcontants.h"
namespace NetHandlers
{
bool SVC_CreateStringTable_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_CreateStringTable* data)
{
if (bitbuf.PeekUBitLong(8) == ':')
{
data->isFileNames = true;
bitbuf.ReadByte();
}
else
{
data->isFileNames = false;
}
bitbuf.ReadString(data->tableName, sizeof(data->tableName));
data->maxEntries = bitbuf.ReadWord();
data->numEntries = bitbuf.ReadUBitLong(math::log2(data->maxEntries) + 1);
if (context.protocol > 23)
{
data->dataLengthInBits = bitbuf.ReadVarInt32();
}
else
{
data->dataLengthInBits = bitbuf.ReadUBitLong(NET_MAX_PAYLOAD_BITS + 1);
}
data->isUserDataFixedSize = bitbuf.ReadOneBit() != 0;
if (data->isUserDataFixedSize)
{
data->userDataSize = bitbuf.ReadUBitLong(12);
data->userDataSizeBits = bitbuf.ReadUBitLong(4);
}
else
{
data->userDataSize = 0;
data->userDataSizeBits = 0;
}
if (context.protocol > 14)
{
data->unk1 = bitbuf.ReadOneBit() != 0;
}
else
{
data->unk1 = false;
}
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_CreateStringTable_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_CreateStringTable* data)
{
if (data->isFileNames)
{
bitbuf.WriteByte(':');
}
bitbuf.WriteString(data->tableName);
bitbuf.WriteWord(data->maxEntries);
bitbuf.WriteUBitLong(data->numEntries, math::log2(data->maxEntries) + 1);
if (context.protocol > 23)
{
bitbuf.WriteVarInt32(data->dataLengthInBits);
}
else
{
bitbuf.WriteUBitLong(data->dataLengthInBits, NET_MAX_PAYLOAD_BITS + 1);
}
bitbuf.WriteOneBit(data->isUserDataFixedSize);
if (data->isUserDataFixedSize)
{
bitbuf.WriteUBitLong(data->userDataSize, 12);
bitbuf.WriteUBitLong(data->userDataSizeBits, 4);
}
if (context.protocol > 14)
{
bitbuf.WriteOneBit(data->unk1);
}
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_CreateStringTable_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_CreateStringTable* data)
{
return true;
}
bool SVC_CreateStringTable_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_CreateStringTable* data)
{
return true;
}
void SVC_CreateStringTable_ToString_Internal(std::ostringstream& out, NetMsg::SVC_CreateStringTable* data)
{
out << "svc_CreateStringTable: table " << data->tableName
<< ", entries " << data->numEntries
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits)
<< " userdatasize " << data->userDataSize
<< " userdatabits " << data->userDataSizeBits;
}
}

View File

@ -0,0 +1,24 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_CreateStringTable
{
bool isFileNames;
char tableName[256];
uint16_t maxEntries;
uint16_t numEntries;
uint32_t dataLengthInBits;
bool isUserDataFixedSize;
uint16_t userDataSize;
uint8_t userDataSizeBits;
bool unk1;
std::unique_ptr<uint8_t[]> data;
};
}
DECLARE_NET_HANDLERS(SVC_CreateStringTable);

View File

@ -0,0 +1,44 @@
#include "svc_crosshairangle.h"
#include "bitbuf.h"
#include <iomanip>
namespace NetHandlers
{
bool SVC_CrosshairAngle_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_CrosshairAngle* data)
{
data->x = bitbuf.ReadBitAngle(16);
data->y = bitbuf.ReadBitAngle(16);
data->z = bitbuf.ReadBitAngle(16);
return !bitbuf.IsOverflowed();
}
bool SVC_CrosshairAngle_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_CrosshairAngle* data)
{
bitbuf.WriteBitAngle(data->x, 16);
bitbuf.WriteBitAngle(data->y, 16);
bitbuf.WriteBitAngle(data->z, 16);
return !bitbuf.IsOverflowed();
}
bool SVC_CrosshairAngle_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_CrosshairAngle* data)
{
return true;
}
bool SVC_CrosshairAngle_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_CrosshairAngle* data)
{
return true;
}
void SVC_CrosshairAngle_ToString_Internal(std::ostringstream& out, NetMsg::SVC_CrosshairAngle* data)
{
const std::streamsize oldPrecision = out.precision();
out << "svc_CrosshairAngle:"
<< std::setprecision(1) << std::fixed
<< " (" << data->x
<< " " << data->y
<< " " << data->z << ")"
<< std::defaultfloat << std::setprecision(oldPrecision);
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_CrosshairAngle
{
float x;
float y;
float z;
};
}
DECLARE_NET_HANDLERS(SVC_CrosshairAngle);

View File

@ -0,0 +1,44 @@
#include "svc_entitymessage.h"
#include "bitbuf.h"
#include "netcontants.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_EntityMessage_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_EntityMessage* data)
{
data->entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
data->classID = bitbuf.ReadUBitLong(MAX_SERVER_CLASS_BITS);
data->dataLengthInBits = bitbuf.ReadUBitLong(11);
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_EntityMessage_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_EntityMessage* data)
{
bitbuf.WriteUBitLong(data->entIndex, MAX_EDICT_BITS);
bitbuf.WriteUBitLong(data->classID, MAX_SERVER_CLASS_BITS);
bitbuf.WriteUBitLong(data->dataLengthInBits, 11);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_EntityMessage_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_EntityMessage* data)
{
return true;
}
bool SVC_EntityMessage_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_EntityMessage* data)
{
return true;
}
void SVC_EntityMessage_ToString_Internal(std::ostringstream& out, NetMsg::SVC_EntityMessage* data)
{
out << "svc_EntityMessage: entity " << data->entIndex
<< ", class " << data->classID
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_EntityMessage
{
std::unique_ptr<uint8_t[]> data;
uint16_t dataLengthInBits;
uint16_t entIndex;
uint16_t classID;
};
}
DECLARE_NET_HANDLERS(SVC_EntityMessage);

View File

@ -0,0 +1,46 @@
#include "svc_fixangle.h"
#include "bitbuf.h"
#include <iomanip>
namespace NetHandlers
{
bool SVC_FixAngle_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_FixAngle* data)
{
data->relative = bitbuf.ReadOneBit() != 0;
data->x = bitbuf.ReadBitAngle(16);
data->y = bitbuf.ReadBitAngle(16);
data->z = bitbuf.ReadBitAngle(16);
return !bitbuf.IsOverflowed();
}
bool SVC_FixAngle_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_FixAngle* data)
{
bitbuf.WriteOneBit(data->relative);
bitbuf.WriteBitAngle(data->x, 16);
bitbuf.WriteBitAngle(data->y, 16);
bitbuf.WriteBitAngle(data->z, 16);
return !bitbuf.IsOverflowed();
}
bool SVC_FixAngle_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_FixAngle* data)
{
return true;
}
bool SVC_FixAngle_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_FixAngle* data)
{
return true;
}
void SVC_FixAngle_ToString_Internal(std::ostringstream& out, NetMsg::SVC_FixAngle* data)
{
const std::streamsize oldPrecision = out.precision();
out << "svc_FixAngle: " << (data->relative ? "relative" : "absolute")
<< std::setprecision(1) << std::fixed
<< " " << data->x
<< " " << data->y
<< " " << data->z
<< std::defaultfloat << std::setprecision(oldPrecision);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_FixAngle
{
bool relative;
float x;
float y;
float z;
};
}
DECLARE_NET_HANDLERS(SVC_FixAngle);

View File

@ -0,0 +1,38 @@
#include "svc_gameevent.h"
#include "bitbuf.h"
#include "netcontants.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_GameEvent_BitRead_Internal(bf_read& 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);
return !bitbuf.IsOverflowed();
}
bool SVC_GameEvent_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data)
{
bitbuf.WriteUBitLong(data->dataLengthInBits, 11);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_GameEvent_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data)
{
return true;
}
bool SVC_GameEvent_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_GameEvent* data)
{
return true;
}
void SVC_GameEvent_ToString_Internal(std::ostringstream& out, NetMsg::SVC_GameEvent* data)
{
out << "svc_GameEvent: bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,16 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_GameEvent
{
std::unique_ptr<uint8_t[]> data;
uint16_t dataLengthInBits;
};
}
DECLARE_NET_HANDLERS(SVC_GameEvent);

View File

@ -0,0 +1,64 @@
#include "svc_gameeventlist.h"
#include "bitbuf.h"
#include "netcontants.h"
#include "netmath.h"
using EventDescriptor = NetMsg::SVC_GameEventList::EventDescriptor;
using EventValue = NetMsg::SVC_GameEventList::EventValue;
namespace NetHandlers
{
bool SVC_GameEventList_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEventList* data)
{
data->eventDescriptors.resize(bitbuf.ReadUBitLong(MAX_EVENT_BITS));
data->dataLengthInBits = bitbuf.ReadUBitLong(20);
for (EventDescriptor& event : data->eventDescriptors)
{
event.id = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
bitbuf.ReadString(event.name, sizeof(event.name));
EventValue value;
while ((value.type = bitbuf.ReadUBitLong(3)) > 0)
{
bitbuf.ReadString(value.name, sizeof(value.name));
event.values.push_back(value);
}
event.values.shrink_to_fit();
}
return !bitbuf.IsOverflowed();
}
bool SVC_GameEventList_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_GameEventList* data)
{
bitbuf.WriteUBitLong(data->eventDescriptors.size(), MAX_EVENT_BITS);
bitbuf.WriteUBitLong(data->dataLengthInBits, 20);
for (EventDescriptor& event : data->eventDescriptors)
{
bitbuf.WriteUBitLong(event.id, MAX_EVENT_BITS);
bitbuf.WriteString(event.name);
for (EventValue& value : event.values)
{
bitbuf.WriteUBitLong(value.type, 3);
bitbuf.WriteString(value.name);
}
bitbuf.WriteUBitLong(0, 3);
}
return !bitbuf.IsOverflowed();
}
bool SVC_GameEventList_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_GameEventList* data)
{
return true;
}
bool SVC_GameEventList_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_GameEventList* data)
{
return true;
}
void SVC_GameEventList_ToString_Internal(std::ostringstream& out, NetMsg::SVC_GameEventList* data)
{
out << "svc_GameEventList: number " << data->eventDescriptors.size()
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,29 @@
#pragma once
#include "nethandlers.h"
#include "netcontants.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;
};
uint16_t dataLengthInBits;
std::vector<EventDescriptor> eventDescriptors;
};
}
DECLARE_NET_HANDLERS(SVC_GameEventList);

View File

@ -0,0 +1,36 @@
#include "svc_getcvarvalue.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool SVC_GetCvarValue_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_GetCvarValue* data)
{
data->cookie = bitbuf.ReadSBitLong(32);
bitbuf.ReadString(data->cvarName, sizeof(data->cvarName));
return !bitbuf.IsOverflowed();
}
bool SVC_GetCvarValue_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_GetCvarValue* data)
{
bitbuf.WriteSBitLong(data->cookie, 32);
bitbuf.WriteString(data->cvarName);
return !bitbuf.IsOverflowed();
}
bool SVC_GetCvarValue_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_GetCvarValue* data)
{
return true;
}
bool SVC_GetCvarValue_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_GetCvarValue* data)
{
return true;
}
void SVC_GetCvarValue_ToString_Internal(std::ostringstream& out, NetMsg::SVC_GetCvarValue* data)
{
out << "svc_GetCvarValue: cvar: " << data->cvarName
<< ", cookie: " << data->cookie;
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_GetCvarValue
{
int32_t cookie;
char cvarName[256];
};
}
DECLARE_NET_HANDLERS(SVC_GetCvarValue);

View File

@ -0,0 +1,35 @@
#include "svc_hltv.h"
#include <cassert>
namespace NetHandlers
{
bool SVC_HLTV_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_HLTV* data)
{
assert(false);
return true;
}
bool SVC_HLTV_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_HLTV* data)
{
assert(false);
return true;
}
bool SVC_HLTV_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_HLTV* data)
{
assert(false);
return true;
}
bool SVC_HLTV_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_HLTV* data)
{
assert(false);
return true;
}
void SVC_HLTV_ToString_Internal(std::ostringstream& out, NetMsg::SVC_HLTV* data)
{
out << "svc_HLTV";
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_HLTV
{
};
}
DECLARE_NET_HANDLERS(SVC_HLTV);

View File

@ -0,0 +1,56 @@
#include "svc_menu.h"
#include "bitbuf.h"
using DialogType = NetMsg::SVC_Menu::DialogType;
#define KEYVALUES_TOKEN_SIZE 1024
static const char* KeyValuesBin_GetName(uint8_t* data, size_t dataLength)
{
if (dataLength <= 2)
{
return nullptr;
}
return reinterpret_cast<const char*>(data + 1);
}
namespace NetHandlers
{
bool SVC_Menu_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_Menu* data)
{
data->type = static_cast<DialogType>(bitbuf.ReadShort());
data->dataLengthInBytes = bitbuf.ReadWord();
data->menuBinaryKeyValues.reset(new uint8_t[data->dataLengthInBytes]);
bitbuf.ReadBytes(data->menuBinaryKeyValues.get(), data->dataLengthInBytes);
return !bitbuf.IsOverflowed();
}
bool SVC_Menu_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_Menu* data)
{
bitbuf.WriteShort(static_cast<uint16_t>(data->type));
bitbuf.WriteWord(data->dataLengthInBytes);
bitbuf.WriteBytes(data->menuBinaryKeyValues.get(), data->dataLengthInBytes);
return !bitbuf.IsOverflowed();
}
bool SVC_Menu_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_Menu* data)
{
return true;
}
bool SVC_Menu_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_Menu* data)
{
return true;
}
void SVC_Menu_ToString_Internal(std::ostringstream& out, NetMsg::SVC_Menu* data)
{
// binary keyvalues in form [type][name][value]
// [char][cstr][type]
const char* name = KeyValuesBin_GetName(data->menuBinaryKeyValues.get(), data->dataLengthInBytes);
out << "svc_Menu: " << static_cast<uint16_t>(data->type)
<< " \"" << (name ? name : "No KeyValues")
<< "\" (len:" << data->dataLengthInBytes << ")";
}
}

View File

@ -0,0 +1,32 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_Menu
{
enum class DialogType : uint16_t
{
// just an on screen message
DIALOG_MSG = 0,
// an options menu
DIALOG_MENU,
// a richtext dialog
DIALOG_TEXT,
// an entry box
DIALOG_ENTRY,
// Ask the client to connect to a specified IP address.
// Only the "time" and "title" keys are used.
DIALOG_ASKCONNECT
};
std::unique_ptr<uint8_t[]> menuBinaryKeyValues;
uint16_t dataLengthInBytes;
DialogType type;
};
}
DECLARE_NET_HANDLERS(SVC_Menu);

View File

@ -0,0 +1,63 @@
#include "svc_packetentities.h"
#include "bitbuf.h"
#include "netcontants.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_PacketEntities_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_PacketEntities* data)
{
data->maxEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
data->isDelta = bitbuf.ReadOneBit() != 0;
if (data->isDelta)
{
data->deltaFromTick = bitbuf.ReadLong();
}
else
{
data->deltaFromTick = -1;
}
data->baselineIndex = bitbuf.ReadUBitLong(1);
data->numUpdatedEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
data->dataLengthInBits = bitbuf.ReadUBitLong(DELTASIZE_BITS);
data->updateBaseline = bitbuf.ReadOneBit() != 0;
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_PacketEntities_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_PacketEntities* data)
{
bitbuf.WriteUBitLong(data->maxEntries, MAX_EDICT_BITS);
if (data->isDelta)
{
bitbuf.WriteLong(data->deltaFromTick);
}
bitbuf.WriteUBitLong(data->baselineIndex, 1);
bitbuf.WriteUBitLong(data->numUpdatedEntries, MAX_EDICT_BITS);
bitbuf.WriteUBitLong(data->dataLengthInBits, DELTASIZE_BITS);
bitbuf.WriteOneBit(data->updateBaseline);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_PacketEntities_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_PacketEntities* data)
{
return true;
}
bool SVC_PacketEntities_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_PacketEntities* data)
{
return true;
}
void SVC_PacketEntities_ToString_Internal(std::ostringstream& out, NetMsg::SVC_PacketEntities* data)
{
out << "svc_PacketEntities: delta " << data->deltaFromTick
<< ", max " << data->maxEntries
<< ", changed " << data->numUpdatedEntries
<< "," << (data->updateBaseline ? " BL update," : "")
<< " bytes" << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,22 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_PacketEntities
{
std::unique_ptr<uint8_t[]> data;
uint32_t dataLengthInBits;
uint32_t deltaFromTick;
uint16_t maxEntries;
uint16_t numUpdatedEntries;
uint8_t baselineIndex;
bool updateBaseline;
bool isDelta;
};
}
DECLARE_NET_HANDLERS(SVC_PacketEntities);

View File

@ -0,0 +1,36 @@
#include "svc_prefetch.h"
#include "bitbuf.h"
#include "netcontants.h"
namespace NetHandlers
{
bool SVC_Prefetch_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_Prefetch* data)
{
data->type = NetMsg::SVC_Prefetch::SOUND;
data->soundIndex = bitbuf.ReadUBitLong(MAX_SOUND_INDEX_BITS);
return !bitbuf.IsOverflowed();
}
bool SVC_Prefetch_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_Prefetch* data)
{
bitbuf.WriteUBitLong(data->soundIndex, MAX_SOUND_INDEX_BITS);
return !bitbuf.IsOverflowed();
}
bool SVC_Prefetch_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_Prefetch* data)
{
return true;
}
bool SVC_Prefetch_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_Prefetch* data)
{
return true;
}
void SVC_Prefetch_ToString_Internal(std::ostringstream& out, NetMsg::SVC_Prefetch* data)
{
out << "svc_Prefetch: type " << data->type
<< " index " << data->soundIndex;
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_Prefetch
{
enum Types
{
SOUND = 0
};
uint16_t type;
uint16_t soundIndex;
};
}
DECLARE_NET_HANDLERS(SVC_Prefetch);

View File

@ -0,0 +1,33 @@
#include "svc_print.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool SVC_Print_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_Print* data)
{
bitbuf.ReadString(data->text, sizeof(data->text));
return !bitbuf.IsOverflowed();
}
bool SVC_Print_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_Print* data)
{
bitbuf.WriteString(data->text);
return !bitbuf.IsOverflowed();
}
bool SVC_Print_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_Print* data)
{
return true;
}
bool SVC_Print_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_Print* data)
{
return true;
}
void SVC_Print_ToString_Internal(std::ostringstream& out, NetMsg::SVC_Print* data)
{
out << "svc_Print: \"" << data->text << '"';
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_Print
{
char text[2048];
};
}
DECLARE_NET_HANDLERS(SVC_Print);

View File

@ -0,0 +1,40 @@
#include "svc_sendtable.h"
#include "bitbuf.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_SendTable_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_SendTable* data)
{
data->needsDecoder = bitbuf.ReadOneBit() != 0;
data->dataLengthInBits = bitbuf.ReadShort();
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_SendTable_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_SendTable* data)
{
bitbuf.WriteOneBit(data->needsDecoder);
bitbuf.WriteShort(data->dataLengthInBits);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_SendTable_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_SendTable* data)
{
return true;
}
bool SVC_SendTable_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_SendTable* data)
{
return true;
}
void SVC_SendTable_ToString_Internal(std::ostringstream& out, NetMsg::SVC_SendTable* data)
{
out << "svc_SendTable: needs Decoder " << (data->needsDecoder ? "yes" : "no")
<< ",bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_SendTable
{
bool needsDecoder;
int16_t dataLengthInBits;
std::unique_ptr<uint8_t[]> data;
};
}
DECLARE_NET_HANDLERS(SVC_SendTable);

View File

@ -0,0 +1,83 @@
#include "svc_serverinfo.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool SVC_ServerInfo_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_ServerInfo* data)
{
data->protocol = bitbuf.ReadShort();
data->serverCount = bitbuf.ReadLong();
data->isHLTV = bitbuf.ReadOneBit() != 0;
data->isDedicated = bitbuf.ReadOneBit() != 0;
data->clientCRC = bitbuf.ReadLong();
data->maxClasses = bitbuf.ReadWord();
if (context.protocol <= 17)
{
data->mapCRC = bitbuf.ReadLong();
}
else
{
bitbuf.ReadBytes(data->unk1, sizeof(data->unk1));
}
data->playerSlot = bitbuf.ReadByte();
data->maxClients = bitbuf.ReadByte();
data->tickInterval = bitbuf.ReadFloat();
data->os = bitbuf.ReadChar();
bitbuf.ReadString(data->gameDir, sizeof(data->gameDir));
bitbuf.ReadString(data->mapName, sizeof(data->mapName));
bitbuf.ReadString(data->skyName, sizeof(data->skyName));
bitbuf.ReadString(data->hostName, sizeof(data->hostName));
if (context.protocol > 15)
{
data->unk2 = bitbuf.ReadOneBit() != 0;
}
return !bitbuf.IsOverflowed();
}
bool SVC_ServerInfo_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_ServerInfo* data)
{
bitbuf.WriteShort(data->protocol);
bitbuf.WriteLong(data->serverCount);
bitbuf.WriteOneBit(data->isHLTV);
bitbuf.WriteOneBit(data->isDedicated);
bitbuf.WriteLong(data->clientCRC);
bitbuf.WriteWord(data->maxClasses);
if (context.protocol <= 17)
{
bitbuf.WriteLong(data->mapCRC);
}
else
{
bitbuf.WriteBytes(data->unk1, sizeof(data->unk1));
}
bitbuf.WriteByte(data->playerSlot);
bitbuf.WriteByte(data->maxClients);
bitbuf.WriteFloat(data->tickInterval);
bitbuf.WriteChar(data->os);
bitbuf.WriteString(data->gameDir);
bitbuf.WriteString(data->mapName);
bitbuf.WriteString(data->skyName);
bitbuf.WriteString(data->hostName);
if (context.protocol > 15)
{
bitbuf.WriteOneBit(data->unk2);
}
return !bitbuf.IsOverflowed();
}
bool SVC_ServerInfo_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_ServerInfo* data)
{
return true;
}
bool SVC_ServerInfo_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_ServerInfo* data)
{
return true;
}
void SVC_ServerInfo_ToString_Internal(std::ostringstream& out, NetMsg::SVC_ServerInfo* data)
{
out << "svc_ServerInfo: game \"" << data->gameDir << "\", map \"" << data->mapName << "\", max " << data->maxClients;
}
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_ServerInfo
{
int16_t protocol; // protocol version
uint32_t serverCount; // number of changelevels since server start
bool isHLTV; // HLTV server ?
bool isDedicated; // dedicated server ?
uint32_t clientCRC; // client.dll CRC server is using
uint16_t maxClasses; // max number of server classes
uint32_t mapCRC; // server map CRC
uint8_t unk1[16];
uint8_t playerSlot; // our client slot number
uint8_t maxClients; // max number of clients on server
float tickInterval; // server tick interval
char os; // 'l' = linux, 'w' = Win32
char gameDir[MAX_OSPATH]; // game directory eg "tf2"
char mapName[MAX_OSPATH]; // name of current map
char skyName[MAX_OSPATH]; // name of current skybox
char hostName[MAX_OSPATH]; // host name
bool unk2;
};
}
DECLARE_NET_HANDLERS(SVC_ServerInfo);

View File

@ -0,0 +1,33 @@
#include "svc_setpause.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool SVC_SetPause_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_SetPause* data)
{
data->isPaused = bitbuf.ReadOneBit() != 0;
return !bitbuf.IsOverflowed();
}
bool SVC_SetPause_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_SetPause* data)
{
bitbuf.WriteOneBit(data->isPaused);
return !bitbuf.IsOverflowed();
}
bool SVC_SetPause_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_SetPause* data)
{
return true;
}
bool SVC_SetPause_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_SetPause* data)
{
return true;
}
void SVC_SetPause_ToString_Internal(std::ostringstream& out, NetMsg::SVC_SetPause* data)
{
out << "svc_SetPause: " << (data->isPaused ? "paused" : "unpaused");
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_SetPause
{
bool isPaused;
};
}
DECLARE_NET_HANDLERS(SVC_SetPause);

View File

@ -0,0 +1,34 @@
#include "svc_setview.h"
#include "bitbuf.h"
#include "netcontants.h"
namespace NetHandlers
{
bool SVC_SetView_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_SetView* data)
{
data->entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
return !bitbuf.IsOverflowed();
}
bool SVC_SetView_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_SetView* data)
{
bitbuf.WriteUBitLong(data->entIndex, MAX_EDICT_BITS);
return !bitbuf.IsOverflowed();
}
bool SVC_SetView_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_SetView* data)
{
return true;
}
bool SVC_SetView_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_SetView* data)
{
return true;
}
void SVC_SetView_ToString_Internal(std::ostringstream& out, NetMsg::SVC_SetView* data)
{
out << "svc_SetView: view entity " << data->entIndex;
}
}

View File

@ -0,0 +1,14 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_SetView
{
uint16_t entIndex;
};
}
DECLARE_NET_HANDLERS(SVC_SetView);

View File

@ -0,0 +1,59 @@
#include "svc_sounds.h"
#include "bitbuf.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_Sounds_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_Sounds* data)
{
data->reliableSound = bitbuf.ReadOneBit() != 0;
if (data->reliableSound)
{
data->numSounds = 1;
data->dataLengthInBits = bitbuf.ReadUBitLong(8);
}
else
{
data->numSounds = bitbuf.ReadUBitLong(8);
data->dataLengthInBits = bitbuf.ReadUBitLong(16);
}
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_Sounds_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_Sounds* data)
{
if (data->reliableSound)
{
bitbuf.WriteOneBit(1);
bitbuf.WriteUBitLong(data->dataLengthInBits, 8);
}
else
{
bitbuf.WriteOneBit(0);
bitbuf.WriteUBitLong(data->numSounds, 8);
bitbuf.WriteUBitLong(data->dataLengthInBits, 16);
}
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_Sounds_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_Sounds* data)
{
return true;
}
bool SVC_Sounds_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_Sounds* data)
{
return true;
}
void SVC_Sounds_ToString_Internal(std::ostringstream& out, NetMsg::SVC_Sounds* data)
{
out << "svc_Sounds: number " << data->numSounds
<< (data->reliableSound ? ", reliable" : "")
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_Sounds
{
bool reliableSound;
uint8_t numSounds;
uint16_t dataLengthInBits;
std::unique_ptr<uint8_t[]> data;
};
}
DECLARE_NET_HANDLERS(SVC_Sounds);

View File

@ -0,0 +1,41 @@
#include "svc_tempentities.h"
#include "bitbuf.h"
#include "netcontants.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_TempEntities_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_TempEntities* data)
{
data->numEntries = bitbuf.ReadUBitLong(EVENT_INDEX_BITS);
data->dataLengthInBits = bitbuf.ReadUBitLong(NET_MAX_PAYLOAD_BITS);
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_TempEntities_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_TempEntities* data)
{
bitbuf.WriteUBitLong(data->numEntries, EVENT_INDEX_BITS);
bitbuf.WriteUBitLong(data->dataLengthInBits, NET_MAX_PAYLOAD_BITS);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_TempEntities_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_TempEntities* data)
{
return true;
}
bool SVC_TempEntities_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_TempEntities* data)
{
return true;
}
void SVC_TempEntities_ToString_Internal(std::ostringstream& out, NetMsg::SVC_TempEntities* data)
{
out << "svc_TempEntities: number " << data->numEntries
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_TempEntities
{
std::unique_ptr<uint8_t[]> data;
uint32_t dataLengthInBits;
uint32_t numEntries;
};
}
DECLARE_NET_HANDLERS(SVC_TempEntities);

View File

@ -0,0 +1,35 @@
#include "svc_terrainmod.h"
#include <cassert>
namespace NetHandlers
{
bool SVC_TerrainMod_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_TerrainMod* data)
{
assert(false);
return true;
}
bool SVC_TerrainMod_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_TerrainMod* data)
{
assert(false);
return true;
}
bool SVC_TerrainMod_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_TerrainMod* data)
{
assert(false);
return true;
}
bool SVC_TerrainMod_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_TerrainMod* data)
{
assert(false);
return true;
}
void SVC_TerrainMod_ToString_Internal(std::ostringstream& out, NetMsg::SVC_TerrainMod* data)
{
out << "svc_TerrainMod";
}
}

View File

@ -0,0 +1,13 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_TerrainMod
{
};
}
DECLARE_NET_HANDLERS(SVC_TerrainMod);

View File

@ -0,0 +1,52 @@
#include "svc_updatestringtable.h"
#include "bitbuf.h"
#include "netmath.h"
#include "netcontants.h"
namespace NetHandlers
{
bool SVC_UpdateStringTable_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_UpdateStringTable* data)
{
data->tableID = bitbuf.ReadUBitLong(math::log2(MAX_TABLES));
data->numChangedEntries = (bitbuf.ReadOneBit() != 0) ? bitbuf.ReadWord() : 1;
data->dataLengthInBits = bitbuf.ReadUBitLong(20);
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_UpdateStringTable_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_UpdateStringTable* data)
{
bitbuf.WriteUBitLong(data->tableID, math::log2(MAX_TABLES));
if (data->numChangedEntries != 1)
{
bitbuf.WriteOneBit(1);
bitbuf.WriteWord(data->numChangedEntries);
}
else
{
bitbuf.WriteOneBit(0);
}
bitbuf.WriteUBitLong(data->dataLengthInBits, 20);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_UpdateStringTable_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_UpdateStringTable* data)
{
return true;
}
bool SVC_UpdateStringTable_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_UpdateStringTable* data)
{
return true;
}
void SVC_UpdateStringTable_ToString_Internal(std::ostringstream& out, NetMsg::SVC_UpdateStringTable* data)
{
out << "svc_UpdateStringTable: table " << data->tableID
<< ", changed " << data->numChangedEntries
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,19 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_UpdateStringTable
{
uint32_t tableID;
bool twoOrMoreChangedEntries;
uint16_t numChangedEntries;
uint32_t dataLengthInBits;
std::unique_ptr<uint8_t[]> data;
};
}
DECLARE_NET_HANDLERS(SVC_UpdateStringTable);

View File

@ -0,0 +1,43 @@
#include "svc_usermessage.h"
#include "bitbuf.h"
#include "netmath.h"
#include "netcontants.h"
#include <cassert>
namespace NetHandlers
{
bool SVC_UserMessage_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_UserMessage* data)
{
data->msgType = bitbuf.ReadByte();
data->dataLengthInBits = bitbuf.ReadUBitLong(11);
assert(math::BitsToBytes(data->dataLengthInBits) <= MAX_USER_MSG_DATA);
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_UserMessage_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_UserMessage* data)
{
bitbuf.WriteByte(data->msgType);
bitbuf.WriteUBitLong(data->dataLengthInBits, 11);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_UserMessage_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_UserMessage* data)
{
return true;
}
bool SVC_UserMessage_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_UserMessage* data)
{
return true;
}
void SVC_UserMessage_ToString_Internal(std::ostringstream& out, NetMsg::SVC_UserMessage* data)
{
out << "svc_UserMessage: type " << data->msgType
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,17 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_UserMessage
{
std::unique_ptr<uint8_t[]> data;
uint16_t dataLengthInBits;
uint8_t msgType;
};
}
DECLARE_NET_HANDLERS(SVC_UserMessage);

View File

@ -0,0 +1,42 @@
#include "svc_voicedata.h"
#include "bitbuf.h"
#include "netmath.h"
namespace NetHandlers
{
bool SVC_VoiceData_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_VoiceData* data)
{
data->fromClientIndex = bitbuf.ReadByte();
data->proximity = !!bitbuf.ReadByte();
data->dataLengthInBits = bitbuf.ReadWord();
data->data.reset(new uint8_t[math::BitsToBytes(data->dataLengthInBits)]);
bitbuf.ReadBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_VoiceData_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_VoiceData* data)
{
bitbuf.WriteByte(data->fromClientIndex);
bitbuf.WriteByte(data->proximity);
bitbuf.WriteWord(data->dataLengthInBits);
bitbuf.WriteBits(data->data.get(), data->dataLengthInBits);
return !bitbuf.IsOverflowed();
}
bool SVC_VoiceData_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_VoiceData* data)
{
return true;
}
bool SVC_VoiceData_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_VoiceData* data)
{
return true;
}
void SVC_VoiceData_ToString_Internal(std::ostringstream& out, NetMsg::SVC_VoiceData* data)
{
out << "svc_VoiceData: client " << data->fromClientIndex
<< ", bytes " << math::BitsToBytes(data->dataLengthInBits);
}
}

View File

@ -0,0 +1,18 @@
#pragma once
#include "nethandlers.h"
#include <memory>
namespace NetMsg
{
struct SVC_VoiceData
{
uint8_t fromClientIndex;
bool proximity; // stored in a byte
uint16_t dataLengthInBits;
std::unique_ptr<uint8_t[]> data;
};
}
DECLARE_NET_HANDLERS(SVC_VoiceData);

View File

@ -0,0 +1,36 @@
#include "svc_voiceinit.h"
#include "bitbuf.h"
namespace NetHandlers
{
bool SVC_VoiceInit_BitRead_Internal(bf_read& bitbuf, SourceGameContext& context, NetMsg::SVC_VoiceInit* data)
{
bitbuf.ReadString(data->voiceCodec, sizeof(data->voiceCodec));
data->quality = bitbuf.ReadByte();
return !bitbuf.IsOverflowed();
}
bool SVC_VoiceInit_BitWrite_Internal(bf_write& bitbuf, SourceGameContext& context, NetMsg::SVC_VoiceInit* data)
{
bitbuf.WriteString(data->voiceCodec);
bitbuf.WriteByte(data->quality);
return !bitbuf.IsOverflowed();
}
bool SVC_VoiceInit_JsonRead_Internal(JsonRead& jsonbuf, SourceGameContext& context, NetMsg::SVC_VoiceInit* data)
{
return true;
}
bool SVC_VoiceInit_JsonWrite_Internal(JsonWrite& jsonbuf, SourceGameContext& context, NetMsg::SVC_VoiceInit* data)
{
return true;
}
void SVC_VoiceInit_ToString_Internal(std::ostringstream& out, NetMsg::SVC_VoiceInit* data)
{
out << "svc_VoiceInit: codec \"" << data->voiceCodec
<< "\", qualitty " << data->quality;
}
}

View File

@ -0,0 +1,15 @@
#pragma once
#include "nethandlers.h"
namespace NetMsg
{
struct SVC_VoiceInit
{
char voiceCodec[MAX_OSPATH]; // used voice codec .dll
uint8_t quality; // custom quality setting
};
}
DECLARE_NET_HANDLERS(SVC_VoiceInit);

View File

@ -33,7 +33,7 @@ using byte = char;
#define Q_memcpy memcpy
bool is_little_endian()
inline bool is_little_endian()
{
union {
uint32 i;

View File

@ -5,6 +5,7 @@ solution "demboyz"
startproject "demboyz"
configurations { "Debug", "Release" }
platforms "x32"
flags "MultiProcessorCompile"
project "demboyz"
kind "ConsoleApp"