]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/lib/net.qh
Shorten a few names
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / net.qh
index 7cb9bb8967959214bde61b14b7788358b2446b07..2994ea164bb1d58a9f9bee7e2a8a71ed9ad52d99 100644 (file)
@@ -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) \
@@ -33,22 +44,23 @@ REGISTRY(TempEntities, BITS(8) - 80)
 REGISTER_REGISTRY(TempEntities)
 REGISTRY_SORT(TempEntities)
 REGISTRY_CHECK(TempEntities)
-STATIC_INIT(RegisterTempEntities_renumber) { FOREACH(TempEntities, true, it.m_id = 80 + i); }
+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__); \
                        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) \
@@ -64,7 +76,7 @@ REGISTRY(LinkedEntities, BITS(8) - 1)
 REGISTER_REGISTRY(LinkedEntities)
 REGISTRY_SORT(LinkedEntities)
 REGISTRY_CHECK(LinkedEntities)
-STATIC_INIT(RegisterLinkedEntities_renumber) { FOREACH(LinkedEntities, true, it.m_id = 1 + i); }
+STATIC_INIT(LinkedEntities_renumber) { FOREACH(LinkedEntities, true, it.m_id = 1 + i); }
 
 
 
@@ -95,9 +107,11 @@ 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;
+       STATIC_INIT(g_uncustomizables) { g_uncustomizables = IL_NEW(); }
+
        void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
        {
                if (e.classname == "") e.classname = "net_linked";
@@ -135,11 +149,13 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
                setcefc(e, customizer);
                e.uncustomizeentityforclient = uncustomizer;
                e.uncustomizeentityforclient_set = !!uncustomizer;
+               if(uncustomizer)
+                       IL_PUSH(g_uncustomizables, e);
        }
 
        void UncustomizeEntitiesRun()
        {
-               FOREACH_ENTITY_FLOAT(uncustomizeentityforclient_set, true, it.uncustomizeentityforclient(it));
+               IL_EACH(g_uncustomizables, it.uncustomizeentityforclient_set, it.uncustomizeentityforclient(it));
        }
 
        STRING_ITERATOR(g_buf, string_null, 0);
@@ -156,13 +172,13 @@ STATIC_INIT(C2S_Protocol_renumber) { FOREACH(C2S_Protocol, true, it.m_id = i); }
                {
                        entity reader = C2S_Protocol_from(C2S);
                        if (reader && reader.m_read && reader.m_read(NULL, sender, true)) continue;
-                       LOG_SEVEREF("Net_ClientCommand() with malformed C2S=%d\n", C2S);
+                       LOG_SEVEREF("Net_ClientCommand() with malformed C2S=%d", C2S);
                        return;
                }
                g_buf_i--;
                int expected = strlen(buf);
-               if (g_buf_i > expected) LOG_WARNINGF("Underflow: %d", g_buf_i - expected);
-               if (g_buf_i < expected) LOG_WARNINGF("Overrflow: %d", expected - g_buf_i);
+               if (g_buf_i > expected) LOG_WARNF("Underflow: %d", g_buf_i - expected);
+               if (g_buf_i < expected) LOG_WARNF("Overrflow: %d", expected - g_buf_i);
        }
 
 #endif
@@ -171,13 +187,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;
 
@@ -185,22 +201,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
@@ -214,7 +228,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) \
@@ -241,13 +259,27 @@ 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
 
@@ -265,8 +297,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()
@@ -275,6 +311,10 @@ USING(Stream, int);
                ydec_single(g_buf, ret);
                return ret;
        }
+       int ReadShort()
+       {
+               return (ReadByte() << 8) | (ReadByte());
+       }
        void WriteByte(int to, int b);
 #endif
 
@@ -287,12 +327,13 @@ USING(Stream, int);
 #define Read_string() ReadString()
 #define Write_string(to, f) WriteString(to, f)
 
-#ifndef MENUQC
+#ifdef GAMEQC
        const float APPROXPASTTIME_ACCURACY_REQUIREMENT = 0.05;
        #define APPROXPASTTIME_MAX (16384 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
        #define APPROXPASTTIME_RANGE (64 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
 
        #ifdef CSQC
+               float servertime;
                entity ReadCSQCEntity()
                {
                        int f = ReadShort();
@@ -305,14 +346,14 @@ 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())
 
                float ReadApproxPastTime()
                {
@@ -343,9 +384,9 @@ 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
 
                // this will use the value:
                //   128
@@ -370,7 +411,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), { \
@@ -381,6 +422,6 @@ USING(Stream, int);
                                } \
                        }); \
                        msg_entity = prev; \
-               MACRO_END
+               MACRO_END
        #endif
 #endif