fix 4781 and refactor of the client id for server demos

This commit is contained in:
c0d3d3v 2022-03-04 21:23:32 +01:00
parent 237a9170bd
commit 3438642dd8
No known key found for this signature in database
GPG key ID: 068AF680530DFF31
15 changed files with 46 additions and 34 deletions

View file

@ -14,9 +14,16 @@
#include <game/generated/protocol.h> #include <game/generated/protocol.h>
#include <game/generated/protocol7.h> #include <game/generated/protocol7.h>
#include <game/generated/protocolglue.h> #include <game/generated/protocolglue.h>
#include <game/version.h>
struct CAntibotRoundData; struct CAntibotRoundData;
// When recording a demo on the server, the ClientID -1 is used
enum
{
SERVER_DEMO_CLIENT = -1
};
class IServer : public IInterface class IServer : public IInterface
{ {
MACRO_INTERFACE("server", 0) MACRO_INTERFACE("server", 0)
@ -150,13 +157,19 @@ public:
return SendMsg(&Packer, Flags, ClientID); return SendMsg(&Packer, Flags, ClientID);
} }
int GetClientVersion(int ClientID) const
{
CClientInfo Info;
GetClientInfo(ClientID, &Info);
return Info.m_DDNetVersion;
}
bool Translate(int &Target, int Client) bool Translate(int &Target, int Client)
{ {
if(IsSixup(Client)) if(IsSixup(Client))
return true; return true;
CClientInfo Info; int ClientVersion = Client != SERVER_DEMO_CLIENT ? GetClientVersion(Client) : CLIENT_VERSIONNR;
GetClientInfo(Client, &Info); if(ClientVersion >= VERSION_DDNET_OLD)
if(Info.m_DDNetVersion >= VERSION_DDNET_OLD)
return true; return true;
int *pMap = GetIdMap(Client); int *pMap = GetIdMap(Client);
bool Found = false; bool Found = false;
@ -176,9 +189,8 @@ public:
{ {
if(IsSixup(Client)) if(IsSixup(Client))
return true; return true;
CClientInfo Info; int ClientVersion = Client != SERVER_DEMO_CLIENT ? GetClientVersion(Client) : CLIENT_VERSIONNR;
GetClientInfo(Client, &Info); if(ClientVersion >= VERSION_DDNET_OLD)
if(Info.m_DDNetVersion >= VERSION_DDNET_OLD)
return true; return true;
Target = clamp(Target, 0, VANILLA_MAX_CLIENTS - 1); Target = clamp(Target, 0, VANILLA_MAX_CLIENTS - 1);
int *pMap = GetIdMap(Client); int *pMap = GetIdMap(Client);

View file

@ -462,7 +462,7 @@ public:
bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; } bool ErrorShutdown() const { return m_aErrorShutdownReason[0] != 0; }
void SetErrorShutdown(const char *pReason); void SetErrorShutdown(const char *pReason);
bool IsSixup(int ClientID) const { return m_aClients[ClientID].m_Sixup; } bool IsSixup(int ClientID) const { return ClientID != SERVER_DEMO_CLIENT && m_aClients[ClientID].m_Sixup; }
#ifdef CONF_FAMILY_UNIX #ifdef CONF_FAMILY_UNIX
enum CONN_LOGGING_CMD enum CONN_LOGGING_CMD

View file

@ -1077,7 +1077,7 @@ void CCharacter::SnapCharacter(int SnappingClient, int ID)
AmmoCount = 10; AmmoCount = 10;
} }
if(m_pPlayer->GetCID() == SnappingClient || SnappingClient == -1 || if(m_pPlayer->GetCID() == SnappingClient || SnappingClient == SERVER_DEMO_CLIENT ||
(!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID)) (!g_Config.m_SvStrictSpectateMode && m_pPlayer->GetCID() == GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID))
{ {
Health = m_Health; Health = m_Health;
@ -1153,7 +1153,7 @@ void CCharacter::SnapCharacter(int SnappingClient, int ID)
bool CCharacter::CanSnapCharacter(int SnappingClient) bool CCharacter::CanSnapCharacter(int SnappingClient)
{ {
if(SnappingClient < 0) if(SnappingClient == SERVER_DEMO_CLIENT)
return true; return true;
CCharacter *pSnapChar = GameServer()->GetPlayerChar(SnappingClient); CCharacter *pSnapChar = GameServer()->GetPlayerChar(SnappingClient);
@ -1176,7 +1176,7 @@ void CCharacter::Snap(int SnappingClient)
{ {
int ID = m_pPlayer->GetCID(); int ID = m_pPlayer->GetCID();
if(SnappingClient > -1 && !Server()->Translate(ID, SnappingClient)) if(!Server()->Translate(ID, SnappingClient))
return; return;
if(NetworkClipped(SnappingClient) || !CanSnapCharacter(SnappingClient)) if(NetworkClipped(SnappingClient) || !CanSnapCharacter(SnappingClient))

View file

@ -54,7 +54,7 @@ void CDoor::Snap(int SnappingClient)
pObj->m_X = (int)m_Pos.x; pObj->m_X = (int)m_Pos.x;
pObj->m_Y = (int)m_Pos.y; pObj->m_Y = (int)m_Pos.y;
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
CNetObj_EntityEx *pEntData = 0; CNetObj_EntityEx *pEntData = 0;
if(SnappingClientVersion >= VERSION_DDNET_SWITCH) if(SnappingClientVersion >= VERSION_DDNET_SWITCH)
@ -74,7 +74,7 @@ void CDoor::Snap(int SnappingClient)
{ {
CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient);
if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);
if(Char && Char->Team() != TEAM_SUPER && Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()]) if(Char && Char->Team() != TEAM_SUPER && Char->IsAlive() && GameServer()->Collision()->m_NumSwitchers > 0 && GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[Char->Team()])

View file

@ -186,13 +186,13 @@ void CDragger::Snap(int SnappingClient)
CCharacter *pChar = GameServer()->GetPlayerChar(SnappingClient); CCharacter *pChar = GameServer()->GetPlayerChar(SnappingClient);
if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
pChar = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); pChar = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);
if(pChar && pChar->Team() != m_CaughtTeam) if(pChar && pChar->Team() != m_CaughtTeam)
return; return;
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
CNetObj_EntityEx *pEntData = 0; CNetObj_EntityEx *pEntData = 0;
if(SnappingClientVersion >= VERSION_DDNET_SWITCH) if(SnappingClientVersion >= VERSION_DDNET_SWITCH)

View file

@ -117,11 +117,11 @@ void CGun::Snap(int SnappingClient)
CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient);
if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) &&
GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
CNetObj_EntityEx *pEntData = 0; CNetObj_EntityEx *pEntData = 0;
if(SnappingClientVersion >= VERSION_DDNET_SWITCH) if(SnappingClientVersion >= VERSION_DDNET_SWITCH)

View file

@ -276,7 +276,7 @@ void CLaser::Snap(int SnappingClient)
if(pOwnerChar && pOwnerChar->IsAlive()) if(pOwnerChar && pOwnerChar->IsAlive())
TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner); TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner);
if(!CmaskIsSet(TeamMask, SnappingClient)) if(SnappingClient != SERVER_DEMO_CLIENT && !CmaskIsSet(TeamMask, SnappingClient))
return; return;
CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser))); CNetObj_Laser *pObj = static_cast<CNetObj_Laser *>(Server()->SnapNewItem(NETOBJTYPE_LASER, GetID(), sizeof(CNetObj_Laser)));
if(!pObj) if(!pObj)

