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