Fixed some formatting.

This commit is contained in:
Andrew 2013-02-25 13:39:07 -06:00
parent 23474da175
commit b56b819c35
3 changed files with 339 additions and 334 deletions

View File

@ -38,13 +38,13 @@ namespace Commandline {
* Specifies how flags are decorated * Specifies how flags are decorated
*/ */
enum class FlagStyle { enum class FlagStyle {
GNU, /**< --option and -o (GNU Style) */ GNU, /**< --option and -o (GNU Style) */
Unix, /**< -option and -o (Unix Style) */ Unix, /**< -option and -o (Unix Style) */
Windows, /**< /option and /o (Windows Style) */ Windows, /**< /option and /o (Windows Style) */
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
Default = Windows Default = Windows
#else #else
Default = GNU Default = GNU
#endif #endif
}; };
@ -52,13 +52,13 @@ enum class FlagStyle {
* @brief The ArgumentStyle enum * @brief The ArgumentStyle enum
*/ */
enum class ArgumentStyle { enum class ArgumentStyle {
Space, /**< --option=value */ Space, /**< --option=value */
Equals, /**< --option value */ Equals, /**< --option value */
SpaceAndEquals, /**< --option[= ]value */ SpaceAndEquals, /**< --option[= ]value */
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
Default = Equals Default = Equals
#else #else
Default = SpaceAndEquals Default = SpaceAndEquals
#endif #endif
}; };
@ -68,13 +68,13 @@ enum class ArgumentStyle {
class ParsingError : public std::exception class ParsingError : public std::exception
{ {
public: public:
ParsingError(const QString &what); ParsingError(const QString &what);
ParsingError(const ParsingError &e); ParsingError(const ParsingError &e);
~ParsingError() throw() {} ~ParsingError() throw() {}
const char *what() const throw(); const char *what() const throw();
QString qwhat() const; QString qwhat() const;
private: private:
QString m_what; QString m_what;
}; };
/** /**
@ -83,154 +83,154 @@ private:
class Parser class Parser
{ {
public: public:
/** /**
* @brief Parser constructor * @brief Parser constructor
* @param flagStyle the FlagStyle to use in this Parser * @param flagStyle the FlagStyle to use in this Parser
* @param argStyle the ArgumentStyle 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 flagStyle=FlagStyle::Default, ArgumentStyle argStyle=ArgumentStyle::Default);
/** /**
* @brief set the flag style * @brief set the flag style
* @param style * @param style
*/ */
void setFlagStyle(FlagStyle style); void setFlagStyle(FlagStyle style);
/** /**
* @brief get the flag style * @brief get the flag style
* @return * @return
*/ */
FlagStyle flagStyle(); FlagStyle flagStyle();
/** /**
* @brief set the argument style * @brief set the argument style
* @param style * @param style
*/ */
void setArgumentStyle(ArgumentStyle style); void setArgumentStyle(ArgumentStyle style);
/** /**
* @brief get the argument style * @brief get the argument style
* @return * @return
*/ */
ArgumentStyle argumentStyle(); ArgumentStyle argumentStyle();
/** /**
* @brief define a boolean switch * @brief define a boolean switch
* @param name the parameter name * @param name the parameter name
* @param def the default value * @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 * @brief define an option that takes an additional argument
* @param name the parameter name * @param name the parameter name
* @param def the default value * @param def the default value
*/ */
void addOption(QString name, QVariant def=QVariant()); void addOption(QString name, QVariant def=QVariant());
/** /**
* @brief define a positional argument * @brief define a positional argument
* @param name the parameter name * @param name the parameter name
* @param required wether this argument is required * @param required wether this argument is required
* @param def the default value * @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 * @brief adds a flag to an existing parameter
* @param name the (existing) parameter name * @param name the (existing) parameter name
* @param flag the flag character * @param flag the flag character
* @see addSwitch addArgument addOption * @see addSwitch addArgument addOption
* Note: any one parameter can only have one flag * Note: any one parameter can only have one flag
*/ */
void addShortOpt(QString name, QChar flag); void addShortOpt(QString name, QChar flag);
/** /**
* @brief adds documentation to a Parameter * @brief adds documentation to a Parameter
* @param name the parameter name * @param name the parameter name
* @param metavar a string to be displayed as placeholder for the value * @param metavar a string to be displayed as placeholder for the value
* @param doc a QString containing the documentation * @param doc a QString containing the documentation
* Note: on positional arguments, metavar replaces the name as displayed. * Note: on positional arguments, metavar replaces the name as displayed.
* on options , metavar replaces the value placeholder * 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 * @brief generate a help message
* @param progName the program name to use in the help message * @param progName the program name to use in the help message
* @param helpIndent how much the parameter documentation should be indented * @param helpIndent how much the parameter documentation should be indented
* @param flagsInUsage whether we should use flags instead of options in the usage * @param flagsInUsage whether we should use flags instead of options in the usage
* @return a help message * @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 * @brief generate a short usage message
* @param progName the program name to use in the usage message * @param progName the program name to use in the usage message
* @param useFlags whether we should use flags instead of options * @param useFlags whether we should use flags instead of options
* @return a usage message * @return a usage message
*/ */
QString compileUsage(QString progName, bool useFlags=true); QString compileUsage(QString progName, bool useFlags=true);
/** /**
* @brief parse * @brief parse
* @param argv a QStringList containing the program ARGV * @param argv a QStringList containing the program ARGV
* @return a QHash mapping argument names to their values * @return a QHash mapping argument names to their values
*/ */
QHash<QString, QVariant> parse(QStringList argv); QHash<QString, QVariant> parse(QStringList argv);
/** /**
* @brief clear all definitions * @brief clear all definitions
*/ */
void clear(); void clear();
~Parser(); ~Parser();
private: private:
FlagStyle m_flagStyle; FlagStyle m_flagStyle;
ArgumentStyle m_argStyle; ArgumentStyle m_argStyle;
enum class OptionType { enum class OptionType {
Switch, Switch,
Option Option
}; };
// Important: the common part MUST BE COMMON ON ALL THREE structs // Important: the common part MUST BE COMMON ON ALL THREE structs
struct CommonDef { struct CommonDef {
QString name; QString name;
QString doc; QString doc;
QString metavar; QString metavar;
QVariant def; QVariant def;
}; };
struct OptionDef { struct OptionDef {
// common // common
QString name; QString name;
QString doc; QString doc;
QString metavar; QString metavar;
QVariant def; QVariant def;
// option // option
OptionType type; OptionType type;
QChar flag; QChar flag;
}; };
struct PositionalDef { struct PositionalDef {
// common // common
QString name; QString name;
QString doc; QString doc;
QString metavar; QString metavar;
QVariant def; QVariant def;
// positional // positional
bool required; bool required;
}; };
QHash<QString, OptionDef *> m_options; QHash<QString, OptionDef *> m_options;
QHash<QChar, OptionDef *> m_flags; QHash<QChar, OptionDef *> m_flags;
QHash<QString, CommonDef *> m_params; QHash<QString, CommonDef *> m_params;
QList<PositionalDef *> m_positionals; QList<PositionalDef *> m_positionals;
QList<OptionDef *> m_optionList; QList<OptionDef *> m_optionList;
void getPrefix(QString &opt, QString &flag); void getPrefix(QString &opt, QString &flag);
}; };
} }