View file

@ -104,7 +104,7 @@ void CLight::Snap(int SnappingClient)
if(NetworkClipped(SnappingClient, m_Pos) && NetworkClipped(SnappingClient, m_To)) if(NetworkClipped(SnappingClient, m_Pos) && NetworkClipped(SnappingClient, m_To))
return; return;
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
CNetObj_EntityEx *pEntData = 0; CNetObj_EntityEx *pEntData = 0;
if(SnappingClientVersion >= VERSION_DDNET_SWITCH && (m_Layer == LAYER_SWITCH || length(m_Core) > 0)) if(SnappingClientVersion >= VERSION_DDNET_SWITCH && (m_Layer == LAYER_SWITCH || length(m_Core) > 0))
@ -112,7 +112,7 @@ void CLight::Snap(int SnappingClient)
CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient);
if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);
if(pEntData) if(pEntData)

View file

@ -157,10 +157,10 @@ void CPickup::Snap(int SnappingClient)
CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient); CCharacter *Char = GameServer()->GetPlayerChar(SnappingClient);
if(SnappingClient > -1 && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW) if(SnappingClient != SERVER_DEMO_CLIENT && (GameServer()->m_apPlayers[SnappingClient]->GetTeam() == -1 || GameServer()->m_apPlayers[SnappingClient]->IsPaused()) && GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID != SPEC_FREEVIEW)
Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID); Char = GameServer()->GetPlayerChar(GameServer()->m_apPlayers[SnappingClient]->m_SpectatorID);
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
CNetObj_EntityEx *pEntData = 0; CNetObj_EntityEx *pEntData = 0;
if(SnappingClientVersion >= VERSION_DDNET_SWITCH && (m_Layer == LAYER_SWITCH || length(m_Core) > 0)) if(SnappingClientVersion >= VERSION_DDNET_SWITCH && (m_Layer == LAYER_SWITCH || length(m_Core) > 0))

