mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 01:58:19 +00:00
Make spectators stay specs on map changed
Based on PRs to the upstream: https://github.com/teeworlds/teeworlds/pull/2065 https://github.com/teeworlds/teeworlds/pull/2066 Co-authored-by: Jordy Ruiz <jordy.ruiz@univ-lille.fr> Co-authored-by: heinrich5991 <heinrich5991@gmail.com>
This commit is contained in:
parent
2790270abf
commit
6b49bf1388
|
@ -267,7 +267,22 @@ public:
|
|||
|
||||
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) = 0;
|
||||
|
||||
virtual void OnClientConnected(int ClientID) = 0;
|
||||
// Called before map reload, for any data that the game wants to
|
||||
// persist to the next map.
|
||||
//
|
||||
// Has the size of the return value of `PersistentClientDataSize()`.
|
||||
//
|
||||
// Returns whether the game should be supplied with the data when the
|
||||
// client connects for the next map.
|
||||
virtual bool OnClientDataPersist(int ClientID, void *pData) = 0;
|
||||
|
||||
// Called when a client connects.
|
||||
//
|
||||
// If it is reconnecting to the game after a map change, the
|
||||
// `pPersistentData` point is nonnull and contains the data the game
|
||||
// previously stored.
|
||||
virtual void OnClientConnected(int ClientID, void *pPersistentData) = 0;
|
||||
|
||||
virtual void OnClientEnter(int ClientID) = 0;
|
||||
virtual void OnClientDrop(int ClientID, const char *pReason) = 0;
|
||||
virtual void OnClientDirectInput(int ClientID, void *pInput) = 0;
|
||||
|
@ -277,6 +292,8 @@ public:
|
|||
virtual bool IsClientReady(int ClientID) const = 0;
|
||||
virtual bool IsClientPlayer(int ClientID) const = 0;
|
||||
|
||||
virtual int PersistentClientDataSize() const = 0;
|
||||
|
||||
virtual CUuid GameUuid() const = 0;
|
||||
virtual const char *GameType() const = 0;
|
||||
virtual const char *Version() const = 0;
|
||||
|
|
|
@ -1465,7 +1465,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
}
|
||||
else if(Msg == NETMSG_READY)
|
||||
{
|
||||
if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && m_aClients[ClientID].m_State == CClient::STATE_CONNECTING)
|
||||
if((pPacket->m_Flags & NET_CHUNKFLAG_VITAL) != 0 && (m_aClients[ClientID].m_State == CClient::STATE_CONNECTING))
|
||||
{
|
||||
char aAddrStr[NETADDR_MAXSTRSIZE];
|
||||
net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true);
|
||||
|
@ -1473,8 +1473,15 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
|
|||
char aBuf[256];
|
||||
str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%d addr=<{%s}> secure=%s", ClientID, aAddrStr, m_NetServer.HasSecurityToken(ClientID) ? "yes" : "no");
|
||||
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
|
||||
|
||||
void *pPersistentData = 0;
|
||||
if(m_aClients[ClientID].m_HasPersistentData)
|
||||
{
|
||||
pPersistentData = m_aClients[ClientID].m_pPersistentData;
|
||||
m_aClients[ClientID].m_HasPersistentData = false;
|
||||
}
|
||||
m_aClients[ClientID].m_State = CClient::STATE_READY;
|
||||
GameServer()->OnClientConnected(ClientID);
|
||||
GameServer()->OnClientConnected(ClientID, pPersistentData);
|
||||
}
|
||||
|
||||
SendConnectionReady(ClientID);
|
||||
|
@ -2349,6 +2356,14 @@ int CServer::Run()
|
|||
|
||||
m_PrintCBIndex = Console()->RegisterPrintCallback(g_Config.m_ConsoleOutputLevel, SendRconLineAuthed, this);
|
||||
|
||||
{
|
||||
int Size = GameServer()->PersistentClientDataSize();
|
||||
for(auto &Client : m_aClients)
|
||||
{
|
||||
Client.m_pPersistentData = malloc(Size);
|
||||
}
|
||||
}
|
||||
|
||||
// load map
|
||||
if(!LoadMap(g_Config.m_SvMap))
|
||||
{
|
||||
|
@ -2458,6 +2473,16 @@ int CServer::Run()
|
|||
if(LoadMap(g_Config.m_SvMap))
|
||||
{
|
||||
// new map loaded
|
||||
|
||||
// ask the game to for the data it wants to persist past a map change
|
||||
for(int i = 0; i < MAX_CLIENTS; i++)
|
||||
{
|
||||
if(m_aClients[i].m_State == CClient::STATE_INGAME)
|
||||
{
|
||||
m_aClients[i].m_HasPersistentData = GameServer()->OnClientDataPersist(i, m_aClients[i].m_pPersistentData);
|
||||
}
|
||||
}
|
||||
|
||||
GameServer()->OnShutdown();
|
||||
|
||||
for(int ClientID = 0; ClientID < MAX_CLIENTS; ClientID++)
|
||||
|
@ -2466,7 +2491,9 @@ int CServer::Run()
|
|||
continue;
|
||||
|
||||
SendMap(ClientID);
|
||||
bool HasPersistentData = m_aClients[ClientID].m_HasPersistentData;
|
||||
m_aClients[ClientID].Reset();
|
||||
m_aClients[ClientID].m_HasPersistentData = HasPersistentData;
|
||||
m_aClients[ClientID].m_State = CClient::STATE_CONNECTING;
|
||||
}
|
||||
|
||||
|
|
|
@ -178,6 +178,9 @@ public:
|
|||
|
||||
const IConsole::CCommandInfo *m_pRconCmdToSend;
|
||||
|
||||
bool m_HasPersistentData;
|
||||
void *m_pPersistentData;
|
||||
|
||||
void Reset();
|
||||
|
||||
// DDRace
|
||||
|
|
|
@ -1332,8 +1332,26 @@ void CGameContext::OnClientEnter(int ClientID)
|
|||
}
|
||||
}
|
||||
|
||||
void CGameContext::OnClientConnected(int ClientID)
|
||||
bool CGameContext::OnClientDataPersist(int ClientID, void *pData)
|
||||
{
|
||||
CPersistentClientData *pPersistent = (CPersistentClientData *)pData;
|
||||
if(!m_apPlayers[ClientID])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
pPersistent->m_IsSpectator = m_apPlayers[ClientID]->GetTeam() == TEAM_SPECTATORS;
|
||||
return true;
|
||||
}
|
||||
|
||||
void CGameContext::OnClientConnected(int ClientID, void *pData)
|
||||
{
|
||||
CPersistentClientData *pPersistentData = (CPersistentClientData *)pData;
|
||||
bool Spec = false;
|
||||
if(pPersistentData)
|
||||
{
|
||||
Spec = pPersistentData->m_IsSpectator;
|
||||
}
|
||||
|
||||
{
|
||||
bool Empty = true;
|
||||
for(auto &pPlayer : m_apPlayers)
|
||||
|
@ -1351,7 +1369,7 @@ void CGameContext::OnClientConnected(int ClientID)
|
|||
}
|
||||
|
||||
// Check which team the player should be on
|
||||
const int StartTeam = g_Config.m_SvTournamentMode ? TEAM_SPECTATORS : m_pController->GetAutoTeam(ClientID);
|
||||
const int StartTeam = (Spec || g_Config.m_SvTournamentMode) ? TEAM_SPECTATORS : m_pController->GetAutoTeam(ClientID);
|
||||
|
||||
if(!m_apPlayers[ClientID])
|
||||
m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, StartTeam);
|
||||
|
@ -3350,7 +3368,7 @@ void CGameContext::OnInit(/*class IKernel *pKernel*/)
|
|||
{
|
||||
for(int i = 0; i < g_Config.m_DbgDummies; i++)
|
||||
{
|
||||
OnClientConnected(MAX_CLIENTS - i - 1);
|
||||
OnClientConnected(MAX_CLIENTS - i - 1, 0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -3593,7 +3611,7 @@ bool CGameContext::IsClientReady(int ClientID) const
|
|||
|
||||
bool CGameContext::IsClientPlayer(int ClientID) const
|
||||
{
|
||||
return m_apPlayers[ClientID] && m_apPlayers[ClientID]->GetTeam() == TEAM_SPECTATORS ? false : true;
|
||||
return m_apPlayers[ClientID] && m_apPlayers[ClientID]->GetTeam() != TEAM_SPECTATORS;
|
||||
}
|
||||
|
||||
CUuid CGameContext::GameUuid() const { return m_GameUuid; }
|
||||
|
|
|
@ -123,6 +123,11 @@ class CGameContext : public IGameServer
|
|||
|
||||
bool m_Resetting;
|
||||
|
||||
struct CPersistentClientData
|
||||
{
|
||||
bool m_IsSpectator;
|
||||
};
|
||||
|
||||
public:
|
||||
IServer *Server() const { return m_pServer; }
|
||||
CConfig *Config() { return m_pConfig; }
|
||||
|
@ -246,7 +251,8 @@ public:
|
|||
void CensorMessage(char *pCensoredMessage, const char *pMessage, int Size);
|
||||
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID);
|
||||
|
||||
virtual void OnClientConnected(int ClientID);
|
||||
virtual bool OnClientDataPersist(int ClientID, void *pData);
|
||||
virtual void OnClientConnected(int ClientID, void *pData);
|
||||
virtual void OnClientEnter(int ClientID);
|
||||
virtual void OnClientDrop(int ClientID, const char *pReason);
|
||||
virtual void OnClientDirectInput(int ClientID, void *pInput);
|
||||
|
@ -258,6 +264,7 @@ public:
|
|||
|
||||
virtual bool IsClientReady(int ClientID) const;
|
||||
virtual bool IsClientPlayer(int ClientID) const;
|
||||
virtual int PersistentClientDataSize() const { return sizeof(CPersistentClientData); }
|
||||
|
||||
virtual CUuid GameUuid() const;
|
||||
virtual const char *GameType() const;
|
||||
|
|
Loading…
Reference in a new issue