24 #include "modreader.h" 
   26 #include "datastreamoperatorwrapper.h" 
   27 #include "wadseeker/zip/unarchive.h" 
   30 #include <QDataStream> 
   33 #include <QTemporaryDir> 
   35 QSharedPointer<ModReader> ModReader::create(
const QString &path)
 
   38         if (f.suffix().compare(
"wad", Qt::CaseInsensitive) == 0)
 
   40                 return QSharedPointer<ModReader>(
new WadReader(path));
 
   42         else if (f.suffix().compare(
"zip", Qt::CaseInsensitive) == 0 ||
 
   43                 f.suffix().compare(
"7z", Qt::CaseInsensitive) == 0)
 
   47         else if (f.suffix().compare(
"pk3", Qt::CaseInsensitive) == 0 ||
 
   48                 f.suffix().compare(
"pk7", Qt::CaseInsensitive) == 0)
 
   50                 return QSharedPointer<ModReader>(
new PkReader(path));
 
   52         return QSharedPointer<ModReader> ();
 
   60         QList<DirectoryEntry> directory;
 
   70 WadReader::~WadReader()
 
   77         if (f.open(QIODevice::ReadOnly))
 
   79                 QDataStream streamUnwrapped(&f);
 
   80                 streamUnwrapped.setByteOrder(QDataStream::LittleEndian);
 
   83                 QString isIwadText = stream.
readRaw(4);
 
   84                 d->isIwad = (isIwadText == 
"IWAD");
 
   87                 int directoryPosition = stream.readQInt32();
 
   92                         dirEntry.position = stream.readQInt32();
 
   93                         dirEntry.size = stream.readQInt32();
 
   94                         dirEntry.name = stream.
readRaw(8);
 
   95                         d->directory << dirEntry;
 
  117                 names << dirEntry.name;
 
  119         QStringList maps = getClassicMaps(names);
 
  120         maps << getUdmfMaps(names);
 
  124 QStringList WadReader::getClassicMaps(
const QStringList &names)
 
  127         QStringList initialMandatoryLumps = {
"THINGS", 
"LINEDEFS", 
"SIDEDEFS", 
"VERTEXES"};
 
  128         QStringList extraMandatoryLumps = {
"SECTORS", 
"REJECT"};
 
  130         for (
int mainIter = 0; mainIter < names.size() - (initialMandatoryLumps.size() + extraMandatoryLumps.size()); ++mainIter)
 
  132                 bool allInitsFound = 
true;
 
  133                 for (
int subInitIter = 0; subInitIter < initialMandatoryLumps.size(); ++subInitIter)
 
  135                         allInitsFound &= (names[mainIter + subInitIter + 1] == initialMandatoryLumps[subInitIter]);
 
  141                         int extrasChecked = 0;
 
  143                         for (
int subExtraIter = 0; mainIter + subExtraIter + 1 < names.size(); ++subExtraIter)
 
  145                                 if (extrasChecked == extraMandatoryLumps.size())
 
  147                                         maps << names[mainIter];
 
  150                                 if (names[mainIter + subExtraIter + 1] == extraMandatoryLumps[extrasChecked])
 
  158 QStringList WadReader::getUdmfMaps(
const QStringList &names)
 
  161         QString firstLump = 
"TEXTMAP";
 
  162         QString lastLump = 
"ENDMAP";
 
  163         unsigned char lumpAmount = 2;
 
  165         for (
int mainIter = 0; mainIter < names.size() - lumpAmount; ++mainIter)
 
  167                 if (names[mainIter + 1] == firstLump)
 
  169                         for (
int checkIter = lumpAmount; mainIter + checkIter < names.size(); ++checkIter)
 
  171                                 if (names[mainIter + checkIter] == lastLump)
 
  173                                         maps << names[mainIter];
 
  174                                         mainIter += checkIter;
 
  184 DClass<CompressedReader>
 
  187         QScopedPointer<UnArchive> archive;
 
  189         QStringList directory;
 
  197         d->archive.reset(
nullptr);
 
  200 CompressedReader::~CompressedReader()
 
  206         d->archive.reset(UnArchive::openArchive(d->filepath));
 
  207         if (!d->archive.isNull())
 
  209                 d->directory = d->archive->files();
 
  218         return getAllMapsRootDir();
 
  221 QStringList CompressedReader::getAllMapsRootDir()
 
  223         QStringList rootPaths;
 
  225         QTemporaryDir tempDir;
 
  227         if (tempDir.isValid())
 
  229                 for (QString dirEntry : d->directory)
 
  231                         if (!dirEntry.contains(
"/"))
 
  233                                 QString extractedFilePath = tempDir.path() + QDir::separator() + dirEntry;
 
  234                                 QSharedPointer<ModReader> modReader = ModReader::create(extractedFilePath);
 
  235                                 if (!modReader.isNull() && !d->archive.isNull() &&
 
  236                                         d->archive->extract(d->archive->findFileEntry(dirEntry), extractedFilePath))
 
  239                                         mapList << modReader->getAllMaps();
 
  254         QStringList rootPaths;
 
  255         for (
const QString &dirEntry : d->directory)
 
  257                 QFileInfo fileInfo(dirEntry);
 
  258                 if (dirEntry.startsWith(
"maps/", Qt::CaseInsensitive) &&
 
  259                         fileInfo.suffix().compare(
"wad", Qt::CaseInsensitive) == 0)
 
  261                         mapList << fileInfo.baseName();
 
  264         mapList << getAllMapsRootDir();