mirror of
https://github.com/OpenMW/openmw.git
synced 2025-06-25 04:11:33 +00:00
Merge branch 'fix_asan_error_on_save' into 'master'
Fix dangling pointer access on clicking save in the main menu (#7007) Closes #7007 See merge request OpenMW/openmw!2408
This commit is contained in:
commit
4d01489011
3 changed files with 21 additions and 18 deletions
|
@ -176,26 +176,28 @@ namespace MWGui
|
||||||
{
|
{
|
||||||
if (it->begin()!=it->end())
|
if (it->begin()!=it->end())
|
||||||
{
|
{
|
||||||
|
const ESM::SavedGame& signature = it->getSignature();
|
||||||
|
|
||||||
std::stringstream title;
|
std::stringstream title;
|
||||||
title << it->getSignature().mPlayerName;
|
title << signature.mPlayerName;
|
||||||
|
|
||||||
// For a custom class, we will not find it in the store (unless we loaded the savegame first).
|
// For a custom class, we will not find it in the store (unless we loaded the savegame first).
|
||||||
// Fall back to name stored in savegame header in that case.
|
// Fall back to name stored in savegame header in that case.
|
||||||
std::string_view className;
|
std::string_view className;
|
||||||
if (it->getSignature().mPlayerClassId.empty())
|
if (signature.mPlayerClassId.empty())
|
||||||
className = it->getSignature().mPlayerClassName;
|
className = signature.mPlayerClassName;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Find the localised name for this class from the store
|
// Find the localised name for this class from the store
|
||||||
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>().search(
|
const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get<ESM::Class>()
|
||||||
it->getSignature().mPlayerClassId);
|
.search(signature.mPlayerClassId);
|
||||||
if (class_)
|
if (class_)
|
||||||
className = class_->mName;
|
className = class_->mName;
|
||||||
else
|
else
|
||||||
className = "?"; // From an older savegame format that did not support custom classes properly.
|
className = "?"; // From an older savegame format that did not support custom classes properly.
|
||||||
}
|
}
|
||||||
|
|
||||||
title << " (#{sLevel} " << it->getSignature().mPlayerLevel << " " << MyGUI::TextIterator::toTagsString(toUString(className)) << ")";
|
title << " (#{sLevel} " << signature.mPlayerLevel << " " << MyGUI::TextIterator::toTagsString(toUString(className)) << ")";
|
||||||
|
|
||||||
mCharacterSelection->addItem (MyGUI::LanguageManager::getInstance().replaceTags(title.str()));
|
mCharacterSelection->addItem (MyGUI::LanguageManager::getInstance().replaceTags(title.str()));
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
#include <components/esm/defs.hpp>
|
#include <components/esm/defs.hpp>
|
||||||
#include <components/esm3/esmreader.hpp>
|
#include <components/esm3/esmreader.hpp>
|
||||||
|
@ -172,23 +174,22 @@ MWState::Character::SlotIterator MWState::Character::end() const
|
||||||
return mSlots.rend();
|
return mSlots.rend();
|
||||||
}
|
}
|
||||||
|
|
||||||
ESM::SavedGame MWState::Character::getSignature() const
|
const ESM::SavedGame& MWState::Character::getSignature() const
|
||||||
{
|
{
|
||||||
if (mSlots.empty())
|
if (mSlots.empty())
|
||||||
throw std::logic_error ("character signature not available");
|
throw std::logic_error ("character signature not available");
|
||||||
|
|
||||||
std::vector<Slot>::const_iterator iter (mSlots.begin());
|
const auto tiePlayerLevelAndTimeStamp = [] (const Slot& v)
|
||||||
|
{
|
||||||
|
return std::tie(v.mProfile.mPlayerLevel, v.mTimeStamp);
|
||||||
|
};
|
||||||
|
|
||||||
Slot slot = *iter;
|
const auto lessByPlayerLevelAndTimeStamp = [&] (const Slot& l, const Slot& r)
|
||||||
|
{
|
||||||
|
return tiePlayerLevelAndTimeStamp(l) < tiePlayerLevelAndTimeStamp(r);
|
||||||
|
};
|
||||||
|
|
||||||
for (++iter; iter!=mSlots.end(); ++iter)
|
return std::max_element(mSlots.begin(), mSlots.end(), lessByPlayerLevelAndTimeStamp)->mProfile;
|
||||||
if (iter->mProfile.mPlayerLevel>slot.mProfile.mPlayerLevel)
|
|
||||||
slot = *iter;
|
|
||||||
else if (iter->mProfile.mPlayerLevel==slot.mProfile.mPlayerLevel &&
|
|
||||||
iter->mTimeStamp>slot.mTimeStamp)
|
|
||||||
slot = *iter;
|
|
||||||
|
|
||||||
return slot.mProfile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::filesystem::path& MWState::Character::getPath() const
|
const std::filesystem::path& MWState::Character::getPath() const
|
||||||
|
|
|
@ -62,7 +62,7 @@ namespace MWState
|
||||||
|
|
||||||
const std::filesystem::path& getPath() const;
|
const std::filesystem::path& getPath() const;
|
||||||
|
|
||||||
ESM::SavedGame getSignature() const;
|
const ESM::SavedGame& getSignature() const;
|
||||||
///< Return signature information for this character.
|
///< Return signature information for this character.
|
||||||
///
|
///
|
||||||
/// \attention This function must not be called if there are no slots.
|
/// \attention This function must not be called if there are no slots.
|
||||||
|
|
Loading…
Reference in a new issue