Split asset name map into separate 32-bit and 64-bit files (necessary to avoid name conflict errors)
This commit is contained in:
parent
9d6798b7ae
commit
336744ed49
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<AssetNameMap ArchiveVer="0" FileVer="0">
|
<AssetNameMap ArchiveVer="0" FileVer="0" Game="MPRM">
|
||||||
<AssetNameMap>
|
<AssetNameMap>
|
||||||
<Asset>
|
<Asset>
|
||||||
<Key>00027340</Key>
|
<Key>00027340</Key>
|
File diff suppressed because it is too large
Load Diff
|
@ -51,6 +51,7 @@ public:
|
||||||
static CAssetID FromString(const TString& rkString);
|
static CAssetID FromString(const TString& rkString);
|
||||||
static CAssetID RandomID();
|
static CAssetID RandomID();
|
||||||
|
|
||||||
|
inline static EIDLength GameIDLength(EGame Game) { return (Game == eUnknownGame ? eInvalidIDLength : (Game <= eEchoes ? e32Bit : e64Bit)); }
|
||||||
inline static CAssetID InvalidID(EIDLength IDLength) { return (IDLength == e32Bit ? skInvalidID32 : skInvalidID64); }
|
inline static CAssetID InvalidID(EIDLength IDLength) { return (IDLength == e32Bit ? skInvalidID32 : skInvalidID64); }
|
||||||
inline static CAssetID InvalidID(EGame Game) { return InvalidID(Game <= eEchoes ? e32Bit : e64Bit); }
|
inline static CAssetID InvalidID(EGame Game) { return InvalidID(Game <= eEchoes ? e32Bit : e64Bit); }
|
||||||
|
|
||||||
|
|
|
@ -1,20 +1,43 @@
|
||||||
#include "CAssetNameMap.h"
|
#include "CAssetNameMap.h"
|
||||||
|
|
||||||
bool CAssetNameMap::LoadAssetNames(TString Path /*= gkAssetMapPath*/)
|
bool CAssetNameMap::LoadAssetNames(TString Path /*= ""*/)
|
||||||
{
|
{
|
||||||
|
if (Path.IsEmpty())
|
||||||
|
Path = DefaultNameMapPath(mIDLength);
|
||||||
|
|
||||||
CXMLReader Reader(Path);
|
CXMLReader Reader(Path);
|
||||||
|
|
||||||
if (Reader.IsValid())
|
if (Reader.IsValid())
|
||||||
|
{
|
||||||
|
CAssetID FileIDLength = CAssetID::GameIDLength(Reader.Game());
|
||||||
|
|
||||||
|
if (FileIDLength == mIDLength)
|
||||||
{
|
{
|
||||||
Serialize(Reader);
|
Serialize(Reader);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
else
|
||||||
|
{
|
||||||
|
TString ExpectedIDLength = (mIDLength == e32Bit ? "32-bit" : "64-bit");
|
||||||
|
TString GotIDLength = (FileIDLength == e32Bit ? "32-bit" : "64-bit");
|
||||||
|
Log::Error("Failed to load asset names; expected " + ExpectedIDLength + " IDs, got " + GotIDLength);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log::Error("Failed to load asset names; couldn't open XML.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CAssetNameMap::SaveAssetNames(TString Path /*= gkAssetMapPath*/)
|
bool CAssetNameMap::SaveAssetNames(TString Path /*= ""*/)
|
||||||
{
|
{
|
||||||
CXMLWriter Writer(Path, "AssetNameMap", 0, eUnknownGame);
|
if (Path.IsEmpty())
|
||||||
|
Path = DefaultNameMapPath(mIDLength);
|
||||||
|
|
||||||
|
EGame Game = (mIDLength == e32Bit ? ePrime : eCorruption);
|
||||||
|
CXMLWriter Writer(Path, "AssetNameMap", 0, Game);
|
||||||
Serialize(Writer);
|
Serialize(Writer);
|
||||||
return Writer.Save();
|
return Writer.Save();
|
||||||
}
|
}
|
||||||
|
@ -42,6 +65,8 @@ bool CAssetNameMap::GetNameInfo(CAssetID ID, TString& rOutDirectory, TString& rO
|
||||||
void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
||||||
{
|
{
|
||||||
// Do a first pass to remove old paths from used set to prevent false positives from eg. if two resources switch places
|
// Do a first pass to remove old paths from used set to prevent false positives from eg. if two resources switch places
|
||||||
|
ASSERT( CAssetID::GameIDLength(pStore->Game()) == mIDLength );
|
||||||
|
|
||||||
for (CResourceIterator It(pStore); It; ++It)
|
for (CResourceIterator It(pStore); It; ++It)
|
||||||
{
|
{
|
||||||
if (It->IsCategorized() || It->IsNamed())
|
if (It->IsCategorized() || It->IsNamed())
|
||||||
|
@ -64,6 +89,8 @@ void CAssetNameMap::CopyFromStore(CResourceStore *pStore /*= gpResourceStore*/)
|
||||||
if (It->IsCategorized() || It->IsNamed())
|
if (It->IsCategorized() || It->IsNamed())
|
||||||
{
|
{
|
||||||
CAssetID ID = It->ID();
|
CAssetID ID = It->ID();
|
||||||
|
ASSERT(ID.Length() == mIDLength);
|
||||||
|
|
||||||
TWideString Name = It->Name();
|
TWideString Name = It->Name();
|
||||||
TWideString Directory = It->Directory()->FullPath();
|
TWideString Directory = It->Directory()->FullPath();
|
||||||
CFourCC Type = It->CookedExtension();
|
CFourCC Type = It->CookedExtension();
|
||||||
|
@ -107,7 +134,8 @@ void CAssetNameMap::Serialize(IArchive& rArc)
|
||||||
|
|
||||||
void CAssetNameMap::PostLoadValidate()
|
void CAssetNameMap::PostLoadValidate()
|
||||||
{
|
{
|
||||||
// Make sure the newly loaded map doesn't contain any name conflicts.
|
// Make sure the newly loaded map doesn't contain any errors or name conflicts.
|
||||||
|
bool FoundErrors = false;
|
||||||
mIsValid = false;
|
mIsValid = false;
|
||||||
std::set<SAssetNameInfo> Dupes;
|
std::set<SAssetNameInfo> Dupes;
|
||||||
|
|
||||||
|
@ -117,8 +145,27 @@ void CAssetNameMap::PostLoadValidate()
|
||||||
|
|
||||||
if (mUsedSet.find(rkInfo) != mUsedSet.end())
|
if (mUsedSet.find(rkInfo) != mUsedSet.end())
|
||||||
Dupes.insert(rkInfo);
|
Dupes.insert(rkInfo);
|
||||||
|
|
||||||
else
|
else
|
||||||
|
{
|
||||||
mUsedSet.insert(rkInfo);
|
mUsedSet.insert(rkInfo);
|
||||||
|
|
||||||
|
// Verify the name/path is valid
|
||||||
|
if (!CResourceStore::IsValidResourcePath(rkInfo.Directory, rkInfo.Name))
|
||||||
|
{
|
||||||
|
Log::Error("Invalid resource path in asset name map: " + rkInfo.Directory.ToUTF8() + rkInfo.Name.ToUTF8() + "." + rkInfo.Type.ToString());
|
||||||
|
Iter = mMap.erase(Iter);
|
||||||
|
FoundErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify correct ID length
|
||||||
|
if (Iter->first.Length() != mIDLength)
|
||||||
|
{
|
||||||
|
Log::Error("Incorrect asset ID length in asset name map: " + Iter->first.ToString());
|
||||||
|
Iter = mMap.erase(Iter);
|
||||||
|
FoundErrors = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we detected any dupes, then this map can't be used
|
// If we detected any dupes, then this map can't be used
|
||||||
|
@ -136,5 +183,17 @@ void CAssetNameMap::PostLoadValidate()
|
||||||
mMap.clear();
|
mMap.clear();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
mIsValid = true;
|
mIsValid = !FoundErrors;
|
||||||
|
}
|
||||||
|
|
||||||
|
TString CAssetNameMap::DefaultNameMapPath(EIDLength IDLength)
|
||||||
|
{
|
||||||
|
ASSERT(IDLength != eInvalidIDLength);
|
||||||
|
TString Suffix = (IDLength == e32Bit ? "32" : "64");
|
||||||
|
return gkAssetMapPath + Suffix + "." + gkAssetMapExt;
|
||||||
|
}
|
||||||
|
|
||||||
|
TString CAssetNameMap::DefaultNameMapPath(EGame Game)
|
||||||
|
{
|
||||||
|
return DefaultNameMapPath( CAssetID::GameIDLength(Game) );
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
const TString gkAssetMapPath = "..\\resources\\gameinfo\\AssetNameMap.xml";
|
const TString gkAssetMapPath = "..\\resources\\gameinfo\\AssetNameMap";
|
||||||
const TString gkAssetMapExt = "xml";
|
const TString gkAssetMapExt = "xml";
|
||||||
|
|
||||||
class CAssetNameMap
|
class CAssetNameMap
|
||||||
|
@ -43,20 +43,24 @@ class CAssetNameMap
|
||||||
std::set<SAssetNameInfo> mUsedSet; // Used to prevent name conflicts
|
std::set<SAssetNameInfo> mUsedSet; // Used to prevent name conflicts
|
||||||
std::map<CAssetID, SAssetNameInfo> mMap;
|
std::map<CAssetID, SAssetNameInfo> mMap;
|
||||||
bool mIsValid;
|
bool mIsValid;
|
||||||
|
EIDLength mIDLength;
|
||||||
|
|
||||||
// Private Methods
|
// Private Methods
|
||||||
void Serialize(IArchive& rArc);
|
void Serialize(IArchive& rArc);
|
||||||
void PostLoadValidate();
|
void PostLoadValidate();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CAssetNameMap() : mIsValid(true) {}
|
CAssetNameMap(EIDLength IDLength) : mIsValid(true), mIDLength(IDLength) { ASSERT(mIDLength != eInvalidIDLength); }
|
||||||
bool LoadAssetNames(TString Path = gkAssetMapPath);
|
CAssetNameMap(EGame Game) : mIsValid(true), mIDLength( CAssetID::GameIDLength(Game) ) { ASSERT(mIDLength != eInvalidIDLength); }
|
||||||
bool SaveAssetNames(TString Path = gkAssetMapPath);
|
bool LoadAssetNames(TString Path = "");
|
||||||
|
bool SaveAssetNames(TString Path = "");
|
||||||
bool GetNameInfo(CAssetID ID, TString& rOutDirectory, TString& rOutName);
|
bool GetNameInfo(CAssetID ID, TString& rOutDirectory, TString& rOutName);
|
||||||
void CopyFromStore(CResourceStore *pStore);
|
void CopyFromStore(CResourceStore *pStore);
|
||||||
|
|
||||||
|
static TString DefaultNameMapPath(EIDLength IDLength);
|
||||||
|
static TString DefaultNameMapPath(EGame Game);
|
||||||
|
|
||||||
inline bool IsValid() const { return mIsValid; }
|
inline bool IsValid() const { return mIsValid; }
|
||||||
inline static TString DefaultNameMapPath() { return gkAssetMapPath; }
|
|
||||||
inline static TString GetExtension() { return gkAssetMapExt; }
|
inline static TString GetExtension() { return gkAssetMapExt; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -624,6 +624,7 @@ void CResourceStore::ImportNamesFromPakContentsTxt(const TString& rkTxtPath, boo
|
||||||
// Read file contents -first- then move assets -after-; this
|
// Read file contents -first- then move assets -after-; this
|
||||||
// 1. avoids anything fucking up if the contents file is badly formatted and we crash, and
|
// 1. avoids anything fucking up if the contents file is badly formatted and we crash, and
|
||||||
// 2. avoids extra redundant moves (since there are redundant entries in the file)
|
// 2. avoids extra redundant moves (since there are redundant entries in the file)
|
||||||
|
// todo: move to CAssetNameMap?
|
||||||
std::map<CResourceEntry*, TString> PathMap;
|
std::map<CResourceEntry*, TString> PathMap;
|
||||||
FILE *pContentsFile;
|
FILE *pContentsFile;
|
||||||
fopen_s(&pContentsFile, *rkTxtPath, "r");
|
fopen_s(&pContentsFile, *rkTxtPath, "r");
|
||||||
|
|
|
@ -66,7 +66,7 @@ void CExportGameDialog::InitUI(QString ExportDir)
|
||||||
|
|
||||||
ExportDir.replace('/', '\\');
|
ExportDir.replace('/', '\\');
|
||||||
|
|
||||||
TWideString DefaultNameMapPath = CAssetNameMap::DefaultNameMapPath();
|
TWideString DefaultNameMapPath = CAssetNameMap::DefaultNameMapPath(mGame);
|
||||||
if (!FileUtil::Exists(DefaultNameMapPath)) DefaultNameMapPath = L"";
|
if (!FileUtil::Exists(DefaultNameMapPath)) DefaultNameMapPath = L"";
|
||||||
|
|
||||||
TWideString DefaultGameInfoPath = CGameInfo::GetDefaultGameInfoPath(mGame);
|
TWideString DefaultGameInfoPath = CGameInfo::GetDefaultGameInfoPath(mGame);
|
||||||
|
@ -339,7 +339,7 @@ void CExportGameDialog::Export()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
CAssetNameMap NameMap;
|
CAssetNameMap NameMap(mGame);
|
||||||
|
|
||||||
if (!NameMapPath.isEmpty())
|
if (!NameMapPath.isEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
@ -334,7 +334,7 @@ void CResourceBrowser::OnGenerateAssetNames()
|
||||||
|
|
||||||
void CResourceBrowser::OnImportNamesFromAssetNameMap()
|
void CResourceBrowser::OnImportNamesFromAssetNameMap()
|
||||||
{
|
{
|
||||||
CAssetNameMap Map;
|
CAssetNameMap Map( mpStore->Game() );
|
||||||
bool LoadSuccess = Map.LoadAssetNames();
|
bool LoadSuccess = Map.LoadAssetNames();
|
||||||
|
|
||||||
if (!LoadSuccess)
|
if (!LoadSuccess)
|
||||||
|
@ -370,21 +370,15 @@ void CResourceBrowser::ExportAssetNames()
|
||||||
if (OutFile.isEmpty()) return;
|
if (OutFile.isEmpty()) return;
|
||||||
TString OutFileStr = TO_TSTRING(OutFile);
|
TString OutFileStr = TO_TSTRING(OutFile);
|
||||||
|
|
||||||
CAssetNameMap NameMap;
|
CAssetNameMap NameMap(mpStore->Game());
|
||||||
|
|
||||||
if (FileUtil::Exists(OutFileStr))
|
if (FileUtil::Exists(OutFileStr))
|
||||||
{
|
{
|
||||||
bool LoadSuccess = NameMap.LoadAssetNames(OutFileStr);
|
bool LoadSuccess = NameMap.LoadAssetNames(OutFileStr);
|
||||||
|
|
||||||
if (!LoadSuccess)
|
if (!LoadSuccess || !NameMap.IsValid())
|
||||||
{
|
{
|
||||||
UICommon::ErrorMsg(this, "Unable to export; failed to load existing names from the original asset name map file!");
|
UICommon::ErrorMsg(this, "Unable to export; failed to load existing names from the original asset name map file! See the log for details.");
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
else if (!NameMap.IsValid())
|
|
||||||
{
|
|
||||||
UICommon::ErrorMsg(this, "Unable to export; the original asset name map file is invalid! See the log for details.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +386,7 @@ void CResourceBrowser::ExportAssetNames()
|
||||||
NameMap.CopyFromStore(mpStore);
|
NameMap.CopyFromStore(mpStore);
|
||||||
bool SaveSuccess = NameMap.SaveAssetNames(OutFileStr);
|
bool SaveSuccess = NameMap.SaveAssetNames(OutFileStr);
|
||||||
|
|
||||||
if (SaveSuccess)
|
if (!SaveSuccess)
|
||||||
UICommon::ErrorMsg(this, "Failed to export asset names!");
|
UICommon::ErrorMsg(this, "Failed to export asset names!");
|
||||||
else
|
else
|
||||||
UICommon::InfoMsg(this, "Success", "Asset names exported successfully!");
|
UICommon::InfoMsg(this, "Success", "Asset names exported successfully!");
|
||||||
|
|
Loading…
Reference in New Issue