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