| 736 | //========================================================================== |
| 737 | |
| 738 | TArray<GrpEntry> GrpScan() |
| 739 | { |
| 740 | TArray<GrpEntry> foundGames; |
| 741 | |
| 742 | TArray<FileEntry*> sortedFileList; |
| 743 | TArray<GrpInfo*> sortedGroupList; |
| 744 | TArray<GrpInfo*> contentGroupList; |
| 745 | TArray<GrpInfo*> addonList; |
| 746 | |
| 747 | auto allFiles = CollectAllFilesInSearchPath(); |
| 748 | auto allGroups = ParseAllGrpInfos(allFiles); |
| 749 | |
| 750 | auto cachedCRCs = LoadCRCCache(); |
| 751 | auto numCRCs = cachedCRCs.Size(); |
| 752 | |
| 753 | for (unsigned i = 0; i < allGroups.Size(); i++) |
| 754 | allGroups[i].index = i; |
| 755 | |
| 756 | // Remove all unnecessary content from the file list. Since this contains all data from the search path's directories it can be quite large. |
| 757 | // Sort both lists by file size so that we only need to pass over each list once to weed out all unrelated content. Go backward to avoid too much item movement |
| 758 | // (most will be deleted anyway.) |
| 759 | |
| 760 | |
| 761 | for (auto& f : allFiles) sortedFileList.Push(&f); |
| 762 | for (auto& g : allGroups) |
| 763 | { |
| 764 | if (g.isAddon) |
| 765 | addonList.Push(&g); |
| 766 | else if (g.CRC == 0 && g.mustcontain.Size() > 0) |
| 767 | contentGroupList.Push(&g); |
| 768 | else |
| 769 | sortedGroupList.Push(&g); |
| 770 | } |
| 771 | |
| 772 | // As a first pass we need to look for all known game resources which only are identified by a content list |
| 773 | if (contentGroupList.Size()) |
| 774 | { |
| 775 | for (auto fe : sortedFileList) |
| 776 | { |
| 777 | FString fn = fe->FileName.MakeLower(); |
| 778 | for (auto ext : res_exts) |
| 779 | { |
| 780 | if (strcmp(ext, fn.GetChars() + fn.Len() - 4) == 0) |
| 781 | { |
| 782 | auto resf = FResourceFile::OpenResourceFile(fe->FileName.GetChars(), true); |
| 783 | if (resf) |
| 784 | { |
| 785 | for (auto grp : contentGroupList) |
| 786 | { |
| 787 | bool ok = true; |
| 788 | for (auto &lump : grp->mustcontain) |
| 789 | { |
| 790 | if (resf->FindEntry(lump.GetChars()) < 0) |
| 791 | { |
| 792 | ok = false; |
| 793 | break; |
| 794 | } |
| 795 | } |
no test coverage detected