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_SERVER_H
4#define ENGINE_SERVER_SERVER_H
5
6#include "antibot.h"
7#include "authmanager.h"
8#include "name_ban.h"
9#include "snap_id_pool.h"
10
11#include <base/hash.h>
12
13#include <engine/console.h>
14#include <engine/server.h>
15#include <engine/shared/demo.h>
16#include <engine/shared/econ.h>
17#include <engine/shared/fifo.h>
18#include <engine/shared/http.h>
19#include <engine/shared/netban.h>
20#include <engine/shared/network.h>
21#include <engine/shared/protocol.h>
22#include <engine/shared/snapshot.h>
23#include <engine/shared/uuid_manager.h>
24
25#include <memory>
26#include <optional>
27#include <vector>
28
29#if defined(CONF_UPNP)
30#include "upnp.h"
31#endif
32
33class CConfig;
34class CHostLookup;
35class CLogMessage;
36class CMsgPacker;
37class CPacker;
38class IEngine;
39class IEngineHttp;
40class ILogger;
41
42class CServerBan : public CNetBan
43{
44 class CServer *m_pServer;
45
46 template<class T>
47 int BanExt(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason, bool VerbatimReason);
48
49public:
50 class CServer *Server() const { return m_pServer; }
51
52 void InitServerBan(class IConsole *pConsole, class IStorage *pStorage, class CServer *pServer);
53
54 int BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason, bool VerbatimReason) override;
55 int BanRange(const CNetRange *pRange, int Seconds, const char *pReason) override;
56
57 static void ConBanExt(class IConsole::IResult *pResult, void *pUser);
58 static void ConBanRegion(class IConsole::IResult *pResult, void *pUser);
59 static void ConBanRegionRange(class IConsole::IResult *pResult, void *pUser);
60};
61
62class CServer : public IServer
63{
64 friend class CServerLogger;
65
66 class IGameServer *m_pGameServer;
67 class CConfig *m_pConfig;
68 class IConsole *m_pConsole;
69 IEngineHttp *m_pHttp;
70 class IStorage *m_pStorage;
71 class IEngineAntibot *m_pAntibot;
72 class IRegister *m_pRegister;
73 IEngine *m_pEngine;
74
75#if defined(CONF_UPNP)
76 CUPnP m_UPnP;
77#endif
78
79#if defined(CONF_FAMILY_UNIX)
80 UNIXSOCKETADDR m_ConnLoggingDestAddr;
81 bool m_ConnLoggingSocketCreated;
82 UNIXSOCKET m_ConnLoggingSocket;
83#endif
84
85 class CDbConnectionPool *m_pConnectionPool;
86
87 int m_PreviousDebugDummies = 0;
88 void UpdateDebugDummies(bool ForceDisconnect);
89
90public:
91 class IGameServer *GameServer() { return m_pGameServer; }
92 class CConfig *Config() { return m_pConfig; }
93 const CConfig *Config() const { return m_pConfig; }
94 class IConsole *Console() { return m_pConsole; }
95 class IStorage *Storage() { return m_pStorage; }
96 class IEngineAntibot *Antibot() { return m_pAntibot; }
97 class CDbConnectionPool *DbPool() { return m_pConnectionPool; }
98 IEngine *Engine() { return m_pEngine; }
99
100 enum
101 {
102 MAX_RCONCMD_SEND = 16,
103 };
104
105 enum class EDnsblState
106 {
107 NONE,
108 PENDING,
109 BLACKLISTED,
110 WHITELISTED,
111 };
112
113 static const char *DnsblStateStr(EDnsblState State);
114
115 class CClient
116 {
117 public:
118 enum
119 {
120 STATE_REDIRECTED = -1,
121 STATE_EMPTY,
122 STATE_PREAUTH,
123 STATE_AUTH,
124 STATE_CONNECTING,
125 STATE_READY,
126 STATE_INGAME,
127 };
128
129 enum
130 {
131 SNAPRATE_INIT = 0,
132 SNAPRATE_FULL,
133 SNAPRATE_RECOVER,
134 };
135
136 class CInput
137 {
138 public:
139 int m_aData[MAX_INPUT_SIZE];
140 int m_GameTick; // the tick that was chosen for the input
141 };
142
143 // connection state info
144 int m_State;
145 int m_Latency;
146 int m_SnapRate;
147
148 double m_Traffic;
149 int64_t m_TrafficSince;
150
151 int m_LastAckedSnapshot;
152 int m_LastInputTick;
153 CSnapshotStorage m_Snapshots;
154
155 CNetMsg_Sv_PreInput m_LastPreInput = {};
156 CInput m_LatestInput;
157 CInput m_aInputs[200]; // TODO: handle input better
158 int m_CurrentInput;
159
160 char m_aName[MAX_NAME_LENGTH];
161 char m_aClan[MAX_CLAN_LENGTH];
162 /**
163 * Country code in ISO 3166-1 numeric.
164 */
165 int m_Country;
166 std::optional<int> m_Score;
167 int m_AuthKey;
168 int m_AuthTries;
169 bool m_AuthHidden;
170 int m_NextMapChunk;
171 int m_Flags;
172 bool m_ShowIps;
173 bool m_DebugDummy;
174 bool m_ForceHighBandwidthOnSpectate;
175 NETADDR m_DebugDummyAddr;
176 std::array<char, NETADDR_MAXSTRSIZE> m_aDebugDummyAddrString;
177 std::array<char, NETADDR_MAXSTRSIZE> m_aDebugDummyAddrStringNoPort;
178
179 const IConsole::ICommandInfo *m_pRconCmdToSend;
180 enum
181 {
182 MAPLIST_UNINITIALIZED = -1,
183 MAPLIST_DISABLED = -2,
184 MAPLIST_DONE = -3,
185 };
186 int m_MaplistEntryToSend;
187
188 bool m_HasPersistentData;
189 void *m_pPersistentData;
190
191 void Reset();
192
193 // DDRace
194
195 bool m_GotDDNetVersionPacket;
196 bool m_DDNetVersionSettled;
197 int m_DDNetVersion;
198 char m_aDDNetVersionStr[64];
199 CUuid m_ConnectionId;
200 int64_t m_RedirectDropTime;
201
202 // DNSBL
203 EDnsblState m_DnsblState;
204 std::shared_ptr<CHostLookup> m_pDnsblLookup;
205
206 bool m_Sixup;
207
208 bool IncludedInServerInfo() const
209 {
210 return m_State != STATE_EMPTY && !m_DebugDummy;
211 }
212 };
213
214 IConsole::EAccessLevel ConsoleAccessLevel(int ClientId) const;
215
216 CClient m_aClients[MAX_CLIENTS];
217 int m_aIdMap[MAX_CLIENTS * VANILLA_MAX_CLIENTS];
218
219 CSnapshotDelta m_SnapshotDelta;
220 CSnapshotDelta m_SnapshotDeltaSixup;
221 CSnapshotBuilder m_SnapshotBuilder;
222 CSnapIdPool m_IdPool;
223 CNetServer m_NetServer;
224 CEcon m_Econ;
225 CFifo m_Fifo;
226 CServerBan m_ServerBan;
227
228 int64_t m_GameStartTime;
229
230 enum
231 {
232 UNINITIALIZED = 0,
233 RUNNING = 1,
234 STOPPING = 2
235 };
236
237 int m_RunServer;
238
239 bool m_MapReload;
240 bool m_SameMapReload;
241 bool m_ReloadedWhenEmpty;
242 int m_RconClientId;
243 int m_RconAuthLevel;
244 int m_PrintCBIndex;
245 char m_aShutdownReason[128];
246 void *m_pPersistentData;
247
248 enum
249 {
250 MAP_TYPE_SIX = 0,
251 MAP_TYPE_SIXUP,
252 NUM_MAP_TYPES
253 };
254
255 enum
256 {
257 RECORDER_MANUAL = MAX_CLIENTS,
258 RECORDER_AUTO = MAX_CLIENTS + 1,
259 NUM_RECORDERS = MAX_CLIENTS + 2,
260 };
261
262 SHA256_DIGEST m_aCurrentMapSha256[NUM_MAP_TYPES];
263 unsigned m_aCurrentMapCrc[NUM_MAP_TYPES];
264 unsigned char *m_apCurrentMapData[NUM_MAP_TYPES];
265 unsigned int m_aCurrentMapSize[NUM_MAP_TYPES];
266 char m_aMapDownloadUrl[256];
267
268 CDemoRecorder m_aDemoRecorder[NUM_RECORDERS];
269 CAuthManager m_AuthManager;
270
271 int64_t m_ServerInfoFirstRequest;
272 int m_ServerInfoNumRequests;
273
274 char m_aErrorShutdownReason[128];
275
276 CNameBans m_NameBans;
277
278 size_t m_AnnouncementLastLine;
279 std::vector<std::string> m_vAnnouncements;
280
281 std::shared_ptr<ILogger> m_pFileLogger = nullptr;
282 std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
283
284 CServer();
285 ~CServer() override;
286
287 bool IsClientNameAvailable(int ClientId, const char *pNameRequest);
288 bool SetClientNameImpl(int ClientId, const char *pNameRequest, bool Set);
289 bool SetClientClanImpl(int ClientId, const char *pClanRequest, bool Set);
290
291 bool WouldClientNameChange(int ClientId, const char *pNameRequest) override;
292 bool WouldClientClanChange(int ClientId, const char *pClanRequest) override;
293 void SetClientName(int ClientId, const char *pName) override;
294 void SetClientClan(int ClientId, const char *pClan) override;
295 void SetClientCountry(int ClientId, int Country) override;
296 void SetClientScore(int ClientId, std::optional<int> Score) override;
297 void SetClientFlags(int ClientId, int Flags) override;
298
299 void Kick(int ClientId, const char *pReason) override;
300 void Ban(int ClientId, int Seconds, const char *pReason, bool VerbatimReason) override;
301 void ReconnectClient(int ClientId);
302 void RedirectClient(int ClientId, int Port) override;
303
304 void DemoRecorder_HandleAutoStart() override;
305
306 int64_t TickStartTime(int Tick);
307
308 int Init();
309
310 static bool StrHideIps(const char *pInput, char *pOutputWithIps, size_t OutputWithIpsSize, char *pOutputWithoutIps, size_t OutputWithoutIpsSize);
311 void SendLogLine(const CLogMessage *pMessage);
312 void SetRconCid(int ClientId) override;
313 int GetAuthedState(int ClientId) const override;
314 bool IsRconAuthed(int ClientId) const override;
315 bool IsRconAuthedAdmin(int ClientId) const override;
316 const char *GetAuthName(int ClientId) const override;
317 bool HasAuthHidden(int ClientId) const override;
318 bool GetClientInfo(int ClientId, CClientInfo *pInfo) const override;
319 void SetClientDDNetVersion(int ClientId, int DDNetVersion) override;
320 const NETADDR *ClientAddr(int ClientId) const override;
321 const std::array<char, NETADDR_MAXSTRSIZE> &ClientAddrStringImpl(int ClientId, bool IncludePort) const override;
322 const char *ClientName(int ClientId) const override;
323 const char *ClientClan(int ClientId) const override;
324 int ClientCountry(int ClientId) const override;
325 bool ClientSlotEmpty(int ClientId) const override;
326 bool ClientIngame(int ClientId) const override;
327 int Port() const override;
328 int MaxClients() const override;
329 int ClientCount() const override;
330 int DistinctClientCount() const override;
331
332 int GetClientVersion(int ClientId) const override;
333 int SendMsg(CMsgPacker *pMsg, int Flags, int ClientId) override;
334
335 void DoSnapshot();
336
337 static int NewClientCallback(int ClientId, void *pUser, bool Sixup);
338 static int NewClientNoAuthCallback(int ClientId, void *pUser);
339 static int DelClientCallback(int ClientId, const char *pReason, void *pUser);
340
341 static int ClientRejoinCallback(int ClientId, void *pUser);
342
343 void SendRconType(int ClientId, bool UsernameReq);
344 void SendCapabilities(int ClientId);
345 void SendMap(int ClientId);
346 void SendMapData(int ClientId, int Chunk);
347 void SendMapReload(int ClientId);
348 void SendConnectionReady(int ClientId);
349 void SendRconLine(int ClientId, const char *pLine);
350 // Accepts -1 as ClientId to mean "all clients with at least auth level admin"
351 void SendRconLogLine(int ClientId, const CLogMessage *pMessage);
352
353 void SendRconCmdAdd(const IConsole::ICommandInfo *pCommandInfo, int ClientId);
354 void SendRconCmdRem(const IConsole::ICommandInfo *pCommandInfo, int ClientId);
355 void SendRconCmdGroupStart(int ClientId);
356 void SendRconCmdGroupEnd(int ClientId);
357 int NumRconCommands(int ClientId);
358 void UpdateClientRconCommands(int ClientId);
359
360 class CMaplistEntry
361 {
362 public:
363 char m_aName[128];
364
365 CMaplistEntry() = default;
366 CMaplistEntry(const char *pName);
367 bool operator<(const CMaplistEntry &Other) const;
368 };
369 std::vector<CMaplistEntry> m_vMaplistEntries;
370 void SendMaplistGroupStart(int ClientId);
371 void SendMaplistGroupEnd(int ClientId);
372 void UpdateClientMaplistEntries(int ClientId);
373
374 bool CheckReservedSlotAuth(int ClientId, const char *pPassword);
375 void ProcessClientPacket(CNetChunk *pPacket);
376 void OnNetMsgClientVer(int ClientId, CUuid *pConnectionId, int DDNetVersion, const char *pDDNetVersionStr);
377 void OnNetMsgInfo(int ClientId, const char *pVersion, const char *pPasswordOrNullptr);
378 void OnNetMsgReady(int ClientId);
379 void OnNetMsgEnterGame(int ClientId);
380 void OnNetMsgRconCmd(int ClientId, const char *pCmd);
381 void OnNetMsgRconAuth(int ClientId, const char *pName, const char *pPw, bool SendRconCmds);
382
383 class CCache
384 {
385 public:
386 class CCacheChunk
387 {
388 public:
389 CCacheChunk(const void *pData, int Size);
390 CCacheChunk(const CCacheChunk &) = delete;
391 CCacheChunk(CCacheChunk &&) = default;
392
393 std::vector<uint8_t> m_vData;
394 };
395
396 std::vector<CCacheChunk> m_vCache;
397
398 CCache();
399 ~CCache();
400
401 void AddChunk(const void *pData, int Size);
402 void Clear();
403 };
404 CCache m_aServerInfoCache[3 * 2];
405 CCache m_aSixupServerInfoCache[2];
406 bool m_ServerInfoNeedsUpdate = false;
407 bool m_ServerInfoNeedsResend = false;
408
409 void FillAntibot(CAntibotRoundData *pData) override;
410
411 void ExpireServerInfo() override;
412 void ExpireServerInfoAndQueueResend();
413 void CacheServerInfo(CCache *pCache, int Type, bool SendClients);
414 void CacheServerInfoSixup(CCache *pCache, bool SendClients, int MaxConsideredClients);
415 void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients);
416 void GetServerInfoSixup(CPacker *pPacker, bool SendClients);
417 bool RateLimitServerInfoConnless();
418 void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type);
419 void UpdateRegisterServerInfo();
420 void UpdateServerInfo(bool Resend);
421
422 void PumpNetwork(bool PacketWaiting);
423
424 void ChangeMap(const char *pMap) override;
425 void ReloadMap() override;
426 int LoadMap(const char *pMapName);
427
428 void SaveDemo(int ClientId, float Time) override;
429 void StartRecord(int ClientId) override;
430 void StopRecord(int ClientId) override;
431 bool IsRecording(int ClientId) override;
432 void StopDemos() override;
433
434 int Run();
435
436 static void ConKick(IConsole::IResult *pResult, void *pUser);
437 static void ConStatus(IConsole::IResult *pResult, void *pUser);
438 static void ConShutdown(IConsole::IResult *pResult, void *pUser);
439 static void ConRecord(IConsole::IResult *pResult, void *pUser);
440 static void ConStopRecord(IConsole::IResult *pResult, void *pUser);
441 static void ConMapReload(IConsole::IResult *pResult, void *pUser);
442 static void ConLogout(IConsole::IResult *pResult, void *pUser);
443 static void ConShowIps(IConsole::IResult *pResult, void *pUser);
444 static void ConHideAuthStatus(IConsole::IResult *pResult, void *pUser);
445 static void ConForceHighBandwidthOnSpectate(IConsole::IResult *pResult, void *pUser);
446
447 static void ConAuthAdd(IConsole::IResult *pResult, void *pUser);
448 static void ConAuthAddHashed(IConsole::IResult *pResult, void *pUser);
449 static void ConAuthUpdate(IConsole::IResult *pResult, void *pUser);
450 static void ConAuthUpdateHashed(IConsole::IResult *pResult, void *pUser);
451 static void ConAuthRemove(IConsole::IResult *pResult, void *pUser);
452 static void ConAuthList(IConsole::IResult *pResult, void *pUser);
453
454 // console commands for sqlmasters
455 static void ConAddSqlServer(IConsole::IResult *pResult, void *pUserData);
456 static void ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData);
457
458 static void ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData);
459 static void ConReloadMaplist(IConsole::IResult *pResult, void *pUserData);
460
461 static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
462 static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
463 static void ConchainCommandAccessUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
464
465 void LogoutClient(int ClientId, const char *pReason);
466 void LogoutKey(int Key, const char *pReason);
467
468 void ConchainRconPasswordChangeGeneric(const char *pRoleName, const char *pCurrent, IConsole::IResult *pResult);
469 static void ConchainRconPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
470 static void ConchainRconModPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
471 static void ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
472 static void ConchainMapUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
473 static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
474 static void ConchainRegisterCommunityTokenRedact(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
475 static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
476 static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
477 static void ConchainAnnouncementFilename(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
478 static void ConchainInputFifo(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
479
480#if defined(CONF_FAMILY_UNIX)
481 static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
482#endif
483
484 void RegisterCommands();
485
486 std::optional<int> SnapNewId() override;
487 void SnapFreeId(int Id) override;
488 bool SnapNewItem(int Type, int Id, const void *pData, int Size) override;
489 void SnapSetStaticsize(int ItemType, int Size) override;
490 void SnapSetStaticsize7(int ItemType, int Size) override;
491
492 // DDRace
493
494 int m_aPrevStates[MAX_CLIENTS];
495 const char *GetAnnouncementLine() override;
496 void ReadAnnouncementsFile();
497
498 static int MaplistEntryCallback(const char *pFilename, int IsDir, int DirType, void *pUser);
499 void InitMaplist();
500
501 int *GetIdMap(int ClientId) override;
502
503 void InitDnsbl(int ClientId);
504 bool DnsblWhite(int ClientId) override
505 {
506 return m_aClients[ClientId].m_DnsblState == EDnsblState::NONE ||
507 m_aClients[ClientId].m_DnsblState == EDnsblState::WHITELISTED;
508 }
509 bool DnsblPending(int ClientId) override
510 {
511 return m_aClients[ClientId].m_DnsblState == EDnsblState::PENDING;
512 }
513 bool DnsblBlack(int ClientId) override
514 {
515 return m_aClients[ClientId].m_DnsblState == EDnsblState::BLACKLISTED;
516 }
517
518 static bool CanClientUseCommandCallback(int ClientId, const IConsole::ICommandInfo *pCommand, void *pUser);
519 bool CanClientUseCommand(int ClientId, const IConsole::ICommandInfo *pCommand) const;
520 void AuthRemoveKey(int KeySlot);
521 bool ClientPrevIngame(int ClientId) override { return m_aPrevStates[ClientId] == CClient::STATE_INGAME; }
522 const char *GetNetErrorString(int ClientId) override { return m_NetServer.ErrorString(ClientId); }
523 void ResetNetErrorString(int ClientId) override { m_NetServer.ResetErrorString(ClientId); }
524 bool SetTimedOut(int ClientId, int OrigId) override;
525 void SetTimeoutProtected(int ClientId) override { m_NetServer.IgnoreTimeouts(ClientId); }
526
527 void SendMsgRaw(int ClientId, const void *pData, int Size, int Flags) override;
528
529 bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; }
530 void SetErrorShutdown(const char *pReason) override;
531
532 bool IsSixup(int ClientId) const override { return ClientId != SERVER_DEMO_CLIENT && m_aClients[ClientId].m_Sixup; }
533
534 void SetLoggers(std::shared_ptr<ILogger> &&pFileLogger, std::shared_ptr<ILogger> &&pStdoutLogger);
535
536#ifdef CONF_FAMILY_UNIX
537 enum CONN_LOGGING_CMD
538 {
539 OPEN_SESSION = 1,
540 CLOSE_SESSION = 2,
541 };
542
543 void SendConnLoggingCommand(CONN_LOGGING_CMD Cmd, const NETADDR *pAddr);
544#endif
545};
546
547bool IsInterrupted();
548
549extern CServer *CreateServer();
550#endif
551