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 CSnapshotDelta m_SnapshotDeltaSixup;
216 CSnapshotBuilder m_SnapshotBuilder;
217 CSnapIdPool m_IdPool;
218 CNetServer m_NetServer;
219 CEcon m_Econ;
220 CFifo m_Fifo;
221 CServerBan m_ServerBan;
222 CHttp m_Http;
223
224 int64_t m_GameStartTime;
225
226 enum
227 {
228 UNINITIALIZED = 0,
229 RUNNING = 1,
230 STOPPING = 2
231 };
232
233 int m_RunServer;
234
235 bool m_MapReload;
236 bool m_SameMapReload;
237 bool m_ReloadedWhenEmpty;
238 int m_RconClientId;
239 int m_RconAuthLevel;
240 int m_PrintCBIndex;
241 char m_aShutdownReason[128];
242 void *m_pPersistentData;
243
244 enum
245 {
246 MAP_TYPE_SIX = 0,
247 MAP_TYPE_SIXUP,
248 NUM_MAP_TYPES
249 };
250
251 enum
252 {
253 RECORDER_MANUAL = MAX_CLIENTS,
254 RECORDER_AUTO = MAX_CLIENTS + 1,
255 NUM_RECORDERS = MAX_CLIENTS + 2,
256 };
257
258 SHA256_DIGEST m_aCurrentMapSha256[NUM_MAP_TYPES];
259 unsigned m_aCurrentMapCrc[NUM_MAP_TYPES];
260 unsigned char *m_apCurrentMapData[NUM_MAP_TYPES];
261 unsigned int m_aCurrentMapSize[NUM_MAP_TYPES];
262 char m_aMapDownloadUrl[256];
263
264 CDemoRecorder m_aDemoRecorder[NUM_RECORDERS];
265 CAuthManager m_AuthManager;
266
267 int64_t m_ServerInfoFirstRequest;
268 int m_ServerInfoNumRequests;
269
270 char m_aErrorShutdownReason[128];
271
272 CNameBans m_NameBans;
273
274 size_t m_AnnouncementLastLine;
275 std::vector<std::string> m_vAnnouncements;
276
277 std::shared_ptr<ILogger> m_pFileLogger = nullptr;
278 std::shared_ptr<ILogger> m_pStdoutLogger = nullptr;
279
280 CServer();
281 ~CServer() override;
282
283 bool IsClientNameAvailable(int ClientId, const char *pNameRequest);
284 bool SetClientNameImpl(int ClientId, const char *pNameRequest, bool Set);
285 bool SetClientClanImpl(int ClientId, const char *pClanRequest, bool Set);
286
287 bool WouldClientNameChange(int ClientId, const char *pNameRequest) override;
288 bool WouldClientClanChange(int ClientId, const char *pClanRequest) override;
289 void SetClientName(int ClientId, const char *pName) override;
290 void SetClientClan(int ClientId, const char *pClan) override;
291 void SetClientCountry(int ClientId, int Country) override;
292 void SetClientScore(int ClientId, std::optional<int> Score) override;
293 void SetClientFlags(int ClientId, int Flags) override;
294
295 void Kick(int ClientId, const char *pReason) override;
296 void Ban(int ClientId, int Seconds, const char *pReason, bool VerbatimReason) override;
297 void ReconnectClient(int ClientId);
298 void RedirectClient(int ClientId, int Port) override;
299
300 void DemoRecorder_HandleAutoStart() override;
301
302 int64_t TickStartTime(int Tick);
303
304 int Init();
305
306 static bool StrHideIps(const char *pInput, char *pOutputWithIps, int OutputWithIpsSize, char *pOutputWithoutIps, int OutputWithoutIpsSize);
307 void SendLogLine(const CLogMessage *pMessage);
308 void SetRconCid(int ClientId) override;
309 int GetAuthedState(int ClientId) const override;
310 bool IsRconAuthed(int ClientId) const override;
311 bool IsRconAuthedAdmin(int ClientId) const override;
312 const char *GetAuthName(int ClientId) const override;
313 bool HasAuthHidden(int ClientId) const override;
314 bool GetClientInfo(int ClientId, CClientInfo *pInfo) const override;
315 void SetClientDDNetVersion(int ClientId, int DDNetVersion) override;
316 const NETADDR *ClientAddr(int ClientId) const override;
317 const std::array<char, NETADDR_MAXSTRSIZE> &ClientAddrStringImpl(int ClientId, bool IncludePort) const override;
318 const char *ClientName(int ClientId) const override;
319 const char *ClientClan(int ClientId) const override;
320 int ClientCountry(int ClientId) const override;
321 bool ClientSlotEmpty(int ClientId) const override;
322 bool ClientIngame(int ClientId) const override;
323 int Port() const override;
324 int MaxClients() const override;
325 int ClientCount() const override;
326 int DistinctClientCount() const override;
327
328 int GetClientVersion(int ClientId) const override;
329 int SendMsg(CMsgPacker *pMsg, int Flags, int ClientId) override;
330
331 void DoSnapshot();
332
333 static int NewClientCallback(int ClientId, void *pUser, bool Sixup);
334 static int NewClientNoAuthCallback(int ClientId, void *pUser);
335 static int DelClientCallback(int ClientId, const char *pReason, void *pUser);
336
337 static int ClientRejoinCallback(int ClientId, void *pUser);
338
339 void SendRconType(int ClientId, bool UsernameReq);
340 void SendCapabilities(int ClientId);
341 void SendMap(int ClientId);
342 void SendMapData(int ClientId, int Chunk);
343 void SendMapReload(int ClientId);
344 void SendConnectionReady(int ClientId);
345 void SendRconLine(int ClientId, const char *pLine);
346 // Accepts -1 as ClientId to mean "all clients with at least auth level admin"
347 void SendRconLogLine(int ClientId, const CLogMessage *pMessage);
348
349 void SendRconCmdAdd(const IConsole::ICommandInfo *pCommandInfo, int ClientId);
350 void SendRconCmdRem(const IConsole::ICommandInfo *pCommandInfo, int ClientId);
351 void SendRconCmdGroupStart(int ClientId);
352 void SendRconCmdGroupEnd(int ClientId);
353 int NumRconCommands(int ClientId);
354 void UpdateClientRconCommands(int ClientId);
355
356 class CMaplistEntry
357 {
358 public:
359 char m_aName[128];
360
361 CMaplistEntry() = default;
362 CMaplistEntry(const char *pName);
363 bool operator<(const CMaplistEntry &Other) const;
364 };
365 std::vector<CMaplistEntry> m_vMaplistEntries;
366 void SendMaplistGroupStart(int ClientId);
367 void SendMaplistGroupEnd(int ClientId);
368 void UpdateClientMaplistEntries(int ClientId);
369
370 bool CheckReservedSlotAuth(int ClientId, const char *pPassword);
371 void ProcessClientPacket(CNetChunk *pPacket);
372 void OnNetMsgClientVer(int ClientId, CUuid *pConnectionId, int DDNetVersion, const char *pDDNetVersionStr);
373 void OnNetMsgInfo(int ClientId, const char *pVersion, const char *pPasswordOrNullptr);
374 void OnNetMsgReady(int ClientId);
375 void OnNetMsgEnterGame(int ClientId);
376 void OnNetMsgRconCmd(int ClientId, const char *pCmd);
377 void OnNetMsgRconAuth(int ClientId, const char *pName, const char *pPw, bool SendRconCmds);
378
379 class CCache
380 {
381 public:
382 class CCacheChunk
383 {
384 public:
385 CCacheChunk(const void *pData, int Size);
386 CCacheChunk(const CCacheChunk &) = delete;
387 CCacheChunk(CCacheChunk &&) = default;
388
389 std::vector<uint8_t> m_vData;
390 };
391
392 std::vector<CCacheChunk> m_vCache;
393
394 CCache();
395 ~CCache();
396
397 void AddChunk(const void *pData, int Size);
398 void Clear();
399 };
400 CCache m_aServerInfoCache[3 * 2];
401 CCache m_aSixupServerInfoCache[2];
402 bool m_ServerInfoNeedsUpdate = false;
403 bool m_ServerInfoNeedsResend = false;
404
405 void FillAntibot(CAntibotRoundData *pData) override;
406
407 void ExpireServerInfo() override;
408 void ExpireServerInfoAndQueueResend();
409 void CacheServerInfo(CCache *pCache, int Type, bool SendClients);
410 void CacheServerInfoSixup(CCache *pCache, bool SendClients, int MaxConsideredClients);
411 void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients);
412 void GetServerInfoSixup(CPacker *pPacker, bool SendClients);
413 bool RateLimitServerInfoConnless();
414 void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type);
415 void UpdateRegisterServerInfo();
416 void UpdateServerInfo(bool Resend);
417
418 void PumpNetwork(bool PacketWaiting);
419
420 void ChangeMap(const char *pMap) override;
421 void ReloadMap() override;
422 int LoadMap(const char *pMapName);
423
424 void SaveDemo(int ClientId, float Time) override;
425 void StartRecord(int ClientId) override;
426 void StopRecord(int ClientId) override;
427 bool IsRecording(int ClientId) override;
428 void StopDemos() override;
429
430 int Run();
431
432 static void ConKick(IConsole::IResult *pResult, void *pUser);
433 static void ConStatus(IConsole::IResult *pResult, void *pUser);
434 static void ConShutdown(IConsole::IResult *pResult, void *pUser);
435 static void ConRecord(IConsole::IResult *pResult, void *pUser);
436 static void ConStopRecord(IConsole::IResult *pResult, void *pUser);
437 static void ConMapReload(IConsole::IResult *pResult, void *pUser);
438 static void ConLogout(IConsole::IResult *pResult, void *pUser);
439 static void ConShowIps(IConsole::IResult *pResult, void *pUser);
440 static void ConHideAuthStatus(IConsole::IResult *pResult, void *pUser);
441 static void ConForceHighBandwidthOnSpectate(IConsole::IResult *pResult, void *pUser);
442
443 static void ConAuthAdd(IConsole::IResult *pResult, void *pUser);
444 static void ConAuthAddHashed(IConsole::IResult *pResult, void *pUser);
445 static void ConAuthUpdate(IConsole::IResult *pResult, void *pUser);
446 static void ConAuthUpdateHashed(IConsole::IResult *pResult, void *pUser);
447 static void ConAuthRemove(IConsole::IResult *pResult, void *pUser);
448 static void ConAuthList(IConsole::IResult *pResult, void *pUser);
449
450 // console commands for sqlmasters
451 static void ConAddSqlServer(IConsole::IResult *pResult, void *pUserData);
452 static void ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData);
453
454 static void ConReloadAnnouncement(IConsole::IResult *pResult, void *pUserData);
455 static void ConReloadMaplist(IConsole::IResult *pResult, void *pUserData);
456
457 static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
458 static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
459 static void ConchainCommandAccessUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
460
461 void LogoutClient(int ClientId, const char *pReason);
462 void LogoutKey(int Key, const char *pReason);
463
464 void ConchainRconPasswordChangeGeneric(const char *pRoleName, const char *pCurrent, IConsole::IResult *pResult);
465 static void ConchainRconPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
466 static void ConchainRconModPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
467 static void ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
468 static void ConchainMapUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
469 static void ConchainSixupUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
470 static void ConchainRegisterCommunityTokenRedact(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
471 static void ConchainLoglevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
472 static void ConchainStdoutOutputLevel(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
473 static void ConchainAnnouncementFilename(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
474 static void ConchainInputFifo(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
475
476#if defined(CONF_FAMILY_UNIX)
477 static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
478#endif
479
480 void RegisterCommands();
481
482 int SnapNewId() override;
483 void SnapFreeId(int Id) override;
484 bool SnapNewItem(int Type, int Id, const void *pData, int Size) override;
485 void SnapSetStaticsize(int ItemType, int Size) override;
486 void SnapSetStaticsize7(int ItemType, int Size) override;
487
488 // DDRace
489
490 int m_aPrevStates[MAX_CLIENTS];
491 const char *GetAnnouncementLine() override;
492 void ReadAnnouncementsFile();
493
494 static int MaplistEntryCallback(const char *pFilename, int IsDir, int DirType, void *pUser);
495 void InitMaplist();
496
497 int *GetIdMap(int ClientId) override;
498
499 void InitDnsbl(int ClientId);
500 bool DnsblWhite(int ClientId) override
501 {
502 return m_aClients[ClientId].m_DnsblState == EDnsblState::NONE ||
503 m_aClients[ClientId].m_DnsblState == EDnsblState::WHITELISTED;
504 }
505 bool DnsblPending(int ClientId) override
506 {
507 return m_aClients[ClientId].m_DnsblState == EDnsblState::PENDING;
508 }
509 bool DnsblBlack(int ClientId) override
510 {
511 return m_aClients[ClientId].m_DnsblState == EDnsblState::BLACKLISTED;
512 }
513
514 static bool CanClientUseCommandCallback(int ClientId, const IConsole::ICommandInfo *pCommand, void *pUser);
515 bool CanClientUseCommand(int ClientId, const IConsole::ICommandInfo *pCommand) const;
516 void AuthRemoveKey(int KeySlot);
517 bool ClientPrevIngame(int ClientId) override { return m_aPrevStates[ClientId] == CClient::STATE_INGAME; }
518 const char *GetNetErrorString(int ClientId) override { return m_NetServer.ErrorString(ClientId); }
519 void ResetNetErrorString(int ClientId) override { m_NetServer.ResetErrorString(ClientId); }
520 bool SetTimedOut(int ClientId, int OrigId) override;
521 void SetTimeoutProtected(int ClientId) override { m_NetServer.IgnoreTimeouts(ClientId); }
522
523 void SendMsgRaw(int ClientId, const void *pData, int Size, int Flags) override;
524
525 bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; }
526 void SetErrorShutdown(const char *pReason) override;
527
528 bool IsSixup(int ClientId) const override { return ClientId != SERVER_DEMO_CLIENT && m_aClients[ClientId].m_Sixup; }
529
530 void SetLoggers(std::shared_ptr<ILogger> &&pFileLogger, std::shared_ptr<ILogger> &&pStdoutLogger);
531
532#ifdef CONF_FAMILY_UNIX
533 enum CONN_LOGGING_CMD
534 {
535 OPEN_SESSION = 1,
536 CLOSE_SESSION = 2,
537 };
538
539 void SendConnLoggingCommand(CONN_LOGGING_CMD Cmd, const NETADDR *pAddr);
540#endif
541};
542
543bool IsInterrupted();
544
545extern CServer *CreateServer();
546#endif
547