Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C4Update: Add AllowMissingTarget option to AutoUpdate.txt #127

Merged
merged 4 commits into from
Oct 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
98 changes: 63 additions & 35 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 All @@ -707,8 +732,8 @@ bool C4UpdatePackage::MakeUpdate(const char *strFile1, const char *strFile2, con
}

// compare groups, create update
bool fModified = false;
bool fSuccess = MkUp(&Group1, &Group2, &UpGroup, &fModified);
bool includeInUpdate{false};
bool fSuccess = MkUp(&Group1, &Group2, &UpGroup, includeInUpdate);
// close (save) it
UpGroup.Close(false);
// error?
Expand All @@ -723,7 +748,7 @@ bool C4UpdatePackage::MakeUpdate(const char *strFile1, const char *strFile2, con
return true;
}

bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bool *fModified)
bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bool &includeInUpdate)
{
// (CAUTION: pGrp1 may be nullptr - that means that there is no counterpart for Grp2
// in the base group)
Expand All @@ -734,27 +759,27 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
pGrp1->GetOriginal() != pGrp2->GetOriginal() ||
!SEqual(pGrp1->GetMaker(), pGrp2->GetMaker()) ||
!SEqual(pGrp1->GetPassword(), pGrp2->GetPassword()))
*fModified = true;
includeInUpdate = true;
// set header
pUpGrp->SetHead(*pGrp2);
// compare entries
char strItemName[_MAX_PATH], strItemName2[_MAX_PATH];
std::string entryList;
strItemName[0] = strItemName2[0] = 0;
pGrp2->ResetSearch(); if (!*fModified) pGrp1->ResetSearch();
pGrp2->ResetSearch(); if (!includeInUpdate) pGrp1->ResetSearch();
int iChangedEntries = 0;
while (pGrp2->FindNextEntry("*", strItemName, nullptr, nullptr, !!strItemName[0]))
{
// add to entry list
if (!entryList.empty()) entryList += '|';
entryList += std::format("{}={}", strItemName, pGrp2->EntryTime(strItemName));
// no modification detected yet? then check order
if (!*fModified)
if (!AllowMissingTarget && !includeInUpdate)
{
if (!pGrp1->FindNextEntry("*", strItemName2, nullptr, nullptr, !!strItemName2[0]))
*fModified = true;
includeInUpdate = true;
else if (!SEqual(strItemName, strItemName2))
*fModified = true;
includeInUpdate = true;
}

// TODO: write DeleteEntries.txt
Expand All @@ -780,17 +805,18 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
if (!UpdGroup.Open(strTempGroupName, true)) { delete pChildGrp1; WriteLog("Error: could not create temp group\n"); return false; }
}
// do nested MkUp-search
bool Modified = false;
bool fSuccess = MkUp(pChildGrp1, &ChildGrp2, &UpdGroup, &Modified);
bool childIncludeInUpdate{false};
bool fSuccess = MkUp(pChildGrp1, &ChildGrp2, &UpdGroup, childIncludeInUpdate);
// sort & close
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)))
Modified = true;
// always add the entire group if missing targets are allowed
// otherwise check entry times
if (AllowMissingTarget || !pGrp1 || (pGrp1->EntryTime(strItemName) != pGrp2->EntryTime(strItemName)))
maxmitti marked this conversation as resolved.
Show resolved Hide resolved
childIncludeInUpdate = true;
// add group (if modified)
if (fSuccess && Modified)
if (fSuccess && childIncludeInUpdate)
{
if (strTempGroupName[0])
if (!pUpGrp->Move(strTempGroupName, strItemName))
Expand All @@ -802,7 +828,7 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
pUpGrp->SaveEntryCore(*pGrp2, strItemName);
pUpGrp->SetSavedEntryCore(strItemName);
// got a modification in a subgroup
*fModified = true;
includeInUpdate = true;
iChangedEntries++;
}
else
Expand All @@ -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 All @@ -841,7 +869,7 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
// set entry core
pUpGrp->SetSavedEntryCore(strItemName);
// modified...
*fModified = true;
includeInUpdate = true;
fCopied = true;
}
iChangedEntries++;
Expand All @@ -859,7 +887,7 @@ bool C4UpdatePackage::MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGrp, bo
}

if (iChangedEntries > 0)
WriteLog("{}: {}/{} changed ({})\n", pGrp2->GetFullName().getData(), iChangedEntries, pGrp2->EntryCount(), *fModified ? "update" : "skip");
WriteLog("{}: {}/{} changed ({})\n", pGrp2->GetFullName().getData(), iChangedEntries, pGrp2->EntryCount(), includeInUpdate ? "update" : "skip");

// success
return true;
Expand Down
5 changes: 3 additions & 2 deletions 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,14 +60,14 @@ 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);
bool DoGrpUpdate(C4Group *pUpdateData, class C4GroupEx *pGrpTo);
static bool Optimize(C4Group *pGrpFrom, class C4GroupEx *pGrpTo, const char *strFileName);

bool MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGr, bool *fModified);
bool MkUp(C4Group *pGrp1, C4Group *pGrp2, C4GroupEx *pUpGr, bool &includeInUpdate);

CStdFile Log;

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 [and allow missing target group when applying update]");
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
Loading