Skip to content

Commit

Permalink
(Mostly) handle Game Redirects
Browse files Browse the repository at this point in the history
Technically taking a shortcut here, but it's a big time save and should
be sufficient 99% of the time, if not 100%.
  • Loading branch information
oblivioncth committed Jun 30, 2024
1 parent d88a12d commit fe74bc9
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/include/fp/fp-db.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,18 @@ class FP_FP_EXPORT Db : public QObject
COL_APP_PATH, COL_LAUNCH_COMMAND};
};

class Table_Game_Redirect
{
public:
static inline const QString NAME = u"game_redirect"_s;

static inline const QString COL_ID = u"id"_s;
static inline const QString COL_SOURCE_ID = u"sourceId"_s;

static inline const QStringList COLUMN_LIST = {COL_ID, COL_SOURCE_ID};
};


class Table_Add_App
{
public:
Expand Down Expand Up @@ -291,6 +303,7 @@ class FP_FP_EXPORT Db : public QObject
{Db::Table_Tag::NAME, Db::Table_Tag::COLUMN_LIST},
{Db::Table_Tag_Alias::NAME, Db::Table_Tag_Alias::COLUMN_LIST},
{Db::Table_Tag_Category::NAME, Db::Table_Tag_Category::COLUMN_LIST},
{Db::Table_Game_Redirect::NAME, Db::Table_Game_Redirect::COLUMN_LIST},
};
static inline const QString GENERAL_QUERY_SIZE_COMMAND = u"COUNT(1)"_s;

Expand All @@ -315,6 +328,7 @@ class FP_FP_EXPORT Db : public QObject
QStringList mPlatformNames;
QStringList mPlaylistList;
QMap<int, TagCategory> mTagMap; // Order matters for display in tag selector
QHash<QUuid, QUuid> mGameRedirects;

//-Constructor-------------------------------------------------------------------------------------------------
public:
Expand All @@ -341,6 +355,7 @@ class FP_FP_EXPORT Db : public QObject
QSqlError checkDatabaseForRequiredColumns(QSet<QString>& missingColumsBuffer);
QSqlError populateAvailableItems();
QSqlError populateTags();
QSqlError populateGameRedirects();

public:
// Validity
Expand Down Expand Up @@ -371,6 +386,7 @@ class FP_FP_EXPORT Db : public QObject
DbError getEntry(Entry& entry, const QUuid& entryId);
DbError getGameData(GameData& data, const QUuid& gameId);
DbError updateGameDataOnDiskState(QList<int> packIds, bool onDisk);
QUuid handleGameRedirects(const QUuid& gameId);

//-Slots ------------------------------------------------------------------------------------------------------
private:
Expand Down
52 changes: 52 additions & 0 deletions lib/src/fp-db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ Db::Db(const QString& databaseName, const Key&) :
return;
}

// Populate game redirects
if((databaseError = populateGameRedirects()).isValid())
{
mError = DbError(DbError::SqlError, databaseError.text());
return;
}

// Give the ok
mValid = true;
validityGuard.dismiss();
Expand Down Expand Up @@ -412,6 +419,42 @@ QSqlError Db::populateTags()
return QSqlError();
}

QSqlError Db::populateGameRedirects()
{
// Get database
QSqlDatabase fpDb;
QSqlError dbError = getThreadConnection(fpDb);
if(dbError.isValid())
return dbError;

// Ensure map is reset
mGameRedirects.clear();

// Make redirect query
QSqlQuery redirectQuery(u"SELECT `"_s + Table_Game_Redirect::COLUMN_LIST.join(u"`,`"_s) + u"` FROM "_s + Table_Game_Redirect::NAME, fpDb);

// Return if error occurs
if(redirectQuery.lastError().isValid())
return redirectQuery.lastError();

// Parse query
while(redirectQuery.next())
{
QUuid src(redirectQuery.value(Table_Game_Redirect::COL_SOURCE_ID).toString());
if(src.isNull())
continue;

QUuid dest(redirectQuery.value(Table_Game_Redirect::COL_ID).toString());
if(dest.isNull())
continue;

mGameRedirects[src] = dest;
}

// Return invalid SqlError
return QSqlError();
}

DbError Db::queryGamesByPlatform(QList<QueryBuffer>& resultBuffer, const QStringList& platforms, const InclusionOptions& inclusionOptions,
std::optional<const QList<QUuid>*> idInclusionFilter)
{
Expand Down Expand Up @@ -883,6 +926,15 @@ DbError Db::updateGameDataOnDiskState(QList<int> packIds, bool onDisk)
return DbError();
}

/* TODO: Technically this is a shortcut. The regular launcher will check for Game Redirects in all cases where an ID is searched
* for, often using coalesce (see https://github.com/FlashpointProject/FPA-Rust/blob/03a4ddc4af9ae0b2773c5f678268cb9c944d893f/crates/flashpoint-archive/src/game/mod.rs#L323).
* This makes sense if anyone is using this lib for any reason (which although that is the intention, currently no one is); but in the case of CLIFp/FIL, where
* IDs are only sought out directly, or in bulk, we can just swap the target ID (if a direct is present) before even hitting the database with it.
* Just keep in mind the ideal long term thing to do is have the redirects considered whenever checking the database for a game ID at all. This could
* also be an issue if a source ID is still used somewhere else in the DB, for example add_app or game_data, but that does not seem to be the case currently.
*/
QUuid Db::handleGameRedirects(const QUuid& gameId) { return mGameRedirects.value(gameId, gameId); }

//-Slots ------------------------------------------------------------------------------------------------------
//Private:
void Db::connectedThreadDestroyed(QObject* thread)
Expand Down

0 comments on commit fe74bc9

Please sign in to comment.