Merge pull request #2065 from Dune-jr/feature-stayasspec

Make it so that spectators stay as spectators when map changes
This commit is contained in:
oy 2019-03-17 19:15:30 +01:00 committed by GitHub
commit 594796cd42
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 27 additions and 13 deletions

View file

@ -85,7 +85,7 @@ public:
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) = 0; virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID) = 0;
virtual void OnClientConnected(int ClientID) = 0; virtual void OnClientConnected(int ClientID, bool AsSpec) = 0;
virtual void OnClientEnter(int ClientID) = 0; virtual void OnClientEnter(int ClientID) = 0;
virtual void OnClientDrop(int ClientID, const char *pReason) = 0; virtual void OnClientDrop(int ClientID, const char *pReason) = 0;
virtual void OnClientDirectInput(int ClientID, void *pInput) = 0; virtual void OnClientDirectInput(int ClientID, void *pInput) = 0;
@ -93,6 +93,7 @@ public:
virtual bool IsClientReady(int ClientID) const = 0; virtual bool IsClientReady(int ClientID) const = 0;
virtual bool IsClientPlayer(int ClientID) const = 0; virtual bool IsClientPlayer(int ClientID) const = 0;
virtual bool IsClientSpectator(int ClientID) const = 0;
virtual const char *GameType() const = 0; virtual const char *GameType() const = 0;
virtual const char *Version() const = 0; virtual const char *Version() const = 0;

View file

@ -858,7 +858,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
} }
else if(Msg == NETMSG_REQUEST_MAP_DATA) else if(Msg == NETMSG_REQUEST_MAP_DATA)
{ {
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 || m_aClients[ClientID].m_State == CClient::STATE_CONNECTING_AS_SPEC)
{ {
int ChunkSize = MAP_CHUNK_SIZE; int ChunkSize = MAP_CHUNK_SIZE;
@ -892,7 +892,7 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
} }
else if(Msg == NETMSG_READY) 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 || m_aClients[ClientID].m_State == CClient::STATE_CONNECTING_AS_SPEC))
{ {
char aAddrStr[NETADDR_MAXSTRSIZE]; char aAddrStr[NETADDR_MAXSTRSIZE];
net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true); net_addr_str(m_NetServer.ClientAddr(ClientID), aAddrStr, sizeof(aAddrStr), true);
@ -900,8 +900,10 @@ void CServer::ProcessClientPacket(CNetChunk *pPacket)
char aBuf[256]; char aBuf[256];
str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr); str_format(aBuf, sizeof(aBuf), "player is ready. ClientID=%x addr=%s", ClientID, aAddrStr);
Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf); Console()->Print(IConsole::OUTPUT_LEVEL_ADDINFO, "server", aBuf);
bool ConnectAsSpec = m_aClients[ClientID].m_State == CClient::STATE_CONNECTING_AS_SPEC;
m_aClients[ClientID].m_State = CClient::STATE_READY; m_aClients[ClientID].m_State = CClient::STATE_READY;
GameServer()->OnClientConnected(ClientID); GameServer()->OnClientConnected(ClientID, ConnectAsSpec);
SendConnectionReady(ClientID); SendConnectionReady(ClientID);
} }
} }
@ -1359,6 +1361,10 @@ int CServer::Run()
if(LoadMap(g_Config.m_SvMap)) if(LoadMap(g_Config.m_SvMap))
{ {
// new map loaded // new map loaded
bool aSpecs[MAX_CLIENTS];
for(int c = 0; c < MAX_CLIENTS; c++)
aSpecs[c] = GameServer()->IsClientSpectator(c);
GameServer()->OnShutdown(); GameServer()->OnShutdown();
for(int c = 0; c < MAX_CLIENTS; c++) for(int c = 0; c < MAX_CLIENTS; c++)
@ -1368,7 +1374,7 @@ int CServer::Run()
SendMap(c); SendMap(c);
m_aClients[c].Reset(); m_aClients[c].Reset();
m_aClients[c].m_State = CClient::STATE_CONNECTING; m_aClients[c].m_State = aSpecs[c] ? CClient::STATE_CONNECTING_AS_SPEC : CClient::STATE_CONNECTING;
} }
m_GameStartTime = time_get(); m_GameStartTime = time_get();

View file

