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();