Merge pull request #7747 from Robyt3/Map-UUID-Unknown-Handling

Propagate unknown UUID-based map items in map tools
This commit is contained in:
heinrich5991 2024-01-06 22:18:30 +00:00 committed by GitHub
commit 7aba25d3f7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 81 additions and 46 deletions

View file

@ -450,20 +450,27 @@ int CDataFileReader::GetItemSize(int Index) const
return m_pDataFile->m_Info.m_pItemOffsets[Index + 1] - m_pDataFile->m_Info.m_pItemOffsets[Index] - sizeof(CDatafileItem);
}
int CDataFileReader::GetExternalItemType(int InternalType)
int CDataFileReader::GetExternalItemType(int InternalType, CUuid *pUuid)
{
if(InternalType <= OFFSET_UUID_TYPE || InternalType == ITEMTYPE_EX)
{
if(pUuid)
*pUuid = UUID_ZEROED;
return InternalType;
}
int TypeIndex = FindItemIndex(ITEMTYPE_EX, InternalType);
if(TypeIndex < 0 || GetItemSize(TypeIndex) < (int)sizeof(CItemEx))
{
if(pUuid)
*pUuid = UUID_ZEROED;
return InternalType;
}
const CItemEx *pItemEx = (const CItemEx *)GetItem(TypeIndex);
CUuid Uuid = pItemEx->ToUuid();
if(pUuid)
*pUuid = Uuid;
// Propagate UUID_UNKNOWN, it doesn't hurt.
return g_UuidManager.LookupUuid(pItemEx->ToUuid());
return g_UuidManager.LookupUuid(Uuid);
}
int CDataFileReader::GetInternalItemType(int ExternalType)
@ -490,7 +497,7 @@ int CDataFileReader::GetInternalItemType(int ExternalType)
return -1;
}
void *CDataFileReader::GetItem(int Index, int *pType, int *pID)
void *CDataFileReader::GetItem(int Index, int *pType, int *pID, CUuid *pUuid)
{
if(!m_pDataFile)
{
@ -498,14 +505,18 @@ void *CDataFileReader::GetItem(int Index, int *pType, int *pID)
*pType = 0;
if(pID)
*pID = 0;
if(pUuid)
*pUuid = UUID_ZEROED;
return nullptr;
}
CDatafileItem *pItem = (CDatafileItem *)(m_pDataFile->m_Info.m_pItemStart + m_pDataFile->m_Info.m_pItemOffsets[Index]);
// remove sign extension
const int Type = GetExternalItemType((pItem->m_TypeAndID >> 16) & 0xffff, pUuid);
if(pType)
{
// remove sign extension
*pType = GetExternalItemType((pItem->m_TypeAndID >> 16) & 0xffff);
*pType = Type;
}
if(pID)
{
@ -643,35 +654,51 @@ int CDataFileWriter::GetTypeFromIndex(int Index) const
return ITEMTYPE_EX - Index - 1;
}
int CDataFileWriter::GetExtendedItemTypeIndex(int Type)
int CDataFileWriter::GetExtendedItemTypeIndex(int Type, const CUuid *pUuid)
{
int Index = 0;
for(int ExtendedItemType : m_vExtendedItemTypes)
if(Type == -1)
{
if(ExtendedItemType == Type)
return Index;
++Index;
// Unknown type, search for UUID
for(const auto &ExtendedItemType : m_vExtendedItemTypes)
{
if(ExtendedItemType.m_Uuid == *pUuid)
return Index;
++Index;
}
}
else
{
for(const auto &ExtendedItemType : m_vExtendedItemTypes)
{
if(ExtendedItemType.m_Type == Type)
return Index;
++Index;
}
}
// Type not found, add it.
m_vExtendedItemTypes.push_back(Type);
CExtendedItemType ExtendedType;
ExtendedType.m_Type = Type;
ExtendedType.m_Uuid = Type == -1 ? *pUuid : g_UuidManager.GetUuid(Type);
m_vExtendedItemTypes.push_back(ExtendedType);
CItemEx ExtendedType = CItemEx::FromUuid(g_UuidManager.GetUuid(Type));
AddItem(ITEMTYPE_EX, GetTypeFromIndex(Index), sizeof(ExtendedType), &ExtendedType);
CItemEx ItemEx = CItemEx::FromUuid(ExtendedType.m_Uuid);
AddItem(ITEMTYPE_EX, GetTypeFromIndex(Index), sizeof(ItemEx), &ItemEx);
return Index;
}
int CDataFileWriter::AddItem(int Type, int ID, size_t Size, const void *pData)
int CDataFileWriter::AddItem(int Type, int ID, size_t Size, const void *pData, const CUuid *pUuid)
{
dbg_assert((Type >= 0 && Type < MAX_ITEM_TYPES) || Type >= OFFSET_UUID, "Invalid type");
dbg_assert((Type >= 0 && Type < MAX_ITEM_TYPES) || Type >= OFFSET_UUID || (Type == -1 && pUuid != nullptr), "Invalid type");
dbg_assert(ID >= 0 && ID <= ITEMTYPE_EX, "Invalid ID");
dbg_assert(Size == 0 || pData != nullptr, "Data missing"); // Items without data are allowed
dbg_assert(Size <= (size_t)std::numeric_limits<int>::max(), "Data too large");
dbg_assert(Size % sizeof(int) == 0, "Invalid data boundary");
if(Type >= OFFSET_UUID)
if(Type == -1 || Type >= OFFSET_UUID)
{
Type = GetTypeFromIndex(GetExtendedItemTypeIndex(Type));
Type = GetTypeFromIndex(GetExtendedItemTypeIndex(Type, pUuid));
}
const int NumItems = m_vItems.size();

View file

@ -8,6 +8,8 @@
#include <base/hash.h>
#include <base/types.h>
#include "uuid_manager.h"
#include <array>
#include <vector>
@ -25,7 +27,7 @@ class CDataFileReader
void *GetDataImpl(int Index, bool Swap);
int GetFileDataSize(int Index) const;
int GetExternalItemType(int InternalType);
int GetExternalItemType(int InternalType, CUuid *pUuid);
int GetInternalItemType(int ExternalType);
public:
@ -54,7 +56,7 @@ public:
int NumData() const;
int GetItemSize(int Index) const;
void *GetItem(int Index, int *pType = nullptr, int *pID = nullptr);
void *GetItem(int Index, int *pType = nullptr, int *pID = nullptr, CUuid *pUuid = nullptr);
void GetType(int Type, int *pStart, int *pNum);
int FindItemIndex(int Type, int ID);
void *FindItem(int Type, int ID);
@ -94,6 +96,12 @@ class CDataFileWriter
int m_Last;
};
struct CExtendedItemType
{
int m_Type;
CUuid m_Uuid;
};
enum
{
MAX_ITEM_TYPES = 0x10000,
@ -103,10 +111,10 @@ class CDataFileWriter
std::array<CItemTypeInfo, MAX_ITEM_TYPES> m_aItemTypes;
std::vector<CItemInfo> m_vItems;
std::vector<CDataInfo> m_vDatas;
std::vector<int> m_vExtendedItemTypes;
std::vector<CExtendedItemType> m_vExtendedItemTypes;
int GetTypeFromIndex(int Index) const;
int GetExtendedItemTypeIndex(int Type);
int GetExtendedItemTypeIndex(int Type, const CUuid *pUuid);
public:
CDataFileWriter();
@ -122,7 +130,7 @@ public:
~CDataFileWriter();
bool Open(class IStorage *pStorage, const char *pFilename, int StorageType = IStorage::TYPE_SAVE);
int AddItem(int Type, int ID, size_t Size, const void *pData);
int AddItem(int Type, int ID, size_t Size, const void *pData, const CUuid *pUuid = nullptr);
int AddData(size_t Size, const void *pData, int CompressionLevel = Z_DEFAULT_COMPRESSION);
int AddDataSwapped(size_t Size, const void *pData);
int AddDataString(const char *pStr);

View file

@ -218,11 +218,11 @@ int main(int argc, const char **argv)
for(int Index = 0; Index < g_DataReader.NumItems(); Index++)
{
int Type, ID;
void *pItem = g_DataReader.GetItem(Index, &Type, &ID);
CUuid Uuid;
void *pItem = g_DataReader.GetItem(Index, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
@ -239,7 +239,7 @@ int main(int argc, const char **argv)
Size = sizeof(CMapItemImage);
NewImageItem.m_Version = CMapItemImage::CURRENT_VERSION;
}
g_DataWriter.AddItem(Type, ID, Size, pItem);
g_DataWriter.AddItem(Type, ID, Size, pItem, &Uuid);
}
// add all data

View file

@ -375,11 +375,11 @@ void SaveOutputMap(CDataFileReader &InputMap, CDataFileWriter &OutputMap, CMapIt
for(int i = 0; i < InputMap.NumItems(); i++)
{
int ID, Type;
void *pItem = InputMap.GetItem(i, &Type, &ID);
CUuid Uuid;
void *pItem = InputMap.GetItem(i, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
@ -388,7 +388,7 @@ void SaveOutputMap(CDataFileReader &InputMap, CDataFileWriter &OutputMap, CMapIt
pItem = pNewItem;
int Size = InputMap.GetItemSize(i);
OutputMap.AddItem(Type, ID, Size, pItem);
OutputMap.AddItem(Type, ID, Size, pItem, &Uuid);
}
for(int i = 0; i < InputMap.NumData(); i++)

View file

@ -139,11 +139,11 @@ int main(int argc, const char **argv)
for(int Index = 0, i = 0; Index < Reader.NumItems(); Index++)
{
int Type, ID;
void *pPtr = Reader.GetItem(Index, &Type, &ID);
CUuid Uuid;
void *pPtr = Reader.GetItem(Index, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
@ -205,7 +205,7 @@ int main(int argc, const char **argv)
}
int Size = Reader.GetItemSize(Index);
Writer.AddItem(Type, ID, Size, pPtr);
Writer.AddItem(Type, ID, Size, pPtr, &Uuid);
}
// add all data

View file

@ -166,11 +166,11 @@ void SaveOutputMap(CDataFileReader &InputMap, CDataFileWriter &OutputMap)
for(int i = 0; i < InputMap.NumItems(); i++)
{
int ID, Type;
void *pItem = InputMap.GetItem(i, &Type, &ID);
CUuid Uuid;
void *pItem = InputMap.GetItem(i, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
@ -179,7 +179,7 @@ void SaveOutputMap(CDataFileReader &InputMap, CDataFileWriter &OutputMap)
pItem = g_apNewItem[i];
int Size = InputMap.GetItemSize(i);
OutputMap.AddItem(Type, ID, Size, pItem);
OutputMap.AddItem(Type, ID, Size, pItem, &Uuid);
}
for(int i = 0; i < InputMap.NumData(); i++)

View file

@ -148,11 +148,11 @@ int main(int argc, const char **argv)
for(int Index = 0; Index < g_DataReader.NumItems(); Index++)
{
int Type, ID;
void *pItem = g_DataReader.GetItem(Index, &Type, &ID);
CUuid Uuid;
void *pItem = g_DataReader.GetItem(Index, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
@ -169,7 +169,7 @@ int main(int argc, const char **argv)
NewImageItem.m_Version = CMapItemImage::CURRENT_VERSION;
}
Writer.AddItem(Type, ID, Size, pItem);
Writer.AddItem(Type, ID, Size, pItem, &Uuid);
}
if(g_NewDataID == -1)

View file

@ -30,17 +30,17 @@ static int ResaveMap(const char *pSourceMap, const char *pDestinationMap, IStora
for(int Index = 0; Index < Reader.NumItems(); Index++)
{
int Type, ID;
const void *pPtr = Reader.GetItem(Index, &Type, &ID);
CUuid Uuid;
const void *pPtr = Reader.GetItem(Index, &Type, &ID, &Uuid);
// Filter items with unknown type, as we can't write them back.
// Filter ITEMTYPE_EX items, they will be automatically added again.
if(Type < 0 || Type == ITEMTYPE_EX)
if(Type == ITEMTYPE_EX)
{
continue;
}
int Size = Reader.GetItemSize(Index);
Writer.AddItem(Type, ID, Size, pPtr);
Writer.AddItem(Type, ID, Size, pPtr, &Uuid);
}
// add all data