Skip to content

Commit

Permalink
c4group: Add AddMissingTarget to AutoUpdate.txt and expose it in c4gr…
Browse files Browse the repository at this point in the history
…oup to allow update groups to work even if the target is missing
  • Loading branch information
Fulgen301 committed Oct 2, 2024
1 parent 7268090 commit 8b29199
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 24 deletions.
70 changes: 49 additions & 21 deletions src/C4Update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ void C4UpdatePackageCore::CompileFunc(StdCompiler *pComp)
pComp->Value(mkNamingAdapt(toC4CStr(DestPath), "DestPath", ""));
pComp->Value(mkNamingAdapt(GrpUpdate, "GrpUpdate", 0));
pComp->Value(mkNamingAdapt(UpGrpCnt, "TargetCount", 0));
pComp->Value(mkNamingAdapt(AllowMissingTarget, "AllowMissingTarget", false));
pComp->Value(mkNamingAdapt(mkArrayAdapt(GrpChks1, 0u), "GrpChks1"));
pComp->Value(mkNamingAdapt(GrpChks2, "GrpChks2", 0u));
pComp->Value(mkNamingAdapt(mkArrayAdapt(GrpContentsCRC1, 0u), "GrpContentsCRC1"));
Expand Down Expand Up @@ -325,31 +326,44 @@ bool C4UpdatePackage::Execute(C4Group *pGroup)
}

// try to open it
bool targetMissing{false};
if (!TargetGrp.Open(strTarget, !GrpUpdate))
return false;
{
if (AllowMissingTarget && !ItemExists(strTarget) && TargetGrp.Open(strTarget, true))
{
targetMissing = true;
}
else
{
return false;
}
}

// check if the update is allowed
if (GrpUpdate)
{
// check checksum
uint32_t iContentsCRC32;
if (!C4Group_GetFileContentsCRC(TargetGrp.GetFullName().getData(), &iContentsCRC32))
return false;
int i = 0;
for (; i < UpGrpCnt; i++)
if (GrpContentsCRC1[i] && iContentsCRC32 == GrpContentsCRC1[i])
break;
if (i >= UpGrpCnt)
if (!targetMissing)
{
uint32_t iCRC32;
if (!C4Group_GetFileCRC(TargetGrp.GetFullName().getData(), &iCRC32))
// check checksum
uint32_t iContentsCRC32;
if (!C4Group_GetFileContentsCRC(TargetGrp.GetFullName().getData(), &iContentsCRC32))
return false;
int i = 0;
for (; i < UpGrpCnt; i++)
if (iCRC32 == GrpChks1[i])
if (GrpContentsCRC1[i] && iContentsCRC32 == GrpContentsCRC1[i])
break;
if (i >= UpGrpCnt)
return false;
{
uint32_t iCRC32;
if (!C4Group_GetFileCRC(TargetGrp.GetFullName().getData(), &iCRC32))
return false;
int i = 0;
for (; i < UpGrpCnt; i++)
if (iCRC32 == GrpChks1[i])
break;
if (i >= UpGrpCnt)
return false;
}
}
}
else
Expand Down Expand Up @@ -438,7 +452,17 @@ C4UpdatePackage::CheckResult C4UpdatePackage::Check(C4Group *pGroup)
// check source file
C4Group TargetGrp;
if (!TargetGrp.Open(DestPath))
return CheckResult::NoSource;
{
// make sure corrupted target files aren't overwritten
if (AllowMissingTarget && !ItemExists(DestPath))
{
return CheckResult::Ok;
}
else
{
return CheckResult::NoSource;
}
}
if (!TargetGrp.IsPacked())
return CheckResult::BadSource;
TargetGrp.Close();
Expand Down Expand Up @@ -624,7 +648,7 @@ bool C4UpdatePackage::Optimize(C4Group *pGrpFrom, C4GroupEx *pGrpTo, const char
return true;
}

