Try fix issue with savegames

This commit is contained in:
Learath2 2024-07-24 16:25:54 +02:00
parent a84a53c5fe
commit 90c4a552ed
5 changed files with 41 additions and 7 deletions

View file

@ -752,6 +752,11 @@ bool CPlayer::CanOverrideDefaultEmote() const
return m_LastEyeEmote == 0 || m_LastEyeEmote + (int64_t)g_Config.m_SvEyeEmoteChangeDelay * Server()->TickSpeed() < Server()->Tick(); return m_LastEyeEmote == 0 || m_LastEyeEmote + (int64_t)g_Config.m_SvEyeEmoteChangeDelay * Server()->TickSpeed() < Server()->Tick();
} }
bool CPlayer::CanSpec() const
{
return m_pCharacter->IsGrounded() && m_pCharacter->m_Pos == m_pCharacter->m_PrevPos;
}
void CPlayer::ProcessPause() void CPlayer::ProcessPause()
{ {
if(m_ForcePauseTime && m_ForcePauseTime < Server()->Tick()) if(m_ForcePauseTime && m_ForcePauseTime < Server()->Tick())
@ -760,7 +765,7 @@ void CPlayer::ProcessPause()
Pause(PAUSE_NONE, true); Pause(PAUSE_NONE, true);
} }
if(m_Paused == PAUSE_SPEC && !m_pCharacter->IsPaused() && m_pCharacter->IsGrounded() && m_pCharacter->m_Pos == m_pCharacter->m_PrevPos) if(m_Paused == PAUSE_SPEC && !m_pCharacter->IsPaused() && CanSpec())
{ {
m_pCharacter->Pause(true); m_pCharacter->Pause(true);
GameServer()->CreateDeath(m_pCharacter->m_Pos, m_ClientId, GameServer()->m_pController->GetMaskForPlayerWorldEvent(m_ClientId)); GameServer()->CreateDeath(m_pCharacter->m_Pos, m_ClientId, GameServer()->m_pController->GetMaskForPlayerWorldEvent(m_ClientId));

View file

@ -179,6 +179,7 @@ public:
int Pause(int State, bool Force); int Pause(int State, bool Force);
int ForcePause(int Time); int ForcePause(int Time);
int IsPaused() const; int IsPaused() const;
bool CanSpec() const;
bool IsPlaying() const; bool IsPlaying() const;
int64_t m_Last_KickVote; int64_t m_Last_KickVote;

View file

@ -17,7 +17,14 @@ void CSaveTee::Save(CCharacter *pChr)
str_copy(m_aName, pChr->Server()->ClientName(m_ClientId), sizeof(m_aName)); str_copy(m_aName, pChr->Server()->ClientName(m_ClientId), sizeof(m_aName));
m_Alive = pChr->m_Alive; m_Alive = pChr->m_Alive;
// This is extremely suspect code, probably interacts badly with force pause
m_Paused = absolute(pChr->m_pPlayer->IsPaused()); m_Paused = absolute(pChr->m_pPlayer->IsPaused());
if(m_Paused == CPlayer::PAUSE_SPEC && !pChr->m_Paused)
{
m_Paused = CPlayer::PAUSE_NONE;
}
m_NeededFaketuning = pChr->m_NeededFaketuning; m_NeededFaketuning = pChr->m_NeededFaketuning;
m_TeeStarted = pChr->Teams()->TeeStarted(m_ClientId); m_TeeStarted = pChr->Teams()->TeeStarted(m_ClientId);
@ -121,8 +128,10 @@ void CSaveTee::Save(CCharacter *pChr)
FormatUuid(pChr->GameServer()->GameUuid(), m_aGameUuid, sizeof(m_aGameUuid)); FormatUuid(pChr->GameServer()->GameUuid(), m_aGameUuid, sizeof(m_aGameUuid));
} }
void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap) bool CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
{ {
bool Valid = true;
pChr->m_pPlayer->Pause(m_Paused, true); pChr->m_pPlayer->Pause(m_Paused, true);
pChr->m_Alive = m_Alive; pChr->m_Alive = m_Alive;
@ -239,6 +248,13 @@ void CSaveTee::Load(CCharacter *pChr, int Team, bool IsSwap)
pChr->ForceSetRescue(RESCUEMODE_AUTO); pChr->ForceSetRescue(RESCUEMODE_AUTO);
pChr->ForceSetRescue(RESCUEMODE_MANUAL); pChr->ForceSetRescue(RESCUEMODE_MANUAL);
} }
if(pChr->m_pPlayer->IsPaused() == -1 * CPlayer::PAUSE_SPEC && !pChr->m_pPlayer->CanSpec())
{
Valid = false;
}
return Valid;
} }
char *CSaveTee::GetString(const CSaveTeam *pTeam) char *CSaveTee::GetString(const CSaveTeam *pTeam)
@ -570,7 +586,7 @@ bool CSaveTeam::HandleSaveError(int Result, int ClientId, CGameContext *pGameCon
return true; return true;
} }
void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong) bool CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong)
{ {
IGameController *pController = pGameServer->m_pController; IGameController *pController = pGameServer->m_pController;
CGameTeams *pTeams = &pController->Teams(); CGameTeams *pTeams = &pController->Teams();
@ -579,6 +595,7 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
pTeams->SetTeamLock(Team, m_TeamLocked); pTeams->SetTeamLock(Team, m_TeamLocked);
pTeams->SetPractice(Team, m_Practice); pTeams->SetPractice(Team, m_Practice);
bool ContainsInvalidPlayer = false;
int aPlayerCids[MAX_CLIENTS]; int aPlayerCids[MAX_CLIENTS];
for(int i = m_MembersCount; i-- > 0;) for(int i = m_MembersCount; i-- > 0;)
{ {
@ -587,7 +604,7 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
if(pGameServer->m_apPlayers[ClientId] && pTeams->m_Core.Team(ClientId) == Team) if(pGameServer->m_apPlayers[ClientId] && pTeams->m_Core.Team(ClientId) == Team)
{ {
CCharacter *pChr = MatchCharacter(pGameServer, m_pSavedTees[i].GetClientId(), i, KeepCurrentWeakStrong); CCharacter *pChr = MatchCharacter(pGameServer, m_pSavedTees[i].GetClientId(), i, KeepCurrentWeakStrong);
m_pSavedTees[i].Load(pChr, Team); ContainsInvalidPlayer |= !m_pSavedTees[i].Load(pChr, Team);
} }
} }
@ -603,6 +620,8 @@ void CSaveTeam::Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakSt
} }
// remove projectiles and laser // remove projectiles and laser
pGameServer->m_World.RemoveEntitiesFromPlayers(aPlayerCids, m_MembersCount); pGameServer->m_World.RemoveEntitiesFromPlayers(aPlayerCids, m_MembersCount);
return !ContainsInvalidPlayer;
} }
CCharacter *CSaveTeam::MatchCharacter(CGameContext *pGameServer, int ClientId, int SaveId, bool KeepCurrentCharacter) const CCharacter *CSaveTeam::MatchCharacter(CGameContext *pGameServer, int ClientId, int SaveId, bool KeepCurrentCharacter) const

