Skip to content

Commit

Permalink
Now reading scenery_packs.ini for X-Plane to allow disabling of scene…
Browse files Browse the repository at this point in the history
  • Loading branch information
albar965 committed Aug 4, 2018
1 parent 1b45cc3 commit 09faf99
Show file tree
Hide file tree
Showing 5 changed files with 379 additions and 34 deletions.
6 changes: 4 additions & 2 deletions atools.pro
Expand Up @@ -266,7 +266,8 @@ HEADERS += src/atools.h \
src/fs/online/onlinetypes.h \
src/zip/gzip.h \
src/sql/sqltransaction.h \
src/logging/loggingtypes.h
src/logging/loggingtypes.h \
src/fs/xp/scenerypacks.h

SOURCES += src/atools.cpp \
src/exception.cpp \
Expand Down Expand Up @@ -475,7 +476,8 @@ SOURCES += src/atools.cpp \
src/fs/online/onlinedatamanager.cpp \
src/fs/online/onlinetypes.cpp \
src/zip/gzip.cpp \
src/sql/sqltransaction.cpp
src/sql/sqltransaction.cpp \
src/fs/xp/scenerypacks.cpp


unix {
Expand Down
187 changes: 187 additions & 0 deletions src/fs/xp/scenerypacks.cpp
@@ -0,0 +1,187 @@
/*****************************************************************************
* Copyright 2015-2018 Alexander Barthel albar965@mailbox.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

#include "fs/xp/scenerypacks.h"
#include "atools.h"
#include "exception.h"

#include <QFile>
#include <QFileInfo>

namespace atools {
namespace fs {
namespace xp {

SceneryPacks::SceneryPacks()
{

}

SceneryPacks::~SceneryPacks()
{

}

void SceneryPacks::read(const QString& basePath)
{
entries.clear();
index.clear();

// X-Plane 11/Custom Scenery/scenery_packs.ini
//
// I
// 1000 Version
// SCENERY
//
// SCENERY_PACK Custom Scenery/X-Plane Landmarks - Chicago/
// Listing the pack as SCENERY_PACK_DISABLED disables loading entirely.

QString filepath = atools::buildPathNoCase({basePath, "Custom Scenery", "scenery_packs.ini"});
QFile file(filepath);
if(file.open(QIODevice::ReadOnly | QIODevice::Text))
{
QTextStream stream(&file);
QString msg(tr("Cannot open file \"%1\". Not a scenery_packs.ini file. %2."));

// I ================
QString line = stream.readLine().trimmed();
if(line != "I" && line != "A")
throw atools::Exception(msg.arg(filepath).arg(tr("Intital \"I\" or \"A\" missing")));

// 1000 Version ================
line = stream.readLine().trimmed();
if(line.section(' ', 1, 1) != "Version")
throw atools::Exception(msg.arg(filepath).arg(tr("\"Version\" missing")));

bool ok;
fileVersion = line.section(' ', 0, 0).toInt(&ok);
if(!ok)
throw atools::Exception(msg.arg(filepath).arg(tr("Version number not valid")));

// SCENERY ================
line = stream.readLine().trimmed();
if(line != "SCENERY")
throw atools::Exception(msg.arg(filepath).arg(tr("\"SCENERY\" missing")));

// Empty line ================
line = stream.readLine().trimmed();
if(!line.isEmpty())
throw atools::Exception(msg.arg(filepath).arg(tr("Empty line after \"SCENERY\" missing")));

int lineNum = 5;
while(!stream.atEnd())
{
line = stream.readLine().trimmed();
if(!line.isEmpty())
{
SceneryPack pack;
QString key = line.section(' ', 0, 0);
if(key != "SCENERY_PACK" && key != "SCENERY_PACK_DISABLED")
{
// Add an entry for each invalid line
pack.disabled = true;
pack.valid = false;
pack.errorText = tr("Invalid entry at line %1 in \"%2\".").arg(lineNum).arg(file.fileName());
pack.errorLine = lineNum;
entries.append(pack);
}
else
{
// Global Airports are excluded and read separately
QString pathstr = line.section(' ', 1);
if(pathstr.toLower() == "custom scenery/global airports/" ||
pathstr.toLower() == "custom scenery/global airports")
continue;

// SCENERY_PACK Custom Scenery/X-Plane Landmarks - Chicago/ ================
pack.disabled = key != "SCENERY_PACK";

QFileInfo fileinfoBase, fileinfoPath(pathstr);

if(fileinfoPath.isAbsolute())
// Use absolute path as given
fileinfoBase = QFileInfo(atools::buildPathNoCase({fileinfoPath.filePath()}));
else
// Use relative path to base directory
fileinfoBase = QFileInfo(atools::buildPathNoCase({basePath, fileinfoPath.filePath()}));
pack.valid = fileinfoBase.exists() && fileinfoBase.isDir();

// path to apt.dat file
QFileInfo aptdatFileinfo(atools::buildPathNoCase({fileinfoBase.absoluteFilePath(),
"Earth nav data", "apt.dat"}));

if(!pack.valid || (aptdatFileinfo.exists() && aptdatFileinfo.isFile()))
{
// If path is valid so far but apt.dat does not exist - ignore silently

if(!pack.valid)
{
// Report only errors on missing base path
// Path does not exist - use base path for reporting
pack.filepath = fileinfoBase.filePath();

if(!fileinfoBase.exists())
pack.errorText = tr("\"%1\" at line %2 in \"%3\" does not exist.").
arg(fileinfoBase.filePath()).arg(lineNum).arg(file.fileName());
else if(!fileinfoBase.isDir())
pack.errorText = tr("\"%1\" at line %2 in \"%3\" is not a directory.").
arg(fileinfoBase.filePath()).arg(lineNum).arg(file.fileName());
else if(!fileinfoBase.isReadable())
pack.errorText = tr("\"%1\" at line %2 in \"%3\" is not readable.").
arg(fileinfoBase.filePath()).arg(lineNum).arg(file.fileName());
pack.errorLine = lineNum;
}
else
{
// All valid
pack.filepath = atools::buildPathNoCase({fileinfoBase.absoluteFilePath(), "Earth nav data", "apt.dat"});
pack.errorLine = -1;

// Add only to index if path exists
QString canonicalFilePath = QFileInfo(pack.filepath).canonicalFilePath();
if(!canonicalFilePath.isEmpty())
index.insert(canonicalFilePath, entries.size());
}

entries.append(pack);
}
}
}
lineNum++;
}

file.close();
}
else
throw atools::Exception(tr("Cannot open file \"%1\". Reason: %2.").arg(filepath).arg(file.errorString()));
}

const QVector<SceneryPack>& SceneryPacks::getEntries() const
{
return entries;
}

const SceneryPack *SceneryPacks::getEntryByPath(const QString& filepath) const
{
QFileInfo fi(filepath);
int idx = index.value(fi.canonicalFilePath(), -1);
return idx >= 0 ? &entries.at(idx) : nullptr;
}

} // namespace xp
} // namespace fs
} // namespace atools
93 changes: 93 additions & 0 deletions src/fs/xp/scenerypacks.h
@@ -0,0 +1,93 @@
/*****************************************************************************
* Copyright 2015-2018 Alexander Barthel albar965@mailbox.org
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*****************************************************************************/

#ifndef ATOOLS_XP_XPSCENERYPACKS_H
#define ATOOLS_XP_XPSCENERYPACKS_H

#include <QApplication>
#include <QVector>

namespace atools {
namespace fs {
namespace xp {

struct SceneryPack
{
QString filepath /* File path to apt.dat if exists or base directory if not valid */,
errorText /* Error message to display if base path is not valid */;

bool disabled /* Disable by SCENERY_PACK_DISABLED */,
valid /* File exists */;

int errorLine /* Line number in file */;
};

/*
* Reads X-Plane scenery_packs.ini and returns a list with missing paths for error reports and valid
* entries (disabled or not).
*
* X-Plane 11/Custom Scenery/scenery_packs.ini
*
* I
* 1000 Version
* SCENERY
*
* SCENERY_PACK Custom Scenery/X-Plane Landmarks - Chicago/
* SCENERY_PACK Custom Scenery/2NC0_Mountain_Air_by_hapet/
* SCENERY_PACK Custom Scenery/A_ENSB_ESCI/
* SCENERY_PACK Custom Scenery/Aerodrome NTMU Ua_Huka XPFR/
* SCENERY_PACK Custom Scenery/BIGR_Scenery_Pack/
*
* Listing the pack as SCENERY_PACK_DISABLED disables loading entirely.
* Global Airports are excluded and read separately
*/
class SceneryPacks
{
Q_DECLARE_TR_FUNCTIONS(XpSceneryPacks)

public:
SceneryPacks();
~SceneryPacks();

/* Read file and fill entries list. */
void read(const QString& basePath);

/* Get list of entries from file after calling read */
const QVector<SceneryPack>& getEntries() const;

/* Get an entry by canonical path. Returns null if it does not exist or path does not exist */
const SceneryPack *getEntryByPath(const QString& filepath) const;

int getFileVersion() const
{
return fileVersion;
}

private:
QVector<SceneryPack> entries;

/* Canonical path to index in entry list */
QHash<QString, int> index;
int fileVersion;

};

} // namespace xp
} // namespace fs
} // namespace atools

#endif // ATOOLS_XP_XPSCENERYPACKS_H

0 comments on commit 09faf99

Please sign in to comment.