1
0
Fork 1
mirror of https://github.com/TES3MP/openmw-tes3mp.git synced 2025-04-02 02:06:42 +00:00

Use descriptive names for save files and character folders (Fixes #1449)

This commit is contained in:
scrawl 2014-06-10 00:22:00 +02:00
parent e796fa2313
commit 7721e54191
5 changed files with 58 additions and 31 deletions

View file

@ -54,9 +54,28 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
Slot slot; Slot slot;
std::ostringstream stream; std::ostringstream stream;
stream << mNext++;
// The profile description is user-supplied, so we need to escape the path
for (std::string::const_iterator it = profile.mDescription.begin(); it != profile.mDescription.end(); ++it)
{
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
stream << *it;
else
stream << "_";
}
slot.mPath = mPath / stream.str(); slot.mPath = mPath / stream.str();
// Append an index if necessary to ensure a unique file
int i=0;
while (boost::filesystem::exists(slot.mPath))
{
std::ostringstream test;
test << stream.str();
test << " - " << ++i;
slot.mPath = mPath / test.str();
}
slot.mProfile = profile; slot.mProfile = profile;
slot.mTimeStamp = std::time (0); slot.mTimeStamp = std::time (0);
@ -64,7 +83,7 @@ void MWState::Character::addSlot (const ESM::SavedGame& profile)
} }
MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game) MWState::Character::Character (const boost::filesystem::path& saves, const std::string& game)
: mPath (saves), mNext (0) : mPath (saves)
{ {
if (!boost::filesystem::is_directory (mPath)) if (!boost::filesystem::is_directory (mPath))
{ {
@ -82,13 +101,6 @@ MWState::Character::Character (const boost::filesystem::path& saves, const std::
addSlot (slotPath, game); addSlot (slotPath, game);
} }
catch (...) {} // ignoring bad saved game files for now catch (...) {} // ignoring bad saved game files for now
std::istringstream stream (slotPath.filename().string());
int index = 0;
if ((stream >> index) && index>=mNext)
mNext = index+1;
} }
std::sort (mSlots.begin(), mSlots.end()); std::sort (mSlots.begin(), mSlots.end());

View file

@ -26,7 +26,6 @@ namespace MWState
boost::filesystem::path mPath; boost::filesystem::path mPath;
std::vector<Slot> mSlots; std::vector<Slot> mSlots;
int mNext;
void addSlot (const boost::filesystem::path& path, const std::string& game); void addSlot (const boost::filesystem::path& path, const std::string& game);

View file

@ -8,7 +8,7 @@
MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves, MWState::CharacterManager::CharacterManager (const boost::filesystem::path& saves,
const std::string& game) const std::string& game)
: mPath (saves), mNext (0), mCurrent (0), mGame (game) : mPath (saves), mCurrent (0), mGame (game)
{ {
if (!boost::filesystem::is_directory (mPath)) if (!boost::filesystem::is_directory (mPath))
{ {
@ -28,21 +28,14 @@ MWState::CharacterManager::CharacterManager (const boost::filesystem::path& save
if (character.begin()!=character.end()) if (character.begin()!=character.end())
mCharacters.push_back (character); mCharacters.push_back (character);
} }
std::istringstream stream (characterDir.filename().string());
int index = 0;
if ((stream >> index) && index>=mNext)
mNext = index+1;
} }
} }
} }
MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create) MWState::Character *MWState::CharacterManager::getCurrentCharacter (bool create, const std::string& name)
{ {
if (!mCurrent && create) if (!mCurrent && create)
createCharacter(); createCharacter(name);
return mCurrent; return mCurrent;
} }
@ -63,13 +56,31 @@ void MWState::CharacterManager::deleteSlot(const MWState::Character *character,
} }
} }
void MWState::CharacterManager::createCharacter() void MWState::CharacterManager::createCharacter(const std::string& name)
{ {
std::ostringstream stream; std::ostringstream stream;
stream << mNext++;
// The character name is user-supplied, so we need to escape the path
for (std::string::const_iterator it = name.begin(); it != name.end(); ++it)
{
if (std::isalnum(*it)) // Ignores multibyte characters and non alphanumeric characters
stream << *it;
else
stream << "_";
}
boost::filesystem::path path = mPath / stream.str(); boost::filesystem::path path = mPath / stream.str();
// Append an index if necessary to ensure a unique directory
int i=0;
while (boost::filesystem::exists(path))
{
std::ostringstream test;
test << stream.str();
test << " - " << ++i;
path = mPath / test.str();
}
mCharacters.push_back (Character (path, mGame)); mCharacters.push_back (Character (path, mGame));
mCurrent = &mCharacters.back(); mCurrent = &mCharacters.back();

View file

@ -10,7 +10,6 @@ namespace MWState
class CharacterManager class CharacterManager
{ {
boost::filesystem::path mPath; boost::filesystem::path mPath;
int mNext;
// Uses std::list, so that mCurrent stays valid when characters are deleted // Uses std::list, so that mCurrent stays valid when characters are deleted
std::list<Character> mCharacters; std::list<Character> mCharacters;
@ -32,13 +31,15 @@ namespace MWState
CharacterManager (const boost::filesystem::path& saves, const std::string& game); CharacterManager (const boost::filesystem::path& saves, const std::string& game);
Character *getCurrentCharacter (bool create = true); Character *getCurrentCharacter (bool create, const std::string& name);
///< \param create Create a new character, if there is no current character. ///< \param create Create a new character, if there is no current character.
/// \param name The character name to use in case a new character is created.
void deleteSlot(const MWState::Character *character, const MWState::Slot *slot); void deleteSlot(const MWState::Character *character, const MWState::Slot *slot);
void createCharacter(); void createCharacter(const std::string& name);
///< Create new character within saved game management ///< Create new character within saved game management
/// \param name Name for the character (does not need to be unique)
void setCurrentCharacter (const Character *character); void setCurrentCharacter (const Character *character);

View file

@ -184,9 +184,9 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
encoded->read(&profile.mScreenshot[0], encoded->size()); encoded->read(&profile.mScreenshot[0], encoded->size());
if (!slot) if (!slot)
slot = mCharacterManager.getCurrentCharacter()->createSlot (profile); slot = getCurrentCharacter()->createSlot (profile);
else else
slot = mCharacterManager.getCurrentCharacter()->updateSlot (slot, profile); slot = getCurrentCharacter()->updateSlot (slot, profile);
boost::filesystem::ofstream stream (slot->mPath, std::ios::binary); boost::filesystem::ofstream stream (slot->mPath, std::ios::binary);
@ -252,7 +252,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot
// If no file was written, clean up the slot // If no file was written, clean up the slot
if (slot && !boost::filesystem::exists(slot->mPath)) if (slot && !boost::filesystem::exists(slot->mPath))
mCharacterManager.getCurrentCharacter()->deleteSlot(slot); getCurrentCharacter()->deleteSlot(slot);
} }
} }
@ -419,7 +419,10 @@ void MWState::StateManager::deleteGame(const MWState::Character *character, cons
MWState::Character *MWState::StateManager::getCurrentCharacter (bool create) MWState::Character *MWState::StateManager::getCurrentCharacter (bool create)
{ {
return mCharacterManager.getCurrentCharacter (create); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr();
std::string name = player.getClass().getName(player);
return mCharacterManager.getCurrentCharacter (create, name);
} }
MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin() MWState::StateManager::CharacterIterator MWState::StateManager::characterBegin()
@ -440,11 +443,12 @@ void MWState::StateManager::update (float duration)
if (mAskLoadRecent) if (mAskLoadRecent)
{ {
int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton(); int iButton = MWBase::Environment::get().getWindowManager()->readPressedButton();
if(iButton==0) MWState::Character *curCharacter = getCurrentCharacter(false);
if(iButton==0 && curCharacter)
{ {
mAskLoadRecent = false; mAskLoadRecent = false;
//Load last saved game for current character //Load last saved game for current character
MWState::Character *curCharacter = getCurrentCharacter();
MWState::Slot lastSave = *curCharacter->begin(); MWState::Slot lastSave = *curCharacter->begin();
loadGame(curCharacter, &lastSave); loadGame(curCharacter, &lastSave);
} }