X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Flib%2Fnet.qh;h=522b4ff2301f86b4e22f8c6d008e79a4f8103f83;hb=9910dcfe9d678de703aa6808822aec00d3fb1757;hp=30ab014ec988f1a2fae062bbe36115b003257872;hpb=a0df81d6263c9d3783070ac4078c6954a26d845c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/lib/net.qh b/qcsrc/lib/net.qh index 30ab014ec..522b4ff23 100644 --- a/qcsrc/lib/net.qh +++ b/qcsrc/lib/net.qh @@ -4,19 +4,30 @@ #include "sort.qh" #include "yenc.qh" +// netcode mismatch and not sure what caused it? developer_csqcentities 1 + .string netname; .int m_id; .bool(entity this, entity sender, bool isNew) m_read; #define NET_HANDLE(id, param) bool Net_Handle_##id(entity this, entity sender, param) +#define NET_GUARD(id) \ + bool Net_Handle_##id##_guard(entity this, entity sender, bool isNew) { \ + bool valid = false; \ + serialize_marker(to, valid); \ + if (!valid) LOG_FATALF("Last message not fully parsed: %s", _net_prevmsgstr); \ + _net_prevmsgstr = #id; \ + return Net_Handle_##id(this, sender, isNew); \ + } #ifdef CSQC +string _net_prevmsgstr; #define REGISTER_NET_TEMP(id) \ NET_HANDLE(id, bool); \ - REGISTER(TempEntities, NET, id, m_id, new_pure(net_temp_packet)) \ - { \ + NET_GUARD(id); \ + REGISTER(TempEntities, NET, id, m_id, new_pure(net_temp_packet)) { \ this.netname = #id; \ - this.m_read = Net_Handle_##id; \ + this.m_read = Net_Handle_##id##_guard; \ } #else #define REGISTER_NET_TEMP(id) \ @@ -29,26 +40,28 @@ #define REGISTER_NET_S2C(id) REGISTER_NET_TEMP(id) REGISTRY(TempEntities, BITS(8) - 80) -#define TempEntities_from(i) _TempEntities_from(i, NULL) REGISTER_REGISTRY(TempEntities) REGISTRY_SORT(TempEntities) REGISTRY_CHECK(TempEntities) -STATIC_INIT(RegisterTempEntities_renumber) { FOREACH(TempEntities, true, it.m_id = 80 + i); } + +REGISTRY_DEFINE_GET(TempEntities, NULL) +STATIC_INIT(TempEntities_renumber) { FOREACH(TempEntities, true, it.m_id = 80 + i); } #ifdef CSQC #define REGISTER_NET_LINKED(id) \ - [[accumulate]] NET_HANDLE(id, bool isnew) \ + ACCUMULATE NET_HANDLE(id, bool isnew) \ { \ this = __self; \ - this.sourceLoc = __FILE__ ":" STR(__LINE__); \ + this.sourceLoc = __FILE__":"STR(__LINE__); \ if (!this) isnew = true; \ } \ + NET_GUARD(id); \ REGISTER(LinkedEntities, NET, id, m_id, new_pure(net_linked_packet)) \ { \ this.netname = #id; \ - this.m_read = Net_Handle_##id; \ + this.m_read = Net_Handle_##id##_guard; \ } #else #define REGISTER_NET_LINKED(id) \ @@ -60,11 +73,12 @@ STATIC_INIT(RegisterTempEntities_renumber) { FOREACH(TempEntities, true, it.m_id #endif REGISTRY(LinkedEntities, BITS(8) - 1) -#define LinkedEntities_from(i) _LinkedEntities_from(i, NULL) REGISTER_REGISTRY(LinkedEntities) REGISTRY_SORT(LinkedEntities) REGISTRY_CHECK(LinkedEntities) -STATIC_INIT(RegisterLinkedEntities_renumber) { FOREACH(LinkedEntities, true, it.m_id = 1 + i); } + +REGISTRY_DEFINE_GET(LinkedEntities, NULL) +STATIC_INIT(LinkedEntities_renumber) { FOREACH(LinkedEntities, true, it.m_id = 1 + i); } @@ -86,16 +100,16 @@ STATIC_INIT(RegisterLinkedEntities_renumber) { FOREACH(LinkedEntities, true, it. #endif REGISTRY(C2S_Protocol, BITS(8) - 1) -#define C2S_Protocol_from(i) _C2S_Protocol_from(i, NULL) REGISTER_REGISTRY(C2S_Protocol) REGISTRY_SORT(C2S_Protocol) REGISTRY_CHECK(C2S_Protocol) + +REGISTRY_DEFINE_GET(C2S_Protocol, NULL) STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } #ifdef SVQC const int MSG_ENTITY = 5; - .int Version; // deprecated, use SendFlags .int SendFlags; IntrusiveList g_uncustomizables; @@ -159,7 +173,7 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } STRING_ITERATOR_SET(g_buf, buf, 0); for (int C2S; (C2S = ReadByte()) >= 0; ) { - entity reader = C2S_Protocol_from(C2S); + entity reader = REGISTRY_GET(C2S_Protocol, C2S); if (reader && reader.m_read && reader.m_read(NULL, sender, true)) continue; LOG_SEVEREF("Net_ClientCommand() with malformed C2S=%d", C2S); return; @@ -176,13 +190,13 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } const int MSG_C2S = 0; #define Net_Accept(classname) \ - MACRO_BEGIN { \ - if (!this) this = new(classname); \ - } MACRO_END + MACRO_BEGIN \ + if (!this) this = new(classname); \ + MACRO_END #define Net_Reject() \ - MACRO_BEGIN { \ - if (this) delete(this); \ - } MACRO_END + MACRO_BEGIN \ + if (this) delete(this); \ + MACRO_END string g_buf; @@ -190,22 +204,20 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); } { if (g_buf == "") return; localcmd("\ncmd c2s \"", strreplace("$", "$$", g_buf), "\"\n"); - strunzone(g_buf); - g_buf = string_null; + strfree(g_buf); } #endif #if defined(CSQC) #define WriteHeader(to, id) \ - MACRO_BEGIN { \ - WriteByte(to, NET_##id.m_id); \ - } MACRO_END + WriteByte(to, NET_##id.m_id) #elif defined(SVQC) #define WriteHeader(to, id) \ - MACRO_BEGIN { \ + MACRO_BEGIN \ if (NET_##id##_istemp) WriteByte(to, SVC_TEMPENTITY); \ WriteByte(to, NET_##id.m_id); \ - } MACRO_END + bool _net_valid = false; serialize_marker(to, _net_valid); \ + MACRO_END #endif // serialization: new style @@ -219,7 +231,11 @@ USING(Stream, int); #define stream_writing(stream) false #endif -#define serialize(T, stream, ...) serialize_##T(stream, __VA_ARGS__) +#define serialize(T, stream, ...) \ +MACRO_BEGIN \ + noref Stream _stream = stream; \ + serialize_##T(_stream, __VA_ARGS__); \ +MACRO_END #if defined(SVQC) #define serialize_byte(stream, this) \ @@ -246,17 +262,31 @@ USING(Stream, int); #endif #define serialize_vector(stream, this) \ - MACRO_BEGIN \ +MACRO_BEGIN \ vector _v = this; \ serialize_float(stream, _v.x); \ serialize_float(stream, _v.y); \ serialize_float(stream, _v.z); \ this = _v; \ - MACRO_END +MACRO_END + +#define serialize_marker(stream, this) \ +MACRO_BEGIN \ + if (NDEBUG) { \ + this = true; \ + } else { \ + int _de = 0xDE, _ad = 0xAD, _be = 0xBE, _ef = 0xEF; \ + serialize_byte(stream, _de); \ + serialize_byte(stream, _ad); \ + serialize_byte(stream, _be); \ + serialize_byte(stream, _ef); \ + this = (_de == 0xDE && _ad == 0xAD && _be == 0xBE && _ef == 0xEF); \ + } \ +MACRO_END // serialization: old -#define ReadRegistered(r) r##_from(Read_byte()) +#define ReadRegistered(r) REGISTRY_GET(r, Read_byte()) #define WriteRegistered(r, to, it) Write_byte(to, it.m_id) #define Read_byte() ReadByte() @@ -270,8 +300,12 @@ USING(Stream, int); string s = string_null; yenc_single(b, s); string tmp = strcat(g_buf, s); - if (g_buf) strunzone(g_buf); - g_buf = strzone(tmp); + strcpy(g_buf, tmp); + } + void WriteShort(int to, int b) + { + WriteByte(to, (b >> 8) & 0xFF); + WriteByte(to, b & 0xFF); } #elif defined(SVQC) int ReadByte() @@ -280,6 +314,10 @@ USING(Stream, int); ydec_single(g_buf, ret); return ret; } + int ReadShort() + { + return (ReadByte() << 8) | (ReadByte()); + } void WriteByte(int to, int b); #endif @@ -298,6 +336,7 @@ USING(Stream, int); #define APPROXPASTTIME_RANGE (64 * APPROXPASTTIME_ACCURACY_REQUIREMENT) #ifdef CSQC + float servertime; entity ReadCSQCEntity() { int f = ReadShort(); @@ -310,14 +349,23 @@ USING(Stream, int); v += ReadByte(); // note: this is unsigned return v; } - #define ReadInt48_t() vec3(ReadInt24_t(), ReadInt24_t(), 0) + #define ReadInt48_t() vec2(ReadInt24_t(), ReadInt24_t()) #define ReadInt72_t() vec3(ReadInt24_t(), ReadInt24_t(), ReadInt24_t()) - int _ReadSByte; + noref int _ReadSByte; #define ReadSByte() (_ReadSByte = ReadByte(), (_ReadSByte & BIT(7) ? -128 : 0) + (_ReadSByte & BITS(7))) #define ReadFloat() ReadCoord() #define ReadVector() vec3(ReadFloat(), ReadFloat(), ReadFloat()) - #define ReadVector2D() vec3(ReadFloat(), ReadFloat(), 0) + #define ReadVector2D() vec2(ReadFloat(), ReadFloat()) + #define ReadAngleVector() vec3(ReadAngle(), ReadAngle(), ReadAngle()) + #define ReadAngleVector2D() vec2(ReadAngle(), ReadAngle()) + + int Readbits(int num) + { + if (num > 16) return ReadInt24_t(); + if (num > 8) return ReadShort(); + return ReadByte(); + } float ReadApproxPastTime() { @@ -348,9 +396,18 @@ USING(Stream, int); WriteInt24_t(dst, val.z); } - #define WriteFloat(to, f) WriteCoord(to, f) - #define WriteVector(to, v) MACRO_BEGIN { WriteFloat(to, v.x); WriteFloat(to, v.y); WriteFloat(to, v.z); } MACRO_END - #define WriteVector2D(to, v) MACRO_BEGIN { WriteFloat(to, v.x); WriteFloat(to, v.y); } MACRO_END + #define WriteFloat(to, f) WriteCoord(to, f) + #define WriteVector(to, v) MACRO_BEGIN WriteFloat(to, v.x); WriteFloat(to, v.y); WriteFloat(to, v.z); MACRO_END + #define WriteVector2D(to, v) MACRO_BEGIN WriteFloat(to, v.x); WriteFloat(to, v.y); MACRO_END + #define WriteAngleVector(to, v) MACRO_BEGIN WriteAngle(to, v.x); WriteAngle(to, v.y); WriteAngle(to, v.z); MACRO_END + #define WriteAngleVector2D(to, v) MACRO_BEGIN WriteAngle(to, v.x); WriteAngle(to, v.y); MACRO_END + + void Writebits(float dst, float val, int num) + { + if (num > 16) { WriteInt24_t(dst, val); return; } + if (num > 8) { WriteShort(dst, val); return; } + WriteByte(dst, val); + } // this will use the value: // 128 @@ -375,7 +432,7 @@ USING(Stream, int); } // allow writing to also pass through to spectators (like so spectators see the same centerprints as players for example) - #define WRITESPECTATABLE_MSG_ONE(to, statement) MACRO_BEGIN { \ + #define WRITESPECTATABLE_MSG_ONE(to, statement) MACRO_BEGIN \ entity prev = msg_entity; \ entity dst = to; \ FOREACH_CLIENT(IS_REAL_CLIENT(it), { \ @@ -386,6 +443,6 @@ USING(Stream, int); } \ }); \ msg_entity = prev; \ - } MACRO_END + MACRO_END #endif #endif