1
0
forked from 0ad/0ad

Fix bug where 'archive' XMB files could end up being written to the user mod

Users sometimes ended up with bad (wrong version) XMB files in the user
mod. This resulted in A25 loading a black screen.
There is a combination of unfortunate code paths that lead to this. The
core issue is that:
- cdd75deafb changed the XMB loading code that if there is an error in
Init from a cached XMB, it reports an error. This error happens to be
silent, because the GUI expects CXeromyces to do its own error reporting
(a pretty poor decision, all in all, but whatever). This explained why
the black screen showed no errors.
- The code flow attemps to load an 'archive' XMB first, then only a
loose cache. _But_ if the XMB that fails to load is an archive (which
generally never happens except when using incompatible mods, which is
generally less easy in A25 since we added code to stop that), then the
game will try to recreate the XMB as an 'archived' path, not a 'loose
cache' path as it would usually do.
- Because the 'archived' path already exists in the VFS, the game will
attempt to overwrite that. It so happens that in non-dev copies, this
writes to the user mod.
- Because the user-mod is always loaded, this was unexpected for users.

Fixing this is rather simple: the game should never attempt to write
'archive' XMBs in that function. Added explicit barrier, which shouldn't
matter performance-wise but fixes the issue by writing in the proper
place, and also properly recovering in case of read failure.
I will note that the game will still try to load the archived file, and
recreate it every time, but I don't think that's a particularly big
deal, in general having engine-incompatible mods in the future should be
harder because of A25 changes there.
(NB: users that have used both A24 and A25 should perhaps still be
advised to check their user mod folder, otherwise they'll end up
recreating those files forever).

Reported by: dave_k
Fixes #6320

Differential Revision: https://code.wildfiregames.com/D4275
This was SVN commit r26272.
This commit is contained in:
wraitii 2022-01-30 12:50:43 +00:00
parent e0d98cd94d
commit d740b4f335
2 changed files with 5 additions and 6 deletions

View File

@ -535,6 +535,7 @@ void CGUI::LoadXmlFile(const VfsPath& Filename, std::unordered_set<VfsPath>& Pat
CXeromyces xeroFile;
if (xeroFile.Load(g_VFS, Filename, "gui") != PSRETURN_OK)
// The error has already been reported by CXeromyces
return;
XMBElement node = xeroFile.GetRoot();

View File

@ -126,14 +126,12 @@ PSRETURN CXeromyces::Load(const PIVFS& vfs, const VfsPath& filename, const std::
if (ret == INFO::OK)
{
// Found a cached XMB - load it
if (m_Data.ReadFromFile(vfs, xmbPath))
{
if(!Initialise(m_Data))
return PSRETURN_Xeromyces_XMLParseError;
if (m_Data.ReadFromFile(vfs, xmbPath) && Initialise(m_Data))
return PSRETURN_OK;
}
// If this fails then we'll continue and (re)create the loose cache -
// this failure legitimately happens due to partially-written XMB files.
// this failure legitimately happens due to partially-written XMB files or XMB version upgrades.
// NB: at this point xmbPath may point to an archived file, we want to write a loose cached version.
xmbPath = cacheLoader.LooseCachePath(filename, validatorGrammarHash, XMBStorage::XMBVersion);
}
else if (ret == INFO::SKIPPED)
{