15#define NET_HANDLE(id, param) bool \
16 Net_Handle_##id(entity this, entity sender, param)
18#define NET_GUARD(id) \
19 bool Net_Handle_##id##_guard(entity this, entity sender, bool isNew) \
22 net_guard_marker(to, valid); \
24 LOG_FATALF("Last message not fully parsed: %s", _net_prevmsgstr); \
25 _net_prevmsgstr = #id; \
26 return Net_Handle_##id(this, sender, isNew); \
31 #define REGISTER_NET_TEMP(id) \
32 NET_HANDLE(id, bool); \
34 REGISTER(TempEntities, NET, id, m_id, new_pure(net_temp_packet)) \
37 this.m_read = Net_Handle_##id##_guard; \
40 #define REGISTER_NET_TEMP(id) \
41 const bool NET_##id##_istemp = true; \
42 REGISTER(TempEntities, NET, id, m_id, new_pure(net_temp_packet)) \
50 #define net_guard_marker(stream, this) MACRO_BEGIN \
55 int _de = ReadByte(); \
56 int _ad = ReadByte(); \
57 int _be = ReadByte(); \
58 int _ef = ReadByte(); \
59 this = (_de == 0xDE && _ad == 0xAD && _be == 0xBE && _ef == 0xEF); \
63 #define net_guard_marker(stream, this) MACRO_BEGIN \
68 WriteByte(stream, 0xDE); \
69 WriteByte(stream, 0xAD); \
70 WriteByte(stream, 0xBE); \
71 WriteByte(stream, 0xEF); \
85 FOREACH(TempEntities,
true, it.m_id = 80 + i);
91 #define REGISTER_NET_LINKED(id) \
92 ACCUMULATE NET_HANDLE(id, bool isNew) \
95 this.sourceLoc = __FILE__":"STR(__LINE__); \
100 REGISTER(LinkedEntities, NET, id, m_id, new_pure(net_linked_packet)) \
102 this.netname = #id; \
103 this.m_read = Net_Handle_##id##_guard; \
106 #define REGISTER_NET_LINKED(id) \
107 const bool NET_##id##_istemp = false; \
108 REGISTER(LinkedEntities, NET, id, m_id, new_pure(net_linked_packet)) \
110 this.netname = #id; \
122 FOREACH(LinkedEntities,
true, it.m_id = 1 + i);
128 #define REGISTER_NET_C2S(id) \
129 NET_HANDLE(id, bool); \
130 REGISTER(C2S_Protocol, NET, id, m_id, new_pure(net_c2s_packet)) \
132 this.netname = #id; \
133 this.m_read = Net_Handle_##id; \
136 #define REGISTER_NET_C2S(id) \
137 const bool NET_##id##_istemp = true; \
138 REGISTER(C2S_Protocol, NET, id, m_id, new_pure(net_c2s_packet)) \
140 this.netname = #id; \
152 FOREACH(C2S_Protocol,
true, it.m_id = i);
169 if (e.classname ==
"")
171 LOG_WARN(
"Net_LinkEntity called on an entity without a classname, assigning default");
172 e.classname =
"net_linked";
175 if (e.modelindex == 0)
179 _setmodel(e,
"null");
184 e.SendFlags = 0xFFFFFF;
191 e.nextthink =
time + dt;
201 .void(
entity this) uncustomizeentityforclient;
207 e.uncustomizeentityforclient = uncustomizer;
208 e.uncustomizeentityforclient_set = !!uncustomizer;
229 for (
int C2S; (C2S =
ReadByte()) >= 0; )
232 if (reader && reader.m_read && reader.m_read(
NULL, sender,
true))
234 LOG_SEVEREF(
"Net_ClientCommand() with malformed C2S=%d", C2S);
238 int expected =
strlen(buf);
239 if (g_buf_i > expected)
LOG_WARNF(
"Underflow: %d", g_buf_i - expected);
240 if (g_buf_i < expected)
LOG_WARNF(
"Overrflow: %d", expected - g_buf_i);
243 const int MSG_C2S = 0;
245 #define Net_Accept(classname) MACRO_BEGIN \
247 this = new(classname); \
249 #define Net_Reject() MACRO_BEGIN \
259 localcmd(
"\ncmd c2s \"", strreplace(
"$",
"$$", g_buf),
"\"\n");
265 #define WriteHeader(to, id) \
266 WriteByte(to, NET_##id.m_id)
268 #define WriteHeader(to, id) \
270 if (NET_##id##_istemp) \
271 WriteByte(to, SVC_TEMPENTITY); \
272 WriteByte(to, NET_##id.m_id); \
273 bool _net_valid = false; \
274 net_guard_marker(to, _net_valid); \
282 #define stream_reading(stream) false
283 #define stream_writing(stream) true
285 #define stream_reading(stream) true
286 #define stream_writing(stream) false
291#define ReadRegistered(r) \
292 REGISTRY_GET(r, (REGISTRY_COUNT(r) >= 255 ? ReadShort() : ReadByte()))
293#define WriteRegistered(r, to, it) \
294 (REGISTRY_COUNT(r) >= 255 ? WriteShort(to, it.m_id) : WriteByte(to, it.m_id))
303 string tmp =
strcat(g_buf, s);
326#define APPROXPASTTIME_MAX (16384 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
327#define APPROXPASTTIME_RANGE (64 * APPROXPASTTIME_ACCURACY_REQUIREMENT)
340 int v = ReadShort() << 8;
344 #define ReadInt48_t() vec2(ReadInt24_t(), ReadInt24_t())
345 #define ReadInt72_t() vec3(ReadInt24_t(), ReadInt24_t(), ReadInt24_t())
348 #define ReadSByte() (_ReadSByte = ReadByte(), (_ReadSByte & BIT(7) ? -128 : 0) + (_ReadSByte & BITS(7)))
349 #define ReadFloat() ReadCoord()
350 #define ReadVector() vec3(ReadFloat(), ReadFloat(), ReadFloat())
351 #define ReadVector2D() vec2(ReadFloat(), ReadFloat())
352 #define ReadAngleVector() vec3(ReadAngle(), ReadAngle(), ReadAngle())
353 #define ReadAngleVector2D() vec2(ReadAngle(), ReadAngle())
358 if (num > 8)
return ReadShort();
371 void WriteInt24_t(
float dst,
float val)
377 void WriteInt48_t(
float dst,
vector val)
379 WriteInt24_t(dst, val.x);
380 WriteInt24_t(dst, val.y);
382 void WriteInt72_t(
float dst,
vector val)
384 WriteInt24_t(dst, val.x);
385 WriteInt24_t(dst, val.y);
386 WriteInt24_t(dst, val.z);
389 #define WriteFloat(to, f) \
391 #define WriteVector(to, v) MACRO_BEGIN \
392 WriteFloat(to, v.x); \
393 WriteFloat(to, v.y); \
394 WriteFloat(to, v.z); \
396 #define WriteVector2D(to, v) MACRO_BEGIN \
397 WriteFloat(to, v.x); \
398 WriteFloat(to, v.y); \
400 #define WriteAngleVector(to, v) MACRO_BEGIN \
401 WriteAngle(to, v.x); \
402 WriteAngle(to, v.y); \
403 WriteAngle(to, v.z); \
405 #define WriteAngleVector2D(to, v) MACRO_BEGIN \
406 WriteAngle(to, v.x); \
407 WriteAngle(to, v.y); \
410 void Writebits(
float dst,
float val,
int num)
412 if (num > 16) { WriteInt24_t(dst, val);
return; }
413 if (num > 8) {
WriteShort(dst, val);
return; }
422 void WriteApproxPastTime(
float dst,
float t)
439 #define WRITESPECTATABLE_MSG_ONE(to, statement) MACRO_BEGIN \
440 entity prev = msg_entity; \
442 FOREACH_CLIENT(IS_REAL_CLIENT(it), \
444 if (it == dst || (it.classname == STR_SPECTATOR && it.enemy == dst)) \
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
limitations: NULL cannot be present elements can only be present once a maximum of IL_MAX lists can e...
const float EF_NODEPTHTEST
void SUB_Remove(entity this)
Remove entity.
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
#define IL_EACH(this, cond, body)
#define STRING_ITERATOR(this, s, i)
#define STRING_ITERATOR_SET(this, s, i)
#define FOREACH(list, cond, body)
void WriteByte(int to, int b)
void SetCustomizer(entity e, bool(entity this, entity client) customizer, void(entity this) uncustomizer)
float ReadApproxPastTime()
void Net_ClientCommand(entity sender, string command)
void Net_UnlinkEntity(entity e)
#define APPROXPASTTIME_MAX
void UncustomizeEntitiesRun()
IntrusiveList g_uncustomizables
float uncustomizeentityforclient_set
void Net_LinkEntity(entity e, bool docull, float dt, bool(entity this, entity to, int sendflags) sendfunc)
void WriteShort(int to, int b)
const float APPROXPASTTIME_ACCURACY_REQUIREMENT
strcat(_("^F4Countdown stopped!"), "\n^BG", _("Teams are too unbalanced."))
#define REGISTRY_SORT(...)
#define REGISTER_REGISTRY(id)
#define REGISTRY(id, max)
Declare a new registry.
#define REGISTRY_CHECK(id)
#define REGISTRY_DEFINE_GET(id, null)
#define REGISTRY_GET(id, i)
#define setSendEntity(e, f)
#define STATIC_INIT(func)
during worldspawn
#define yenc_single(c, ret)
#define ydec_single(stringiter, ret)