diff options
-rw-r--r-- | data/appsettings.cpp | 2 | ||||
-rw-r--r-- | data/appsettings.h | 2 | ||||
-rw-r--r-- | data/minecraftprocess.cpp | 324 | ||||
-rw-r--r-- | gui/mainwindow.cpp | 6 | ||||
-rw-r--r-- | gui/settingsdialog.cpp | 4 | ||||
-rw-r--r-- | libinstance/include/instance.h | 12 | ||||
-rw-r--r-- | libinstance/src/instance.cpp | 7 | ||||
-rw-r--r-- | libsettings/include/settingsobject.h | 5 | ||||
-rw-r--r-- | libsettings/src/settingsobject.cpp | 2 | ||||
-rw-r--r-- | libutil/include/cmdutils.h | 62 | ||||
-rw-r--r-- | libutil/include/userutils.h | 6 | ||||
-rw-r--r-- | libutil/src/cmdutils.cpp | 654 | ||||
-rw-r--r-- | libutil/src/userutils.cpp | 158 | ||||
-rw-r--r-- | main.cpp | 6 |
14 files changed, 651 insertions, 599 deletions
diff --git a/data/appsettings.cpp b/data/appsettings.cpp index bdb66535..6b724cd9 100644 --- a/data/appsettings.cpp +++ b/data/appsettings.cpp @@ -20,8 +20,6 @@ #include <QPoint> #include <QColor> -AppSettings *settings; - AppSettings::AppSettings(QObject *parent) : BasicSettingsObject(parent) { diff --git a/data/appsettings.h b/data/appsettings.h index fc0098fc..ba4ef242 100644 --- a/data/appsettings.h +++ b/data/appsettings.h @@ -27,6 +27,4 @@ public: explicit AppSettings(QObject *parent = 0); }; -extern AppSettings *settings; - #endif // APPSETTINGS_H diff --git a/data/minecraftprocess.cpp b/data/minecraftprocess.cpp index d08b767c..1eea8f82 100644 --- a/data/minecraftprocess.cpp +++ b/data/minecraftprocess.cpp @@ -34,213 +34,215 @@ // commandline splitter QStringList MinecraftProcess::splitArgs(QString args) { - QStringList argv; - QString current; - bool escape = false; - QChar inquotes; - for (int i=0; i<args.length(); i++) - { - QChar cchar = args.at(i); - - // \ escaped - if (escape) { - current += cchar; - escape = false; - // in "quotes" - } else if (!inquotes.isNull()) { - if (cchar == 0x5C) - escape = true; - else if (cchar == inquotes) - inquotes = 0; - else - current += cchar; - // otherwise - } else { - if (cchar == 0x20) { - if (!current.isEmpty()) { - argv << current; - current.clear(); - } - } else if (cchar == 0x22 || cchar == 0x27) - inquotes = cchar; - else - current += cchar; - } - } - if (!current.isEmpty()) - argv << current; - return argv; + QStringList argv; + QString current; + bool escape = false; + QChar inquotes; + for (int i=0; i<args.length(); i++) + { + QChar cchar = args.at(i); + + // \ escaped + if (escape) { + current += cchar; + escape = false; + // in "quotes" + } else if (!inquotes.isNull()) { + if (cchar == 0x5C) + escape = true; + else if (cchar == inquotes) + inquotes = 0; + else + current += cchar; + // otherwise + } else { + if (cchar == 0x20) { + if (!current.isEmpty()) { + argv << current; + current.clear(); + } + } else if (cchar == 0x22 || cchar == 0x27) + inquotes = cchar; + else + current += cchar; + } + } + if (!current.isEmpty()) + argv << current; + return argv; } // prepare tools inline void MinecraftProcess::extractIcon(InstancePtr inst, QString destination) { - QImage(":/icons/instances/" + inst->iconKey()).save(destination); + QImage(":/icons/instances/" + inst->iconKey()).save(destination); } inline void MinecraftProcess::extractLauncher(QString destination) { - QFile(":/launcher/launcher.jar").copy(destination); + QFile(":/launcher/launcher.jar").copy(destination); } void MinecraftProcess::prepare(InstancePtr inst) { - extractLauncher(PathCombine(inst->minecraftDir(), LAUNCHER_FILE)); - extractIcon(inst, PathCombine(inst->minecraftDir(), "icon.png")); + extractLauncher(PathCombine(inst->minecraftDir(), LAUNCHER_FILE)); + extractIcon(inst, PathCombine(inst->minecraftDir(), "icon.png")); } // constructor MinecraftProcess::MinecraftProcess(InstancePtr inst, QString user, QString session, ConsoleWindow *console) : - m_instance(inst), m_user(user), m_session(session), m_console(console) + m_instance(inst), m_user(user), m_session(session), m_console(console) { - connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(finish(int, QProcess::ExitStatus))); - - // prepare the process environment - QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); - + connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(finish(int, QProcess::ExitStatus))); + + // prepare the process environment + QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); + #ifdef LINUX - // Strip IBus - if (env.value("XMODIFIERS").contains(IBUS)) - env.insert("XMODIFIERS", env.value("XMODIFIERS").replace(IBUS, "")); + // Strip IBus + if (env.value("XMODIFIERS").contains(IBUS)) + env.insert("XMODIFIERS", env.value("XMODIFIERS").replace(IBUS, "")); #endif - - // export some infos - env.insert("INST_NAME", inst->name()); - env.insert("INST_ID", inst->id()); - env.insert("INST_DIR", QDir(inst->rootDir()).absolutePath()); - - this->setProcessEnvironment(env); - m_prepostlaunchprocess.setProcessEnvironment(env); - - // set the cwd - QDir mcDir(inst->minecraftDir()); - this->setWorkingDirectory(mcDir.absolutePath()); - m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath()); - - // std channels - connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr())); - connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); + + // export some infos + env.insert("INST_NAME", inst->name()); + env.insert("INST_ID", inst->id()); + env.insert("INST_DIR", QDir(inst->rootDir()).absolutePath()); + + this->setProcessEnvironment(env); + m_prepostlaunchprocess.setProcessEnvironment(env); + + // set the cwd + QDir mcDir(inst->minecraftDir()); + this->setWorkingDirectory(mcDir.absolutePath()); + m_prepostlaunchprocess.setWorkingDirectory(mcDir.absolutePath()); + + // std channels + connect(this, SIGNAL(readyReadStandardError()), SLOT(on_stdErr())); + connect(this, SIGNAL(readyReadStandardOutput()), SLOT(on_stdOut())); } // console window void MinecraftProcess::on_stdErr() { - if (m_console != nullptr) - m_console->write(readAllStandardError(), ConsoleWindow::ERROR); + if (m_console != nullptr) + m_console->write(readAllStandardError(), ConsoleWindow::ERROR); } void MinecraftProcess::on_stdOut() { - if (m_console != nullptr) - m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT); + if (m_console != nullptr) + m_console->write(readAllStandardOutput(), ConsoleWindow::DEFAULT); } void MinecraftProcess::log(QString text) { - if (m_console != nullptr) - m_console->write(text); - else - qDebug(qPrintable(text)); + if (m_console != nullptr) + m_console->write(text); + else + qDebug(qPrintable(text)); } // exit handler void MinecraftProcess::finish(int code, ExitStatus status) { - if (status != NormalExit) - { - //TODO: error handling - } - - log("Minecraft exited."); - - m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code)); - - // run post-exit - if (!m_instance->getPostExitCommand().isEmpty()) - { - m_prepostlaunchprocess.start(m_instance->getPostExitCommand()); - m_prepostlaunchprocess.waitForFinished(); - if (m_prepostlaunchprocess.exitStatus() != NormalExit) - { - //TODO: error handling - } - } - - if (m_console != nullptr) - m_console->setMayClose(true); - - emit ended(); + if (status != NormalExit) + { + //TODO: error handling + } + + log("Minecraft exited."); + + m_prepostlaunchprocess.processEnvironment().insert("INST_EXITCODE", QString(code)); + + // run post-exit + if (!m_instance->settings().get("PostExitCommand").toString().isEmpty()) + { + m_prepostlaunchprocess.start(m_instance->settings().get("PostExitCommand").toString()); + m_prepostlaunchprocess.waitForFinished(); + if (m_prepostlaunchprocess.exitStatus() != NormalExit) + { + //TODO: error handling + } + } + + if (m_console != nullptr) + m_console->setMayClose(true); + + emit ended(); } void MinecraftProcess::launch() { - if (!m_instance->getPreLaunchCommand().isEmpty()) - { - m_prepostlaunchprocess.start(m_instance->getPreLaunchCommand()); - m_prepostlaunchprocess.waitForFinished(); - if (m_prepostlaunchprocess.exitStatus() != NormalExit) - { - //TODO: error handling - return; - } - } - - m_instance->setLastLaunch(); - - prepare(m_instance); - - genArgs(); - - log(QString("Minecraft folder is: '%1'").arg(workingDirectory())); - log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '"))); - - start(m_instance->getJavaPath(), m_arguments); - if (!waitForStarted()) - { - //TODO: error handling - } - - if(m_console != nullptr) - m_console->setMayClose(false); + if (!m_instance->settings().get("PreLaunchCommand").toString().isEmpty()) + { + m_prepostlaunchprocess.start(m_instance->settings().get("PreLaunchCommand").toString()); + m_prepostlaunchprocess.waitForFinished(); + if (m_prepostlaunchprocess.exitStatus() != NormalExit) + { + //TODO: error handling + return; + } + } + + m_instance->setLastLaunch(); + + prepare(m_instance); + + genArgs(); + + log(QString("Minecraft folder is: '%1'").arg(workingDirectory())); + log(QString("Instance launched with arguments: '%1'").arg(m_arguments.join("' '"))); + + start(m_instance->settings().get("JavaPath").toString(), m_arguments); + if (!waitForStarted()) + { + //TODO: error handling + } + + if(m_console != nullptr) + m_console->setMayClose(false); } void MinecraftProcess::genArgs() { - // start fresh - m_arguments.clear(); - - // window size - QString windowSize; - if (m_instance->getLaunchMaximized()) - windowSize = "max"; - else - windowSize = QString("%1x%2").arg(m_instance->getMinecraftWinWidth()).arg(m_instance->getMinecraftWinHeight()); - - // window title - QString windowTitle; - windowTitle.append("MultiMC: ").append(m_instance->name()); - - // Java arguments - m_arguments.append(splitArgs(m_instance->getJvmArgs())); - + // start fresh + m_arguments.clear(); + + // window size + QString windowSize; + if (m_instance->settings().get("LaunchMaximized").toBool()) + windowSize = "max"; + else + windowSize = QString("%1x%2"). + arg(m_instance->settings().get("MinecraftWinWidth").toInt()). + arg(m_instance->settings().get("MinecraftWinHeight").toInt()); + + // window title + QString windowTitle; + windowTitle.append("MultiMC: ").append(m_instance->name()); + + // Java arguments + m_arguments.append(splitArgs(m_instance->settings().get("JvmArgs").toString())); + #ifdef OSX - // OSX dock icon and name - m_arguments << "-Xdock:icon=icon.png"; - m_arguments << QString("-Xdock:name=\"%1\"").arg(windowTitle); + // OSX dock icon and name + m_arguments << "-Xdock:icon=icon.png"; + m_arguments << QString("-Xdock:name=\"%1\"").arg(windowTitle); #endif - - // lwjgl - QString lwjgl = m_instance->lwjglVersion(); - if (lwjgl != "Mojang") - lwjgl = QDir(settings->getLWJGLDir() + "/" + lwjgl).absolutePath(); - - // launcher arguments - m_arguments << QString("-Xms%1m").arg(m_instance->getMinMemAlloc()); - m_arguments << QString("-Xmx%1m").arg(m_instance->getMaxMemAlloc()); - m_arguments << "-jar" << LAUNCHER_FILE; - m_arguments << m_user; - m_arguments << m_session; - m_arguments << windowTitle; - m_arguments << windowSize; - m_arguments << lwjgl; + + // lwjgl + QString lwjgl = m_instance->lwjglVersion(); + if (lwjgl != "Mojang") + lwjgl = QDir(globalSettings->get("LWJGLDir").toString() + "/" + lwjgl).absolutePath(); + + // launcher arguments + m_arguments << QString("-Xms%1m").arg(m_instance->settings().get("MinMemAlloc").toInt()); + m_arguments << QString("-Xmx%1m").arg(m_instance->settings().get("MaxMemAlloc").toInt()); + m_arguments << "-jar" << LAUNCHER_FILE; + m_arguments << m_user; + m_arguments << m_session; + m_arguments << windowTitle; + m_arguments << windowSize; + m_arguments << lwjgl; } diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 87661da6..447a6619 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -53,7 +53,7 @@ void openInDefaultProgram(QString filename); MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), - instList(settings->get("InstanceDir").toString()) + instList(globalSettings->get("InstanceDir").toString()) { ui->setupUi(this); @@ -78,7 +78,7 @@ void MainWindow::on_actionAddInstance_triggered() void MainWindow::on_actionViewInstanceFolder_triggered() { - openInDefaultProgram(settings->get("InstanceDir").toString()); + openInDefaultProgram(globalSettings->get("InstanceDir").toString()); } void MainWindow::on_actionRefresh_triggered() @@ -88,7 +88,7 @@ void MainWindow::on_actionRefresh_triggered() void MainWindow::on_actionViewCentralModsFolder_triggered() { - openInDefaultProgram(settings->get("CentralModsDir").toString()); + openInDefaultProgram(globalSettings->get("CentralModsDir").toString()); } void MainWindow::on_actionCheckUpdate_triggered() diff --git a/gui/settingsdialog.cpp b/gui/settingsdialog.cpp index bc10560d..7c8eacd1 100644 --- a/gui/settingsdialog.cpp +++ b/gui/settingsdialog.cpp @@ -27,7 +27,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) : { ui->setupUi(this); - loadSettings(settings); + loadSettings(globalSettings); updateCheckboxStuff(); } @@ -84,7 +84,7 @@ void SettingsDialog::on_maximizedCheckBox_clicked(bool checked) void SettingsDialog::on_buttonBox_accepted() { - applySettings(settings); + applySettings(globalSettings); } void SettingsDialog::applySettings(SettingsObject *s) diff --git a/libinstance/include/instance.h b/libinstance/include/instance.h index fcf5fa97..5a9a7b02 100644 --- a/libinstance/include/instance.h +++ b/libinstance/include/instance.h @@ -19,6 +19,8 @@ #include <QObject> #include <QDateTime> +#include <settingsobject.h> + #include "inifile.h" #include "libinstance_config.h" @@ -280,6 +282,16 @@ public: */ virtual void updateCurrentVersion(bool keepCurrent = false) = 0; + + //// Settings System //// + + /*! + * \brief Gets this instance's settings object. + * This settings object stores instance-specific settings. + * \return A pointer to this instance's settings object. + */ + virtual SettingsObject &settings(); + protected: /*! * \brief Gets the value of the given field in the instance's config file. diff --git a/libinstance/src/instance.cpp b/libinstance/src/instance.cpp index ac0eca24..85b43640 100644 --- a/libinstance/src/instance.cpp +++ b/libinstance/src/instance.cpp @@ -17,6 +17,8 @@ #include <QFileInfo> +#include "settingsobject.h" + #include "pathutils.h" Instance::Instance(const QString &rootDir, QObject *parent) : @@ -104,3 +106,8 @@ void Instance::setField(const QString &name, QVariant val) { config.set(name, val); } + +SettingsObject &Instance::settings() +{ + return *globalSettings; +} diff --git a/libsettings/include/settingsobject.h b/libsettings/include/settingsobject.h index 3f09b72c..f35d01b1 100644 --- a/libsettings/include/settingsobject.h +++ b/libsettings/include/settingsobject.h @@ -162,4 +162,9 @@ private: QMap<QString, Setting *> m_settings; }; +/*! + * \brief A global settings object. + */ +LIBMMCSETTINGS_EXPORT extern SettingsObject *globalSettings; + #endif // SETTINGSOBJECT_H diff --git a/libsettings/src/settingsobject.cpp b/libsettings/src/settingsobject.cpp index 27fbb40a..98c7b479 100644 --- a/libsettings/src/settingsobject.cpp +++ b/libsettings/src/settingsobject.cpp @@ -18,6 +18,8 @@ #include <QVariant> +SettingsObject *globalSettings; + SettingsObject::SettingsObject(QObject *parent) : QObject(parent) { diff --git a/libutil/include/cmdutils.h b/libutil/include/cmdutils.h index d75a1773..984826d6 100644 --- a/libutil/include/cmdutils.h +++ b/libutil/include/cmdutils.h @@ -25,6 +25,8 @@ #include <QHash> #include <QStringList> +#include "libutil_config.h" + /** * @file libutil/include/cmdutils.h * @brief commandline parsing utilities @@ -37,7 +39,11 @@ namespace Commandline { * @brief The FlagStyle enum * Specifies how flags are decorated */ -enum class FlagStyle { + +namespace FlagStyle +{ +enum LIBMMCUTIL_EXPORT Enum +{ GNU, /**< --option and -o (GNU Style) */ Unix, /**< -option and -o (Unix Style) */ Windows, /**< /option and /o (Windows Style) */ @@ -47,11 +53,15 @@ enum class FlagStyle { Default = GNU #endif }; +} /** * @brief The ArgumentStyle enum */ -enum class ArgumentStyle { +namespace ArgumentStyle +{ +enum LIBMMCUTIL_EXPORT Enum +{ Space, /**< --option=value */ Equals, /**< --option value */ SpaceAndEquals, /**< --option[= ]value */ @@ -61,11 +71,21 @@ enum class ArgumentStyle { Default = SpaceAndEquals #endif }; +} + +namespace OptionType +{ +enum LIBMMCUTIL_EXPORT Enum +{ + Switch, + Option +}; +} /** * @brief The ParsingError class */ -class ParsingError : public std::exception +class LIBMMCUTIL_EXPORT ParsingError : public std::exception { public: ParsingError(const QString &what); @@ -80,7 +100,7 @@ private: /** * @brief The Parser class */ -class Parser +class LIBMMCUTIL_EXPORT Parser { public: /** @@ -88,45 +108,46 @@ public: * @param flagStyle the FlagStyle to use in this Parser * @param argStyle the ArgumentStyle to use in this Parser */ - Parser(FlagStyle flagStyle=FlagStyle::Default, ArgumentStyle argStyle=ArgumentStyle::Default); + Parser(FlagStyle::Enum flagStyle = FlagStyle::Default, + ArgumentStyle::Enum argStyle = ArgumentStyle::Default); /** * @brief set the flag style * @param style */ - void setFlagStyle(FlagStyle style); + void setFlagStyle(FlagStyle::Enum style); /** * @brief get the flag style * @return */ - FlagStyle flagStyle(); + FlagStyle::Enum flagStyle(); /** * @brief set the argument style * @param style */ - void setArgumentStyle(ArgumentStyle style); + void setArgumentStyle(ArgumentStyle::Enum style); /** * @brief get the argument style * @return */ - ArgumentStyle argumentStyle(); + ArgumentStyle::Enum argumentStyle(); /** * @brief define a boolean switch * @param name the parameter name * @param def the default value */ - void addSwitch(QString name, bool def=false); + void addSwitch(QString name, bool def = false); /** * @brief define an option that takes an additional argument * @param name the parameter name * @param def the default value */ - void addOption(QString name, QVariant def=QVariant()); + void addOption(QString name, QVariant def = QVariant()); /** * @brief define a positional argument @@ -134,7 +155,7 @@ public: * @param required wether this argument is required * @param def the default value */ - void addArgument(QString name, bool required=true, QVariant def=QVariant()); + void addArgument(QString name, bool required = true, QVariant def = QVariant()); /** * @brief adds a flag to an existing parameter @@ -153,7 +174,7 @@ public: * Note: on positional arguments, metavar replaces the name as displayed. * on options , metavar replaces the value placeholder */ - void addDocumentation(QString name, QString doc, QString metavar=QString()); + void addDocumentation(QString name, QString doc, QString metavar = QString()); /** * @brief generate a help message @@ -162,7 +183,7 @@ public: * @param flagsInUsage whether we should use flags instead of options in the usage * @return a help message */ - QString compileHelp(QString progName, int helpIndent=22, bool flagsInUsage=true); + QString compileHelp(QString progName, int helpIndent = 22, bool flagsInUsage = true); /** * @brief generate a short usage message @@ -170,7 +191,7 @@ public: * @param useFlags whether we should use flags instead of options * @return a usage message */ - QString compileUsage(QString progName, bool useFlags=true); + QString compileUsage(QString progName, bool useFlags = true); /** * @brief parse @@ -187,13 +208,8 @@ public: ~Parser(); private: - FlagStyle m_flagStyle; - ArgumentStyle m_argStyle; - - enum class OptionType { - Switch, - Option - }; + FlagStyle::Enum m_flagStyle; + ArgumentStyle::Enum m_argStyle; // Important: the common part MUST BE COMMON ON ALL THREE structs struct CommonDef { @@ -210,7 +226,7 @@ private: QString metavar; QVariant def; // option - OptionType type; + OptionType::Enum type; QChar flag; }; diff --git a/libutil/include/userutils.h b/libutil/include/userutils.h index 2ea1d457..06a8ca16 100644 --- a/libutil/include/userutils.h +++ b/libutil/include/userutils.h @@ -3,15 +3,17 @@ #include <QString> +#include "libutil_config.h" + namespace Util { // Get the Directory representing the User's Desktop -QString getDesktopDir(); +LIBMMCUTIL_EXPORT QString getDesktopDir(); // Create a shortcut at *location*, pointing to *dest* called with the arguments *args* // call it *name* and assign it the icon *icon* // return true if operation succeeded -bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation); +LIBMMCUTIL_EXPORT bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation); } #endif // USERUTILS_H diff --git a/libutil/src/cmdutils.cpp b/libutil/src/cmdutils.cpp index cff7acb9..3bf4e872 100644 --- a/libutil/src/cmdutils.cpp +++ b/libutil/src/cmdutils.cpp @@ -24,410 +24,410 @@ namespace Util { namespace Commandline { -Parser::Parser(FlagStyle flagStyle, ArgumentStyle argStyle) +Parser::Parser(FlagStyle::Enum flagStyle, ArgumentStyle::Enum argStyle) { - m_flagStyle = flagStyle; - m_argStyle = argStyle; + m_flagStyle = flagStyle; + m_argStyle = argStyle; } // styles setter/getter -void Parser::setArgumentStyle(ArgumentStyle style) +void Parser::setArgumentStyle(ArgumentStyle::Enum style) { - m_argStyle = style; + m_argStyle = style; } -ArgumentStyle Parser::argumentStyle() +ArgumentStyle::Enum Parser::argumentStyle() { - return m_argStyle; + return m_argStyle; } -void Parser::setFlagStyle(FlagStyle style) +void Parser::setFlagStyle(FlagStyle::Enum style) { - m_flagStyle = style; + m_flagStyle = style; } -FlagStyle Parser::flagStyle() +FlagStyle::Enum Parser::flagStyle() { - return m_flagStyle; + return m_flagStyle; } // setup methods void Parser::addSwitch(QString name, bool def) { - if (m_params.contains(name)) - throw "Name not unique"; - - OptionDef *param = new OptionDef; - param->type = OptionType::Switch; - param->name = name; - param->metavar = QString("<%1>").arg(name); - param->def = def; - - m_options[name] = param; - m_params[name] = (CommonDef *)param; - m_optionList.append(param); + if (m_params.contains(name)) + throw "Name not unique"; + + OptionDef *param = new OptionDef; + param->type = OptionType::Switch; + param->name = name; + param->metavar = QString("<%1>").arg(name); + param->def = def; + + m_options[name] = param; + m_params[name] = (CommonDef *)param; + m_optionList.append(param); } void Parser::addOption(QString name, QVariant def) { - if (m_params.contains(name)) - throw "Name not unique"; - - OptionDef *param = new OptionDef; - param->type = OptionType::Option; - param->name = name; - param->metavar = QString("<%1>").arg(name); - param->def = def; - - m_options[name] = param; - m_params[name] = (CommonDef *)param; - m_optionList.append(param); + if (m_params.contains(name)) + throw "Name not unique"; + + OptionDef *param = new OptionDef; + param->type = OptionType::Option; + param->name = name; + param->metavar = QString("<%1>").arg(name); + param->def = def; + + m_options[name] = param; + m_params[name] = (CommonDef *)param; + m_optionList.append(param); } void Parser::addArgument(QString name, bool required, QVariant def) { - if (m_params.contains(name)) - throw "Name not unique"; - - PositionalDef *param = new PositionalDef; - param->name = name; - param->def = def; - param->required = required; - param->metavar = name; - - m_positionals.append(param); - m_params[name] = (CommonDef *)param; + if (m_params.contains(name)) + throw "Name not unique"; + + PositionalDef *param = new PositionalDef; + param->name = name; + param->def = def; + param->required = required; + param->metavar = name; + + m_positionals.append(param); + m_params[name] = (CommonDef *)param; } void Parser::addDocumentation(QString name, QString doc, QString metavar) { - if (!m_params.contains(name)) - throw "Name does not exist"; - - CommonDef *param = m_params[name]; - param->doc = doc; - if (!metavar.isNull()) - param->metavar = metavar; + if (!m_params.contains(name)) + throw "Name does not exist"; + + CommonDef *param = m_params[name]; + param->doc = doc; + if (!metavar.isNull()) + param->metavar = metavar; } void Parser::addShortOpt(QString name, QChar flag) { - if (!m_params.contains(name)) - throw "Name does not exist"; - if (!m_options.contains(name)) - throw "Name is not an Option or Swtich"; - - OptionDef *param = m_options[name]; - m_flags[flag] = param; - param->flag = flag; + if (!m_params.contains(name)) + throw "Name does not exist"; + if (!m_options.contains(name)) + throw "Name is not an Option or Swtich"; + + OptionDef *param = m_options[name]; + m_flags[flag] = param; + param->flag = flag; } // help methods QString Parser::compileHelp(QString progName, int helpIndent, bool useFlags) { - QStringList help; - help << compileUsage(progName, useFlags) << "\r\n"; - - // positionals - if (!m_positionals.isEmpty()) - { - help << "\r\n"; - help << "Positional arguments:\r\n"; - QListIterator<PositionalDef *> it2(m_positionals); - while(it2.hasNext()) - { - PositionalDef *param = it2.next(); - help << " " << param->metavar; - help << " " << QString(helpIndent - param->metavar.length() - 1, ' '); - help << param->doc << "\r\n"; - } - } - - // Options - if (!m_optionList.isEmpty()) - { - help << "\r\n"; - QString optPrefix, flagPrefix; - getPrefix(optPrefix, flagPrefix); - - help << "Options & Switches:\r\n"; - QListIterator<OptionDef *> it(m_optionList); - while(it.hasNext()) - { - OptionDef *option = it.next(); - help << " "; - int nameLength = optPrefix.length() + option->name.length(); - if (!option->flag.isNull()) - { - nameLength += 3 + flagPrefix.length(); - help << flagPrefix << option->flag << ", "; - } - help << optPrefix << option->name; - if (option->type == OptionType::Option) - { - QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar); - nameLength += arg.length(); - help << arg; - } - help << " " << QString(helpIndent - nameLength - 1, ' '); - help << option->doc << "\r\n"; - } - } - - return help.join(""); + QStringList help; + help << compileUsage(progName, useFlags) << "\r\n"; + + // positionals + if (!m_positionals.isEmpty()) + { + help << "\r\n"; + help << "Positional arguments:\r\n"; + QListIterator<PositionalDef *> it2(m_positionals); + while(it2.hasNext()) + { + PositionalDef *param = it2.next(); + help << " " << param->metavar; + help << " " << QString(helpIndent - param->metavar.length() - 1, ' '); + help << param->doc << "\r\n"; + } + } + + // Options + if (!m_optionList.isEmpty()) + { + help << "\r\n"; + QString optPrefix, flagPrefix; + getPrefix(optPrefix, flagPrefix); + + help << "Options & Switches:\r\n"; + QListIterator<OptionDef *> it(m_optionList); + while(it.hasNext()) + { + OptionDef *option = it.next(); + help << " "; + int nameLength = optPrefix.length() + option->name.length(); + if (!option->flag.isNull()) + { + nameLength += 3 + flagPrefix.length(); + help << flagPrefix << option->flag << ", "; + } + help << optPrefix << option->name; + if (option->type == OptionType::Option) + { + QString arg = QString("%1%2").arg(((m_argStyle == ArgumentStyle::Equals) ? "=" : " "), option->metavar); + nameLength += arg.length(); + help << arg; + } + help << " " << QString(helpIndent - nameLength - 1, ' '); + help << option->doc << "\r\n"; + } + } + + return help.join(""); } QString Parser::compileUsage(QString progName, bool useFlags) { - QStringList usage; - usage << "Usage: " << progName; - - QString optPrefix, flagPrefix; - getPrefix(optPrefix, flagPrefix); - - // options - QListIterator<OptionDef *> it(m_optionList); - while(it.hasNext()) - { - OptionDef *option = it.next(); - usage << " ["; - if (!option->flag.isNull() && useFlags) - usage << flagPrefix << option->flag; - else - usage << optPrefix << option->name; - if (option->type == OptionType::Option) - usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar; - usage << "]"; - } - - // arguments - QListIterator<PositionalDef *> it2(m_positionals); - while(it2.hasNext()) - { - PositionalDef *param = it2.next(); - usage << " " << (param->required ? "<" : "["); - usage << param->metavar; - usage << (param->required ? ">" : "]"); - } - - return usage.join(""); + QStringList usage; + usage << "Usage: " << progName; + + QString optPrefix, flagPrefix; + getPrefix(optPrefix, flagPrefix); + + // options + QListIterator<OptionDef *> it(m_optionList); + while(it.hasNext()) + { + OptionDef *option = it.next(); + usage << " ["; + if (!option->flag.isNull() && useFlags) + usage << flagPrefix << option->flag; + else + usage << optPrefix << option->name; + if (option->type == OptionType::Option) + usage << ((m_argStyle == ArgumentStyle::Equals) ? "=" : " ") << option->metavar; + usage << "]"; + } + + // arguments + QListIterator<PositionalDef *> it2(m_positionals); + while(it2.hasNext()) + { + PositionalDef *param = it2.next(); + usage << " " << (param->required ? "<" : "["); + usage << param->metavar; + usage << (param->required ? ">" : "]"); + } + + return usage.join(""); } // parsing QHash<QString, QVariant> Parser::parse(QStringList argv) { - QHash<QString, QVariant> map; - - QStringListIterator it(argv); - QString programName = it.next(); - - QString optionPrefix; - QString flagPrefix; - QListIterator<PositionalDef *> positionals(m_positionals); - QStringList expecting; - - getPrefix(optionPrefix, flagPrefix); - - while (it.hasNext()) - { - QString arg = it.next(); - - if (!expecting.isEmpty()) - // we were expecting an argument - { - QString name = expecting.first(); - - if (map.contains(name)) - throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); - - map[name] = QVariant(arg); - - expecting.removeFirst(); - continue; - } - - if (arg.startsWith(optionPrefix)) - // we have an option - { - //qDebug("Found option %s", qPrintable(arg)); - - QString name = arg.mid(optionPrefix.length()); - QString equals; - - if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("=")) - { - int i = name.indexOf("="); - equals = name.mid(i+1); - name = name.left(i); - } - - if (m_options.contains(name)) - { - if (map.contains(name)) - throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); - - OptionDef *option = m_options[name]; - if (option->type == OptionType::Switch) - map[name] = true; - else //if (option->type == OptionType::Option) - { - if (m_argStyle == ArgumentStyle::Space) - expecting.append(name); - else if (!equals.isNull()) - map[name] = equals; - else if (m_argStyle == ArgumentStyle::SpaceAndEquals) - expecting.append(name); - else - throw ParsingError(QString("Option %2%1 reqires an argument.").arg(name, optionPrefix)); - } - - continue; - } - - throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix)); - } - - if (arg.startsWith(flagPrefix)) - // we have (a) flag(s) - { - //qDebug("Found flags %s", qPrintable(arg)); - - QString flags = arg.mid(flagPrefix.length()); - QString equals; - - if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("=")) - { - int i = flags.indexOf("="); - equals = flags.mid(i+1); - flags = flags.left(i); - } - - for (int i = 0; i < flags.length(); i++) - { - QChar flag = flags.at(i); - - if (!m_flags.contains(flag)) - throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix)); - - OptionDef *option = m_flags[flag]; - - if (map.contains(option->name)) - throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix)); - - if (option->type == OptionType::Switch) - map[option->name] = true; - else //if (option->type == OptionType::Option) - { - if (m_argStyle == ArgumentStyle::Space) - expecting.append(option->name); - else if (!equals.isNull()) - if (i == flags.length()-1) - map[option->name] = equals; - else - throw ParsingError(QString("Flag %4%2 of Argument-requiring Option %1 not last flag in %4%3").arg(option->name, flag, flags, flagPrefix)); - else if (m_argStyle == ArgumentStyle::SpaceAndEquals) - expecting.append(option->name); - else - throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)").arg(option->name, flag, flagPrefix)); - } - } - - continue; - } - - // must be a positional argument - if (!positionals.hasNext()) - throw ParsingError(QString("Don't know what to do with '%1'").arg(arg)); - - PositionalDef *param = positionals.next(); - - map[param->name] = arg; - } - - // check if we're missing something - if (!expecting.isEmpty()) - throw ParsingError(QString("Was still expecting arguments for %2%1").arg(expecting.join(QString(", ")+optionPrefix), optionPrefix)); - - while (positionals.hasNext()) - { - PositionalDef *param = positionals.next(); - if (param->required) - throw ParsingError(QString("Missing required positional argument '%1'").arg(param->name)); - else - map[param->name] = param->def; - } - - // fill out gaps - QListIterator<OptionDef *> iter(m_optionList); - while (iter.hasNext()) - { - OptionDef *option = iter.next(); - if (!map.contains(option->name)) - map[option->name] = option->def; - } - - return map; + QHash<QString, QVariant> map; + + QStringListIterator it(argv); + QString programName = it.next(); + + QString optionPrefix; + QString flagPrefix; + QListIterator<PositionalDef *> positionals(m_positionals); + QStringList expecting; + + getPrefix(optionPrefix, flagPrefix); + + while (it.hasNext()) + { + QString arg = it.next(); + + if (!expecting.isEmpty()) + // we were expecting an argument + { + QString name = expecting.first(); + + if (map.contains(name)) + throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); + + map[name] = QVariant(arg); + + expecting.removeFirst(); + continue; + } + + if (arg.startsWith(optionPrefix)) + // we have an option + { + //qDebug("Found option %s", qPrintable(arg)); + + QString name = arg.mid(optionPrefix.length()); + QString equals; + + if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && name.contains("=")) + { + int i = name.indexOf("="); + equals = name.mid(i+1); + name = name.left(i); + } + + if (m_options.contains(name)) + { + if (map.contains(name)) + throw ParsingError(QString("Option %2%1 was given multiple times").arg(name, optionPrefix)); + + OptionDef *option = m_options[name]; + if (option->type == OptionType::Switch) + map[name] = true; + else //if (option->type == OptionType::Option) + { + if (m_argStyle == ArgumentStyle::Space) + expecting.append(name); + else if (!equals.isNull()) + map[name] = equals; + else if (m_argStyle == ArgumentStyle::SpaceAndEquals) + expecting.append(name); + else + throw ParsingError(QString("Option %2%1 reqires an argument.").arg(name, optionPrefix)); + } + + continue; + } + + throw ParsingError(QString("Unknown Option %2%1").arg(name, optionPrefix)); + } + + if (arg.startsWith(flagPrefix)) + // we have (a) flag(s) + { + //qDebug("Found flags %s", qPrintable(arg)); + + QString flags = arg.mid(flagPrefix.length()); + QString equals; + + if ((m_argStyle == ArgumentStyle::Equals || m_argStyle == ArgumentStyle::SpaceAndEquals) && flags.contains("=")) + { + int i = flags.indexOf("="); + equals = flags.mid(i+1); + flags = flags.left(i); + } + + for (int i = 0; i < flags.length(); i++) + { + QChar flag = flags.at(i); + + if (!m_flags.contains(flag)) + throw ParsingError(QString("Unknown flag %2%1").arg(flag, flagPrefix)); + + OptionDef *option = m_flags[flag]; + + if (map.contains(option->name)) + throw ParsingError(QString("Option %2%1 was given multiple times").arg(option->name, optionPrefix)); + + if (option->type == OptionType::Switch) + map[option->name] = true; + else //if (option->type == OptionType::Option) + { + if (m_argStyle == ArgumentStyle::Space) + expecting.append(option->name); + else if (!equals.isNull()) + if (i == flags.length()-1) + map[option->name] = equals; + else + throw ParsingError(QString("Flag %4%2 of Argument-requiring Option %1 not last flag in %4%3").arg(option->name, flag, flags, flagPrefix)); + else if (m_argStyle == ArgumentStyle::SpaceAndEquals) + expecting.append(option->name); + else + throw ParsingError(QString("Option %1 reqires an argument. (flag %3%2)").arg(option->name, flag, flagPrefix)); + } + } + + continue; + } + + // must be a positional argument + if (!positionals.hasNext()) + throw ParsingError(QString("Don't know what to do with '%1'").arg(arg)); + + PositionalDef *param = positionals.next(); + + map[param->name] = arg; + } + + // check if we're missing something + if (!expecting.isEmpty()) + throw ParsingError(QString("Was still expecting arguments for %2%1").arg(expecting.join(QString(", ")+optionPrefix), optionPrefix)); + + while (positionals.hasNext()) + { + PositionalDef *param = positionals.next(); + if (param->required) + throw ParsingError(QString("Missing required positional argument '%1'").arg(param->name)); + else + map[param->name] = param->def; + } + + // fill out gaps + QListIterator<OptionDef *> iter(m_optionList); + while (iter.hasNext()) + { + OptionDef *option = iter.next(); + if (!map.contains(option->name)) + map[option->name] = option->def; + } + + return map; } //clear defs void Parser::clear() { - m_flags.clear(); - m_params.clear(); - m_options.clear(); - - QMutableListIterator<OptionDef *> it(m_optionList); - while(it.hasNext()) - { - OptionDef *option = it.next(); - it.remove(); - delete option; - } - - QMutableListIterator<PositionalDef *> it2(m_positionals); - while(it2.hasNext()) - { - PositionalDef *arg = it2.next(); - it2.remove(); - delete arg; - } + m_flags.clear(); + m_params.clear(); + m_options.clear(); + + QMutableListIterator<OptionDef *> it(m_optionList); + while(it.hasNext()) + { + OptionDef *option = it.next(); + it.remove(); + delete option; + } + + QMutableListIterator<PositionalDef *> it2(m_positionals); + while(it2.hasNext()) + { + PositionalDef *arg = it2.next(); + it2.remove(); + delete arg; + } } //Destructor Parser::~Parser() { - clear(); + clear(); } //getPrefix void Parser::getPrefix(QString &opt, QString &flag) { - if (m_flagStyle == FlagStyle::Windows) - opt = flag = "/"; - else if (m_flagStyle == FlagStyle::Unix) - opt = flag = "-"; - //else if (m_flagStyle == FlagStyle::GNU) - else { - opt = "--"; - flag = "-"; - } + if (m_flagStyle == FlagStyle::Windows) + opt = flag = "/"; + else if (m_flagStyle == FlagStyle::Unix) + opt = flag = "-"; + //else if (m_flagStyle == FlagStyle::GNU) + else { + opt = "--"; + flag = "-"; + } } // ParsingError ParsingError::ParsingError(const QString &what) { - m_what = what; + m_what = what; } ParsingError::ParsingError(const ParsingError &e) { - m_what = e.m_what; + m_what = e.m_what; } const char *ParsingError::what() const throw() { - return m_what.toLocal8Bit().constData(); + return m_what.toLocal8Bit().constData(); } QString ParsingError::qwhat() const { - return m_what; + return m_what; } } diff --git a/libutil/src/userutils.cpp b/libutil/src/userutils.cpp index f3778d08..b70841ed 100644 --- a/libutil/src/userutils.cpp +++ b/libutil/src/userutils.cpp @@ -20,94 +20,104 @@ bool called_coinit = false; -HRESULT CreateLink(LPCSTR linkPath, LPCWSTR targetPath, LPCWSTR args) +HRESULT CreateLink(LPCSTR linkPath, LPCSTR targetPath, LPCSTR args) { - HRESULT hres; - - if (!called_coinit) - { - hres = CoInitialize(NULL); - called_coinit = true; - - if (!SUCCEEDED(hres)) - { - qWarning("Failed to initialize COM. Error 0x%08X", hres); - return hres; - } - } - - - IShellLink* link; - hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link); - - if (SUCCEEDED(hres)) - { - IPersistFile* persistFile; - - link->SetPath(targetPath); - link->SetArguments(args); - - hres = link->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile); - if (SUCCEEDED(hres)) - { - WCHAR wstr[MAX_PATH]; - - MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH); - - hres = persistFile->Save(wstr, TRUE); - persistFile->Release(); - } - link->Release(); - } - return hres; + HRESULT hres; + + if (!called_coinit) + { + hres = CoInitialize(NULL); + called_coinit = true; + + if (!SUCCEEDED(hres)) + { + qWarning("Failed to initialize COM. Error 0x%08X", hres); + return hres; + } + } + + + IShellLink* link; + hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&link); + + if (SUCCEEDED(hres)) + { + IPersistFile* persistFile; + + link->SetPath(targetPath); + link->SetArguments(args); + + hres = link->QueryInterface(IID_IPersistFile, (LPVOID*)&persistFile); + if (SUCCEEDED(hres)) + { + WCHAR wstr[MAX_PATH]; + + MultiByteToWideChar(CP_ACP, 0, linkPath, -1, wstr, MAX_PATH); + + hres = persistFile->Save(wstr, TRUE); + persistFile->Release(); + } + link->Release(); + } + return hres; } #endif QString Util::getDesktopDir() { - return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); + return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); } // Cross-platform Shortcut creation bool Util::createShortCut(QString location, QString dest, QStringList args, QString name, QString icon) { #if LINUX - location = PathCombine(location, name + ".desktop"); - qDebug("location: %s", qPrintable(location)); - - QFile f(location); - f.open(QIODevice::WriteOnly | QIODevice::Text); - QTextStream stream(&f); - - QString argstring; - if (!args.empty()) - argstring = " '" + args.join("' '") + "'"; - - stream << "[Desktop Entry]" << "\n"; - stream << "Type=Application" << "\n"; - stream << "TryExec=" << dest.toLocal8Bit() << "\n"; - stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n"; - stream << "Name=" << name.toLocal8Bit() << "\n"; - stream << "Icon=" << icon.toLocal8Bit() << "\n"; - - stream.flush(); - f.close(); - - f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); - - return true; + location = PathCombine(location, name + ".desktop"); + qDebug("location: %s", qPrintable(location)); + + QFile f(location); + f.open(QIODevice::WriteOnly | QIODevice::Text); + QTextStream stream(&f); + + QString argstring; + if (!args.empty()) + argstring = " '" + args.join("' '") + "'"; + + stream << "[Desktop Entry]" << "\n"; + stream << "Type=Application" << "\n"; + stream << "TryExec=" << dest.toLocal8Bit() << "\n"; + stream << "Exec=" << dest.toLocal8Bit() << argstring.toLocal8Bit() << "\n"; + stream << "Name=" << name.toLocal8Bit() << "\n"; + stream << "Icon=" << icon.toLocal8Bit() << "\n"; + + stream.flush(); + f.close(); + + f.setPermissions(f.permissions() | QFileDevice::ExeOwner | QFileDevice::ExeGroup | QFileDevice::ExeOther); + + return true; #elif WINDOWS - QFile file(path, name + ".lnk"); - WCHAR *file_w; - WCHAR *dest_w; - WCHAR *args_w; - file.fileName().toWCharArray(file_w); - dest.toWCharArray(dest_w); - args.toWCharArray(args_w); - return SUCCEEDED(CreateLink(file_w, dest_w, args_w)); + // TODO: Fix +// QFile file(PathCombine(location, name + ".lnk")); +// WCHAR *file_w; +// WCHAR *dest_w; +// WCHAR *args_w; +// file.fileName().toWCharArray(file_w); +// dest.toWCharArray(dest_w); + +// QString argStr; +// for (int i = 0; i < args.count(); i++) +// { +// argStr.append(args[i]); +// argStr.append(" "); +// } +// argStr.toWCharArray(args_w); + +// return SUCCEEDED(CreateLink(file_w, dest_w, args_w)); + return false; #else - qWarning("Desktop Shortcuts not supported on your platform!"); - return false; + qWarning("Desktop Shortcuts not supported on your platform!"); + return false; #endif } @@ -52,7 +52,7 @@ private: MinecraftProcess *proc; ConsoleWindow *console; public: - InstanceLauncher(QString instId) : QObject(), instances(settings->get("InstanceDir").toString()) + InstanceLauncher(QString instId) : QObject(), instances(globalSettings->get("InstanceDir").toString()) { this->instId = instId; } @@ -85,7 +85,7 @@ private slots: { // TODO: console console = new ConsoleWindow(); - proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), console); + proc = new MinecraftProcess(instance, response.username(), response.sessionID(), console); //if (instance->getShowConsole()) console->show(); connect(proc, SIGNAL(ended()), SLOT(onTerminated())); @@ -217,7 +217,7 @@ int main(int argc, char *argv[]) QDir::setCurrent(args["dir"].toString()); // load settings - settings = new AppSettings(&app); + globalSettings = new AppSettings(&app); // Register meta types. qRegisterMetaType<LoginResponse>("LoginResponse"); |