Added initial netmsg handlers, need to confirm them with current demo protocol
This commit is contained in:
parent
5fc4c59245
commit
9a6c95a327
@ -1,6 +1,7 @@
|
|||||||
|
|
||||||
#include "demofile.h"
|
#include "demofile.h"
|
||||||
#include "demofilebitbuf.h"
|
#include "demofilebitbuf.h"
|
||||||
|
#include "netmessages.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
@ -11,28 +12,32 @@ void ParseGameEvent(const std::string& eventBuf)
|
|||||||
{
|
{
|
||||||
CBitRead bitBuf(eventBuf.data(), eventBuf.size());
|
CBitRead bitBuf(eventBuf.data(), eventBuf.size());
|
||||||
uint32 eventId = bitBuf.ReadUBitLong(9);
|
uint32 eventId = bitBuf.ReadUBitLong(9);
|
||||||
printf("%s\n", eventNames[eventId-1].c_str());
|
printf("%s\n", eventNames[eventId].c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParsePacket(const std::string& packetBuf)
|
void ParsePacket(const char* packetBuf, const int numBytes)
|
||||||
{
|
{
|
||||||
auto data = packetBuf.data();
|
assert(numBytes <= NET_MAX_PAYLOAD);
|
||||||
CBitRead bitBuf(packetBuf.data(), packetBuf.size());
|
CBitRead bitBuf(packetBuf, numBytes);
|
||||||
uint32 typeId = bitBuf.ReadUBitLong(5);
|
while (bitBuf.GetNumBitsLeft() >= NETMSG_TYPE_BITS)
|
||||||
printf("%i\n", typeId);
|
|
||||||
if (typeId != 25)
|
|
||||||
{
|
{
|
||||||
return;
|
uint32 typeId = bitBuf.ReadUBitLong(NETMSG_TYPE_BITS);
|
||||||
|
printf("%i\n", typeId);
|
||||||
|
ProcessNetMsg(typeId, bitBuf);
|
||||||
|
/*if (typeId != 25)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 length = bitBuf.ReadUBitLong(11);
|
||||||
|
int numBytes = (length / 8) + (length % 8 > 0);
|
||||||
|
|
||||||
|
std::string subpacket;
|
||||||
|
subpacket.resize(numBytes);
|
||||||
|
|
||||||
|
bitBuf.ReadBits(&subpacket[0], length);
|
||||||
|
ParseGameEvent(subpacket);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32 length = bitBuf.ReadUBitLong(11);
|
|
||||||
int numBytes = (length / 8) + (length % 8 > 0);
|
|
||||||
|
|
||||||
std::string subpacket;
|
|
||||||
subpacket.resize(numBytes);
|
|
||||||
|
|
||||||
bitBuf.ReadBits(&subpacket[0], length);
|
|
||||||
ParseGameEvent(subpacket);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ParseEventNames(const char* eventfile, std::vector<std::string>& eventNames)
|
void ParseEventNames(const char* eventfile, std::vector<std::string>& eventNames)
|
||||||
@ -45,6 +50,24 @@ void ParseEventNames(const char* eventfile, std::vector<std::string>& eventNames
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ParseSignonData(const std::string& signonData)
|
||||||
|
{
|
||||||
|
CBitRead bitbuf(signonData.data(), signonData.length());
|
||||||
|
const char cmd = bitbuf.ReadChar();
|
||||||
|
assert(cmd == dem_signon);
|
||||||
|
const int32 tick = bitbuf.ReadLong();
|
||||||
|
bitbuf.SeekRelative(sizeof(democmdinfo_t) * 8);
|
||||||
|
const int32 seq1 = bitbuf.ReadLong();
|
||||||
|
const int32 seq2 = bitbuf.ReadLong();
|
||||||
|
assert(seq1 == seq2);
|
||||||
|
|
||||||
|
const int32 numBytes = bitbuf.ReadLong();
|
||||||
|
std::string packet;
|
||||||
|
packet.resize(numBytes);
|
||||||
|
bitbuf.ReadBytes(&packet[0], numBytes);
|
||||||
|
ParsePacket(packet.data(), numBytes);
|
||||||
|
}
|
||||||
|
|
||||||
int main(const int argc, const char* argv[])
|
int main(const int argc, const char* argv[])
|
||||||
{
|
{
|
||||||
if (argc < 3)
|
if (argc < 3)
|
||||||
@ -62,12 +85,14 @@ int main(const int argc, const char* argv[])
|
|||||||
|
|
||||||
auto demoHeader = demoFile.GetDemoHeader();
|
auto demoHeader = demoFile.GetDemoHeader();
|
||||||
|
|
||||||
|
ParseSignonData(demoFile.GetSignOnData());
|
||||||
|
|
||||||
unsigned char cmd;
|
unsigned char cmd;
|
||||||
int32 tick;
|
int32 tick;
|
||||||
int32 sequenceInfo1;
|
int32 sequenceInfo1;
|
||||||
int32 sequenceInfo2;
|
int32 sequenceInfo2;
|
||||||
democmdinfo_t cmdInfo;
|
democmdinfo_t cmdInfo;
|
||||||
std::string packetBuf;
|
char* packetBuf = (char*)malloc(NET_MAX_PAYLOAD);
|
||||||
demoFile.ReadCmdHeader(cmd, tick);
|
demoFile.ReadCmdHeader(cmd, tick);
|
||||||
|
|
||||||
assert(cmd == dem_synctick && tick == 0);
|
assert(cmd == dem_synctick && tick == 0);
|
||||||
@ -81,11 +106,13 @@ int main(const int argc, const char* argv[])
|
|||||||
switch (cmd)
|
switch (cmd)
|
||||||
{
|
{
|
||||||
case dem_packet:
|
case dem_packet:
|
||||||
demoFile.ReadCmdInfo(cmdInfo);
|
{
|
||||||
demoFile.ReadSequenceInfo(sequenceInfo1, sequenceInfo2);
|
demoFile.ReadCmdInfo(cmdInfo);
|
||||||
assert(sequenceInfo1 == sequenceInfo2);
|
demoFile.ReadSequenceInfo(sequenceInfo1, sequenceInfo2);
|
||||||
demoFile.ReadRawData(packetBuf);
|
assert(sequenceInfo1 == sequenceInfo2);
|
||||||
ParsePacket(packetBuf);
|
const int32 length = demoFile.ReadRawData(packetBuf, NET_MAX_PAYLOAD);
|
||||||
|
ParsePacket(packetBuf, length);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case dem_stop:
|
case dem_stop:
|
||||||
assert(i == numFrames && tick == numTicks);
|
assert(i == numFrames && tick == numTicks);
|
||||||
@ -95,10 +122,12 @@ int main(const int argc, const char* argv[])
|
|||||||
case dem_usercmd:
|
case dem_usercmd:
|
||||||
case dem_datatables:
|
case dem_datatables:
|
||||||
default:
|
default:
|
||||||
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free(packetBuf);
|
||||||
demoFile.Close();
|
demoFile.Close();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -233,6 +233,29 @@ public:
|
|||||||
int64 ReadSignedVarInt64() { return bitbuf::ZigZagDecode64( ReadVarInt64() ); }
|
int64 ReadSignedVarInt64() { return bitbuf::ZigZagDecode64( ReadVarInt64() ); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline unsigned int CBitRead::PeekUBitLong(int numbits)
|
||||||
|
{
|
||||||
|
int nSaveBA = m_nBitsAvail;
|
||||||
|
int nSaveW = m_nInBufWord;
|
||||||
|
uint32 const *pSaveP = m_pDataIn;
|
||||||
|
unsigned int nRet = ReadUBitLong(numbits);
|
||||||
|
m_nBitsAvail = nSaveBA;
|
||||||
|
m_nInBufWord = nSaveW;
|
||||||
|
m_pDataIn = pSaveP;
|
||||||
|
return nRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int CBitRead::ReadLong(void)
|
||||||
|
{
|
||||||
|
return (int)ReadUBitLong(sizeof(long) << 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline float CBitRead::ReadFloat(void)
|
||||||
|
{
|
||||||
|
uint32 nUval = ReadUBitLong(sizeof(long) << 3);
|
||||||
|
return *((float *)&nUval);
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef MIN
|
#ifndef MIN
|
||||||
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
|
#define MIN( a, b ) ( ( ( a ) < ( b ) ) ? ( a ) : ( b ) )
|
||||||
#endif
|
#endif
|
||||||
|
414
demboyz/netmessages.cpp
Normal file
414
demboyz/netmessages.cpp
Normal file
@ -0,0 +1,414 @@
|
|||||||
|
|
||||||
|
#include "netmessages.h"
|
||||||
|
#include "demofilebitbuf.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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_NOP(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
// nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_Disconnect(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
char message[1024];
|
||||||
|
bitbuf.ReadString(message, sizeof(message));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_File(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const unsigned int transferID = bitbuf.ReadUBitLong(32);
|
||||||
|
char filename[1024];
|
||||||
|
bitbuf.ReadString(filename, sizeof(filename));
|
||||||
|
const bool isRequest = bitbuf.ReadOneBit() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_Tick(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
static const float NET_TICK_SCALEUP = 100000.0f;
|
||||||
|
|
||||||
|
const int tick = bitbuf.ReadLong();
|
||||||
|
const float hostFrameTime = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
|
||||||
|
const float hostFrameTimeStdDev = (float)bitbuf.ReadUBitLong(16) / NET_TICK_SCALEUP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_StringCmd(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
char commandBuffer[1024];
|
||||||
|
bitbuf.ReadString(commandBuffer, sizeof(commandBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_SetConVar(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
typedef struct cvar_s
|
||||||
|
{
|
||||||
|
char name[MAX_OSPATH];
|
||||||
|
char value[MAX_OSPATH];
|
||||||
|
} cvar_t;
|
||||||
|
|
||||||
|
const int numVars = bitbuf.ReadByte();
|
||||||
|
cvar_t cvar;
|
||||||
|
for (int i = 0; i < numVars; ++i)
|
||||||
|
{
|
||||||
|
bitbuf.ReadString(cvar.name, sizeof(cvar.name));
|
||||||
|
bitbuf.ReadString(cvar.value, sizeof(cvar.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Net_SignonState(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int signonState = bitbuf.ReadByte();
|
||||||
|
//assert(signonState == SIGNONSTATE_PRESPAWN);
|
||||||
|
const int spawnCount = bitbuf.ReadLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_Print(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
char textBuffer[2048];
|
||||||
|
bitbuf.ReadString(textBuffer, sizeof(textBuffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_ServerInfo(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int protocol = bitbuf.ReadShort(); // protocol version
|
||||||
|
const int serverCount = bitbuf.ReadLong(); // number of changelevels since server start
|
||||||
|
const bool isHLTV = bitbuf.ReadOneBit() != 0; // HLTV server ?
|
||||||
|
const bool isDedicated = bitbuf.ReadOneBit() != 0; // dedicated server ?
|
||||||
|
const int clientCRC = bitbuf.ReadLong(); // client.dll CRC server is using
|
||||||
|
const int maxClasses = bitbuf.ReadWord(); // max number of server classes
|
||||||
|
|
||||||
|
if (protocol <= 17)
|
||||||
|
{
|
||||||
|
const int mapCRC = bitbuf.ReadLong(); // server map CRC
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char unknown[16];
|
||||||
|
bitbuf.ReadBytes(unknown, sizeof(unknown));
|
||||||
|
}
|
||||||
|
const int playerSlot = bitbuf.ReadByte(); // our client slot number
|
||||||
|
const int maxClients = bitbuf.ReadByte(); // max number of clients on server
|
||||||
|
const float tickInterval = bitbuf.ReadFloat(); // server tick interval
|
||||||
|
const char os = bitbuf.ReadChar(); // '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
|
||||||
|
bitbuf.ReadString(gameDir, sizeof(gameDir));
|
||||||
|
bitbuf.ReadString(mapName, sizeof(mapName));
|
||||||
|
bitbuf.ReadString(skyName, sizeof(skyName));
|
||||||
|
bitbuf.ReadString(hostName, sizeof(hostName));
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_SendTable(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const bool needsDecoder = bitbuf.ReadOneBit() != 0;
|
||||||
|
const int dataLengthBits = bitbuf.ReadShort();
|
||||||
|
bitbuf.SeekRelative(dataLengthBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_ClassInfo(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
typedef struct class_s
|
||||||
|
{
|
||||||
|
int classID;
|
||||||
|
char datatablename[256];
|
||||||
|
char classname[256];
|
||||||
|
} class_t;
|
||||||
|
|
||||||
|
const int numServerClasses = bitbuf.ReadShort();
|
||||||
|
const int nServerClassBits = math::log2(numServerClasses) + 1;
|
||||||
|
// if true, client creates own SendTables & classinfos from game.dll
|
||||||
|
const bool createOnClient = bitbuf.ReadOneBit() != 0;
|
||||||
|
if (!createOnClient)
|
||||||
|
{
|
||||||
|
class_t serverclass;
|
||||||
|
for (int i = 0; i < numServerClasses; ++i)
|
||||||
|
{
|
||||||
|
serverclass.classID = bitbuf.ReadUBitLong(nServerClassBits);
|
||||||
|
bitbuf.ReadString(serverclass.classname, sizeof(serverclass.classname));
|
||||||
|
bitbuf.ReadString(serverclass.datatablename, sizeof(serverclass.datatablename));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_SetPause(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const bool paused = bitbuf.ReadOneBit() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_CreateStringTable(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
if (bitbuf.PeekUBitLong(8) == ':')
|
||||||
|
{
|
||||||
|
bitbuf.ReadByte();
|
||||||
|
}
|
||||||
|
|
||||||
|
char tableName[256];
|
||||||
|
bitbuf.ReadString(tableName, sizeof(tableName));
|
||||||
|
const int maxEntries = bitbuf.ReadWord();
|
||||||
|
const int encodeBits = math::log2(maxEntries);
|
||||||
|
const int numEntries = bitbuf.ReadUBitLong(encodeBits + 1);
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS + 3);
|
||||||
|
const bool userDataFixedSize = bitbuf.ReadOneBit() != 0;
|
||||||
|
if (userDataFixedSize)
|
||||||
|
{
|
||||||
|
const int userDataSize = bitbuf.ReadUBitLong(12);
|
||||||
|
const int userDataSizeBits = bitbuf.ReadUBitLong(4);
|
||||||
|
}
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_UpdateStringTable(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int tableId = bitbuf.ReadUBitLong(math::log2(MAX_TABLES));
|
||||||
|
const int numChangedEntries = (bitbuf.ReadOneBit() != 0) ? bitbuf.ReadWord() : 1;
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(20);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_VoiceInit(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
char voiceCodec[MAX_OSPATH]; // used voice codec .dll
|
||||||
|
bitbuf.ReadString(voiceCodec, sizeof(voiceCodec));
|
||||||
|
const int quality = bitbuf.ReadByte(); // custom quality setting
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_VoiceData(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int fromClientIndex = bitbuf.ReadByte();
|
||||||
|
const bool proximity = !!bitbuf.ReadByte();
|
||||||
|
const int lengthInBits = bitbuf.ReadWord();
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_HLTV(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
//const int state = bitbuf.ReadByte();
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_Sounds(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const bool reliableSound = bitbuf.ReadOneBit() != 0;
|
||||||
|
int numSounds;
|
||||||
|
int lengthInBits;
|
||||||
|
if (reliableSound)
|
||||||
|
{
|
||||||
|
numSounds = 1;
|
||||||
|
lengthInBits = bitbuf.ReadUBitLong(8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
numSounds = bitbuf.ReadUBitLong(8);
|
||||||
|
lengthInBits = bitbuf.ReadUBitLong(16);
|
||||||
|
}
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_SetView(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_FixAngle(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const bool relative = bitbuf.ReadOneBit() != 0;
|
||||||
|
const float x = bitbuf.ReadBitAngle(16);
|
||||||
|
const float y = bitbuf.ReadBitAngle(16);
|
||||||
|
const float z = bitbuf.ReadBitAngle(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_CrosshairAngle(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const float x = bitbuf.ReadBitAngle(16);
|
||||||
|
const float y = bitbuf.ReadBitAngle(16);
|
||||||
|
const float z = bitbuf.ReadBitAngle(16);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_BSPDecal(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
Vector pos;
|
||||||
|
bitbuf.ReadBitVec3Coord(pos);
|
||||||
|
const int decalTextureIndex = bitbuf.ReadUBitLong(MAX_DECAL_INDEX_BITS);
|
||||||
|
if (bitbuf.ReadOneBit() != 0)
|
||||||
|
{
|
||||||
|
const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
|
||||||
|
const int modelIndex = bitbuf.ReadUBitLong(SP_MODEL_INDEX_BITS);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int entIndex = 0;
|
||||||
|
const int modelIndex = 0;
|
||||||
|
}
|
||||||
|
const bool lowPriority = bitbuf.ReadOneBit() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_TerrainMod(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_UserMessage(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int msgType = bitbuf.ReadByte();
|
||||||
|
|
||||||
|
// max 256 * 8 bits, see MAX_USER_MSG_DATA
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(11);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_EntityMessage(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int entIndex = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
|
||||||
|
const int classID = bitbuf.ReadUBitLong(MAX_SERVER_CLASS_BITS);
|
||||||
|
|
||||||
|
// max 256 * 8 bits
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(11);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_GameEvent(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(11);
|
||||||
|
//uint32 eventId = bitbuf.ReadUBitLong(9);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_PacketEntities(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int maxEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
|
||||||
|
const bool isDelta = bitbuf.ReadOneBit() != 0;
|
||||||
|
if (isDelta)
|
||||||
|
{
|
||||||
|
const int deltaFrom = bitbuf.ReadLong();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int deltaFrom = -1;
|
||||||
|
}
|
||||||
|
const int numBaseline = bitbuf.ReadUBitLong(1);
|
||||||
|
const int numUpdatedEntries = bitbuf.ReadUBitLong(MAX_EDICT_BITS);
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(DELTASIZE_BITS);
|
||||||
|
const bool updateBaseline = bitbuf.ReadOneBit() != 0;
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_TempEntities(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int numEntries = bitbuf.ReadUBitLong(EVENT_INDEX_BITS);
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(NET_MAX_PALYLOAD_BITS);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_Prefetch(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
SOUND = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
const short type = SOUND; // bitbuf.ReadUBitLong(1);
|
||||||
|
const short soundIndex = bitbuf.ReadUBitLong(MAX_SOUND_INDEX_BITS);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_Menu(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
DIALOG_MSG = 0, // just an on screen message
|
||||||
|
DIALOG_MENU, // an options menu
|
||||||
|
DIALOG_TEXT, // a richtext dialog
|
||||||
|
DIALOG_ENTRY, // an entry box
|
||||||
|
DIALOG_ASKCONNECT // Ask the client to connect to a specified IP address. Only the "time" and "title" keys are used.
|
||||||
|
} DIALOG_TYPE;
|
||||||
|
|
||||||
|
DIALOG_TYPE type = (DIALOG_TYPE)bitbuf.ReadShort();
|
||||||
|
const int lengthInBytes = bitbuf.ReadWord();
|
||||||
|
bitbuf.SeekRelative(lengthInBytes * 8);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_GameEventList(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
const int numEvents = bitbuf.ReadUBitLong(MAX_EVENT_BITS);
|
||||||
|
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);
|
||||||
|
// gameeventmanager.cpp ParseEventList
|
||||||
|
}
|
||||||
|
const int lengthInBits = bitbuf.ReadUBitLong(20);
|
||||||
|
bitbuf.SeekRelative(lengthInBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SVC_GetCvarValue(CBitRead& bitbuf)
|
||||||
|
{
|
||||||
|
typedef int QueryCvarCookie_t;
|
||||||
|
QueryCvarCookie_t cookie = bitbuf.ReadSBitLong(32);
|
||||||
|
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);
|
||||||
|
}
|
114
demboyz/netmessages.h
Normal file
114
demboyz/netmessages.h
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
|
||||||
|
#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);
|
Loading…
Reference in New Issue
Block a user