Skip to content

Commit

Permalink
Add resource path validation
Browse files Browse the repository at this point in the history
  • Loading branch information
psiberx committed Aug 4, 2023
1 parent c51ca7a commit 07e64ac
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 11 deletions.
60 changes: 53 additions & 7 deletions src/App/Tweaks/Batch/TweakChangelog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,21 +84,62 @@ void App::TweakChangelog::ForgetForeignKeys()
m_foreignKeys.clear();
}

void App::TweakChangelog::CheckForIssues(const Core::SharedPtr<Red::TweakDBManager>& aManager)
void App::TweakChangelog::RegisterResourcePath(Red::ResourcePath aPath, Red::TweakDBID aFlatId)
{
if (aPath)
{
m_resourcePaths[aPath] = aFlatId;
}
}

void App::TweakChangelog::ForgetResourcePath(Red::ResourcePath aPath)
{
if (aPath)
{
m_resourcePaths.erase(aPath);
}
}

void App::TweakChangelog::ForgetResourcePaths()
{
Core::Set<Red::TweakDBID> brokenRefIds;
m_resourcePaths.clear();
}

for (const auto& [foreignKey, flatId] : m_foreignKeys)
void App::TweakChangelog::CheckForIssues(const Core::SharedPtr<Red::TweakDBManager>& aManager)
{
{
if (!aManager->IsRecordExists(foreignKey) && !aManager->IsFlatExists(foreignKey))
Core::Set<Red::TweakDBID> brokenRefIds;

for (const auto& [foreignKey, flatId] : m_foreignKeys)
{
brokenRefIds.insert(flatId);
if (!aManager->IsRecordExists(foreignKey) && !aManager->IsFlatExists(foreignKey))
{
brokenRefIds.insert(flatId);
}
}

for (const auto& flatId : brokenRefIds)
{
LogWarning("{} refers to a non-existent record or flat.", aManager->GetName(flatId));
}
}

for (const auto& flatId : brokenRefIds)
{
LogWarning("{} refers to a non-existent record or flat.", aManager->GetName(flatId));
Core::Set<Red::TweakDBID> brokenRefIds;

auto depot = Red::ResourceDepot::Get();
for (const auto& [resourcePath, flatId] : m_resourcePaths)
{
if (!depot->ResourceExists(resourcePath))
{
brokenRefIds.insert(flatId);
}
}

for (const auto& flatId : brokenRefIds)
{
LogWarning("{} refers to a non-existent resource.", aManager->GetName(flatId));
}
}
}

Expand Down Expand Up @@ -228,3 +269,8 @@ void App::TweakChangelog::RevertChanges(const Core::SharedPtr<Red::TweakDBManage
m_assignments.clear();
m_mutations.clear();
}

const Core::Set<Red::TweakDBID>& App::TweakChangelog::GetAffectedRecords() const
{
return m_records;
}
7 changes: 7 additions & 0 deletions src/App/Tweaks/Batch/TweakChangelog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,15 @@ class TweakChangelog : public Core::LoggingAgent
void ForgetForeignKey(Red::TweakDBID aForeignKey);
void ForgetForeignKeys();

void RegisterResourcePath(Red::ResourcePath aPath, Red::TweakDBID aFlatId);
void ForgetResourcePath(Red::ResourcePath aPath);
void ForgetResourcePaths();

void CheckForIssues(const Core::SharedPtr<Red::TweakDBManager>& aManager);
void RevertChanges(const Core::SharedPtr<Red::TweakDBManager>& aManager);

[[nodiscard]] const Core::Set<Red::TweakDBID>& GetAffectedRecords() const;

