ddnet/src/engine/server/server.h

473 lines
13 KiB
C
Raw Normal View History

2010-11-20 10:37:14 +00:00
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
2010-05-29 07:25:38 +00:00
#ifndef ENGINE_SERVER_SERVER_H
#define ENGINE_SERVER_SERVER_H
#include <base/hash.h>
#include <base/math.h>
2016-09-05 09:38:11 +00:00
#include <engine/engine.h>
2010-05-29 07:25:38 +00:00
#include <engine/server.h>
#include <engine/map.h>
#include <engine/shared/demo.h>
#include <engine/shared/protocol.h>
#include <engine/shared/snapshot.h>
#include <engine/shared/network.h>
#include <engine/server/register.h>
#include <engine/shared/console.h>
#include <engine/shared/econ.h>
2016-05-02 21:36:21 +00:00
#include <engine/shared/fifo.h>
#include <engine/shared/netban.h>
#include <engine/shared/uuid_manager.h>
#include <base/tl/array.h>
#include <list>
#include "antibot.h"
2017-03-02 15:16:29 +00:00
#include "authmanager.h"
#include "name_ban.h"
2017-03-02 15:16:29 +00:00
2020-04-19 13:14:21 +00:00
#if defined (CONF_UPNP)
#include "upnp.h"
#endif
2010-05-29 07:25:38 +00:00
class CSnapIDPool
{
enum
{
MAX_IDS = 16*1024,
};
class CID
{
public:
short m_Next;
2018-07-10 09:29:02 +00:00
short m_State; // 0 = free, 1 = allocated, 2 = timed
2010-05-29 07:25:38 +00:00
int m_Timeout;
};
CID m_aIDs[MAX_IDS];
2010-05-29 07:25:38 +00:00
int m_FirstFree;
int m_FirstTimed;
int m_LastTimed;
int m_Usage;
int m_InUsage;
public:
2010-05-29 07:25:38 +00:00
CSnapIDPool();
2010-05-29 07:25:38 +00:00
void Reset();
void RemoveFirstTimeout();
int NewID();
void TimeoutIDs();
void FreeID(int ID);
2010-05-29 07:25:38 +00:00
};
2011-12-29 22:36:53 +00:00
class CServerBan : public CNetBan
{
class CServer *m_pServer;
template<class T> int BanExt(T *pBanPool, const typename T::CDataType *pData, int Seconds, const char *pReason);
public:
class CServer *Server() const { return m_pServer; }
2017-03-21 10:24:44 +00:00
void InitServerBan(class IConsole *pConsole, class IStorage *pStorage, class CServer *pServer);
2011-12-29 22:36:53 +00:00
virtual int BanAddr(const NETADDR *pAddr, int Seconds, const char *pReason);
virtual int BanRange(const CNetRange *pRange, int Seconds, const char *pReason);
2011-12-29 22:36:53 +00:00
static void ConBanExt(class IConsole::IResult *pResult, void *pUser);
2020-08-19 09:38:49 +00:00
static void ConBanRegion(class IConsole::IResult *pResult, void *pUser);
static void ConBanRegionRange(class IConsole::IResult *pResult, void *pUser);
2011-12-29 22:36:53 +00:00
};
2010-05-29 07:25:38 +00:00
class CServer : public IServer
{
class IGameServer *m_pGameServer;
class IConsole *m_pConsole;
class IStorage *m_pStorage;
class IEngineAntibot *m_pAntibot;
2020-04-19 13:14:21 +00:00
#if defined(CONF_UPNP)
CUPnP m_UPnP;
#endif
#if defined(CONF_FAMILY_UNIX)
UNIXSOCKETADDR m_ConnLoggingDestAddr;
bool m_ConnLoggingSocketCreated;
UNIXSOCKET m_ConnLoggingSocket;
#endif
class CDbConnectionPool *m_pConnectionPool;
2010-05-29 07:25:38 +00:00
public:
class IGameServer *GameServer() { return m_pGameServer; }
class IConsole *Console() { return m_pConsole; }
class IStorage *Storage() { return m_pStorage; }
class IEngineAntibot *Antibot() { return m_pAntibot; }
class CDbConnectionPool *DbPool() { return m_pConnectionPool; }
2010-05-29 07:25:38 +00:00
enum
{
MAX_RCONCMD_SEND=16,
};
2010-05-29 07:25:38 +00:00
class CClient
{
public:
2010-05-29 07:25:38 +00:00
enum
{
STATE_EMPTY = 0,
STATE_PREAUTH,
2010-05-29 07:25:38 +00:00
STATE_AUTH,
STATE_CONNECTING,
STATE_READY,
STATE_INGAME,
2010-05-29 07:25:38 +00:00
SNAPRATE_INIT=0,
SNAPRATE_FULL,
2016-09-05 09:38:11 +00:00
SNAPRATE_RECOVER,
DNSBL_STATE_NONE=0,
DNSBL_STATE_PENDING,
DNSBL_STATE_BLACKLISTED,
DNSBL_STATE_WHITELISTED,
2010-05-29 07:25:38 +00:00
};
2010-05-29 07:25:38 +00:00
class CInput
{
public:
int m_aData[MAX_INPUT_SIZE];
int m_GameTick; // the tick that was chosen for the input
};
2010-05-29 07:25:38 +00:00
// connection state info
int m_State;
bool m_SupportsMapSha256;
2010-05-29 07:25:38 +00:00
int m_Latency;
int m_SnapRate;
2013-08-04 15:50:12 +00:00
float m_Traffic;
2013-08-04 02:24:03 +00:00
int64 m_TrafficSince;
2010-05-29 07:25:38 +00:00
int m_LastAckedSnapshot;
int m_LastInputTick;
CSnapshotStorage m_Snapshots;
2010-05-29 07:25:38 +00:00
CInput m_LatestInput;
CInput m_aInputs[200]; // TODO: handle input better
int m_CurrentInput;
2010-05-29 07:25:38 +00:00
char m_aName[MAX_NAME_LENGTH];
char m_aClan[MAX_CLAN_LENGTH];
int m_Country;
2010-05-29 07:25:38 +00:00
int m_Score;
int m_Authed;
2017-03-02 15:16:29 +00:00
int m_AuthKey;
int m_AuthTries;
int m_NextMapChunk;
int m_Flags;
bool m_ShowIps;
const IConsole::CCommandInfo *m_pRconCmdToSend;
2010-05-29 07:25:38 +00:00
void Reset();
2013-12-31 05:13:57 +00:00
// DDRace
NETADDR m_Addr;
bool m_GotDDNetVersionPacket;
bool m_DDNetVersionSettled;
int m_DDNetVersion;
char m_aDDNetVersionStr[64];
CUuid m_ConnectionID;
2016-09-05 09:38:11 +00:00
// DNSBL
int m_DnsblState;
std::shared_ptr<CHostLookup> m_pDnsblLookup;
2020-03-29 02:36:38 +00:00
bool m_Sixup;
2010-05-29 07:25:38 +00:00
};
2010-05-29 07:25:38 +00:00
CClient m_aClients[MAX_CLIENTS];
2013-12-31 05:13:57 +00:00
int IdMap[MAX_CLIENTS * VANILLA_MAX_CLIENTS];
2010-05-29 07:25:38 +00:00
CSnapshotDelta m_SnapshotDelta;
CSnapshotBuilder m_SnapshotBuilder;
CSnapIDPool m_IDPool;
CNetServer m_NetServer;
2011-07-30 11:40:01 +00:00
CEcon m_Econ;
2016-05-02 21:36:21 +00:00
#if defined(CONF_FAMILY_UNIX)
CFifo m_Fifo;
#endif
2011-12-29 22:36:53 +00:00
CServerBan m_ServerBan;
2010-05-29 07:25:38 +00:00
IEngineMap *m_pMap;
int64 m_GameStartTime;
//int m_CurrentGameTick;
enum
{
UNINITIALIZED=0,
RUNNING=1,
STOPPING=2
};
2010-05-29 07:25:38 +00:00
int m_RunServer;
int m_MapReload;
2015-10-22 15:27:30 +00:00
bool m_ReloadedWhenEmpty;
int m_RconClientID;
int m_RconAuthLevel;
2011-07-30 11:40:01 +00:00
int m_PrintCBIndex;
2010-05-29 07:25:38 +00:00
int64 m_Lastheartbeat;
//static NETADDR4 master_server;
2020-06-19 21:52:13 +00:00
enum
{
SIX=0,
SIXUP,
};
char m_aCurrentMap[MAX_PATH_LENGTH];
2020-06-19 21:52:13 +00:00
SHA256_DIGEST m_aCurrentMapSha256[2];
unsigned m_aCurrentMapCrc[2];
unsigned char *m_apCurrentMapData[2];
unsigned int m_aCurrentMapSize[2];
CDemoRecorder m_aDemoRecorder[MAX_CLIENTS+1];
2010-05-29 07:25:38 +00:00
CRegister m_Register;
CRegister m_RegSixup;
2017-03-02 15:16:29 +00:00
CAuthManager m_AuthManager;
int m_RconRestrict;
int64 m_ServerInfoFirstRequest;
int m_ServerInfoNumRequests;
2017-10-13 00:25:50 +00:00
char m_aErrorShutdownReason[128];
array<CNameBan> m_aNameBans;
2010-05-29 07:25:38 +00:00
CServer();
2010-05-29 07:25:38 +00:00
int TrySetClientName(int ClientID, const char *pName);
virtual void SetClientName(int ClientID, const char *pName);
virtual void SetClientClan(int ClientID, char const *pClan);
virtual void SetClientCountry(int ClientID, int Country);
2010-05-29 07:25:38 +00:00
virtual void SetClientScore(int ClientID, int Score);
virtual void SetClientFlags(int ClientID, int Flags);
2010-05-29 07:25:38 +00:00
void Kick(int ClientID, const char *pReason);
2019-02-06 12:06:28 +00:00
void Ban(int ClientID, int Seconds, const char *pReason);
2010-05-29 07:25:38 +00:00
void DemoRecorder_HandleAutoStart();
2012-01-08 23:49:20 +00:00
bool DemoRecorder_IsRecording();
2010-05-29 07:25:38 +00:00
//int Tick()
int64 TickStartTime(int Tick);
//int TickSpeed()
int Init();
void SetRconCID(int ClientID);
2017-06-08 19:58:41 +00:00
int GetAuthedState(int ClientID);
const char *GetAuthName(int ClientID);
void GetMapInfo(char *pMapName, int MapNameSize, int *pMapSize, SHA256_DIGEST *pMapSha256, int *pMapCrc);
2010-05-29 07:25:38 +00:00
int GetClientInfo(int ClientID, CClientInfo *pInfo);
void SetClientDDNetVersion(int ClientID, int DDNetVersion);
void GetClientAddr(int ClientID, char *pAddrStr, int Size);
const char *ClientName(int ClientID);
const char *ClientClan(int ClientID);
int ClientCountry(int ClientID);
2010-05-29 07:25:38 +00:00
bool ClientIngame(int ClientID);
2018-04-03 08:27:19 +00:00
bool ClientAuthed(int ClientID);
int Port() const;
2011-12-04 15:51:33 +00:00
int MaxClients() const;
2018-10-07 22:59:07 +00:00
int ClientCount();
int DistinctClientCount();
2010-05-29 07:25:38 +00:00
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID);
2010-05-29 07:25:38 +00:00
void DoSnapshot();
2020-03-29 02:36:38 +00:00
static int NewClientCallback(int ClientID, void *pUser, bool Sixup);
static int NewClientNoAuthCallback(int ClientID, void *pUser);
static int DelClientCallback(int ClientID, const char *pReason, void *pUser);
2010-05-29 07:25:38 +00:00
2015-08-23 15:51:28 +00:00
static int ClientRejoinCallback(int ClientID, void *pUser);
void SendRconType(int ClientID, bool UsernameReq);
void SendCapabilities(int ClientID);
void SendMap(int ClientID);
void SendMapData(int ClientID, int Chunk);
void SendConnectionReady(int ClientID);
void SendRconLine(int ClientID, const char *pLine);
2014-12-20 15:35:47 +00:00
static void SendRconLineAuthed(const char *pLine, void *pUser, bool Highlighted = false);
void SendRconCmdAdd(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
void SendRconCmdRem(const IConsole::CCommandInfo *pCommandInfo, int ClientID);
void UpdateClientRconCommands();
2010-05-29 07:25:38 +00:00
void ProcessClientPacket(CNetChunk *pPacket);
2019-11-02 23:33:30 +00:00
class CCache {
public:
class CCacheChunk {
public:
CCacheChunk(const void *pData, int Size);
CCacheChunk(const CCacheChunk &) = delete;
2019-11-02 23:33:30 +00:00
int m_DataSize;
2019-11-03 19:58:35 +00:00
unsigned char m_aData[NET_MAX_PAYLOAD];
2019-11-02 23:33:30 +00:00
};
std::list<CCacheChunk> m_lCache;
2019-11-02 23:33:30 +00:00
2019-11-03 00:53:50 +00:00
CCache();
~CCache();
2019-11-02 23:33:30 +00:00
void AddChunk(const void *pData, int Size);
void Clear();
};
CCache m_ServerInfoCache[3 * 2];
CCache m_SixupServerInfoCache[2];
2019-11-03 00:07:10 +00:00
bool m_ServerInfoNeedsUpdate;
2019-11-02 23:33:30 +00:00
2019-11-03 00:07:10 +00:00
void ExpireServerInfo();
2019-11-02 23:33:30 +00:00
void CacheServerInfo(CCache *pCache, int Type, bool SendClients);
void CacheServerInfoSixup(CCache *pCache, bool SendClients);
void SendServerInfo(const NETADDR *pAddr, int Token, int Type, bool SendClients);
void GetServerInfoSixup(CPacker *pPacker, int Token, bool SendClients);
bool RateLimitServerInfoConnless();
void SendServerInfoConnless(const NETADDR *pAddr, int Token, int Type);
2019-11-03 00:07:10 +00:00
void UpdateServerInfo(bool Resend = false);
2010-05-29 07:25:38 +00:00
void PumpNetwork(bool PacketWaiting);
2010-05-29 07:25:38 +00:00
char *GetMapName();
2010-05-29 07:25:38 +00:00
int LoadMap(const char *pMapName);
void SaveDemo(int ClientID, float Time);
void StartRecord(int ClientID);
void StopRecord(int ClientID);
bool IsRecording(int ClientID);
void InitRegister(CNetServer *pNetServer, IEngineMasterServer *pMasterServer, IConsole *pConsole);
2010-05-29 07:25:38 +00:00
int Run();
static void ConTestingCommands(IConsole::IResult *pResult, void *pUser);
static void ConRescue(IConsole::IResult *pResult, void *pUser);
static void ConKick(IConsole::IResult *pResult, void *pUser);
2011-12-29 22:36:53 +00:00
static void ConStatus(IConsole::IResult *pResult, void *pUser);
static void ConShutdown(IConsole::IResult *pResult, void *pUser);
static void ConRecord(IConsole::IResult *pResult, void *pUser);
static void ConStopRecord(IConsole::IResult *pResult, void *pUser);
static void ConMapReload(IConsole::IResult *pResult, void *pUser);
2011-12-26 21:07:57 +00:00
static void ConLogout(IConsole::IResult *pResult, void *pUser);
static void ConShowIps(IConsole::IResult *pResult, void *pUser);
2017-03-02 15:16:29 +00:00
static void ConAuthAdd(IConsole::IResult *pResult, void *pUser);
static void ConAuthAddHashed(IConsole::IResult *pResult, void *pUser);
static void ConAuthUpdate(IConsole::IResult *pResult, void *pUser);
static void ConAuthUpdateHashed(IConsole::IResult *pResult, void *pUser);
static void ConAuthRemove(IConsole::IResult *pResult, void *pUser);
static void ConAuthList(IConsole::IResult *pResult, void *pUser);
static void ConNameBan(IConsole::IResult *pResult, void *pUser);
static void ConNameUnban(IConsole::IResult *pResult, void *pUser);
static void ConNameBans(IConsole::IResult *pResult, void *pUser);
// console commands for sqlmasters
static void ConAddSqlServer(IConsole::IResult *pResult, void *pUserData);
static void ConDumpSqlServers(IConsole::IResult *pResult, void *pUserData);
2010-05-29 07:25:38 +00:00
static void ConchainSpecialInfoupdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainMaxclientsperipUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainCommandAccessUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2011-07-30 11:40:01 +00:00
static void ConchainConsoleOutputLevelUpdate(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2017-03-02 15:16:29 +00:00
void LogoutClient(int ClientID, const char *pReason);
void LogoutKey(int Key, const char *pReason);
void ConchainRconPasswordChangeGeneric(int Level, const char *pCurrent, IConsole::IResult *pResult);
static void ConchainRconPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainRconModPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
static void ConchainRconHelperPasswordChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
2011-01-06 03:46:10 +00:00
#if defined(CONF_FAMILY_UNIX)
static void ConchainConnLoggingServerChange(IConsole::IResult *pResult, void *pUserData, IConsole::FCommandCallback pfnCallback, void *pCallbackUserData);
#endif
2010-05-29 07:25:38 +00:00
void RegisterCommands();
2010-05-29 07:25:38 +00:00
virtual int SnapNewID();
virtual void SnapFreeID(int ID);
virtual void *SnapNewItem(int Type, int ID, int Size);
2010-05-29 07:25:38 +00:00
void SnapSetStaticsize(int ItemType, int Size);
// DDRace
void GetClientAddr(int ClientID, NETADDR *pAddr);
int m_aPrevStates[MAX_CLIENTS];
const char *GetAnnouncementLine(char const *FileName);
unsigned m_AnnouncementLastLine;
void RestrictRconOutput(int ClientID) { m_RconRestrict = ClientID; }
2013-12-31 05:13:57 +00:00
virtual int* GetIdMap(int ClientID);
2016-09-05 09:38:11 +00:00
void InitDnsbl(int ClientID);
bool DnsblWhite(int ClientID)
{
return m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_NONE ||
m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_WHITELISTED;
}
bool DnsblPending(int ClientID)
{
return m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_PENDING;
}
bool DnsblBlack(int ClientID)
{
return m_aClients[ClientID].m_DnsblState == CClient::DNSBL_STATE_BLACKLISTED;
}
void AuthRemoveKey(int KeySlot);
bool ClientPrevIngame(int ClientID) { return m_aPrevStates[ClientID] == CClient::STATE_INGAME; };
const char *GetNetErrorString(int ClientID) { return m_NetServer.ErrorString(ClientID); };
void ResetNetErrorString(int ClientID) { m_NetServer.ResetErrorString(ClientID); };
bool SetTimedOut(int ClientID, int OrigID);
void SetTimeoutProtected(int ClientID) { m_NetServer.SetTimeoutProtected(ClientID); };
2017-10-13 00:25:50 +00:00
void SendMsgRaw(int ClientID, const void *pData, int Size, int Flags);
2017-10-13 00:25:50 +00:00
bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; }
void SetErrorShutdown(const char *pReason);
2020-06-23 15:30:57 +00:00
bool IsSixup(int ClientID) const { return m_aClients[ClientID].m_Sixup; }
2020-03-29 02:36:38 +00:00
#ifdef CONF_FAMILY_UNIX
enum CONN_LOGGING_CMD
{
OPEN_SESSION=1,
CLOSE_SESSION=2,
};
void SendConnLoggingCommand(CONN_LOGGING_CMD cmd, const NETADDR *pAddr);
#endif
2010-05-29 07:25:38 +00:00
};
#endif