New X-Plane flyable plane model string schema

Summary:
New aircraft for XP11 should include a name, author, and studio. These can be used to generate a better model string that doesn't depend on file or directory names.

If the `.acf` contains studio, this is used as the distributor. Otherwise, we use author as distributor instead (truncated in case it is a long list of names).

Then the model string is constructed by combining distributor and model name. If the model name already contains the distributor, we just use the model name.

If the name and distributor are missing, we fall back to the old scheme based on `.acf` filename and dirname.

I have also added a space between aircraft and livery. And I have added default description strings.

After this has landed and been deployed to users, we will need to remove all flyable X-Plane planes from the database and start again with them. (These are the excluded ones.) And we can't accept mappings that use the fallback old scheme if the submitted has renamed the `.acf` file or directory name.

Reviewers: rwinklmeier, kbasan

Reviewed By: kbasan

Subscribers: jenkins

Tags: #swift_pilot_client

Differential Revision: https://dev.swift-project.org/D16
This commit is contained in:
Mathew Sutcliffe
2017-05-02 21:32:26 +01:00
parent fbc9c37646
commit 816f3bd48e

View File

@@ -61,6 +61,58 @@ namespace BlackMisc
}
}
//! Create a unique string to identify a model
static QString stringForFlyableModel(const CAircraftModel &model, const QFileInfo &acfFile)
{
if (model.getDistributor().hasDescription())
{
if (!model.getName().isEmpty())
{
if (model.getName().contains(model.getDistributor().getDescription()))
{
return model.getName();
}
else
{
return model.getDistributor().getDescription() % ' ' % model.getName();
}
}
else if (model.hasAircraftDesignator())
{
return model.getDistributor().getDescription() % ' ' % model.getAircraftIcaoCodeDesignator();
}
}
return acfFile.dir().dirName() % ' ' % acfFile.baseName();
}
//! Create a description string for a model that doesn't already have one
static QString descriptionForFlyableModel(const CAircraftModel &model)
{
if (!model.getName().isEmpty())
{
if (model.getDistributor().hasDescription() && !model.getName().contains(model.getDistributor().getDescription()))
{
return "[ACF] " % model.getName() % " by " % model.getDistributor().getDescription();
}
else
{
return "[ACF] " % model.getName();
}
}
else if (model.hasAircraftDesignator())
{
if (model.getDistributor().hasDescription())
{
return "[ACF] " % model.getAircraftIcaoCodeDesignator() % " by " % model.getDistributor().getDescription();
}
else
{
return "[ACF] " % model.getAircraftIcaoCodeDesignator();
}
}
return "[ACF]";
}
CAircraftModelLoaderXPlane::CAircraftModelLoaderXPlane() : IAircraftModelLoader(CSimulatorInfo::XPLANE)
{ }
@@ -168,10 +220,6 @@ namespace BlackMisc
aircraftIt.next();
if (CFileUtils::isExcludedDirectory(aircraftIt.fileInfo(), excludeDirectories, Qt::CaseInsensitive)) { continue; }
// <dirname> <filename> for the default model and <dirname> <filename> <texturedir> for the liveries
const QString dirName(aircraftIt.fileInfo().dir().dirName());
const QString modelString = QString("%1 %2").arg(dirName, aircraftIt.fileInfo().baseName());
CAircraftModel model;
model.setModelType(CAircraftModel::TypeOwnSimulatorModel);
model.setSimulator(this->getSimulator());
@@ -179,7 +227,6 @@ namespace BlackMisc
const QDateTime lastModifiedTs(aircraftIt.fileInfo().lastModified());
model.setUtcTimestamp(lastModifiedTs);
model.setFileTimestamp(lastModifiedTs);
model.setModelString(modelString);
model.setModelMode(CAircraftModel::Exclude);
QFile file(aircraftIt.filePath());
@@ -201,7 +248,7 @@ namespace BlackMisc
else if (tokens.at(1) == QLatin1String("acf/_descrip"))
{
const QString desc(line.mid(tokens.at(2).position()));
model.setDescription(desc);
model.setDescription("[ACF] " % desc);
}
else if (tokens.at(1) == QLatin1String("acf/_name"))
{
@@ -213,19 +260,29 @@ namespace BlackMisc
const CDistributor dist({}, line.mid(tokens.at(2).position()), {}, {}, CSimulatorInfo::XPLANE);
model.setDistributor(dist);
}
else if (tokens.at(1) == QLatin1String("acf/_author"))
{
if (model.getDistributor().hasDescription()) { continue; }
const thread_local QRegularExpression end("\\W\\s", QRegularExpression::UseUnicodePropertiesOption);
QString author = line.mid(tokens.at(2).position());
author = author.left(author.indexOf(end)).trimmed();
if (author.isEmpty()) { continue; }
const CDistributor dist({}, author, {}, {}, CSimulatorInfo::XPLANE);
model.setDistributor(dist);
}
}
}
file.close();
model.setModelString(stringForFlyableModel(model, aircraftIt.fileInfo()));
if (!model.hasDescription()) { model.setDescription(descriptionForFlyableModel(model)); }
addUniqueModel(model, installedModels);
QDirIterator liveryIt(aircraftIt.fileInfo().canonicalPath() + "/liveries", QDir::Dirs | QDir::NoDotAndDotDot);
while (liveryIt.hasNext())
{
liveryIt.next();
QString modelStringWithLivery = modelString + liveryIt.fileName();
model.setModelString(modelStringWithLivery);
model.setModelString(model.getModelString() % ' ' % liveryIt.fileName());
addUniqueModel(model, installedModels);
}
}
@@ -300,6 +357,7 @@ namespace BlackMisc
model.setDistributor(distributor);
model.setSimulator(this->getSimulator());
model.setDescription("[CSL]");
installedModels.push_back(model);
}
}