private:
struct AssignmentEntry
{
Expand All @@ -39,6 +45,7 @@ class TweakChangelog : public Core::LoggingAgent
Core::Map<Red::TweakDBID, AssignmentEntry> m_assignments;
Core::Map<Red::TweakDBID, MutationEntry> m_mutations;
Core::Map<Red::TweakDBID, Red::TweakDBID> m_foreignKeys;
Core::Map<Red::ResourcePath, Red::TweakDBID> m_resourcePaths;
Core::Set<Red::TweakDBID> m_ownedKeys;
};
}
19 changes: 19 additions & 0 deletions src/App/Tweaks/Batch/TweakChangeset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ void App::TweakChangeset::Commit(const Core::SharedPtr<Red::TweakDBManager>& aMa
{
aChangelog->RevertChanges(aManager);
aChangelog->ForgetForeignKeys();
aChangelog->ForgetResourcePaths();
}

for (const auto& [id, name] : m_pendingNames)
Expand All @@ -198,6 +199,11 @@ void App::TweakChangeset::Commit(const Core::SharedPtr<Red::TweakDBManager>& aMa
LogError("Cannot create record {}.", aManager->GetName(recordId));
continue;
}

if (aChangelog)
{
aChangelog->RegisterRecord(recordId);
}
}
}

Expand Down Expand Up @@ -236,6 +242,19 @@ void App::TweakChangeset::Commit(const Core::SharedPtr<Red::TweakDBManager>& aMa
aChangelog->RegisterForeignKey(foreignKey, flatId);
}
}
else if (aManager->GetReflection()->IsResRefToken(flatType))
{
const auto resRef = reinterpret_cast<Red::ResourceAsyncReference<>*>(flatValue);
aChangelog->RegisterResourcePath(resRef->path, flatId);
}
else if (aManager->GetReflection()->IsResRefTokenArray(flatType))
{
const auto resRefList = reinterpret_cast<Red::DynArray<Red::ResourceAsyncReference<>>*>(flatValue);
for (const auto& resRef : *resRefList)
{
aChangelog->RegisterResourcePath(resRef.path, flatId);
}
}
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/App/Version.rc
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#define VER_PRODUCTVERSION 1,2,0,0
#define VER_FILEVERSION 1,2,0,2308041748
#define VER_FILEVERSION 1,2,0,2308042025

#define VER_PRODUCTNAME_STR "TweakXL\0"
#define VER_PRODUCTVERSION_STR "1.2.0\0"
#define VER_FILEVERSION_STR "1.2.0.2308041748\0"
#define VER_FILEVERSION_STR "1.2.0.2308042025\0"

1 VERSIONINFO
FILEVERSION VER_FILEVERSION
Expand Down
8 changes: 6 additions & 2 deletions src/Red/TweakDB/Reflection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ constexpr auto RecordTypeSuffix = "_Record";
constexpr auto RecordTypeSuffixLength = std::char_traits<char>::length(RecordTypeSuffix);

constexpr auto BaseRecordTypeName = Red::CName("gamedataTweakDBRecord");

constexpr auto ResRefTypeName = Red::CName("raRef:CResource");
constexpr auto ResRefArrayTypeName = Red::CName("array:raRef:CResource");

constexpr auto ResRefTokenTypeName = Red::CName("redResourceReferenceScriptToken");
constexpr auto ResRefTokenArrayTypeName = Red::CName("array:redResourceReferenceScriptToken");

Expand Down Expand Up @@ -474,7 +478,7 @@ bool Red::TweakDBReflection::IsForeignKeyArray(const Red::CBaseRTTIType* aType)

bool Red::TweakDBReflection::IsResRefToken(Red::CName aTypeName)
{
return aTypeName == ResRefTokenTypeName;
return aTypeName == ResRefTokenTypeName || aTypeName == ResRefTypeName;
}

bool Red::TweakDBReflection::IsResRefToken(const Red::CBaseRTTIType* aType)
Expand All @@ -484,7 +488,7 @@ bool Red::TweakDBReflection::IsResRefToken(const Red::CBaseRTTIType* aType)

bool Red::TweakDBReflection::IsResRefTokenArray(Red::CName aTypeName)
{
return aTypeName == ResRefTokenArrayTypeName;
return aTypeName == ResRefTokenArrayTypeName || aTypeName == ResRefArrayTypeName;
}

bool Red::TweakDBReflection::IsResRefTokenArray(const Red::CBaseRTTIType* aType)
Expand Down

0 comments on commit 07e64ac

Please sign in to comment.