Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge to master for v0.9.7 #69

Merged
merged 12 commits into from
Oct 17, 2023
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.24.0...3.26.0)
# Project
# NOTE: DON'T USE TRAILING ZEROS IN VERSIONS
project(CLIFp
VERSION 0.9.6
VERSION 0.9.7
LANGUAGES CXX
DESCRIPTION "Command-line Interface for Flashpoint Archive"
)
Expand Down Expand Up @@ -79,7 +79,7 @@ ob_fetch_qx(

# Fetch libfp (build and import from source)
include(OB/Fetchlibfp)
ob_fetch_libfp("v0.4.2.2")
ob_fetch_libfp("v0.5")

# Fetch QI-QMP (build and import from source)
include(OB/FetchQI-QMP)
Expand Down
10 changes: 7 additions & 3 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,12 @@ set(CLIFP_SOURCE
tools/blockingprocessmanager.cpp
tools/deferredprocessmanager.h
tools/deferredprocessmanager.cpp
tools/mounter.h
tools/mounter.cpp
tools/mounter_proxy.h
tools/mounter_proxy.cpp
tools/mounter_qmp.h
tools/mounter_qmp.cpp
tools/mounter_router.h
tools/mounter_router.cpp
frontend/statusrelay.h
frontend/statusrelay.cpp
controller.h
Expand All @@ -67,9 +71,9 @@ set(CLIFP_LINKS
Qx::Network
Qx::Widgets
Fp::Fp
QI-QMP::Qmpi
QuaZip::QuaZip
magic_enum::magic_enum
QI-QMP::Qmpi
)

if(CMAKE_SYSTEM_NAME STREQUAL Windows)
Expand Down
109 changes: 72 additions & 37 deletions app/src/kernel/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -322,14 +322,46 @@ void Core::attachFlashpoint(std::unique_ptr<Fp::Install> flashpointInstall)
mFlashpointInstall = std::move(flashpointInstall);

// Note install details
QString dmns = QString(magic_enum::enum_flags_name(static_cast<Fp::KnownDaemon>(mFlashpointInstall->services().recognizedDaemons.toInt())).data());
logEvent(NAME, LOG_EVENT_RECOGNIZED_DAEMONS.arg(dmns));
logEvent(NAME, LOG_EVENT_FLASHPOINT_VERSION_TXT.arg(mFlashpointInstall->nameVersionString()));
logEvent(NAME, LOG_EVENT_FLASHPOINT_VERSION.arg(mFlashpointInstall->version().toString()));
logEvent(NAME, LOG_EVENT_FLASHPOINT_EDITION.arg(ENUM_NAME(mFlashpointInstall->edition())));
logEvent(NAME, LOG_EVENT_OUTFITTED_DAEMON.arg(ENUM_NAME(mFlashpointInstall->outfittedDaemon())));

// Initialize child process env var
mChildTitleProcEnv = QProcessEnvironment::systemEnvironment();
// Initialize child process env vars
QProcessEnvironment de = QProcessEnvironment::systemEnvironment();
QString fpPath = mFlashpointInstall->fullPath();

#ifdef __linux__
// Add platform support environment variables
if(mFlashpointInstall->outfittedDaemon() == Fp::Daemon::Qemu) // Appimage based build
{
QString pathValue = de.value(u"PATH"_s);
pathValue.prepend(fpPath + u"/FPSoftware/FPWine/bin:"_s + fpPath + u"/FPSoftware/FPQemuPHP:"_s);
de.insert(u"PATH"_s, pathValue);
qputenv("PATH", pathValue.toLocal8Bit()); // Path needs to be updated for self as well

de.insert(u"GTK_USE_PORTAL"_s, "1");
de.remove(u"LD_PRELOAD"_s);
}
else // Regular Linux build
{
QString winFpPath = u"Z:"_s + fpPath;

de.insert(u"DIR"_s, fpPath);
de.insert(u"WINDOWS_DIR"_s, winFpPath);
de.insert(u"FP_STARTUP_PATH"_s, winFpPath + u"\\FPSoftware"_s);
de.insert(u"FP_BROWSER_PLUGINS"_s, winFpPath + u"\\FPSoftware\\BrowserPlugins"_s);
de.insert(u"WINEPREFIX"_s, fpPath + u"/FPSoftware/Wine"_s);
}
#endif

TExec::setDefaultProcessEnvironment(de);

// Initialize title specific child process env vars
mChildTitleProcEnv = de;

// Add FP root var
mChildTitleProcEnv.insert(u"FP_PATH"_s, mFlashpointInstall->fullPath());
mChildTitleProcEnv.insert(u"FP_PATH"_s, fpPath);

#ifdef __linux__
// Add HTTTP proxy var
Expand Down Expand Up @@ -408,26 +440,29 @@ CoreError Core::enqueueStartupTasks()
logEvent(NAME, LOG_EVENT_ENQ_START);

#ifdef __linux__
/* On Linux X11 Server needs to be temporarily be set to allow connections from root for docker
*
* TODO: It should be OK to skip this (and the corresponding shutdown task that reverses it),
* if docker isn't used, but leaving for now.
/* On Linux X11 Server needs to be temporarily be set to allow connections from root for docker,
* if it's in use
*/
TExec* xhostSet = new TExec(this);
xhostSet->setIdentifier(u"xhost Set"_s);
xhostSet->setStage(Task::Stage::Startup);
xhostSet->setExecutable(u"xhost"_s);
xhostSet->setDirectory(mFlashpointInstall->fullPath());
xhostSet->setParameters({u"+SI:localuser:root"_s});
xhostSet->setProcessType(TExec::ProcessType::Blocking);

mTaskQueue.push(xhostSet);
logTask(NAME, xhostSet);

if(mFlashpointInstall->outfittedDaemon() == Fp::Daemon::Docker)
{
TExec* xhostSet = new TExec(this);
xhostSet->setIdentifier(u"xhost Set"_s);
xhostSet->setStage(Task::Stage::Startup);
xhostSet->setExecutable(u"xhost"_s);
xhostSet->setDirectory(mFlashpointInstall->fullPath());
xhostSet->setParameters({u"+SI:localuser:root"_s});
xhostSet->setProcessType(TExec::ProcessType::Blocking);

mTaskQueue.push(xhostSet);
logTask(NAME, xhostSet);
}
#endif

// Get settings
Fp::Services fpServices = mFlashpointInstall->services();
Fp::Config fpConfig = mFlashpointInstall->config();
Fp::Preferences fpPreferences = mFlashpointInstall->preferences();

// Add Start entries from services
for(const Fp::StartStop& startEntry : qAsConst(fpServices.start))
Expand All @@ -447,14 +482,14 @@ CoreError Core::enqueueStartupTasks()
// Add Server entry from services if applicable
if(fpConfig.startServer)
{
if(!fpServices.server.contains(fpConfig.server))
if(!fpServices.server.contains(fpPreferences.server))
{
CoreError err(CoreError::ConfiguredServerMissing);
postError(NAME, err);
return err;
}

Fp::ServerDaemon configuredServer = fpServices.server.value(fpConfig.server);
Fp::ServerDaemon configuredServer = fpServices.server.value(fpPreferences.server);

TExec* serverTask = new TExec(this);
serverTask->setIdentifier(u"Server"_s);
Expand Down Expand Up @@ -485,7 +520,7 @@ CoreError Core::enqueueStartupTasks()

#ifdef __linux__
// On Linux the startup tasks take a while so make sure the docker image is actually running before proceeding
if(mFlashpointInstall->services().recognizedDaemons.testFlag(Fp::KnownDaemon::Docker))
if(mFlashpointInstall->outfittedDaemon() == Fp::Daemon::Docker)
{
TAwaitDocker* dockerWait = new TAwaitDocker(this);
dockerWait->setStage(Task::Stage::Startup);
Expand Down Expand Up @@ -533,17 +568,20 @@ void Core::enqueueShutdownTasks()
}

#ifdef __linux__
// Undo xhost permissions modifications
TExec* xhostClear = new TExec(this);
xhostClear->setIdentifier(u"xhost Clear"_s);
xhostClear->setStage(Task::Stage::Shutdown);
xhostClear->setExecutable(u"xhost"_s);
xhostClear->setDirectory(mFlashpointInstall->fullPath());
xhostClear->setParameters({"-SI:localuser:root"});
xhostClear->setProcessType(TExec::ProcessType::Blocking);

mTaskQueue.push(xhostClear);
logTask(NAME, xhostClear);
// Undo xhost permissions modifications related to docker
if(mFlashpointInstall->outfittedDaemon() == Fp::Daemon::Docker)
{
TExec* xhostClear = new TExec(this);
xhostClear->setIdentifier(u"xhost Clear"_s);
xhostClear->setStage(Task::Stage::Shutdown);
xhostClear->setExecutable(u"xhost"_s);
xhostClear->setDirectory(mFlashpointInstall->fullPath());
xhostClear->setParameters({"-SI:localuser:root"});
xhostClear->setProcessType(TExec::ProcessType::Blocking);

mTaskQueue.push(xhostClear);
logTask(NAME, xhostClear);
}
#endif
}

Expand Down Expand Up @@ -661,15 +699,12 @@ Qx::Error Core::enqueueDataPackTasks(const Fp::GameData& gameData)
{
logEvent(NAME, LOG_EVENT_DATA_PACK_NEEDS_MOUNT);

// Determine if QEMU is involved
bool qemuUsed = mFlashpointInstall->services().recognizedDaemons.testFlag(Fp::KnownDaemon::Qemu);

// Create task
TMount* mountTask = new TMount(this);
mountTask->setStage(Task::Stage::Auxiliary);
mountTask->setTitleId(gameData.gameId());
mountTask->setPath(packDestFolderPath + '/' + packFileName);
mountTask->setSkipQemu(!qemuUsed);
mountTask->setDaemon(mFlashpointInstall->outfittedDaemon());

mTaskQueue.push(mountTask);
logTask(NAME, mountTask);
Expand Down
5 changes: 4 additions & 1 deletion app/src/kernel/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,10 @@ class Core : public QObject
static inline const QString LOG_EVENT_G_HELP_SHOWN = u"Displayed general help information"_s;
static inline const QString LOG_EVENT_VER_SHOWN = u"Displayed version information"_s;
static inline const QString LOG_EVENT_NOTIFCATION_LEVEL = u"Notification Level is: %1"_s;
static inline const QString LOG_EVENT_RECOGNIZED_DAEMONS = u"Recognized service daemons: %1"_s;
static inline const QString LOG_EVENT_FLASHPOINT_VERSION_TXT = u"Flashpoint version.txt: %1"_s;
static inline const QString LOG_EVENT_FLASHPOINT_VERSION = u"Flashpoint version: %1"_s;
static inline const QString LOG_EVENT_FLASHPOINT_EDITION = u"Flashpoint edition: %1"_s;
static inline const QString LOG_EVENT_OUTFITTED_DAEMON = u"Recognized daemon: %1"_s;
static inline const QString LOG_EVENT_ENQ_START = u"Enqueuing startup tasks..."_s;
static inline const QString LOG_EVENT_ENQ_STOP = u"Enqueuing shutdown tasks..."_s;
static inline const QString LOG_EVENT_ENQ_DATA_PACK = u"Enqueuing Data Pack tasks..."_s;
Expand Down
10 changes: 9 additions & 1 deletion app/src/kernel/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,15 @@ std::unique_ptr<Fp::Install> Driver::findFlashpointInstall()
// Attempt to instantiate
fpInstall = std::make_unique<Fp::Install>(currentDir.absolutePath());
if(fpInstall->isValid())
break;
{
if(fpInstall->outfittedDaemon() == Fp::Daemon::Unknown)
{
mCore->logError(NAME, Qx::GenericError(Qx::Warning, 12011, LOG_WARN_FP_UNRECOGNIZED_DAEMON));
fpInstall.reset();
}
else
break;
}
else
{
mCore->logError(NAME, fpInstall->error().setSeverity(Qx::Warning));
Expand Down
11 changes: 6 additions & 5 deletions app/src/kernel/driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
class QX_ERROR_TYPE(DriverError, "DriverError", 1201)
{
friend class Driver;
//-Class Enums-------------------------------------------------------------
//-Class Enums-------------------------------------------------------------
public:
enum Type
{
Expand All @@ -25,7 +25,7 @@ class QX_ERROR_TYPE(DriverError, "DriverError", 1201)
InvalidInstall = 3,
};

//-Class Variables-------------------------------------------------------------
//-Class Variables-------------------------------------------------------------
private:
static inline const QHash<Type, QString> ERR_STRINGS{
{NoError, u""_s},
Expand All @@ -34,16 +34,16 @@ class QX_ERROR_TYPE(DriverError, "DriverError", 1201)
{InvalidInstall, u"CLIFp does not appear to be deployed in a valid Flashpoint install"_s}
};

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

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

//-Instance Functions-------------------------------------------------------------
//-Instance Functions-------------------------------------------------------------
public:
bool isValid() const;
Type type() const;
Expand Down Expand Up @@ -71,6 +71,7 @@ class Driver : public QObject
// Logging
static inline const QString LOG_EVENT_FLASHPOINT_SEARCH = u"Searching for Flashpoint root..."_s;
static inline const QString LOG_EVENT_FLASHPOINT_ROOT_CHECK = uR"(Checking if "%1" is flashpoint root)"_s;
static inline const QString LOG_WARN_FP_UNRECOGNIZED_DAEMON = "Flashpoint install does not contain a recognized daemon!";
static inline const QString LOG_EVENT_FLASHPOINT_LINK = uR"(Linked to Flashpoint install at: "%1")"_s;
static inline const QString LOG_EVENT_TASK_COUNT = u"%1 task(s) to perform"_s;
static inline const QString LOG_EVENT_QUEUE_START = u"Processing Task queue"_s;
Expand Down
10 changes: 6 additions & 4 deletions app/src/task/t-exec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ QString TExecError::deriveSecondary() const { return mSpecific; }
//Public:
TExec::TExec(QObject* parent) :
Task(parent),
mEnvironment(smDefaultEnv),
mBlockingProcessManager(nullptr)
{}

Expand Down Expand Up @@ -69,6 +70,8 @@ QString TExec::collapseArguments(const QStringList& args)
//Public:
void TExec::installDeferredProcessManager(DeferredProcessManager* manager) { smDeferredProcessManager = manager; }
DeferredProcessManager* TExec::deferredProcessManager() { return smDeferredProcessManager; }
void TExec::setDefaultProcessEnvironment(const QProcessEnvironment pe) { smDefaultEnv = pe; }
QProcessEnvironment TExec::defaultProcessEnvironment() { return smDefaultEnv; }

//-Instance Functions-------------------------------------------------------------
//Private:
Expand Down Expand Up @@ -125,7 +128,7 @@ TExecError TExec::cleanStartProcess(QProcess* process)
// Make sure process starts
if(!process->waitForStarted())
{
TExecError err(TExecError::CouldNotStart, ERR_DETAILS_TEMPLATE.arg(mExecutable, ENUM_NAME(process->error())));
TExecError err(TExecError::CouldNotStart, ERR_DETAILS_TEMPLATE.arg(process->program(), ENUM_NAME(process->error())));
emit errorOccurred(NAME, err);
delete process; // Clear finished process handle from heap
return err;
Expand Down Expand Up @@ -185,8 +188,7 @@ void TExec::perform()
logPreparedProcess(taskProcess);

// Set common process properties
if(!mEnvironment.isEmpty()) // Don't override the QProcess default (use system env.) if no custom env. was set
taskProcess->setProcessEnvironment(mEnvironment);
taskProcess->setProcessEnvironment(mEnvironment);

// Cover each process type
switch(mProcessType)
Expand Down Expand Up @@ -231,7 +233,7 @@ void TExec::perform()
taskProcess->setStandardErrorFile(QProcess::nullDevice());
if(!taskProcess->startDetached())
{
TExecError err(TExecError::CouldNotStart, ERR_DETAILS_TEMPLATE.arg(mExecutable, ENUM_NAME(taskProcess->error())));
TExecError err(TExecError::CouldNotStart, ERR_DETAILS_TEMPLATE.arg(taskProcess->program(), ENUM_NAME(taskProcess->error())));
emit errorOccurred(NAME, err);
emit complete(err);
return;
Expand Down
3 changes: 3 additions & 0 deletions app/src/task/t-exec.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ class TExec : public Task

// Deferred Processes
static inline DeferredProcessManager* smDeferredProcessManager;
static inline QProcessEnvironment smDefaultEnv;

//-Instance Variables------------------------------------------------------------------------------------------------
private:
Expand All @@ -122,6 +123,8 @@ class TExec : public Task
public:
static void installDeferredProcessManager(DeferredProcessManager* manager);
static DeferredProcessManager* deferredProcessManager();
static void setDefaultProcessEnvironment(const QProcessEnvironment pe);
static QProcessEnvironment defaultProcessEnvironment();

//-Instance Functions------------------------------------------------------------------------------------------------------
private:
Expand Down
Loading
Loading