Skip to content

Commit

Permalink
Merge pull request #69 from oblivioncth/dev
Browse files Browse the repository at this point in the history
Merge to master for v0.9.7
  • Loading branch information
oblivioncth authored Oct 17, 2023
2 parents 656e0b4 + 590131b commit 75d9ce1
Show file tree
Hide file tree
Showing 18 changed files with 1,048 additions and 487 deletions.
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

0 comments on commit 75d9ce1

Please sign in to comment.