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_H
|
|
|
|
#define ENGINE_SERVER_H
|
2018-06-05 19:22:40 +00:00
|
|
|
|
2020-06-15 13:37:09 +00:00
|
|
|
#include <type_traits>
|
|
|
|
|
2018-06-05 19:22:40 +00:00
|
|
|
#include <base/hash.h>
|
2018-12-11 08:23:12 +00:00
|
|
|
#include <base/math.h>
|
2018-06-05 19:22:40 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
#include "kernel.h"
|
|
|
|
#include "message.h"
|
2013-12-31 05:13:57 +00:00
|
|
|
#include <game/generated/protocol.h>
|
2020-04-16 08:46:43 +00:00
|
|
|
#include <game/generated/protocol7.h>
|
2020-06-14 17:32:14 +00:00
|
|
|
#include <game/generated/protocolglue.h>
|
2013-12-31 05:13:57 +00:00
|
|
|
#include <engine/shared/protocol.h>
|
2010-05-29 07:25:38 +00:00
|
|
|
|
2020-05-13 20:27:49 +00:00
|
|
|
struct CAntibotRoundData;
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
class IServer : public IInterface
|
|
|
|
{
|
|
|
|
MACRO_INTERFACE("server", 0)
|
|
|
|
protected:
|
|
|
|
int m_CurrentGameTick;
|
|
|
|
int m_TickSpeed;
|
|
|
|
|
|
|
|
public:
|
|
|
|
/*
|
|
|
|
Structure: CClientInfo
|
|
|
|
*/
|
|
|
|
struct CClientInfo
|
|
|
|
{
|
|
|
|
const char *m_pName;
|
|
|
|
int m_Latency;
|
2020-05-22 15:58:41 +00:00
|
|
|
bool m_GotDDNetVersion;
|
|
|
|
int m_DDNetVersion;
|
|
|
|
const char *m_pDDNetVersionStr;
|
|
|
|
const CUuid *m_pConnectionID;
|
2010-05-29 07:25:38 +00:00
|
|
|
};
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
int Tick() const { return m_CurrentGameTick; }
|
|
|
|
int TickSpeed() const { return m_TickSpeed; }
|
|
|
|
|
2020-08-29 12:14:37 +00:00
|
|
|
virtual int Port() const = 0;
|
2011-12-04 15:51:33 +00:00
|
|
|
virtual int MaxClients() const = 0;
|
2018-10-07 22:59:07 +00:00
|
|
|
virtual int ClientCount() = 0;
|
|
|
|
virtual int DistinctClientCount() = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual const char *ClientName(int ClientID) = 0;
|
2011-03-15 10:23:49 +00:00
|
|
|
virtual const char *ClientClan(int ClientID) = 0;
|
|
|
|
virtual int ClientCountry(int ClientID) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual bool ClientIngame(int ClientID) = 0;
|
2018-04-03 08:27:19 +00:00
|
|
|
virtual bool ClientAuthed(int ClientID) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual int GetClientInfo(int ClientID, CClientInfo *pInfo) = 0;
|
2020-05-22 15:58:41 +00:00
|
|
|
virtual void SetClientDDNetVersion(int ClientID, int DDNetVersion) = 0;
|
2011-03-28 18:11:28 +00:00
|
|
|
virtual void GetClientAddr(int ClientID, char *pAddrStr, int Size) = 0;
|
2013-07-30 23:31:53 +00:00
|
|
|
virtual void RestrictRconOutput(int ClientID) = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual int SendMsg(CMsgPacker *pMsg, int Flags, int ClientID) = 0;
|
|
|
|
|
2020-06-15 13:37:09 +00:00
|
|
|
template<class T, typename std::enable_if<!protocol7::is_sixup<T>::value, int>::type = 0>
|
|
|
|
inline int SendPackMsg(T *pMsg, int Flags, int ClientID)
|
2013-12-31 05:13:57 +00:00
|
|
|
{
|
2020-06-15 13:37:09 +00:00
|
|
|
int Result = 0;
|
2013-12-31 05:13:57 +00:00
|
|
|
T tmp;
|
|
|
|
if (ClientID == -1)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
if(ClientIngame(i))
|
|
|
|
{
|
|
|
|
mem_copy(&tmp, pMsg, sizeof(T));
|
2020-06-15 13:37:09 +00:00
|
|
|
Result = SendPackMsgTranslate(&tmp, Flags, i);
|
2013-12-31 05:13:57 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
mem_copy(&tmp, pMsg, sizeof(T));
|
2020-06-15 13:37:09 +00:00
|
|
|
Result = SendPackMsgTranslate(&tmp, Flags, ClientID);
|
2013-12-31 05:13:57 +00:00
|
|
|
}
|
2020-06-15 13:37:09 +00:00
|
|
|
return Result;
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class T, typename std::enable_if<protocol7::is_sixup<T>::value, int>::type = 1>
|
|
|
|
inline int SendPackMsg(T *pMsg, int Flags, int ClientID)
|
|
|
|
{
|
|
|
|
int Result = 0;
|
|
|
|
if(ClientID == -1)
|
|
|
|
{
|
|
|
|
for(int i = 0; i < MAX_CLIENTS; i++)
|
|
|
|
if(ClientIngame(i) && IsSixup(i))
|
|
|
|
Result = SendPackMsgOne(pMsg, Flags, i);
|
|
|
|
}
|
|
|
|
else if(IsSixup(ClientID))
|
|
|
|
Result = SendPackMsgOne(pMsg, Flags, ClientID);
|
|
|
|
|
|
|
|
return Result;
|
2013-12-31 05:13:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
int SendPackMsgTranslate(T *pMsg, int Flags, int ClientID)
|
|
|
|
{
|
|
|
|
return SendPackMsgOne(pMsg, Flags, ClientID);
|
|
|
|
}
|
|
|
|
|
|
|
|
int SendPackMsgTranslate(CNetMsg_Sv_Emoticon *pMsg, int Flags, int ClientID)
|
|
|
|
{
|
|
|
|
return Translate(pMsg->m_ClientID, ClientID) && SendPackMsgOne(pMsg, Flags, ClientID);
|
|
|
|
}
|
|
|
|
|
|
|
|
char msgbuf[1000];
|
|
|
|
|
|
|
|
int SendPackMsgTranslate(CNetMsg_Sv_Chat *pMsg, int Flags, int ClientID)
|
|
|
|
{
|
2020-06-12 12:53:18 +00:00
|
|
|
if(pMsg->m_ClientID >= 0 && !Translate(pMsg->m_ClientID, ClientID))
|
2013-12-31 05:13:57 +00:00
|
|
|
{
|
|
|
|
str_format(msgbuf, sizeof(msgbuf), "%s: %s", ClientName(pMsg->m_ClientID), pMsg->m_pMessage);
|
|
|
|
pMsg->m_pMessage = msgbuf;
|
|
|
|
pMsg->m_ClientID = VANILLA_MAX_CLIENTS - 1;
|
|
|
|
}
|
2020-06-12 12:53:18 +00:00
|
|
|
|
2020-06-12 13:42:13 +00:00
|
|
|
if(IsSixup(ClientID))
|
2020-06-12 12:53:18 +00:00
|
|
|
{
|
|
|
|
protocol7::CNetMsg_Sv_Chat Msg7;
|
|
|
|
Msg7.m_ClientID = pMsg->m_ClientID;
|
|
|
|
Msg7.m_pMessage = pMsg->m_pMessage;
|
|
|
|
Msg7.m_Mode = pMsg->m_Team > 0 ? protocol7::CHAT_TEAM : protocol7::CHAT_ALL;
|
|
|
|
Msg7.m_TargetID = -1;
|
|
|
|
return SendPackMsgOne(&Msg7, Flags, ClientID);
|
|
|
|
}
|
|
|
|
|
2013-12-31 05:13:57 +00:00
|
|
|
return SendPackMsgOne(pMsg, Flags, ClientID);
|
|
|
|
}
|
|
|
|
|
|
|
|
int SendPackMsgTranslate(CNetMsg_Sv_KillMsg *pMsg, int Flags, int ClientID)
|
|
|
|
{
|
|
|
|
if (!Translate(pMsg->m_Victim, ClientID)) return 0;
|
|
|
|
if (!Translate(pMsg->m_Killer, ClientID)) pMsg->m_Killer = pMsg->m_Victim;
|
|
|
|
return SendPackMsgOne(pMsg, Flags, ClientID);
|
|
|
|
}
|
|
|
|
|
|
|
|
template<class T>
|
|
|
|
int SendPackMsgOne(T *pMsg, int Flags, int ClientID)
|
2010-05-29 07:25:38 +00:00
|
|
|
{
|
2020-06-15 13:37:09 +00:00
|
|
|
dbg_assert(ClientID != -1, "SendPackMsgOne called with -1");
|
2020-06-14 17:32:14 +00:00
|
|
|
CMsgPacker Packer(pMsg->MsgID(), false, protocol7::is_sixup<T>::value);
|
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
if(pMsg->Pack(&Packer))
|
|
|
|
return -1;
|
|
|
|
return SendMsg(&Packer, Flags, ClientID);
|
|
|
|
}
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2017-03-21 10:24:44 +00:00
|
|
|
bool Translate(int& Target, int Client)
|
2013-12-31 05:13:57 +00:00
|
|
|
{
|
2020-03-29 02:36:38 +00:00
|
|
|
if(IsSixup(Client))
|
|
|
|
return true;
|
2017-03-21 10:24:44 +00:00
|
|
|
CClientInfo Info;
|
|
|
|
GetClientInfo(Client, &Info);
|
2020-05-22 15:58:41 +00:00
|
|
|
if (Info.m_DDNetVersion >= VERSION_DDNET_OLD)
|
2013-12-31 05:13:57 +00:00
|
|
|
return true;
|
2017-03-21 10:24:44 +00:00
|
|
|
int *pMap = GetIdMap(Client);
|
|
|
|
bool Found = false;
|
2013-12-31 05:13:57 +00:00
|
|
|
for (int i = 0; i < VANILLA_MAX_CLIENTS; i++)
|
|
|
|
{
|
2017-03-21 10:24:44 +00:00
|
|
|
if (Target == pMap[i])
|
2013-12-31 05:13:57 +00:00
|
|
|
{
|
2017-03-21 10:24:44 +00:00
|
|
|
Target = i;
|
|
|
|
Found = true;
|
2013-12-31 05:13:57 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-03-21 10:24:44 +00:00
|
|
|
return Found;
|
2013-12-31 05:13:57 +00:00
|
|
|
}
|
|
|
|
|
2017-03-21 10:24:44 +00:00
|
|
|
bool ReverseTranslate(int& Target, int Client)
|
2013-12-31 05:13:57 +00:00
|
|
|
{
|
2020-03-29 02:36:38 +00:00
|
|
|
if(IsSixup(Client))
|
|
|
|
return true;
|
2017-03-21 10:24:44 +00:00
|
|
|
CClientInfo Info;
|
|
|
|
GetClientInfo(Client, &Info);
|
2020-05-22 15:58:41 +00:00
|
|
|
if (Info.m_DDNetVersion >= VERSION_DDNET_OLD)
|
2013-12-31 05:13:57 +00:00
|
|
|
return true;
|
2018-12-11 08:23:12 +00:00
|
|
|
Target = clamp(Target, 0, VANILLA_MAX_CLIENTS-1);
|
2017-03-21 10:24:44 +00:00
|
|
|
int *pMap = GetIdMap(Client);
|
|
|
|
if (pMap[Target] == -1)
|
2013-12-31 05:13:57 +00:00
|
|
|
return false;
|
2017-03-21 10:24:44 +00:00
|
|
|
Target = pMap[Target];
|
2013-12-31 05:13:57 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-06-05 19:22:40 +00:00
|
|
|
virtual void GetMapInfo(char *pMapName, int MapNameSize, int *pMapSize, SHA256_DIGEST *pSha256, int *pMapCrc) = 0;
|
2017-09-12 12:58:44 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual void SetClientName(int ClientID, char const *pName) = 0;
|
2011-03-15 10:23:49 +00:00
|
|
|
virtual void SetClientClan(int ClientID, char const *pClan) = 0;
|
|
|
|
virtual void SetClientCountry(int ClientID, int Country) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual void SetClientScore(int ClientID, int Score) = 0;
|
2019-04-03 13:07:05 +00:00
|
|
|
virtual void SetClientFlags(int ClientID, int Flags) = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual int SnapNewID() = 0;
|
|
|
|
virtual void SnapFreeID(int ID) = 0;
|
2011-02-12 10:40:36 +00:00
|
|
|
virtual void *SnapNewItem(int Type, int ID, int Size) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
|
|
|
virtual void SnapSetStaticsize(int ItemType, int Size) = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2019-03-02 10:50:33 +00:00
|
|
|
enum {
|
2011-12-31 11:11:48 +00:00
|
|
|
RCON_CID_SERV=-1,
|
|
|
|
RCON_CID_VOTE=-2,
|
|
|
|
};
|
|
|
|
virtual void SetRconCID(int ClientID) = 0;
|
2017-06-08 19:58:41 +00:00
|
|
|
virtual int GetAuthedState(int ClientID) = 0;
|
2018-01-28 02:13:05 +00:00
|
|
|
virtual const char *GetAuthName(int ClientID) = 0;
|
2010-10-09 17:14:42 +00:00
|
|
|
virtual void Kick(int ClientID, const char *pReason) = 0;
|
2019-02-06 12:06:28 +00:00
|
|
|
virtual void Ban(int ClientID, int Seconds, const char *pReason) = 0;
|
2019-02-04 22:09:14 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
|
2011-08-13 00:11:06 +00:00
|
|
|
virtual void DemoRecorder_HandleAutoStart() = 0;
|
2012-01-08 23:49:20 +00:00
|
|
|
virtual bool DemoRecorder_IsRecording() = 0;
|
2011-08-13 00:11:06 +00:00
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
// DDRace
|
|
|
|
|
2014-09-26 00:05:22 +00:00
|
|
|
virtual void SaveDemo(int ClientID, float Time) = 0;
|
|
|
|
virtual void StartRecord(int ClientID) = 0;
|
|
|
|
virtual void StopRecord(int ClientID) = 0;
|
|
|
|
virtual bool IsRecording(int ClientID) = 0;
|
|
|
|
|
2011-04-09 06:41:31 +00:00
|
|
|
virtual void GetClientAddr(int ClientID, NETADDR *pAddr) = 0;
|
2013-12-31 05:13:57 +00:00
|
|
|
|
|
|
|
virtual int* GetIdMap(int ClientID) = 0;
|
2015-11-23 21:49:18 +00:00
|
|
|
|
2016-09-05 09:38:11 +00:00
|
|
|
virtual bool DnsblWhite(int ClientID) = 0;
|
2020-07-07 21:08:46 +00:00
|
|
|
virtual bool DnsblPending(int ClientID) = 0;
|
|
|
|
virtual bool DnsblBlack(int ClientID) = 0;
|
2017-06-06 03:51:12 +00:00
|
|
|
virtual const char *GetAnnouncementLine(char const *FileName) = 0;
|
|
|
|
virtual bool ClientPrevIngame(int ClientID) = 0;
|
|
|
|
virtual const char *GetNetErrorString(int ClientID) = 0;
|
|
|
|
virtual void ResetNetErrorString(int ClientID) = 0;
|
|
|
|
virtual bool SetTimedOut(int ClientID, int OrigID) = 0;
|
|
|
|
virtual void SetTimeoutProtected(int ClientID) = 0;
|
2017-10-13 00:25:50 +00:00
|
|
|
|
|
|
|
virtual void SetErrorShutdown(const char *pReason) = 0;
|
2019-11-03 00:07:10 +00:00
|
|
|
virtual void ExpireServerInfo() = 0;
|
2019-09-15 11:32:40 +00:00
|
|
|
|
2020-05-13 20:27:49 +00:00
|
|
|
virtual void SendMsgRaw(int ClientID, const void *pData, int Size, int Flags) = 0;
|
|
|
|
|
2019-09-15 11:32:40 +00:00
|
|
|
virtual char *GetMapName() = 0;
|
2020-03-29 02:36:38 +00:00
|
|
|
|
2020-06-23 15:30:57 +00:00
|
|
|
virtual bool IsSixup(int ClientID) const = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
class IGameServer : public IInterface
|
|
|
|
{
|
|
|
|
MACRO_INTERFACE("gameserver", 0)
|
|
|
|
protected:
|
|
|
|
public:
|
|
|
|
virtual void OnInit() = 0;
|
|
|
|
virtual void OnConsoleInit() = 0;
|
2015-07-14 20:08:29 +00:00
|
|
|
virtual void OnMapChange(char *pNewMapName, int MapNameSize) = 0;
|
2016-05-04 13:32:24 +00:00
|
|
|
|
|
|
|
// FullShutdown is true if the program is about to exit (not if the map is changed)
|
2020-07-04 17:53:27 +00:00
|
|
|
virtual void OnShutdown() = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual void OnTick() = 0;
|
|
|
|
virtual void OnPreSnap() = 0;
|
|
|
|
virtual void OnSnap(int ClientID) = 0;
|
|
|
|
virtual void OnPostSnap() = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2011-02-12 10:40:36 +00:00
|
|
|
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
|
|
|
|
virtual void OnClientConnected(int ClientID) = 0;
|
|
|
|
virtual void OnClientEnter(int ClientID) = 0;
|
2011-02-14 18:41:32 +00:00
|
|
|
virtual void OnClientDrop(int ClientID, const char *pReason) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual void OnClientDirectInput(int ClientID, void *pInput) = 0;
|
|
|
|
virtual void OnClientPredictedInput(int ClientID, void *pInput) = 0;
|
2019-01-29 19:32:11 +00:00
|
|
|
virtual void OnClientPredictedEarlyInput(int ClientID, void *pInput) = 0;
|
2011-03-15 08:58:57 +00:00
|
|
|
|
|
|
|
virtual bool IsClientReady(int ClientID) = 0;
|
2011-03-20 14:33:49 +00:00
|
|
|
virtual bool IsClientPlayer(int ClientID) = 0;
|
2011-04-13 18:37:12 +00:00
|
|
|
|
2018-02-07 15:43:36 +00:00
|
|
|
virtual CUuid GameUuid() = 0;
|
2011-02-16 11:31:47 +00:00
|
|
|
virtual const char *GameType() = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
virtual const char *Version() = 0;
|
|
|
|
virtual const char *NetVersion() = 0;
|
2011-08-26 18:03:30 +00:00
|
|
|
|
|
|
|
// DDRace
|
|
|
|
|
|
|
|
virtual void OnSetAuthed(int ClientID, int Level) = 0;
|
2017-06-06 05:31:56 +00:00
|
|
|
virtual bool PlayerExists(int ClientID) = 0;
|
2017-09-13 20:35:09 +00:00
|
|
|
|
2020-06-19 20:06:39 +00:00
|
|
|
virtual void OnClientEngineJoin(int ClientID, bool Sixup) = 0;
|
2017-09-13 20:35:09 +00:00
|
|
|
virtual void OnClientEngineDrop(int ClientID, const char *pReason) = 0;
|
2020-05-13 20:27:49 +00:00
|
|
|
|
|
|
|
virtual void FillAntibot(CAntibotRoundData *pData) = 0;
|
2010-05-29 07:25:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
extern IGameServer *CreateGameServer();
|
|
|
|
#endif
|