Skip to content

Commit

Permalink
Add optional argument passthrough to executable for c-play
Browse files Browse the repository at this point in the history
  • Loading branch information
oblivioncth committed Aug 17, 2024
1 parent f0df30f commit 31be81b
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 16 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,11 @@ Options:

- [Title Command](#title-commands) options

Notes:
- You can use `--` to pass arguments directly to the title's underlying executable/script, which can be useful for testing or customizing your experience:

CLIFp play -t "One Stick Man!" -- -monitor 2

--------------------------------------------------------------------------------

**prepare** - Initializes Flashpoint for playing the provided Data Pack based title by UUID. If the title does not use a Data Pack this command has no effect.
Expand Down
19 changes: 17 additions & 2 deletions app/src/command/c-play.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ Fp::AddApp CPlay::buildAdditionalApp(const Fp::Db::QueryBuffer& addAppResult)

//-Instance Functions-------------------------------------------------------------
//Private:
void CPlay::addPassthroughParameters(QString& param)
{
// Consider all positional arguments (can be explicitly added with "-- <args>") to be passthrough
QStringList ptp = mParser.positionalArguments();
if(!ptp.isEmpty())
{
param.append(u' ');
param.append(TExec::joinArguments(ptp));
}
}

QString CPlay::getServerOverride(const Fp::GameData& gd)
{
QString override = gd.isNull() ? QString() : gd.parameters().server();
Expand Down Expand Up @@ -240,13 +251,15 @@ Qx::Error CPlay::enqueueAdditionalApp(const Fp::AddApp& addApp, const QString& p
{
QString addAppPath = mCore.resolveFullAppPath(addApp.appPath(), platform);
QFileInfo addAppPathInfo(addAppPath);
QString param = addApp.launchCommand();
addPassthroughParameters(param);

TExec* addAppTask = new TExec(&mCore);
addAppTask->setIdentifier(addApp.name());
addAppTask->setStage(taskStage);
addAppTask->setExecutable(QDir::cleanPath(addAppPathInfo.absoluteFilePath())); // Like canonical but doesn't care if path DNE
addAppTask->setDirectory(addAppPathInfo.absoluteDir());
addAppTask->setParameters(addApp.launchCommand());
addAppTask->setParameters(param);
addAppTask->setEnvironment(mCore.childTitleProcessEnvironment());
addAppTask->setProcessType(addApp.isWaitExit() || taskStage == Task::Stage::Primary ? TExec::ProcessType::Blocking : TExec::ProcessType::Deferred);

Expand All @@ -268,13 +281,15 @@ Qx::Error CPlay::enqueueGame(const Fp::Game& game, const Fp::GameData& gameData,
QString gamePath = mCore.resolveFullAppPath(!gameData.isNull() ? gameData.appPath() : game.appPath(),
game.platformName());
QFileInfo gamePathInfo(gamePath);
QString param = !gameData.isNull() ? gameData.launchCommand() : game.launchCommand();
addPassthroughParameters(param);

TExec* gameTask = new TExec(&mCore);
gameTask->setIdentifier(game.title());
gameTask->setStage(taskStage);
gameTask->setExecutable(QDir::cleanPath(gamePathInfo.absoluteFilePath())); // Like canonical but doesn't care if path DNE
gameTask->setDirectory(gamePathInfo.absoluteDir());
gameTask->setParameters(!gameData.isNull() ? gameData.launchCommand() : game.launchCommand());
gameTask->setParameters(param);
gameTask->setEnvironment(mCore.childTitleProcessEnvironment());
gameTask->setProcessType(TExec::ProcessType::Blocking);

Expand Down
11 changes: 6 additions & 5 deletions app/src/command/c-play.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,31 @@
class QX_ERROR_TYPE(CPlayError, "CPlayError", 1212)
{
friend class CPlay;
//-Class Enums-------------------------------------------------------------
//-Class Enums-------------------------------------------------------------
public:
enum Type
{
NoError = 0,
InvalidUrl = 1,
};

//-Class Variables-------------------------------------------------------------
//-Class Variables-------------------------------------------------------------
private:
static inline const QHash<Type, QString> ERR_STRINGS{
{NoError, u""_s},
{InvalidUrl, u"The provided 'flashpoint://' scheme URL is invalid."_s}
};

//-Instance Variables-------------------------------------------------------------
//-Instance Variables-------------------------------------------------------------
private:
Type mType;
QString mSpecific;

//-Constructor-------------------------------------------------------------
//-Constructor-------------------------------------------------------------
private:
CPlayError(Type t = NoError, const QString& s = {});

//-Instance Functions-------------------------------------------------------------
//-Instance Functions-------------------------------------------------------------
public:
bool isValid() const;
Type type() const;
Expand Down Expand Up @@ -93,6 +93,7 @@ class CPlay : public TitleCommand

//-Instance Functions------------------------------------------------------------------------------------------------------
private:
void addPassthroughParameters(QString& param);
QString getServerOverride(const Fp::GameData& gd);
Qx::Error handleEntry(const Fp::Game& game);
Qx::Error handleEntry(const Fp::AddApp& addApp);
Expand Down
20 changes: 14 additions & 6 deletions app/src/task/t-exec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
// Project Includes
#include "utility.h"

// TODO: See if any quote handling here can be replaced with std::quoted()

//===============================================================================================================
// TExecError
//===============================================================================================================
Expand Down Expand Up @@ -39,13 +41,13 @@ QString TExecError::deriveSecondary() const { return mSpecific; }
//Public:
TExec::TExec(QObject* parent) :
Task(parent),
mEnvironment(smDefaultEnv),
mBlockingProcessManager(nullptr)
mBlockingProcessManager(nullptr),
mEnvironment(smDefaultEnv)
{}

//-Class Functions----------------------------------------------------------------
//Private:
QString TExec::collapseArguments(const QStringList& args)
//Public:
QString TExec::joinArguments(const QStringList& args)
{
QString reduction;
for(int i = 0; i < args.size(); i++)
Expand All @@ -67,7 +69,6 @@ QString TExec::collapseArguments(const QStringList& args)
return reduction;
}

//Public:
void TExec::installDeferredProcessManager(DeferredProcessManager* manager) { smDeferredProcessManager = manager; }
DeferredProcessManager* TExec::deferredProcessManager() { return smDeferredProcessManager; }
void TExec::setDefaultProcessEnvironment(const QProcessEnvironment pe) { smDefaultEnv = pe; }
Expand All @@ -91,7 +92,7 @@ QString TExec::createEscapedShellArguments()
{
// Collapse
QStringList parameters = std::get<QStringList>(mParameters);
QString collapsedParameters = collapseArguments(parameters);
QString collapsedParameters = joinArguments(parameters);

// Escape
escapedArgs = escapeForShell(collapsedParameters);
Expand Down Expand Up @@ -204,6 +205,13 @@ QString TExec::identifier() const { return mIdentifier; }

void TExec::setExecutable(QString executable) { mExecutable = executable; }
void TExec::setDirectory(QDir directory) { mDirectory = directory; }

/* TODO: Initial testing shows that it may be safe to simply use QProcess::splitCommand() on all single string
* commands so that they can universally be stored as a QStringList and bypass the need for QProcess::setNativeArguments(),
* but this would be a huge change that would needs lots of testing (especially for sh/bat), and perhaps even a separate build
* for people willing to test to test it for a while since it has the potential to break many games if it doesn't work
* out as initially hopped.
*/
void TExec::setParameters(const std::variant<QString, QStringList>& parameters) { mParameters = parameters; }
void TExec::setEnvironment(const QProcessEnvironment& environment) { mEnvironment = environment; }
void TExec::setProcessType(ProcessType processType) { mProcessType = processType; }
Expand Down
4 changes: 1 addition & 3 deletions app/src/task/t-exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,8 @@ class TExec : public Task
TExec(QObject* parent);

//-Class Functions-----------------------------------------------------------------------------------------------------
private:
static QString collapseArguments(const QStringList& args);

public:
static QString joinArguments(const QStringList& args);
static void installDeferredProcessManager(DeferredProcessManager* manager);
static DeferredProcessManager* deferredProcessManager();
static void setDefaultProcessEnvironment(const QProcessEnvironment pe);
Expand Down

0 comments on commit 31be81b

Please sign in to comment.