View File

@ -5,13 +5,13 @@
namespace Util namespace Util
{ {
// Get the Directory representing the User's Desktop // Get the Directory representing the User's Desktop
QString getDesktopDir(); QString getDesktopDir();
// Create a shortcut at *location*, pointing to *dest* called with the arguments *args* // Create a shortcut at *location*, pointing to *dest* called with the arguments *args*
// call it *name* and assign it the icon *icon* // call it *name* and assign it the icon *icon*
// return true if operation succeeded // return true if operation succeeded
bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation); bool createShortCut(QString location, QString dest, QStringList args, QString name, QString iconLocation);
} }
#endif // USERUTILS_H #endif // USERUTILS_H

335
main.cpp
View File

@ -44,192 +44,197 @@ using namespace Util::Commandline;
// Commandline instance launcher // Commandline instance launcher
class InstanceLauncher : public QObject class InstanceLauncher : public QObject
{ {
Q_OBJECT Q_OBJECT
private: private:
InstanceList instances; InstanceList instances;
QString instId; QString instId;
InstancePtr instance; InstancePtr instance;
MinecraftProcess *proc; MinecraftProcess *proc;
ConsoleWindow *console; ConsoleWindow *console;
public: public:
InstanceLauncher(QString instId) : QObject(), instances(settings->getInstanceDir()) InstanceLauncher(QString instId) : QObject(), instances(settings->get("InstanceDir").toString())
{ {
this->instId = instId; this->instId = instId;
} }
private: private:
InstancePtr findInstance(QString instId) InstancePtr findInstance(QString instId)
{ {
QListIterator<InstancePtr> iter(instances); QListIterator<InstancePtr> iter(instances);
InstancePtr inst; InstancePtr inst;
while(iter.hasNext()) while(iter.hasNext())
{ {
inst = iter.next(); inst = iter.next();
if (inst->id() == instId) if (inst->id() == instId)
break; break;
} }
if (inst->id() != instId) if (inst->id() != instId)
return InstancePtr(); return InstancePtr();
else else
return iter.peekPrevious(); return iter.peekPrevious();
} }
private slots: private slots:
void onTerminated() void onTerminated()
{ {
std::cout << "Minecraft exited" << std::endl; std::cout << "Minecraft exited" << std::endl;
QApplication::instance()->quit(); QApplication::instance()->quit();
} }
void onLoginComplete(LoginResponse response) void onLoginComplete(LoginResponse response)
{ {
// TODO: console // TODO: console
console = new ConsoleWindow(); console = new ConsoleWindow();
proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), console); proc = new MinecraftProcess(instance, response.getUsername(), response.getSessionID(), console);
//if (instance->getShowConsole()) //if (instance->getShowConsole())
console->show(); console->show();
connect(proc, SIGNAL(ended()), SLOT(onTerminated())); connect(proc, SIGNAL(ended()), SLOT(onTerminated()));
proc->launch(); proc->launch();
} }
void doLogin(const QString &errorMsg) void doLogin(const QString &errorMsg)
{ {
LoginDialog* loginDlg = new LoginDialog(nullptr, errorMsg); LoginDialog* loginDlg = new LoginDialog(nullptr, errorMsg);
if (loginDlg->exec()) if (loginDlg->exec())
{ {
UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword()); UserInfo uInfo(loginDlg->getUsername(), loginDlg->getPassword());
TaskDialog* tDialog = new TaskDialog(nullptr); TaskDialog* tDialog = new TaskDialog(nullptr);
LoginTask* loginTask = new LoginTask(uInfo, tDialog); LoginTask* loginTask = new LoginTask(uInfo, tDialog);
connect(loginTask, SIGNAL(loginComplete(LoginResponse)), connect(loginTask, SIGNAL(loginComplete(LoginResponse)),
SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection); SLOT(onLoginComplete(LoginResponse)), Qt::QueuedConnection);
connect(loginTask, SIGNAL(loginFailed(QString)), connect(loginTask, SIGNAL(loginFailed(QString)),
SLOT(doLogin(QString)), Qt::QueuedConnection); SLOT(doLogin(QString)), Qt::QueuedConnection);
tDialog->exec(loginTask); tDialog->exec(loginTask);
} }
//onLoginComplete(LoginResponse("Offline","Offline", 1)); //onLoginComplete(LoginResponse("Offline","Offline", 1));
} }
public: public:
int launch() int launch()
{ {
std::cout << "Loading Instances..." << std::endl; std::cout << "Loading Instances..." << std::endl;
instances.loadList(); instances.loadList();
std::cout << "Launching Instance '" << qPrintable(instId) << "'" << std::endl; std::cout << "Launching Instance '" << qPrintable(instId) << "'" << std::endl;
instance = findInstance(instId); instance = findInstance(instId);
if (instance.isNull()) if (instance.isNull())
{ {
std::cout << "Could not find instance requested. note that you have to specify the ID, not the NAME" << std::endl; std::cout << "Could not find instance requested. note that you have to specify the ID, not the NAME" << std::endl;
return 1; return 1;
} }
std::cout << "Logging in..." << std::endl; std::cout << "Logging in..." << std::endl;
doLogin(""); doLogin("");
return QApplication::instance()->exec(); return QApplication::instance()->exec();
} }
}; };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
// initialize Qt // initialize Qt
QApplication app(argc, argv); QApplication app(argc, argv);
app.setOrganizationName("Forkk"); app.setOrganizationName("Forkk");
app.setApplicationName("MultiMC 5"); app.setApplicationName("MultiMC 5");
// Print app header // Print app header
std::cout << "MultiMC 5" << std::endl; std::cout << "MultiMC 5" << std::endl;
std::cout << "(c) 2013 MultiMC Contributors" << std::endl << std::endl; std::cout << "(c) 2013 MultiMC Contributors" << std::endl << std::endl;
// Commandline parsing // Commandline parsing
Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals); Parser parser(FlagStyle::GNU, ArgumentStyle::SpaceAndEquals);
// --help // --help
parser.addSwitch("help"); parser.addSwitch("help");
parser.addShortOpt("help", 'h'); parser.addShortOpt("help", 'h');
parser.addDocumentation("help", "display this help and exit."); parser.addDocumentation("help", "display this help and exit.");
// --version // --version
parser.addSwitch("version"); parser.addSwitch("version");
parser.addShortOpt("version", 'V'); parser.addShortOpt("version", 'V');
parser.addDocumentation("version", "display program version and exit."); parser.addDocumentation("version", "display program version and exit.");
// --dir // --dir
parser.addOption("dir", app.applicationDirPath()); parser.addOption("dir", app.applicationDirPath());
parser.addShortOpt("dir", 'd'); parser.addShortOpt("dir", 'd');
parser.addDocumentation("dir", "use the supplied directory as MultiMC root instead of the binary location (use '.' for current)"); parser.addDocumentation("dir", "use the supplied directory as MultiMC root instead of the binary location (use '.' for current)");
// --update // --update
parser.addOption("update"); parser.addOption("update");
parser.addShortOpt("update", 'u'); parser.addShortOpt("update", 'u');
parser.addDocumentation("update", "replaces the given file with the running executable", "<path>"); parser.addDocumentation("update", "replaces the given file with the running executable", "<path>");
// --quietupdate // --quietupdate
parser.addSwitch("quietupdate"); parser.addSwitch("quietupdate");
parser.addShortOpt("quietupdate", 'U'); parser.addShortOpt("quietupdate", 'U');
parser.addDocumentation("quietupdate", "doesn't restart MultiMC after installing updates"); parser.addDocumentation("quietupdate", "doesn't restart MultiMC after installing updates");
// --launch // --launch
parser.addOption("launch"); parser.addOption("launch");
parser.addShortOpt("launch", 'l'); parser.addShortOpt("launch", 'l');
parser.addDocumentation("launch", "tries to launch the given instance", "<inst>"); parser.addDocumentation("launch", "tries to launch the given instance", "<inst>");
// parse the arguments // parse the arguments
QHash<QString, QVariant> args; QHash<QString, QVariant> args;
try { try
args = parser.parse(app.arguments()); {
} catch(ParsingError e) { args = parser.parse(app.arguments());
std::cerr << "CommandLineError: " << e.what() << std::endl; }
std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters." << std::endl; catch(ParsingError e)
return 1; {
} std::cerr << "CommandLineError: " << e.what() << std::endl;
std::cerr << "Try '%1 -h' to get help on MultiMC's command line parameters." << std::endl;
// display help and exit return 1;
if (args["help"].toBool()) { }
std::cout << qPrintable(parser.compileHelp(app.arguments()[0]));
return 0; // display help and exit
} if (args["help"].toBool())
{
// display version and exit std::cout << qPrintable(parser.compileHelp(app.arguments()[0]));
if (args["version"].toBool()) { return 0;
std::cout << "Version " << VERSION_STR << std::endl; }
std::cout << "Git " << GIT_COMMIT << std::endl;
std::cout << "Tag: " << JENKINS_BUILD_TAG << " " << (ARCH==x64?"x86_64":"x86") << std::endl; // display version and exit
return 0; if (args["version"].toBool())
} {
std::cout << "Version " << VERSION_STR << std::endl;
// update std::cout << "Git " << GIT_COMMIT << std::endl;
// Note: cwd is always the current executable path! std::cout << "Tag: " << JENKINS_BUILD_TAG << " " << (ARCH==x64?"x86_64":"x86") << std::endl;
if (!args["update"].isNull()) return 0;
{ }
std::cout << "Performing MultiMC update: " << qPrintable(args["update"].toString()) << std::endl;
QString cwd = QDir::currentPath(); // update
QDir::setCurrent(app.applicationDirPath()); // Note: cwd is always the current executable path!
QFile file(app.applicationFilePath()); if (!args["update"].isNull())
file.copy(args["update"].toString()); {
if(args["quietupdate"].toBool()) std::cout << "Performing MultiMC update: " << qPrintable(args["update"].toString()) << std::endl;
return 0; QString cwd = QDir::currentPath();
QDir::setCurrent(cwd); QDir::setCurrent(app.applicationDirPath());
} QFile file(app.applicationFilePath());
file.copy(args["update"].toString());
// change directory if(args["quietupdate"].toBool())
QDir::setCurrent(args["dir"].toString()); return 0;
QDir::setCurrent(cwd);
// load settings }
// change directory
QDir::setCurrent(args["dir"].toString());
// load settings
settings = new AppSettings(&app); settings = new AppSettings(&app);
// Register meta types. // Register meta types.
qRegisterMetaType<LoginResponse>("LoginResponse"); qRegisterMetaType<LoginResponse>("LoginResponse");
// Initialize plugins. // Initialize plugins.
PluginManager::get().loadPlugins(PathCombine(qApp->applicationDirPath(), "plugins")); PluginManager::get().loadPlugins(PathCombine(qApp->applicationDirPath(), "plugins"));
PluginManager::get().initInstanceTypes(); PluginManager::get().initInstanceTypes();
// launch instance. // launch instance.
if (!args["launch"].isNull()) if (!args["launch"].isNull())
return InstanceLauncher(args["launch"].toString()).launch(); return InstanceLauncher(args["launch"].toString()).launch();
// show main window // show main window
MainWindow mainWin; MainWindow mainWin;
mainWin.show(); mainWin.show();
// loop // loop
return app.exec(); return app.exec();
} }