bool C4UpdatePackage::MakeUpdate(const char *strFile1, const char *strFile2, const char *strUpdateFile, const char *strName)
bool C4UpdatePackage::MakeUpdate(const char *strFile1, const char *strFile2, const char *strUpdateFile, const char *strName, const bool allowMissingTarget)
{
// open Log
if (!Log.Create("Update.log"))
Expand Down Expand Up @@ -699,6 +723,7 @@ bool C4UpdatePackage::MakeUpdate(const char *strFile1, const char *strFile2, con
}

UpGrpCnt++;
AllowMissingTarget = allowMissingTarget;

// save core
if (!C4UpdatePackageCore::Save(UpGroup))
Expand Down Expand Up @@ -749,7 +774,7 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
if (!entryList.empty()) entryList += '|';
entryList += std::format("{}={}", strItemName, pGrp2->EntryTime(strItemName));
// no modification detected yet? then check order
if (!*fModified)
if (!AllowMissingTarget && !*fModified)
{
if (!pGrp1->FindNextEntry("*", strItemName2, nullptr, nullptr, !!strItemName2[0]))
*fModified = true;
Expand Down Expand Up @@ -786,8 +811,9 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
extern const char **C4Group_SortList;
UpdGroup.SortByList(C4Group_SortList, ChildGrp2.GetName());
UpdGroup.Close(false);
// check entry times
if (!pGrp1 || (pGrp1->EntryTime(strItemName) != pGrp2->EntryTime(strItemName)))
// always add the entire group if mising targets are allowed
// otherwise check entry times
if (AllowMissingTarget || !pGrp1 || (pGrp1->EntryTime(strItemName) != pGrp2->EntryTime(strItemName)))
Modified = true;
// add group (if modified)
if (fSuccess && Modified)
Expand Down Expand Up @@ -818,7 +844,8 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
else
{
// compare them (size & crc32)
if (!pGrp1 ||
if (AllowMissingTarget ||
!pGrp1 ||
pGrp1->EntrySize(strItemName) != pGrp2->EntrySize(strItemName) ||
pGrp1->EntryCRC32(strItemName) != pGrp2->EntryCRC32(strItemName))
{
Expand All @@ -828,7 +855,8 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
pUpGrp->SaveEntryCore(*pGrp2, strItemName);

// already in update grp?
if (pUpGrp->EntryTime(strItemName) != pGrp2->EntryTime(strItemName) ||
if (AllowMissingTarget ||
pUpGrp->EntryTime(strItemName) != pGrp2->EntryTime(strItemName) ||
pUpGrp->EntrySize(strItemName) != pGrp2->EntrySize(strItemName) ||
pUpGrp->EntryCRC32(strItemName) != pGrp2->EntryCRC32(strItemName))
{
Expand Down
3 changes: 2 additions & 1 deletion src/C4Update.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class C4UpdatePackageCore
char DestPath[_MAX_PATH + 1];
int32_t GrpUpdate;
int32_t UpGrpCnt; // number of file versions that can be updated by this package
bool AllowMissingTarget; // if true, missing target files are not considered an error
uint32_t GrpChks1[C4UP_MaxUpGrpCnt], GrpChks2;
uint32_t GrpContentsCRC1[C4UP_MaxUpGrpCnt], GrpContentsCRC2;

Expand All @@ -59,7 +60,7 @@ class C4UpdatePackage : public C4UpdatePackageCore
bool Execute(C4Group *pGroup);
static bool Optimize(C4Group *pGrpFrom, const char *strTarget);
CheckResult Check(C4Group *pGroup);
bool MakeUpdate(const char *strFile1, const char *strFile2, const char *strUpdateFile, const char *strName = nullptr);
bool MakeUpdate(const char *strFile1, const char *strFile2, const char *strUpdateFile, const char *strName, bool allowMissingTarget);

protected:
bool DoUpdate(C4Group *pGrpFrom, class C4GroupEx *pGrpTo, const char *strFileName);
Expand Down
4 changes: 2 additions & 2 deletions src/c4group_ng.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ bool ProcessGroup(const char *FilenamePar)
std::println(stderr, "Closing failed: {}", hGroup.GetError());
}
// generate
else if (!Upd.MakeUpdate(argv[iArg + 1], argv[iArg + 2], szFilename, argv[iArg + 3]))
else if (!Upd.MakeUpdate(argv[iArg + 1], argv[iArg + 2], szFilename, argv[iArg + 3], argv[iArg][2] == 'a'))
{
std::println(stderr, "Update generation failed.");
}
Expand Down Expand Up @@ -645,7 +645,7 @@ int main(int argc, char *argv[])
std::println(" -v View -l List -d Delete -r Rename -s Sort");
std::println(" -p Pack -u Unpack -x Explode");
std::println(" -k Print maker");
std::println(" -g [source] [target] [title] Make update");
std::println(" -g[a] [source] [target] [title] Make update [allow missing target]");
std::println(" -y[d] Apply update [and delete group file]");
std::println("");
std::println("Options: -v Verbose -r Recursive -p Prompt at end");
Expand Down

0 comments on commit 8b29199

Please sign in to comment.