View file

@ -88,7 +88,7 @@ void CPlasma::Snap(int SnappingClient)
if(NetworkClipped(SnappingClient)) if(NetworkClipped(SnappingClient))
return; return;
CCharacter *SnapChar = GameServer()->GetPlayerChar(SnappingClient); CCharacter *SnapChar = GameServer()->GetPlayerChar(SnappingClient);
CPlayer *SnapPlayer = SnappingClient > -1 ? GameServer()->m_apPlayers[SnappingClient] : 0; CPlayer *SnapPlayer = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->m_apPlayers[SnappingClient] : 0;
int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11; int Tick = (Server()->Tick() % Server()->TickSpeed()) % 11;
if(SnapChar && SnapChar->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[SnapChar->Team()]) && (!Tick)) if(SnapChar && SnapChar->IsAlive() && (m_Layer == LAYER_SWITCH && m_Number > 0 && !GameServer()->Collision()->m_pSwitchers[m_Number].m_Status[SnapChar->Team()]) && (!Tick))

View file

@ -317,7 +317,7 @@ void CProjectile::Snap(int SnappingClient)
pEntData->m_EntityClass = ENTITYCLASS_PROJECTILE; pEntData->m_EntityClass = ENTITYCLASS_PROJECTILE;
} }
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
if(SnappingClientVersion < VERSION_DDNET_SWITCH) if(SnappingClientVersion < VERSION_DDNET_SWITCH)
{ {
CCharacter *pSnapChar = GameServer()->GetPlayerChar(SnappingClient); CCharacter *pSnapChar = GameServer()->GetPlayerChar(SnappingClient);
@ -335,7 +335,7 @@ void CProjectile::Snap(int SnappingClient)
if(pOwnerChar && pOwnerChar->IsAlive()) if(pOwnerChar && pOwnerChar->IsAlive())
TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner); TeamMask = pOwnerChar->Teams()->TeamMask(pOwnerChar->Team(), -1, m_Owner);
if(m_Owner != -1 && !CmaskIsSet(TeamMask, SnappingClient)) if(SnappingClient != SERVER_DEMO_CLIENT && m_Owner != -1 && !CmaskIsSet(TeamMask, SnappingClient))
return; return;
CNetObj_DDNetProjectile DDNetProjectile; CNetObj_DDNetProjectile DDNetProjectile;

View file

@ -83,7 +83,7 @@ bool CEntity::GetNearestAirPosPlayer(vec2 PlayerPos, vec2 *OutPos)
bool NetworkClipped(const CGameContext *pGameServer, int SnappingClient, vec2 CheckPos) bool NetworkClipped(const CGameContext *pGameServer, int SnappingClient, vec2 CheckPos)
{ {
if(SnappingClient == -1 || pGameServer->m_apPlayers[SnappingClient]->m_ShowAll) if(SnappingClient == SERVER_DEMO_CLIENT || pGameServer->m_apPlayers[SnappingClient]->m_ShowAll)
return false; return false;
float dx = pGameServer->m_apPlayers[SnappingClient]->m_ViewPos.x - CheckPos.x; float dx = pGameServer->m_apPlayers[SnappingClient]->m_ViewPos.x - CheckPos.x;

View file

@ -47,7 +47,7 @@ void CEventHandler::Snap(int SnappingClient)
{ {
for(int i = 0; i < m_NumEvents; i++) for(int i = 0; i < m_NumEvents; i++)
{ {
if(SnappingClient == -1 || CmaskIsSet(m_aClientMasks[i], SnappingClient)) if(SnappingClient == SERVER_DEMO_CLIENT || CmaskIsSet(m_aClientMasks[i], SnappingClient))
{ {
CNetEvent_Common *ev = (CNetEvent_Common *)&m_aData[m_aOffsets[i]]; CNetEvent_Common *ev = (CNetEvent_Common *)&m_aData[m_aOffsets[i]];
if(!NetworkClipped(GameServer(), SnappingClient, vec2(ev->m_X, ev->m_Y))) if(!NetworkClipped(GameServer(), SnappingClient, vec2(ev->m_X, ev->m_Y)))

View file

@ -555,7 +555,7 @@ void IGameController::Snap(int SnappingClient)
pGameInfoObj->m_RoundCurrent = m_RoundCount + 1; pGameInfoObj->m_RoundCurrent = m_RoundCount + 1;
CCharacter *pChr; CCharacter *pChr;
CPlayer *pPlayer = SnappingClient > -1 ? GameServer()->m_apPlayers[SnappingClient] : 0; CPlayer *pPlayer = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->m_apPlayers[SnappingClient] : 0;
CPlayer *pPlayer2; CPlayer *pPlayer2;
if(pPlayer && (pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER || pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) && pPlayer->GetClientVersion() >= VERSION_DDNET_GAMETICK) if(pPlayer && (pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER || pPlayer->m_TimerType == CPlayer::TIMERTYPE_GAMETIMER_AND_BROADCAST) && pPlayer->GetClientVersion() >= VERSION_DDNET_GAMETICK)

View file

@ -326,7 +326,7 @@ void CPlayer::Snap(int SnappingClient)
return; return;
int id = m_ClientID; int id = m_ClientID;
if(SnappingClient > -1 && !Server()->Translate(id, SnappingClient)) if(!Server()->Translate(id, SnappingClient))
return; return;
CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, id, sizeof(CNetObj_ClientInfo))); CNetObj_ClientInfo *pClientInfo = static_cast<CNetObj_ClientInfo *>(Server()->SnapNewItem(NETOBJTYPE_CLIENTINFO, id, sizeof(CNetObj_ClientInfo)));
@ -341,15 +341,15 @@ void CPlayer::Snap(int SnappingClient)
pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody; pClientInfo->m_ColorBody = m_TeeInfos.m_ColorBody;
pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet; pClientInfo->m_ColorFeet = m_TeeInfos.m_ColorFeet;
int SnappingClientVersion = SnappingClient >= 0 ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR; int SnappingClientVersion = SnappingClient != SERVER_DEMO_CLIENT ? GameServer()->GetClientVersion(SnappingClient) : CLIENT_VERSIONNR;
int Latency = SnappingClient == -1 ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID]; int Latency = SnappingClient == SERVER_DEMO_CLIENT ? m_Latency.m_Min : GameServer()->m_apPlayers[SnappingClient]->m_aActLatency[m_ClientID];
int Score = abs(m_Score) * -1; int Score = abs(m_Score) * -1;
// send 0 if times of others are not shown // send 0 if times of others are not shown
if(SnappingClient != m_ClientID && g_Config.m_SvHideScore) if(SnappingClient != m_ClientID && g_Config.m_SvHideScore)
Score = -9999; Score = -9999;
if(SnappingClient < 0 || !Server()->IsSixup(SnappingClient)) if(!Server()->IsSixup(SnappingClient))
{ {
CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, id, sizeof(CNetObj_PlayerInfo))); CNetObj_PlayerInfo *pPlayerInfo = static_cast<CNetObj_PlayerInfo *>(Server()->SnapNewItem(NETOBJTYPE_PLAYERINFO, id, sizeof(CNetObj_PlayerInfo)));
if(!pPlayerInfo) if(!pPlayerInfo)
@ -383,7 +383,7 @@ void CPlayer::Snap(int SnappingClient)
if(m_ClientID == SnappingClient && (m_Team == TEAM_SPECTATORS || m_Paused)) if(m_ClientID == SnappingClient && (m_Team == TEAM_SPECTATORS || m_Paused))
{ {
if(SnappingClient < 0 || !Server()->IsSixup(SnappingClient)) if(!Server()->IsSixup(SnappingClient))
{ {
CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo))); CNetObj_SpectatorInfo *pSpectatorInfo = static_cast<CNetObj_SpectatorInfo *>(Server()->SnapNewItem(NETOBJTYPE_SPECTATORINFO, m_ClientID, sizeof(CNetObj_SpectatorInfo)));
if(!pSpectatorInfo) if(!pSpectatorInfo)
@ -419,7 +419,7 @@ void CPlayer::Snap(int SnappingClient)
if(m_Paused == PAUSE_PAUSED) if(m_Paused == PAUSE_PAUSED)
pDDNetPlayer->m_Flags |= EXPLAYERFLAG_PAUSED; pDDNetPlayer->m_Flags |= EXPLAYERFLAG_PAUSED;
if(SnappingClient >= 0 && Server()->IsSixup(SnappingClient) && m_pCharacter && m_pCharacter->m_DDRaceState == DDRACE_STARTED && if(Server()->IsSixup(SnappingClient) && m_pCharacter && m_pCharacter->m_DDRaceState == DDRACE_STARTED &&
GameServer()->m_apPlayers[SnappingClient]->m_TimerType == TIMERTYPE_SIXUP) GameServer()->m_apPlayers[SnappingClient]->m_TimerType == TIMERTYPE_SIXUP)
{ {
protocol7::CNetObj_PlayerInfoRace *pRaceInfo = static_cast<protocol7::CNetObj_PlayerInfoRace *>(Server()->SnapNewItem(-protocol7::NETOBJTYPE_PLAYERINFORACE, id, sizeof(protocol7::CNetObj_PlayerInfoRace))); protocol7::CNetObj_PlayerInfoRace *pRaceInfo = static_cast<protocol7::CNetObj_PlayerInfoRace *>(Server()->SnapNewItem(-protocol7::NETOBJTYPE_PLAYERINFORACE, id, sizeof(protocol7::CNetObj_PlayerInfoRace)));
@ -430,7 +430,7 @@ void CPlayer::Snap(int SnappingClient)
bool ShowSpec = m_pCharacter && m_pCharacter->IsPaused() && m_pCharacter->CanSnapCharacter(SnappingClient); bool ShowSpec = m_pCharacter && m_pCharacter->IsPaused() && m_pCharacter->CanSnapCharacter(SnappingClient);
if(SnappingClient >= 0) if(SnappingClient != SERVER_DEMO_CLIENT)
{ {
CPlayer *pSnapPlayer = GameServer()->m_apPlayers[SnappingClient]; CPlayer *pSnapPlayer = GameServer()->m_apPlayers[SnappingClient];
ShowSpec = ShowSpec && (GameServer()->GetDDRaceTeam(m_ClientID) == GameServer()->GetDDRaceTeam(SnappingClient) || pSnapPlayer->m_ShowOthers == SHOW_OTHERS_ON || (pSnapPlayer->GetTeam() == TEAM_SPECTATORS || pSnapPlayer->IsPaused())); ShowSpec = ShowSpec && (GameServer()->GetDDRaceTeam(m_ClientID) == GameServer()->GetDDRaceTeam(SnappingClient) || pSnapPlayer->m_ShowOthers == SHOW_OTHERS_ON || (pSnapPlayer->GetTeam() == TEAM_SPECTATORS || pSnapPlayer->IsPaused()));