@ -92,6 +92,7 @@ public:
STATE_EMPTY = 0, STATE_EMPTY = 0,
STATE_AUTH, STATE_AUTH,
STATE_CONNECTING, STATE_CONNECTING,
STATE_CONNECTING_AS_SPEC,
STATE_READY, STATE_READY,
STATE_INGAME, STATE_INGAME,

View file

@ -656,9 +656,9 @@ void CGameContext::OnClientEnter(int ClientID)
} }
} }
void CGameContext::OnClientConnected(int ClientID, bool Dummy) void CGameContext::OnClientConnected(int ClientID, bool Dummy, bool AsSpec)
{ {
m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, Dummy); m_apPlayers[ClientID] = new(ClientID) CPlayer(this, ClientID, Dummy, AsSpec);
if(Dummy) if(Dummy)
return; return;
@ -1531,7 +1531,12 @@ bool CGameContext::IsClientReady(int ClientID) const
bool CGameContext::IsClientPlayer(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;
}
bool CGameContext::IsClientSpectator(int ClientID) const
{
return m_apPlayers[ClientID] && m_apPlayers[ClientID]->GetTeam() == TEAM_SPECTATORS;
} }
const char *CGameContext::GameType() const { return m_pController && m_pController->GetGameType() ? m_pController->GetGameType() : ""; } const char *CGameContext::GameType() const { return m_pController && m_pController->GetGameType() ? m_pController->GetGameType() : ""; }

View file

@ -163,8 +163,8 @@ public:
virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID); virtual void OnMessage(int MsgID, CUnpacker *pUnpacker, int ClientID);
virtual void OnClientConnected(int ClientID) { OnClientConnected(ClientID, false); } virtual void OnClientConnected(int ClientID, bool AsSpec) { OnClientConnected(ClientID, false, AsSpec); }
void OnClientConnected(int ClientID, bool Dummy); void OnClientConnected(int ClientID, bool Dummy, bool AsSpec);
void OnClientTeamChange(int ClientID); void OnClientTeamChange(int ClientID);
virtual void OnClientEnter(int ClientID); virtual void OnClientEnter(int ClientID);
virtual void OnClientDrop(int ClientID, const char *pReason); virtual void OnClientDrop(int ClientID, const char *pReason);
@ -173,6 +173,7 @@ public:
virtual bool IsClientReady(int ClientID) const; virtual bool IsClientReady(int ClientID) const;
virtual bool IsClientPlayer(int ClientID) const; virtual bool IsClientPlayer(int ClientID) const;
virtual bool IsClientSpectator(int ClientID) const;
virtual const char *GameType() const; virtual const char *GameType() const;
virtual const char *Version() const; virtual const char *Version() const;

View file

@ -12,7 +12,7 @@ MACRO_ALLOC_POOL_ID_IMPL(CPlayer, MAX_CLIENTS)
IServer *CPlayer::Server() const { return m_pGameServer->Server(); } IServer *CPlayer::Server() const { return m_pGameServer->Server(); }
CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy) CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy, bool AsSpec)
{ {
m_pGameServer = pGameServer; m_pGameServer = pGameServer;
m_RespawnTick = Server()->Tick(); m_RespawnTick = Server()->Tick();
@ -20,7 +20,7 @@ CPlayer::CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy)
m_ScoreStartTick = Server()->Tick(); m_ScoreStartTick = Server()->Tick();
m_pCharacter = 0; m_pCharacter = 0;
m_ClientID = ClientID; m_ClientID = ClientID;
m_Team = GameServer()->m_pController->GetStartTeam(); m_Team = AsSpec ? TEAM_SPECTATORS : GameServer()->m_pController->GetStartTeam();
m_SpecMode = SPEC_FREEVIEW; m_SpecMode = SPEC_FREEVIEW;
m_SpectatorID = -1; m_SpectatorID = -1;
m_pSpecFlag = 0; m_pSpecFlag = 0;

View file

@ -19,7 +19,7 @@ class CPlayer
MACRO_ALLOC_POOL_ID() MACRO_ALLOC_POOL_ID()
public: public:
CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy); CPlayer(CGameContext *pGameServer, int ClientID, bool Dummy, bool AsSpec = false);
~CPlayer(); ~CPlayer();
void Init(int CID); void Init(int CID);