First working version of priority handling

This commit is contained in:
Gael Le Mignot 2014-10-26 10:47:13 +01:00
parent 1204ea247e
commit a46fad588b
5 changed files with 69 additions and 3 deletions

View File

@ -21,10 +21,12 @@ class gameDetails
std::string gamename;
std::string title;
std::string icon;;
void filterWithPriorities(const Config& config);
void makeFilepaths(const Config& config);
Json::Value getDetailsAsJson();
virtual ~gameDetails();
protected:
void filterListWithPriorities(std::vector<gameFile>& list, const Config& config);
private:
};

View File

@ -19,6 +19,7 @@ class gameFile
std::string size;
unsigned int platform;
unsigned int language;
int score;
int silent;
void setFilepath(const std::string& path);
std::string getFilepath();

View File

@ -518,9 +518,9 @@ gameDetails API::getGameDetails(const std::string& game_name, const unsigned int
if (!langpacknames.empty()) // found at least one language pack
{
for (unsigned int i = 0; i < langpacknames.size(); ++i)
for (unsigned int j = 0; j < langpacknames.size(); ++j)
{
Json::Value langpack = root["game"][langpacknames[i]];
Json::Value langpack = root["game"][langpacknames[j]];
game.languagepacks.push_back(
gameFile( false, /* language packs don't have "updated" flag */
langpack["id"].isInt() ? std::to_string(langpack["id"].asInt()) : langpack["id"].asString(),

View File

@ -252,6 +252,8 @@ int Downloader::getGameDetails()
game = gogAPI->getGameDetails(gameItems[i].name, conf.iInstallerType, conf.iInstallerLanguage, config.bDuplicateHandler);
if (!gogAPI->getError())
{
game.filterWithPriorities(config);
if (game.extras.empty() && config.bExtras) // Try to get extras from account page if API didn't return any extras
{
game.extras = this->getExtras(gameItems[i].name, gameItems[i].id);
@ -262,6 +264,7 @@ int Downloader::getGameDetails()
{
gameDetails dlc;
dlc = gogAPI->getGameDetails(gameItems[i].dlcnames[j], conf.iInstallerType, conf.iInstallerLanguage, config.bDuplicateHandler);
dlc.filterWithPriorities(config);
if (dlc.extras.empty() && config.bExtras) // Try to get extras from account page if API didn't return any extras
{
dlc.extras = this->getExtras(gameItems[i].dlcnames[j], gameItems[i].id);
@ -2817,8 +2820,11 @@ std::vector<gameDetails> Downloader::getGameDetailsFromJsonNode(Json::Value root
}
}
if (!game.extras.empty() || !game.installers.empty() || !game.patches.empty() || !game.languagepacks.empty() || !game.dlcs.empty())
{
game.filterWithPriorities(config);
details.push_back(game);
}
}
return details;
}
@ -2840,6 +2846,8 @@ void Downloader::updateCache()
config.sGameRegex = ".*";
config.iInstallerLanguage = all_languages;
config.iInstallerType = all_platforms;
config.vLanguagePriority.clear();
config.vPlatformPriority.clear();
this->getGameList();
this->getGameDetails();

View File

@ -11,6 +11,61 @@ gameDetails::~gameDetails()
//dtor
}
void gameDetails::filterWithPriorities(const Config& config)
{
if (config.vPlatformPriority.empty() && config.vLanguagePriority.empty())
return;
filterListWithPriorities(installers, config);
filterListWithPriorities(patches, config);
filterListWithPriorities(languagepacks, config);
}
void gameDetails::filterListWithPriorities(std::vector<gameFile>& list, const Config& config)
{
/*
Compute the score of each item - we use a scoring mechanism and we keep all ties
Like if someone asked French then English and Linux then Windows, but there are
only Windows French, Windows English and Linux English versions, we'll get the
Windows French and Linux English ones.
Score is inverted: lower is better.
*/
int bestscore = -1;
for (std::vector<gameFile>::iterator fileDetails = list.begin(); fileDetails != list.end(); fileDetails++)
{
fileDetails->score = 0;
if (!config.vPlatformPriority.empty())
{
for (size_t i = 0; i != config.vPlatformPriority.size(); i++)
if (fileDetails->platform & config.vPlatformPriority[i])
{
fileDetails->score += i;
break;
}
}
if (!config.vLanguagePriority.empty())
{
for (size_t i = 0; i != config.vLanguagePriority.size(); i++)
if (fileDetails->language & config.vLanguagePriority[i])
{
fileDetails->score += i;
break;
}
}
if ((fileDetails->score < bestscore) or (bestscore < 0))
bestscore = fileDetails->score;
}
for (std::vector<gameFile>::iterator fileDetails = list.begin(); fileDetails != list.end(); )
{
if (fileDetails->score > bestscore)
fileDetails = list.erase(fileDetails);
else
fileDetails++;
}
}
void gameDetails::makeFilepaths(const Config& config)
{
std::string filepath;