DDNet documentation
Loading...
Searching...
No Matches
server.h
Go to the documentation of this file.
1/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
2/* If you are missing that file, acquire a complete release at teeworlds.com. */
3#ifndef ENGINE_SERVER_H
4#define ENGINE_SERVER_H
5
6#include "kernel.h"
7#include "message.h"
8
9#include <base/dbg.h>
10#include <base/hash.h>
11#include <base/math.h>
12#include <base/mem.h>
13#include <base/str.h>
14
17
18#include <generated/protocol.h>
19#include <generated/protocol7.h>
21
22#include <array>
23#include <optional>
24#include <type_traits>
25
27class IMap;
28
29// When recording a demo on the server, the ClientId -1 is used
30enum
31{
33};
34
35class IServer : public IInterface
36{
38protected:
40
41public:
42 /*
43 Structure: CClientInfo
44 */
54
55 int Tick() const { return m_CurrentGameTick; }
56 int TickSpeed() const { return SERVER_TICK_SPEED; }
57
58 virtual int Port() const = 0;
59 virtual int MaxClients() const = 0;
60 virtual int ClientCount() const = 0;
61 virtual int DistinctClientCount() const = 0;
62 virtual const char *ClientName(int ClientId) const = 0;
63 virtual const char *ClientClan(int ClientId) const = 0;
64 virtual int ClientCountry(int ClientId) const = 0;
65 virtual bool ClientSlotEmpty(int ClientId) const = 0;
66 virtual bool ClientIngame(int ClientId) const = 0;
67 virtual bool GetClientInfo(int ClientId, CClientInfo *pInfo) const = 0;
68 virtual void SetClientDDNetVersion(int ClientId, int DDNetVersion) = 0;
69 virtual const NETADDR *ClientAddr(int ClientId) const = 0;
70 virtual const std::array<char, NETADDR_MAXSTRSIZE> &ClientAddrStringImpl(int ClientId, bool IncludePort) const = 0;
71 const char *ClientAddrString(int ClientId, bool IncludePort) const { return ClientAddrStringImpl(ClientId, IncludePort).data(); }
72
83 virtual int GetClientVersion(int ClientId) const = 0;
84 virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientId) = 0;
85
86 template<class T>
88 int SendPackMsg(const T *pMsg, int Flags, int ClientId)
89 {
90 int Result = 0;
91 if(ClientId == -1)
92 {
93 for(int i = 0; i < MaxClients(); i++)
94 if(ClientIngame(i))
95 Result = SendPackMsgTranslate(pMsg, Flags, i);
96 }
97 else
98 {
99 Result = SendPackMsgTranslate(pMsg, Flags, ClientId);
100 }
101 return Result;
102 }
103
104 template<class T>
106 int SendPackMsg(const T *pMsg, int Flags, int ClientId)
107 {
108 int Result = 0;
109 if(ClientId == -1)
110 {
111 for(int i = 0; i < MaxClients(); i++)
112 if(ClientIngame(i) && IsSixup(i))
113 Result = SendPackMsgOne(pMsg, Flags, i);
114 }
115 else if(IsSixup(ClientId))
116 {
117 Result = SendPackMsgOne(pMsg, Flags, ClientId);
118 }
119
120 return Result;
121 }
122
123 template<class T>
124 int SendPackMsgTranslate(const T *pMsg, int Flags, int ClientId)
125 {
126 return SendPackMsgOne(pMsg, Flags, ClientId);
127 }
128
129 int SendPackMsgTranslate(const CNetMsg_Sv_Emoticon *pMsg, int Flags, int ClientId)
130 {
131 CNetMsg_Sv_Emoticon MsgCopy;
132 mem_copy(&MsgCopy, pMsg, sizeof(MsgCopy));
133 return Translate(MsgCopy.m_ClientId, ClientId) && SendPackMsgOne(&MsgCopy, Flags, ClientId);
134 }
135
136 int SendPackMsgTranslate(const CNetMsg_Sv_Chat *pMsg, int Flags, int ClientId)
137 {
138 CNetMsg_Sv_Chat MsgCopy;
139 mem_copy(&MsgCopy, pMsg, sizeof(MsgCopy));
140
141 char aBuf[1000];
142 if(MsgCopy.m_ClientId >= 0 && !Translate(MsgCopy.m_ClientId, ClientId))
143 {
144 str_format(aBuf, sizeof(aBuf), "%s: %s", ClientName(MsgCopy.m_ClientId), MsgCopy.m_pMessage);
145 MsgCopy.m_pMessage = aBuf;
146 MsgCopy.m_ClientId = VANILLA_MAX_CLIENTS - 1;
147 }
148
149 if(IsSixup(ClientId))
150 {
152 Msg7.m_ClientId = MsgCopy.m_ClientId;
153 Msg7.m_pMessage = MsgCopy.m_pMessage;
155 Msg7.m_TargetId = -1;
156 return SendPackMsgOne(&Msg7, Flags, ClientId);
157 }
158
159 return SendPackMsgOne(&MsgCopy, Flags, ClientId);
160 }
161
162 int SendPackMsgTranslate(const CNetMsg_Sv_KillMsg *pMsg, int Flags, int ClientId)
163 {
164 CNetMsg_Sv_KillMsg MsgCopy;
165 mem_copy(&MsgCopy, pMsg, sizeof(MsgCopy));
166 if(!Translate(MsgCopy.m_Victim, ClientId))
167 return 0;
168 if(!Translate(MsgCopy.m_Killer, ClientId))
169 MsgCopy.m_Killer = MsgCopy.m_Victim;
170 return SendPackMsgOne(&MsgCopy, Flags, ClientId);
171 }
172
173 int SendPackMsgTranslate(const CNetMsg_Sv_RaceFinish *pMsg, int Flags, int ClientId)
174 {
175 if(IsSixup(ClientId))
176 {
178 Msg7.m_ClientId = pMsg->m_ClientId;
179 Msg7.m_Diff = pMsg->m_Diff;
180 Msg7.m_Time = pMsg->m_Time;
182 Msg7.m_RecordServer = pMsg->m_RecordServer;
183 return SendPackMsgOne(&Msg7, Flags, ClientId);
184 }
185 return SendPackMsgOne(pMsg, Flags, ClientId);
186 }
187
188 template<class T>
189 int SendPackMsgOne(const T *pMsg, int Flags, int ClientId)
190 {
191 dbg_assert(ClientId != -1, "SendPackMsgOne called with -1");
192 CMsgPacker Packer(T::ms_MsgId, false, protocol7::is_sixup<T>::value);
193
194 if(pMsg->Pack(&Packer))
195 return -1;
196 return SendMsg(&Packer, Flags, ClientId);
197 }
198
199 bool Translate(int &Target, int Client)
200 {
201 if(IsSixup(Client))
202 return true;
204 return true;
205 int *pMap = GetIdMap(Client);
206 bool Found = false;
207 for(int i = 0; i < VANILLA_MAX_CLIENTS; i++)
208 {
209 if(Target == pMap[i])
210 {
211 Target = i;
212 Found = true;
213 break;
214 }
215 }
216 return Found;
217 }
218
219 bool ReverseTranslate(int &Target, int Client)
220 {
221 if(IsSixup(Client))
222 return true;
224 return true;
225 Target = std::clamp(Target, 0, VANILLA_MAX_CLIENTS - 1);
226 int *pMap = GetIdMap(Client);
227 if(pMap[Target] == -1)
228 return false;
229 Target = pMap[Target];
230 return true;
231 }
232
233 virtual bool WouldClientNameChange(int ClientId, const char *pNameRequest) = 0;
234 virtual bool WouldClientClanChange(int ClientId, const char *pClanRequest) = 0;
235 virtual void SetClientName(int ClientId, const char *pName) = 0;
236 virtual void SetClientClan(int ClientId, const char *pClan) = 0;
237 virtual void SetClientCountry(int ClientId, int Country) = 0;
238 virtual void SetClientScore(int ClientId, std::optional<int> Score) = 0;
239 virtual void SetClientFlags(int ClientId, int Flags) = 0;
240
241 virtual std::optional<int> SnapNewId() = 0;
242 virtual void SnapFreeId(int Id) = 0;
243 virtual bool SnapNewItem(int Type, int Id, rust::Slice<const int32_t> Data) = 0;
244
245 template<typename T>
246 bool SnapNewItem(int Id, const T &Data)
247 {
248 const int Type = protocol7::is_sixup<T>::value ? -T::ms_MsgId : T::ms_MsgId;
249 return SnapNewItem(Type, Id, Data.AsSlice());
250 }
251
252 virtual void SnapSetStaticsize(int ItemType, int Size) = 0;
253 virtual void SnapSetStaticsize7(int ItemType, int Size) = 0;
254
255 enum
256 {
259 };
260 virtual void SetRconCid(int ClientId) = 0;
261 virtual int GetAuthedState(int ClientId) const = 0;
262 virtual bool IsRconAuthed(int ClientId) const = 0;
263 virtual bool IsRconAuthedAdmin(int ClientId) const = 0;
264 virtual const char *GetAuthName(int ClientId) const = 0;
265 virtual bool HasAuthHidden(int ClientId) const = 0;
266 virtual void Kick(int ClientId, const char *pReason) = 0;
267 virtual void Ban(int ClientId, int Seconds, const char *pReason, bool VerbatimReason) = 0;
268 virtual void RedirectClient(int ClientId, int Port) = 0;
269 virtual void ChangeMap(const char *pMap) = 0;
270 virtual void ReloadMap() = 0;
271
273
274 // DDRace
275
276 virtual void SaveDemo(int ClientId, float Time) = 0;
277 virtual void StartRecord(int ClientId) = 0;
278 virtual void StopRecord(int ClientId) = 0;
279 virtual bool IsRecording(int ClientId) = 0;
280 virtual void StopDemos() = 0;
281
282 virtual int *GetIdMap(int ClientId) = 0;
283
284 virtual bool DnsblWhite(int ClientId) = 0;
285 virtual bool DnsblPending(int ClientId) = 0;
286 virtual bool DnsblBlack(int ClientId) = 0;
287 virtual const char *GetAnnouncementLine() = 0;
288 virtual bool ClientPrevIngame(int ClientId) = 0;
289 virtual const char *GetNetErrorString(int ClientId) = 0;
290 virtual void ResetNetErrorString(int ClientId) = 0;
291 virtual bool SetTimedOut(int ClientId, int OrigId) = 0;
292 virtual void SetTimeoutProtected(int ClientId) = 0;
293
294 virtual void SetErrorShutdown(const char *pReason) = 0;
295 virtual void ExpireServerInfo() = 0;
296
297 virtual void FillAntibot(CAntibotRoundData *pData) = 0;
298
299 virtual void SendMsgRaw(int ClientId, const void *pData, int Size, int Flags) = 0;
300
301 virtual bool IsSixup(int ClientId) const = 0;
302};
303
305{
306 MACRO_INTERFACE("gameserver")
307protected:
308public:
309 // `pPersistentData` may be null if this is the first time `IGameServer`
310 // is instantiated.
311 virtual void OnInit(const void *pPersistentData) = 0;
312 virtual void OnConsoleInit() = 0;
313 // Returns `true` if map change accepted.
314 [[nodiscard]] virtual bool OnMapChange(char *pNewMapName, int MapNameSize) = 0;
315 // `pPersistentData` may be null if this is the last time `IGameServer`
316 // is destroyed.
317 virtual void OnShutdown(void *pPersistentData) = 0;
318
319 virtual void OnTick() = 0;
320
321 // Snap for a specific client.
322 //
323 // GlobalSnap is true when sending snapshots to all clients,
324 // otherwise only forced high bandwidth clients would receive snap.
325 // RecordingDemo is true when this snapshot will be recorded to a demo.
326 virtual void OnSnap(int ClientId, bool GlobalSnap, bool RecordingDemo) = 0;
327
328 // Called after sending snapshots to all clients.
329 //
330 // Note if any client has force high bandwidth enabled,
331 // this will not be called when only sending snapshots to these clients.
332 virtual void OnPostGlobalSnap() = 0;
333
334 virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId) = 0;
335
336 // Called before map reload, for any data that the game wants to
337 // persist to the next map.
338 //
339 // Has the size of the return value of `PersistentClientDataSize()`.
340 //
341 // Returns whether the game should be supplied with the data when the
342 // client connects for the next map.
343 virtual bool OnClientDataPersist(int ClientId, void *pData) = 0;
344
345 // Called when a client connects.
346 //
347 // If it is reconnecting to the game after a map change, the
348 // `pPersistentData` point is nonnull and contains the data the game
349 // previously stored.
350 virtual void OnClientConnected(int ClientId, void *pPersistentData) = 0;
351
352 virtual void OnClientEnter(int ClientId) = 0;
353 virtual void OnClientDrop(int ClientId, const char *pReason) = 0;
354 virtual void OnClientPrepareInput(int ClientId, void *pInput) = 0;
355 virtual void OnClientDirectInput(int ClientId, const void *pInput) = 0;
356 virtual void OnClientPredictedInput(int ClientId, const void *pInput) = 0;
357 virtual void OnClientPredictedEarlyInput(int ClientId, const void *pInput) = 0;
358
359 virtual void PreInputClients(int ClientId, bool *pClients) = 0;
360
361 virtual bool IsClientReady(int ClientId) const = 0;
362 virtual bool IsClientPlayer(int ClientId) const = 0;
363 virtual bool IsClientHighBandwidth(int ClientId) const = 0;
364
365 virtual int PersistentDataSize() const = 0;
366 virtual int PersistentClientDataSize() const = 0;
367
368 virtual CUuid GameUuid() const = 0;
369 virtual const char *GameType() const = 0;
370 virtual const char *Version() const = 0;
371 virtual const char *NetVersion() const = 0;
372
373 virtual IMap *Map() = 0;
374 virtual const IMap *Map() const = 0;
377
378 // DDRace
379
380 virtual void OnPreTickTeehistorian() = 0;
381
382 virtual void OnSetAuthed(int ClientId, int Level) = 0;
383 virtual bool PlayerExists(int ClientId) const = 0;
384
385 virtual void TeehistorianRecordAntibot(const void *pData, int DataSize) = 0;
386 virtual void TeehistorianRecordPlayerJoin(int ClientId, bool Sixup) = 0;
387 virtual void TeehistorianRecordPlayerDrop(int ClientId, const char *pReason) = 0;
388 virtual void TeehistorianRecordPlayerRejoin(int ClientId) = 0;
389 virtual void TeehistorianRecordPlayerName(int ClientId, const char *pName) = 0;
390 virtual void TeehistorianRecordPlayerFinish(int ClientId, int TimeTicks) = 0;
391 virtual void TeehistorianRecordTeamFinish(int TeamId, int TimeTicks) = 0;
392 virtual void TeehistorianRecordAuthLogin(int ClientId, int Level, const char *pAuthName) = 0;
393
394 virtual void FillAntibot(CAntibotRoundData *pData) = 0;
395
402 virtual void OnUpdatePlayerServerInfo(CJsonWriter *pJsonWriter, int ClientId) = 0;
403};
404
406#endif
Definition jsonwriter.h:15
Definition message.h:10
Definition protocol.h:1710
Definition packer.h:54
Definition server.h:305
virtual const char * GameType() const =0
virtual void TeehistorianRecordPlayerFinish(int ClientId, int TimeTicks)=0
virtual void TeehistorianRecordPlayerName(int ClientId, const char *pName)=0
virtual void OnMessage(int MsgId, CUnpacker *pUnpacker, int ClientId)=0
virtual int PersistentDataSize() const =0
virtual bool OnClientDataPersist(int ClientId, void *pData)=0
virtual void OnUpdatePlayerServerInfo(CJsonWriter *pJsonWriter, int ClientId)=0
virtual void FillAntibot(CAntibotRoundData *pData)=0
virtual IMap * Map()=0
virtual void OnSetAuthed(int ClientId, int Level)=0
virtual void OnClientPredictedInput(int ClientId, const void *pInput)=0
virtual CUuid GameUuid() const =0
virtual void OnPostGlobalSnap()=0
virtual CNetObjHandler * GetNetObjHandler()=0
virtual void OnPreTickTeehistorian()=0
virtual void TeehistorianRecordTeamFinish(int TeamId, int TimeTicks)=0
virtual const char * NetVersion() const =0
virtual void OnClientEnter(int ClientId)=0
virtual void TeehistorianRecordAntibot(const void *pData, int DataSize)=0
virtual void OnTick()=0
virtual void TeehistorianRecordAuthLogin(int ClientId, int Level, const char *pAuthName)=0
virtual void OnClientConnected(int ClientId, void *pPersistentData)=0
virtual void PreInputClients(int ClientId, bool *pClients)=0
virtual void OnConsoleInit()=0
virtual const char * Version() const =0
virtual bool IsClientPlayer(int ClientId) const =0
virtual void OnClientDirectInput(int ClientId, const void *pInput)=0
virtual protocol7::CNetObjHandler * GetNetObjHandler7()=0
virtual void OnClientPredictedEarlyInput(int ClientId, const void *pInput)=0
virtual bool PlayerExists(int ClientId) const =0
virtual void OnClientDrop(int ClientId, const char *pReason)=0
virtual void TeehistorianRecordPlayerDrop(int ClientId, const char *pReason)=0
virtual bool IsClientReady(int ClientId) const =0
virtual void OnShutdown(void *pPersistentData)=0
virtual void OnClientPrepareInput(int ClientId, void *pInput)=0
virtual void TeehistorianRecordPlayerRejoin(int ClientId)=0
virtual void TeehistorianRecordPlayerJoin(int ClientId, bool Sixup)=0
virtual bool OnMapChange(char *pNewMapName, int MapNameSize)=0
virtual void OnSnap(int ClientId, bool GlobalSnap, bool RecordingDemo)=0
virtual int PersistentClientDataSize() const =0
virtual bool IsClientHighBandwidth(int ClientId) const =0
virtual void OnInit(const void *pPersistentData)=0
IInterface()
Definition kernel.h:19
Definition map.h:20
Definition server.h:36
virtual int ClientCount() const =0
virtual void RedirectClient(int ClientId, int Port)=0
virtual void SetTimeoutProtected(int ClientId)=0
bool ReverseTranslate(int &Target, int Client)
Definition server.h:219
virtual bool IsRconAuthedAdmin(int ClientId) const =0
virtual const NETADDR * ClientAddr(int ClientId) const =0
int SendPackMsgTranslate(const CNetMsg_Sv_RaceFinish *pMsg, int Flags, int ClientId)
Definition server.h:173
int SendPackMsg(const T *pMsg, int Flags, int ClientId)
Definition server.h:88
virtual void SetRconCid(int ClientId)=0
bool SnapNewItem(int Id, const T &Data)
Definition server.h:246
virtual bool WouldClientClanChange(int ClientId, const char *pClanRequest)=0
virtual void SetClientName(int ClientId, const char *pName)=0
virtual bool WouldClientNameChange(int ClientId, const char *pNameRequest)=0
int SendPackMsgTranslate(const T *pMsg, int Flags, int ClientId)
Definition server.h:124
virtual void SnapSetStaticsize(int ItemType, int Size)=0
virtual int Port() const =0
virtual bool DnsblBlack(int ClientId)=0
virtual void SnapFreeId(int Id)=0
int Tick() const
Definition server.h:55
virtual bool DnsblWhite(int ClientId)=0
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientId)=0
virtual const char * GetAuthName(int ClientId) const =0
virtual bool IsSixup(int ClientId) const =0
int SendPackMsgTranslate(const CNetMsg_Sv_Chat *pMsg, int Flags, int ClientId)
Definition server.h:136
virtual void StopDemos()=0
virtual void ExpireServerInfo()=0
virtual int ClientCountry(int ClientId) const =0
virtual void Ban(int ClientId, int Seconds, const char *pReason, bool VerbatimReason)=0
virtual int MaxClients() const =0
virtual void SetClientScore(int ClientId, std::optional< int > Score)=0
virtual int * GetIdMap(int ClientId)=0
virtual void ReloadMap()=0
virtual void ChangeMap(const char *pMap)=0
virtual bool ClientPrevIngame(int ClientId)=0
virtual bool GetClientInfo(int ClientId, CClientInfo *pInfo) const =0
virtual void FillAntibot(CAntibotRoundData *pData)=0
virtual const std::array< char, NETADDR_MAXSTRSIZE > & ClientAddrStringImpl(int ClientId, bool IncludePort) const =0
virtual void SetErrorShutdown(const char *pReason)=0
virtual void SetClientFlags(int ClientId, int Flags)=0
virtual bool IsRconAuthed(int ClientId) const =0
const char * ClientAddrString(int ClientId, bool IncludePort) const
Definition server.h:71
virtual bool IsRecording(int ClientId)=0
int SendPackMsgOne(const T *pMsg, int Flags, int ClientId)
Definition server.h:189
virtual int DistinctClientCount() const =0
int TickSpeed() const
Definition server.h:56
virtual const char * ClientName(int ClientId) const =0
int m_CurrentGameTick
Definition server.h:39
virtual int GetAuthedState(int ClientId) const =0
virtual void SetClientDDNetVersion(int ClientId, int DDNetVersion)=0
virtual void SnapSetStaticsize7(int ItemType, int Size)=0
virtual void DemoRecorder_HandleAutoStart()=0
virtual bool HasAuthHidden(int ClientId) const =0
@ RCON_CID_VOTE
Definition server.h:258
@ RCON_CID_SERV
Definition server.h:257
virtual void SetClientClan(int ClientId, const char *pClan)=0
virtual bool ClientIngame(int ClientId) const =0
virtual void StopRecord(int ClientId)=0
bool Translate(int &Target, int Client)
Definition server.h:199
virtual void SetClientCountry(int ClientId, int Country)=0
int SendPackMsgTranslate(const CNetMsg_Sv_KillMsg *pMsg, int Flags, int ClientId)
Definition server.h:162
virtual const char * GetAnnouncementLine()=0
virtual void Kick(int ClientId, const char *pReason)=0
virtual bool DnsblPending(int ClientId)=0
virtual void SaveDemo(int ClientId, float Time)=0
virtual void StartRecord(int ClientId)=0
int SendPackMsgTranslate(const CNetMsg_Sv_Emoticon *pMsg, int Flags, int ClientId)
Definition server.h:129
virtual int GetClientVersion(int ClientId) const =0
virtual void ResetNetErrorString(int ClientId)=0
virtual void SendMsgRaw(int ClientId, const void *pData, int Size, int Flags)=0
virtual const char * ClientClan(int ClientId) const =0
virtual const char * GetNetErrorString(int ClientId)=0
virtual std::optional< int > SnapNewId()=0
virtual bool SnapNewItem(int Type, int Id, rust::Slice< const int32_t > Data)=0
virtual bool SetTimedOut(int ClientId, int OrigId)=0
virtual bool ClientSlotEmpty(int ClientId) const =0
@ SERVER_TICK_SPEED
Definition protocol.h:81
@ VANILLA_MAX_CLIENTS
Definition protocol.h:90
@ VERSION_DDNET_OLD
Definition protocol.h:140
#define dbg_assert(test, fmt,...)
Definition dbg.h:27
void mem_copy(void *dest, const void *source, size_t size)
Definition mem.cpp:6
#define MACRO_INTERFACE(Name)
Definition kernel.h:25
Definition protocol7.h:9
@ CHAT_ALL
Definition protocol7.h:110
@ CHAT_TEAM
Definition protocol7.h:111
@ SERVER_DEMO_CLIENT
Definition server.h:32
IGameServer * CreateGameServer()
Definition gamecontext.cpp:4828
#define str_format
Definition str.cpp:89
Definition antibot_data.h:111
Definition protocol.h:833
const char * m_pMessage
Definition protocol.h:838
int m_ClientId
Definition protocol.h:837
int m_Team
Definition protocol.h:836
Definition protocol.h:928
int m_ClientId
Definition protocol.h:931
Definition protocol.h:850
int m_Victim
Definition protocol.h:854
int m_Killer
Definition protocol.h:853
Definition protocol.h:1411
int m_RecordServer
Definition protocol.h:1418
int m_RecordPersonal
Definition protocol.h:1417
int m_Diff
Definition protocol.h:1416
int m_ClientId
Definition protocol.h:1414
int m_Time
Definition protocol.h:1415
Definition uuid_manager.h:18
Definition server.h:46
const char * m_pName
Definition server.h:47
const CUuid * m_pConnectionId
Definition server.h:52
int m_Latency
Definition server.h:48
int m_DDNetVersion
Definition server.h:50
bool m_GotDDNetVersion
Definition server.h:49
const char * m_pDDNetVersionStr
Definition server.h:51
Definition types.h:168
Definition score_test.cpp:25
Definition protocol7.h:556
int m_TargetId
Definition protocol7.h:562
int m_ClientId
Definition protocol7.h:561
const char * m_pMessage
Definition protocol7.h:563
int m_Mode
Definition protocol7.h:560
Definition protocol7.h:1162
int m_RecordServer
Definition protocol7.h:1170
int m_Time
Definition protocol7.h:1167
int m_RecordPersonal
Definition protocol7.h:1169
int m_ClientId
Definition protocol7.h:1166
int m_Diff
Definition protocol7.h:1168
static constexpr bool value
Definition protocol7.h:259