View file

@ -25,7 +25,7 @@ public:
CSaveTee(); CSaveTee();
~CSaveTee() = default; ~CSaveTee() = default;
void Save(CCharacter *pchr); void Save(CCharacter *pchr);
void Load(CCharacter *pchr, int Team, bool IsSwap = false); bool Load(CCharacter *pchr, int Team, bool IsSwap = false);
char *GetString(const CSaveTeam *pTeam); char *GetString(const CSaveTeam *pTeam);
int FromString(const char *pString); int FromString(const char *pString);
void LoadHookedPlayer(const CSaveTeam *pTeam); void LoadHookedPlayer(const CSaveTeam *pTeam);
@ -149,7 +149,7 @@ public:
// returns true if a team can load, otherwise writes a nice error Message in pMessage // returns true if a team can load, otherwise writes a nice error Message in pMessage
bool MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *pClientId, int NumPlayer, char *pMessage, int MessageLen) const; bool MatchPlayers(const char (*paNames)[MAX_NAME_LENGTH], const int *pClientId, int NumPlayer, char *pMessage, int MessageLen) const;
int Save(CGameContext *pGameServer, int Team, bool Dry = false); int Save(CGameContext *pGameServer, int Team, bool Dry = false);
void Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong); bool Load(CGameContext *pGameServer, int Team, bool KeepCurrentWeakStrong);
CSaveTee *m_pSavedTees = nullptr; CSaveTee *m_pSavedTees = nullptr;

View file

@ -1026,11 +1026,20 @@ void CGameTeams::ProcessSaveTeam()
m_apSaveTeamResult[Team]->m_SaveId, m_apSaveTeamResult[Team]->m_SaveId,
m_apSaveTeamResult[Team]->m_SavedTeam.GetString()); m_apSaveTeamResult[Team]->m_SavedTeam.GetString());
} }
bool TeamValid = false;
if(Count(Team) > 0) if(Count(Team) > 0)
{ {
// keep current weak/strong order as on some maps there is no other way of switching // keep current weak/strong order as on some maps there is no other way of switching
m_apSaveTeamResult[Team]->m_SavedTeam.Load(GameServer(), Team, true); TeamValid = m_apSaveTeamResult[Team]->m_SavedTeam.Load(GameServer(), Team, true);
} }
if(!TeamValid)
{
GameServer()->SendChatTeam(Team, "Your team has been killed because it contains an invalid tee state");
KillTeam(Team, -1, -1);
}
char aSaveId[UUID_MAXSTRSIZE]; char aSaveId[UUID_MAXSTRSIZE];
FormatUuid(m_apSaveTeamResult[Team]->m_SaveId, aSaveId, UUID_MAXSTRSIZE); FormatUuid(m_apSaveTeamResult[Team]->m_SaveId, aSaveId, UUID_MAXSTRSIZE);
dbg_msg("save", "Load successful: %s", aSaveId); dbg_msg("save", "Load successful: %s", aSaveId);