summaryrefslogtreecommitdiffstats
path: root/libmultimc
diff options
context:
space:
mode:
Diffstat (limited to 'libmultimc')
-rw-r--r--libmultimc/CMakeLists.txt96
-rw-r--r--libmultimc/include/appsettings.h32
-rw-r--r--libmultimc/include/gameupdatetask.h52
-rw-r--r--libmultimc/include/instance.h297
-rw-r--r--libmultimc/include/instancelist.h59
-rw-r--r--libmultimc/include/instanceloader.h140
-rw-r--r--libmultimc/include/instancetypeinterface.h86
-rw-r--r--libmultimc/include/instversion.h53
-rw-r--r--libmultimc/include/instversionlist.h45
-rw-r--r--libmultimc/include/libmmc_config.h27
-rw-r--r--libmultimc/include/loginresponse.h96
-rw-r--r--libmultimc/include/logintask.h50
-rw-r--r--libmultimc/include/minecraftprocess.h97
-rw-r--r--libmultimc/include/pluginmanager.h74
-rw-r--r--libmultimc/include/task.h56
-rw-r--r--libmultimc/include/userinfo.h41
-rw-r--r--libmultimc/include/version.h69
-rw-r--r--libmultimc/src/appsettings.cpp68
-rw-r--r--libmultimc/src/gameupdatetask.cpp22
-rw-r--r--libmultimc/src/instance.cpp131
-rw-r--r--libmultimc/src/instancelist.cpp87
-rw-r--r--libmultimc/src/instanceloader.cpp109
-rw-r--r--libmultimc/src/instversion.cpp32
-rw-r--r--libmultimc/src/instversionlist.cpp21
-rw-r--r--libmultimc/src/loginresponse.cpp69
-rw-r--r--libmultimc/src/logintask.cpp121
-rw-r--r--libmultimc/src/minecraftprocess.cpp248
-rw-r--r--libmultimc/src/pluginmanager.cpp105
-rw-r--r--libmultimc/src/task.cpp56
-rw-r--r--libmultimc/src/userinfo.cpp49
-rw-r--r--libmultimc/src/version.cpp46
31 files changed, 2534 insertions, 0 deletions
diff --git a/libmultimc/CMakeLists.txt b/libmultimc/CMakeLists.txt
new file mode 100644
index 00000000..06102d9f
--- /dev/null
+++ b/libmultimc/CMakeLists.txt
@@ -0,0 +1,96 @@
+project(libMultiMC)
+
+set(CMAKE_AUTOMOC ON)
+
+# Find Qt
+find_package(Qt5Core REQUIRED)
+find_package(Qt5Network REQUIRED)
+
+# Include Qt headers.
+include_directories(${Qt5Base_INCLUDE_DIRS})
+include_directories(${Qt5Network_INCLUDE_DIRS})
+
+# Include utility library.
+include_directories(${CMAKE_SOURCE_DIR}/libutil/include)
+
+# Include settings library.
+include_directories(${CMAKE_SOURCE_DIR}/libsettings/include)
+
+SET(LIBINST_HEADERS
+include/libmmc_config.h
+
+
+# Instance Stuff
+include/instance.h
+include/instancelist.h
+include/instanceloader.h
+
+include/instversion.h
+include/instversionlist.h
+
+
+# Plugin Stuff
+include/pluginmanager.h
+include/instancetypeinterface.h
+
+
+# Tasks
+include/task.h
+include/logintask.h
+include/gameupdatetask.h
+
+
+# Login Data
+include/userinfo.h
+include/loginresponse.h
+
+
+# Misc Data
+include/version.h
+include/appsettings.h
+include/minecraftprocess.h
+)
+
+SET(LIBINST_SOURCES
+# Instance Stuff
+src/instance.cpp
+src/instancelist.cpp
+src/instanceloader.cpp
+
+src/instversion.cpp
+src/instversionlist.cpp
+
+
+# Plugin Stuff
+src/pluginmanager.cpp
+
+
+# Tasks
+src/task.cpp
+src/logintask.cpp
+src/gameupdatetask.cpp
+
+
+# Login Data
+src/userinfo.cpp
+src/loginresponse.cpp
+
+
+# Misc Data
+src/version.cpp
+src/appsettings.cpp
+src/minecraftprocess.cpp
+)
+
+# Set the include dir path.
+SET(LIBMULTIMC_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
+
+# Include self.
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
+include_directories(${CMAKE_BINARY_DIR}/include)
+
+add_definitions(-DLIBMULTIMC_LIBRARY)
+
+add_library(libMultiMC SHARED ${LIBINST_SOURCES} ${LIBINST_HEADERS})
+qt5_use_modules(libMultiMC Core Network)
+target_link_libraries(libMultiMC libUtil libSettings)
diff --git a/libmultimc/include/appsettings.h b/libmultimc/include/appsettings.h
new file mode 100644
index 00000000..66ffb7b5
--- /dev/null
+++ b/libmultimc/include/appsettings.h
@@ -0,0 +1,32 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef APPSETTINGS_H
+#define APPSETTINGS_H
+
+#include <QObject>
+
+#include <basicsettingsobject.h>
+
+#include "libmmc_config.h"
+
+class LIBMULTIMC_EXPORT AppSettings : public BasicSettingsObject
+{
+ Q_OBJECT
+public:
+ explicit AppSettings(QObject *parent = 0);
+};
+
+#endif // APPSETTINGS_H
diff --git a/libmultimc/include/gameupdatetask.h b/libmultimc/include/gameupdatetask.h
new file mode 100644
index 00000000..eabfbd1f
--- /dev/null
+++ b/libmultimc/include/gameupdatetask.h
@@ -0,0 +1,52 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GAMEUPDATETASK_H
+#define GAMEUPDATETASK_H
+
+#include <QObject>
+
+#include "loginresponse.h"
+
+#include "libmmc_config.h"
+
+/*!
+ * \brief The game update task is the task that handles downloading instances.
+ * Each instance type has its own class inheriting from this base game update task.
+ */
+class LIBMULTIMC_EXPORT GameUpdateTask : public QObject
+{
+ Q_OBJECT
+public:
+ explicit GameUpdateTask(const LoginResponse &response, QObject *parent = 0);
+
+signals:
+ /*!
+ * \brief Signal emitted when the game update is complete.
+ * \param response The login response received from login task.
+ */
+ void gameUpdateComplete(const LoginResponse &response);
+
+ /*!
+ * \brief Signal emitted if the game update fails.
+ * \param errorMsg An error message to be displayed to the user.
+ */
+ void gameUpdateFailed(const QString &errorMsg);
+
+private:
+ LoginResponse m_response;
+};
+
+#endif // GAMEUPDATETASK_H
diff --git a/libmultimc/include/instance.h b/libmultimc/include/instance.h
new file mode 100644
index 00000000..7de61343
--- /dev/null
+++ b/libmultimc/include/instance.h
@@ -0,0 +1,297 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTANCE_H
+#define INSTANCE_H
+
+#include <QObject>
+#include <QDateTime>
+
+#include <settingsobject.h>
+
+#include "inifile.h"
+
+#include "libmmc_config.h"
+
+class InstanceList;
+
+/*!
+ * \brief Base class for instances.
+ * This class implements many functions that are common between instances and
+ * provides a standard interface for all instances.
+ *
+ * To create a new instance type, create a new class inheriting from this class
+ * and implement the pure virtual functions.
+ */
+class LIBMULTIMC_EXPORT Instance : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Instance(const QString &rootDir, QObject *parent = 0);
+
+ // Please, for the sake of my (and everyone else's) sanity, at least keep this shit
+ // *somewhat* organized. Also, documentation is semi-important here. Please don't
+ // leave undocumented stuff behind.
+
+
+ //////// STUFF ////////
+
+ /*!
+ * \brief Get the instance's ID.
+ * This is a unique identifier string that is, by default, set to the
+ * instance's folder name. It's not always the instance's folder name,
+ * however, as any class deriving from Instance can override the id()
+ * method and change how the ID is determined. The instance's ID
+ * should always remain constant. Undefined behavior results if an
+ * already loaded instance's ID changes.
+ *
+ * \return The instance's ID.
+ */
+ virtual QString id() const;
+
+ /*!
+ * \brief Gets the path to the instance's root directory.
+ * \return The path to the instance's root directory.
+ */
+ virtual QString rootDir() const;
+
+ /*!
+ * \brief Gets the instance list that this instance is a part of.
+ * Returns NULL if this instance is not in a list
+ * (the parent is not an InstanceList).
+ * \return A pointer to the InstanceList containing this instance.
+ */
+ virtual InstanceList *instList() const;
+
+
+ //////// INSTANCE INFO ////////
+
+ //// General Info ////
+
+ /*!
+ * \brief Gets this instance's name.
+ * This is the name that will be displayed to the user.
+ * \return The instance's name.
+ * \sa setName
+ */
+ virtual QString name() { return settings().get("name").toString(); }
+
+ /*!
+ * \brief Sets the instance's name
+ * \param val The instance's new name.
+ */
+ virtual void setName(QString val) { settings().set("name", val); }
+
+ /*!
+ * \brief Gets the instance's icon key.
+ * \return The instance's icon key.
+ * \sa setIconKey()
+ */
+ virtual QString iconKey() const { return settings().get("iconKey").toString(); }
+
+ /*!
+ * \brief Sets the instance's icon key.
+ * \param val The new icon key.
+ */
+ virtual void setIconKey(QString val) { settings().set("iconKey", val); }
+
+
+ /*!
+ * \brief Gets the instance's notes.
+ * \return The instances notes.
+ */
+ virtual QString notes() const { return settings().get("notes").toString(); }
+
+ /*!
+ * \brief Sets the instance's notes.
+ * \param val The instance's new notes.
+ */
+ virtual void setNotes(QString val) { settings().set("notes", val); }
+
+
+ /*!
+ * \brief Checks if the instance's minecraft.jar needs to be rebuilt.
+ * If this is true, the instance's mods will be reinstalled to its
+ * minecraft.jar file. This value is automatically set to true when
+ * the jar mod list changes.
+ * \return Whether or not the instance's jar file should be rebuilt.
+ */
+ virtual bool shouldRebuild() const { return settings().get("NeedsRebuild").toBool(); }
+
+ /*!
+ * \brief Sets whether or not the instance's minecraft.jar needs to be rebuilt.
+ * \param val Whether the instance's minecraft needs to be rebuilt or not.
+ */
+ virtual void setShouldRebuild(bool val) { settings().set("NeedsRebuild", val); }
+
+
+ //// Version Stuff ////
+
+ /*!
+ * \brief Sets the instance's current version.
+ * This value represents the instance's current version. If this value
+ * is different from intendedVersion(), the instance should be updated.
+ * This value is updated by the updateCurrentVersion() function.
+ * \return A string representing the instance's current version.
+ */
+ virtual QString currentVersion() { return settings().get("JarVersion").toString(); }
+
+ /*!
+ * \brief Sets the instance's current version.
+ * This is used to keep track of the instance's current version. Don't
+ * mess with this unless you know what you're doing.
+ * \param val The new value.
+ */
+ virtual void setCurrentVersion(QString val) { settings().set("JarVersion", val); }
+
+
+ /*!
+ * \brief Gets the version of LWJGL that this instance should use.
+ * If no LWJGL version is specified in the instance's config file,
+ * defaults to "Mojang"
+ * \return The instance's LWJGL version.
+ */
+ virtual QString lwjglVersion() { return settings().get("LwjglVersion").toString(); }
+
+ /*!
+ * \brief Sets the version of LWJGL that this instance should use.
+ * \param val The LWJGL version to use
+ */
+ virtual void setLWJGLVersion(QString val) { settings().set("LwjglVersion", val); }
+
+
+ /*!
+ * \brief Gets the version that this instance should try to update to.
+ * If this value differs from currentVersion(), the instance will
+ * download the intended version when it launches.
+ * \return The instance's intended version.
+ */
+ virtual QString intendedVersion() { return settings().get("IntendedJarVersion").toString(); }
+
+ /*!
+ * \brief Sets the version that this instance should try to update to.
+ * \param val The instance's new intended version.
+ */
+ virtual void setIntendedVersion(QString val) { settings().set("IntendedJarVersion", val); }
+
+
+
+ //// Timestamps ////
+
+ /*!
+ * \brief Gets the time that the instance was last launched.
+ * Measured in milliseconds since epoch. QDateTime::currentMSecsSinceEpoch()
+ * \return The time that the instance was last launched.
+ */
+ virtual qint64 lastLaunch() { return settings().get("lastLaunchTime").value<qint64>(); }
+
+ /*!
+ * \brief Sets the time that the instance was last launched.
+ * \param val The time to set. Defaults to QDateTime::currentMSecsSinceEpoch()
+ */
+ virtual void setLastLaunch(qint64 val = QDateTime::currentMSecsSinceEpoch())
+ { settings().set("lastLaunchTime", val); }
+
+
+ ////// Directories //////
+ //! Gets the path to the instance's minecraft folder.
+ QString minecraftDir() const;
+
+ /*!
+ * \brief Gets the path to the instance's instance mods folder.
+ * This is the folder where the jar mods are kept.
+ */
+ QString instModsDir() const;
+
+ //! Gets the path to the instance's bin folder.
+ QString binDir() const;
+
+ //! Gets the path to the instance's saves folder.
+ QString savesDir() const;
+
+ //! Gets the path to the instance's mods folder. (.minecraft/mods)
+ QString mlModsDir() const;
+
+ //! Gets the path to the instance's coremods folder.
+ QString coreModsDir() const;
+
+ //! Gets the path to the instance's resources folder.
+ QString resourceDir() const;
+
+ //! Gets the path to the instance's screenshots folder.
+ QString screenshotsDir() const;
+
+ //! Gets the path to the instance's texture packs folder.
+ QString texturePacksDir() const;
+
+
+ ////// Files //////
+ //! Gets the path to the instance's minecraft.jar
+ QString mcJar() const;
+
+ //! Gets the path to the instance's mcbackup.jar.
+ QString mcBackup() const;
+
+ //! Gets the path to the instance's config file.
+ QString configFile() const;
+
+ //! Gets the path to the instance's modlist file.
+ QString modListFile() const;
+
+
+ //////// OTHER FUNCTIONS ////////
+
+ //// Version System ////
+
+ /*!
+ * \brief Checks whether or not the currentVersion of the instance needs to be updated.
+ * If this returns true, updateCurrentVersion is called. In the
+ * standard instance, this is determined by checking a timestamp
+ * stored in the instance config file against the last modified time of Minecraft.jar.
+ * \return True if updateCurrentVersion() should be called.
+ */
+ virtual bool shouldUpdateCurrentVersion() = 0;
+
+ /*!
+ * \brief Updates the current version.
+ * This function should first set the current version timestamp
+ * (setCurrentVersionTimestamp()) to the current time. Next, if
+ * keepCurrent is false, this function should check what the
+ * instance's current version is and call setCurrentVersion() to
+ * update it. This function will automatically be called when the
+ * instance is loaded if shouldUpdateCurrentVersion returns true.
+ * \param keepCurrent If true, only the version timestamp will be updated.
+ */
+ 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() const;
+
+private:
+ QString m_rootDir;
+ SettingsObject *m_settings;
+};
+
+// pointer for lazy people
+typedef QSharedPointer<Instance> InstancePtr;
+
+#endif // INSTANCE_H
diff --git a/libmultimc/include/instancelist.h b/libmultimc/include/instancelist.h
new file mode 100644
index 00000000..d4e7556a
--- /dev/null
+++ b/libmultimc/include/instancelist.h
@@ -0,0 +1,59 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTANCELIST_H
+#define INSTANCELIST_H
+
+#include <QObject>
+
+#include <QSharedPointer>
+
+#include "siglist.h"
+
+#include "libmmc_config.h"
+
+class Instance;
+
+class LIBMULTIMC_EXPORT InstanceList : public QObject, public SigList< QSharedPointer<Instance> >
+{
+ Q_OBJECT
+public:
+ explicit InstanceList(const QString &instDir, QObject *parent = 0);
+
+ /*!
+ * \brief Error codes returned by functions in the InstanceList class.
+ * NoError Indicates that no error occurred.
+ * UnknownError indicates that an unspecified error occurred.
+ */
+ enum InstListError
+ {
+ NoError = 0,
+ UnknownError
+ };
+
+ QString instDir() const { return m_instDir; }
+
+ /*!
+ * \brief Loads the instance list.
+ */
+ InstListError loadList();
+
+ DEFINE_SIGLIST_SIGNALS(QSharedPointer<Instance>);
+ SETUP_SIGLIST_SIGNALS(QSharedPointer<Instance>);
+protected:
+ QString m_instDir;
+};
+
+#endif // INSTANCELIST_H
diff --git a/libmultimc/include/instanceloader.h b/libmultimc/include/instanceloader.h
new file mode 100644
index 00000000..3326d7d0
--- /dev/null
+++ b/libmultimc/include/instanceloader.h
@@ -0,0 +1,140 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTANCELOADER_H
+#define INSTANCELOADER_H
+
+#include <QObject>
+#include <QMap>
+#include <QList>
+
+#include "libmmc_config.h"
+
+class InstanceTypeInterface;
+class Instance;
+
+typedef QList<const InstanceTypeInterface *> InstTypeList;
+
+/*!
+ * \brief The InstanceLoader is a singleton that manages all of the instance types and handles loading and creating instances.
+ * Instance types are registered with the instance loader through its registerInstType() function.
+ * Creating instances is done through the InstanceLoader's createInstance() function. This function takes
+ */
+class LIBMULTIMC_EXPORT InstanceLoader : public QObject
+{
+ Q_OBJECT
+public:
+ /*!
+ * \brief Gets a reference to the instance loader.
+ */
+ static InstanceLoader &get() { return loader; }
+
+ /*!
+ * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes.
+ *
+ * - NoError indicates that no error occurred.
+ * - OtherError indicates that an unspecified error occurred.
+ * - TypeIDExists is returned by registerInstanceType() if the ID of the type being registered already exists.
+ * - TypeNotRegistered is returned by createInstance() and loadInstance() when the given type is not registered.
+ * - InstExists is returned by createInstance() if the given instance directory is already an instance.
+ * - NotAnInstance is returned by loadInstance() if the given instance directory is not a valid instance.
+ * - WrongInstType is returned by loadInstance() if the given instance directory's type doesn't match the given type.
+ * - CantCreateDir is returned by createInstance( if the given instance directory can't be created.)
+ */
+ enum InstTypeError
+ {
+ NoError = 0,
+ OtherError,
+
+ TypeIDExists,
+
+ TypeNotRegistered,
+ InstExists,
+ NotAnInstance,
+ WrongInstType,
+ CantCreateDir
+ };
+
+ /*!
+ * \brief Registers the given InstanceType with the instance loader.
+ *
+ * \param type The InstanceType to register.
+ * \return An InstTypeError error code.
+ * - TypeIDExists if the given type's is already registered to another instance type.
+ */
+ InstTypeError registerInstanceType(InstanceTypeInterface *type);
+
+ /*!
+ * \brief Creates an instance with the given type and stores it in inst.
+ *
+ * \param inst Pointer to store the created instance in.
+ * \param type The type of instance to create.
+ * \param instDir The instance's directory.
+ * \return An InstTypeError error code.
+ * - TypeNotRegistered if the given type is not registered with the InstanceLoader.
+ * - InstExists if the given instance directory is already an instance.
+ * - CantCreateDir if the given instance directory cannot be created.
+ */
+ InstTypeError createInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir);
+
+ /*!
+ * \brief Loads an instance from the given directory.
+ *
+ * \param inst Pointer to store the loaded instance in.
+ * \param type The type of instance to load.
+ * \param instDir The instance's directory.
+ * \return An InstTypeError error code.
+ * - TypeNotRegistered if the given type is not registered with the InstanceLoader.
+ * - NotAnInstance if the given instance directory isn't a valid instance.
+ * - WrongInstType if the given instance directory's type isn't the same as the given type.
+ */
+ InstTypeError loadInstance(Instance *&inst, const InstanceTypeInterface *type, const QString &instDir);
+
+ /*!
+ * \brief Loads an instance from the given directory.
+ * Checks the instance's INI file to figure out what the instance's type is first.
+ * \param inst Pointer to store the loaded instance in.
+ * \param instDir The instance's directory.
+ * \return An InstTypeError error code.
+ * - TypeNotRegistered if the instance's type is not registered with the InstanceLoader.
+ * - NotAnInstance if the given instance directory isn't a valid instance.
+ */
+ InstTypeError loadInstance(Instance *&inst, const QString &instDir);
+
+ /*!
+ * \brief Finds an instance type with the given ID.
+ * If one cannot be found, returns NULL.
+ *
+ * \param id The ID of the type to find.
+ * \return The type with the given ID. NULL if none were found.
+ */
+ const InstanceTypeInterface *findType(const QString &id);
+
+ /*!
+ * \brief Gets a list of the registered instance types.
+ *
+ * \return A list of instance types.
+ */
+ InstTypeList typeList();
+
+private:
+ InstanceLoader();
+
+ QMap<QString, InstanceTypeInterface *> m_typeMap;
+
+ static InstanceLoader loader;
+};
+
+#endif // INSTANCELOADER_H
diff --git a/libmultimc/include/instancetypeinterface.h b/libmultimc/include/instancetypeinterface.h
new file mode 100644
index 00000000..30a12d99
--- /dev/null
+++ b/libmultimc/include/instancetypeinterface.h
@@ -0,0 +1,86 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTANCETYPE_H
+#define INSTANCETYPE_H
+
+#include <QObject>
+
+#include "instanceloader.h"
+
+//! The InstanceTypeInterface's interface ID.
+#define InstanceTypeInterface_IID "net.forkk.MultiMC.InstanceTypeInterface/0.1"
+
+/*!
+ * \brief The InstanceType class is an interface for all instance types.
+ * InstanceTypes are usually provided by plugins.
+ * It handles loading and creating instances of a certain type. There should be
+ * one of these for each type of instance and they should be registered with the
+ * InstanceLoader.
+ * To create an instance, the InstanceLoader calls the type's createInstance()
+ * function. Loading is done through the loadInstance() function.
+ */
+class InstanceTypeInterface
+{
+public:
+ friend class InstanceLoader;
+
+ /*!
+ * \brief Gets the ID for this instance type.
+ * The type ID should be unique as it is used to identify the type
+ * of instances when they are loaded.
+ * Changing this value at runtime results in undefined behavior.
+ * \return This instance type's ID string.
+ */
+ virtual QString typeID() const = 0;
+
+ /*!
+ * \brief Gets the name of this instance type as it is displayed to the user.
+ * \return The instance type's display name.
+ */
+ virtual QString displayName() const = 0;
+
+ /*!
+ * \brief Gets a longer, more detailed description of this instance type.
+ * \return The instance type's description.
+ */
+ virtual QString description() const = 0;
+
+protected:
+ /*!
+ * \brief Creates an instance and stores it in inst.
+ * \param inst Pointer to store the created instance in.
+ * \param instDir The instance's directory.
+ * \return An InstTypeError error code.
+ * TypeNotRegistered if the given type is not registered with the InstanceLoader.
+ * InstExists if the given instance directory is already an instance.
+ */
+ virtual InstanceLoader::InstTypeError createInstance(Instance *&inst, const QString &instDir) const = 0;
+
+ /*!
+ * \brief Loads an instance from the given directory.
+ * \param inst Pointer to store the loaded instance in.
+ * \param instDir The instance's directory.
+ * \return An InstTypeError error code.
+ * TypeNotRegistered if the given type is not registered with the InstanceLoader.
+ * NotAnInstance if the given instance directory isn't a valid instance.
+ * WrongInstType if the given instance directory's type isn't an instance of this type.
+ */
+ virtual InstanceLoader::InstTypeError loadInstance(Instance *&inst, const QString &instDir) const = 0;
+};
+
+Q_DECLARE_INTERFACE(InstanceTypeInterface, InstanceTypeInterface_IID)
+
+#endif // INSTANCETYPE_H
diff --git a/libmultimc/include/instversion.h b/libmultimc/include/instversion.h
new file mode 100644
index 00000000..3c6b7ac9
--- /dev/null
+++ b/libmultimc/include/instversion.h
@@ -0,0 +1,53 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTVERSION_H
+#define INSTVERSION_H
+
+#include <QObject>
+
+#include "libmmc_config.h"
+
+class InstVersionList;
+
+class LIBMULTIMC_EXPORT InstVersion : public QObject
+{
+ Q_OBJECT
+public:
+ // Constructs a new InstVersion with the given parent. The parent *must*
+ // be the InstVersionList that contains this InstVersion. The InstVersion
+ // should be added to the list immediately after being created as any calls
+ // to id() will likely fail unless the InstVersion is in a list.
+ explicit InstVersion(InstVersionList *parent = 0);
+
+ // Returns this InstVersion's ID. This is usually just the InstVersion's index
+ // within its InstVersionList, but not always.
+ // If this InstVersion is not in an InstVersionList, returns -1.
+ virtual int id() const = 0;
+
+ // Returns this InstVersion's name. This is displayed to the user in the GUI
+ // and is usually just the version number ("1.4.7"), for example.
+ virtual QString name() const = 0;
+
+ // Returns this InstVersion's name. This is usually displayed to the user
+ // in the GUI and specifies what kind of version this is. For example: it
+ // could be "Snapshot", "Latest Version", "MCNostalgia", etc.
+ virtual QString type() const = 0;
+
+ // Returns the version list that this InstVersion is a part of.
+ virtual InstVersionList *versionList() const;
+};
+
+#endif // INSTVERSION_H
diff --git a/libmultimc/include/instversionlist.h b/libmultimc/include/instversionlist.h
new file mode 100644
index 00000000..d64a286f
--- /dev/null
+++ b/libmultimc/include/instversionlist.h
@@ -0,0 +1,45 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef INSTVERSIONLIST_H
+#define INSTVERSIONLIST_H
+
+#include <QObject>
+
+#include "libmmc_config.h"
+
+class InstVersion;
+
+// Class that each instance type's version list derives from. Version lists are
+// the lists that keep track of the available game versions for that instance.
+// This list will not be loaded on startup. It will be loaded when the list's
+// load function is called.
+class LIBMULTIMC_EXPORT InstVersionList : public QObject
+{
+ Q_OBJECT
+public:
+ explicit InstVersionList();
+
+ // Reloads the version list.
+ virtual void loadVersionList() = 0;
+
+ // Gets the version at the given index.
+ virtual const InstVersion *at(int i) const = 0;
+
+ // Returns the number of versions in the list.
+ virtual int count() const = 0;
+};
+
+#endif // INSTVERSIONLIST_H
diff --git a/libmultimc/include/libmmc_config.h b/libmultimc/include/libmmc_config.h
new file mode 100644
index 00000000..0ff2154a
--- /dev/null
+++ b/libmultimc/include/libmmc_config.h
@@ -0,0 +1,27 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#ifndef LIBINSTANCE_CONFIG_H
+//#define LIBINSTANCE_CONFIG_H
+
+#include <QtCore/QtGlobal>
+
+#ifdef LIBMULTIMC_LIBRARY
+# define LIBMULTIMC_EXPORT Q_DECL_EXPORT
+#else
+# define LIBMULTIMC_EXPORT Q_DECL_IMPORT
+#endif
+
+//#endif // LIBINSTANCE_CONFIG_H
diff --git a/libmultimc/include/loginresponse.h b/libmultimc/include/loginresponse.h
new file mode 100644
index 00000000..0b06a972
--- /dev/null
+++ b/libmultimc/include/loginresponse.h
@@ -0,0 +1,96 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOGINRESPONSE_H
+#define LOGINRESPONSE_H
+
+#include <QObject>
+
+#include "libmmc_config.h"
+
+/*!
+ * \brief The LoginResponse class represents a response received from Minecraft's login servers.
+ */
+class LIBMULTIMC_EXPORT LoginResponse : public QObject
+{
+ Q_OBJECT
+public:
+ /*!
+ * \brief Creates a new instance of the LoginResponse class.
+ * \param username The user's username.
+ * \param sessionID The user's session ID.
+ * \param latestVersion The latest version of Minecraft.
+ * \param parent The parent object.
+ */
+ explicit LoginResponse(const QString &username, const QString &sessionID,
+ qint64 latestVersion, QObject *parent = 0);
+ LoginResponse();
+ LoginResponse(const LoginResponse& other);
+
+ /*!
+ * \brief Gets the username.
+ * This one should go without saying.
+ * \return The username.
+ * \sa setUsername()
+ */
+ QString username() const;
+
+ /*!
+ * \brief setUsername Sets the username.
+ * \param username The new username.
+ * \sa username()
+ */
+ void setUsername(const QString& username);
+
+
+ /*!
+ * \brief Gets the session ID.
+ * \return The session ID.
+ * \sa setSessionID()
+ */
+ QString sessionID() const;
+
+ /*!
+ * \brief Sets the session ID.
+ * \param sessionID The new session ID.
+ * \sa sessionID()
+ */
+ void setSessionID(const QString& sessionID);
+
+
+ /*!
+ * \brief Gets the latest version.
+ * This is a value returned by the login servers when a user logs in.
+ * \return The latest version.
+ * \sa setLatestVersion()
+ */
+ qint64 latestVersion() const;
+
+ /*!
+ * \brief Sets the latest version.
+ * \param v The new latest version.
+ * \sa latestVersion()
+ */
+ void setLatestVersion(qint64 v);
+
+private:
+ QString m_username;
+ QString m_sessionID;
+ qint64 m_latestVersion;
+};
+
+Q_DECLARE_METATYPE(LoginResponse)
+
+#endif // LOGINRESPONSE_H
diff --git a/libmultimc/include/logintask.h b/libmultimc/include/logintask.h
new file mode 100644
index 00000000..c1efb223
--- /dev/null
+++ b/libmultimc/include/logintask.h
@@ -0,0 +1,50 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef LOGINTASK_H
+#define LOGINTASK_H
+
+#include "task.h"
+
+#include "userinfo.h"
+#include "loginresponse.h"
+
+#include "libmmc_config.h"
+
+//class QNetworkAccessManager;
+class QNetworkReply;
+
+class LIBMULTIMC_EXPORT LoginTask : public Task
+{
+ Q_OBJECT
+public:
+ explicit LoginTask(const UserInfo& uInfo, QObject *parent = 0);
+
+public slots:
+ void processNetReply(QNetworkReply* reply);
+
+signals:
+ void loginComplete(LoginResponse loginResponse);
+ void loginFailed(const QString& errorMsg);
+
+protected:
+ void executeTask();
+
+ QNetworkReply* netReply;
+
+ UserInfo uInfo;
+};
+
+#endif // LOGINTASK_H
diff --git a/libmultimc/include/minecraftprocess.h b/libmultimc/include/minecraftprocess.h
new file mode 100644
index 00000000..8986f7ad
--- /dev/null
+++ b/libmultimc/include/minecraftprocess.h
@@ -0,0 +1,97 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef MINECRAFTPROCESS_H
+#define MINECRAFTPROCESS_H
+
+#include <QProcess>
+
+#include "instance.h"
+
+#include "libmmc_config.h"
+
+/**
+ * @file data/minecraftprocess.h
+ * @brief The MinecraftProcess class
+ */
+class LIBMULTIMC_EXPORT MinecraftProcess : public QProcess
+{
+ Q_OBJECT
+public:
+ /**
+ * @brief MinecraftProcess constructor
+ * @param inst the Instance pointer to launch
+ * @param user the minecraft username
+ * @param session the minecraft session id
+ * @param console the instance console window
+ */
+ MinecraftProcess(InstancePtr inst, QString user, QString session);
+
+ /**
+ * @brief launch minecraft
+ */
+ void launch();
+
+ /**
+ * @brief extract the instance icon
+ * @param inst the instance
+ * @param destination the destination path
+ */
+ static inline void extractIcon(InstancePtr inst, QString destination);
+
+ /**
+ * @brief extract the MultiMC launcher.jar
+ * @param destination the destination path
+ */
+ static inline void extractLauncher(QString destination);
+
+ /**
+ * @brief prepare the launch by extracting icon and launcher
+ * @param inst the instance
+ */
+ static void prepare(InstancePtr inst);
+
+ /**
+ * @brief split a string into argv items like a shell would do
+ * @param args the argument string
+ * @return a QStringList containing all arguments
+ */
+ static QStringList splitArgs(QString args);
+
+signals:
+ /**
+ * @brief emitted when mc has finished and the PostLaunchCommand was run
+ */
+ void ended();
+
+protected:
+ InstancePtr m_instance;
+ QString m_user;
+ QString m_session;
+ QProcess m_prepostlaunchprocess;
+ QStringList m_arguments;
+
+ void genArgs();
+ void log(QString text);
+
+protected slots:
+ void finish(int, QProcess::ExitStatus status);
+ void on_stdErr();
+ void on_stdOut();
+
+};
+
+#endif // MINECRAFTPROCESS_H
diff --git a/libmultimc/include/pluginmanager.h b/libmultimc/include/pluginmanager.h
new file mode 100644
index 00000000..1fc22a6c
--- /dev/null
+++ b/libmultimc/include/pluginmanager.h
@@ -0,0 +1,74 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef PLUGINMANAGER_H
+#define PLUGINMANAGER_H
+
+#include <QObject>
+#include <QList>
+#include <QPluginLoader>
+
+#include "libmmc_config.h"
+
+/*!
+ * \brief This class is a singleton that manages loading plugins.
+ */
+class LIBMULTIMC_EXPORT PluginManager : public QObject
+{
+ Q_OBJECT
+public:
+ /*!
+ * \brief Gets the plugin manager instance.
+ */
+ static PluginManager &get() { return manager; }
+
+ /*!
+ * \brief Loads plugins from the given directory.
+ * This function does \e not initialize the plugins. It simply loads their
+ * classes. Use the init functions to initialize the various plugin types.
+ * \param The directory to load plugins from.
+ * \return True if successful. False on failure.
+ */
+ bool loadPlugins(QString pluginDir);
+
+ /*!
+ * \brief Checks how many plugins are loaded.
+ * \return The number of plugins.
+ */
+ int count() { return m_plugins.count(); }
+
+ /*!
+ * \brief Gets the plugin at the given index.
+ * \param index The index of the plugin to get.
+ * \return The plugin at the given index.
+ */
+ QPluginLoader *getPlugin(int index);
+
+ /*!
+ * \brief Initializes and registers all the instance types.
+ * This is done by going through the plugin list and registering all of the
+ * plugins that derive from the InstanceTypeInterface with the InstanceLoader.
+ */
+ void initInstanceTypes();
+
+private:
+ PluginManager();
+
+ QList<QPluginLoader *> m_plugins;
+
+ static PluginManager manager;
+};
+
+#endif // PLUGINMANAGER_H
diff --git a/libmultimc/include/task.h b/libmultimc/include/task.h
new file mode 100644
index 00000000..b1a3052d
--- /dev/null
+++ b/libmultimc/include/task.h
@@ -0,0 +1,56 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef TASK_H
+#define TASK_H
+
+#include <QObject>
+#include <QThread>
+#include <QString>
+
+#include "libmmc_config.h"
+
+class LIBMULTIMC_EXPORT Task : public QThread
+{
+ Q_OBJECT
+public:
+ explicit Task(QObject *parent = 0);
+
+ // Starts the task.
+ void startTask();
+
+ QString getStatus() const;
+ int getProgress() const;
+
+public slots:
+ void setStatus(const QString& status);
+ void setProgress(int progress);
+
+signals:
+ void taskStarted(Task* task);
+ void taskEnded(Task* task);
+
+ void statusChanged(const QString& status);
+ void progressChanged(int progress);
+
+protected:
+ virtual void run();
+ virtual void executeTask() = 0;
+
+ QString status;
+ int progress;
+};
+
+#endif // TASK_H
diff --git a/libmultimc/include/userinfo.h b/libmultimc/include/userinfo.h
new file mode 100644
index 00000000..280f98de
--- /dev/null
+++ b/libmultimc/include/userinfo.h
@@ -0,0 +1,41 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef USERINFO_H
+#define USERINFO_H
+
+#include <QObject>
+
+#include "libmmc_config.h"
+
+class LIBMULTIMC_EXPORT UserInfo : public QObject
+{
+ Q_OBJECT
+public:
+ explicit UserInfo(const QString& username, const QString& password, QObject *parent = 0);
+ explicit UserInfo(const UserInfo& other);
+
+ QString username() const;
+ void setUsername(const QString& username);
+
+ QString password() const;
+ void setPassword(const QString& password);
+
+protected:
+ QString m_username;
+ QString m_password;
+};
+
+#endif // USERINFO_H
diff --git a/libmultimc/include/version.h b/libmultimc/include/version.h
new file mode 100644
index 00000000..3025260b
--- /dev/null
+++ b/libmultimc/include/version.h
@@ -0,0 +1,69 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef VERSION_H
+#define VERSION_H
+
+#include <QObject>
+
+#include "libmmc_config.h"
+
+/*!
+ * \brief The Version class represents a MultiMC version number.
+ */
+class LIBMULTIMC_EXPORT Version : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Version(int major = 0, int minor = 0, int revision = 0,
+ int build = 0, QObject *parent = 0);
+
+ Version(const Version& ver);
+
+ /*!
+ * \brief Converts the Version to a string.
+ * \return The version number in string format (major.minor.revision.build).
+ */
+ QString toString() const;
+
+ /*!
+ * \brief The major version number.
+ * For MultiMC 5, this will always be 5.
+ */
+ int major;
+
+ /*!
+ * \brief The minor version number.
+ * This number is incremented when major features are added.
+ */
+ int minor;
+
+ /*!
+ * \brief The revision number.
+ * This number is incremented for bugfixes and small features.
+ */
+ int revision;
+
+ /*!
+ * \brief The build number.
+ * This number is automatically set by Jenkins. It is incremented every time
+ * a new build is run.
+ */
+ int build;
+
+ static Version current;
+};
+
+#endif // VERSION_H
diff --git a/libmultimc/src/appsettings.cpp b/libmultimc/src/appsettings.cpp
new file mode 100644
index 00000000..68d2c015
--- /dev/null
+++ b/libmultimc/src/appsettings.cpp
@@ -0,0 +1,68 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "appsettings.h"
+
+#include <setting.h>
+
+#include <QPoint>
+//#include <QColor>
+
+AppSettings::AppSettings(QObject *parent) :
+ BasicSettingsObject(parent)
+{
+ // Updates
+ registerSetting(new Setting("UseDevBuilds", false));
+ registerSetting(new Setting("AutoUpdate", true));
+
+ // Folders
+ registerSetting(new Setting("InstanceDir", "instances"));
+ registerSetting(new Setting("CentralModsDir", "mods"));
+ registerSetting(new Setting("LWJGLDir", "lwjgl"));
+
+ // Console
+ registerSetting(new Setting("ShowConsole", true));
+ registerSetting(new Setting("AutoCloseConsole", true));
+
+ // Toolbar settings
+ registerSetting(new Setting("InstanceToolbarVisible", true));
+ registerSetting(new Setting("InstanceToolbarPosition", QPoint()));
+
+ // Console Colors
+// registerSetting(new Setting("SysMessageColor", QColor(Qt::blue)));
+// registerSetting(new Setting("StdOutColor", QColor(Qt::black)));
+// registerSetting(new Setting("StdErrColor", QColor(Qt::red)));
+
+ // Window Size
+ registerSetting(new Setting("LaunchCompatMode", false));
+ registerSetting(new Setting("LaunchMaximized", false));
+ registerSetting(new Setting("MinecraftWinWidth", 854));
+ registerSetting(new Setting("MinecraftWinHeight", 480));
+
+ // Auto login
+ registerSetting(new Setting("AutoLogin", false));
+
+ // Memory
+ registerSetting(new Setting("MinMemAlloc", 512));
+ registerSetting(new Setting("MaxMemAlloc", 1024));
+
+ // Java Settings
+ registerSetting(new Setting("JavaPath", "java"));
+ registerSetting(new Setting("JvmArgs", ""));
+
+ // Custom Commands
+ registerSetting(new Setting("PreLaunchCommand", ""));
+ registerSetting(new Setting("PostExitCommand", ""));
+}
diff --git a/libmultimc/src/gameupdatetask.cpp b/libmultimc/src/gameupdatetask.cpp
new file mode 100644
index 00000000..c152147e
--- /dev/null
+++ b/libmultimc/src/gameupdatetask.cpp
@@ -0,0 +1,22 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "gameupdatetask.h"
+
+GameUpdateTask::GameUpdateTask(const LoginResponse &response, QObject *parent) :
+ QObject(parent), m_response(response)
+{
+
+}
diff --git a/libmultimc/src/instance.cpp b/libmultimc/src/instance.cpp
new file mode 100644
index 00000000..377acd32
--- /dev/null
+++ b/libmultimc/src/instance.cpp
@@ -0,0 +1,131 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/instance.h"
+
+#include <QFileInfo>
+
+#include "inisettingsobject.h"
+#include "setting.h"
+#include "overridesetting.h"
+
+#include "pathutils.h"
+
+Instance::Instance(const QString &rootDir, QObject *parent) :
+ QObject(parent)
+{
+ m_rootDir = rootDir;
+ m_settings = new INISettingsObject(PathCombine(rootDir, "instance.cfg"), this);
+
+ settings().registerSetting(new Setting("name", "Unnamed Instance"));
+ settings().registerSetting(new Setting("iconKey", "default"));
+ settings().registerSetting(new Setting("notes", ""));
+ settings().registerSetting(new Setting("NeedsRebuild", true));
+ settings().registerSetting(new Setting("JarVersion", "Unknown"));
+ settings().registerSetting(new Setting("LwjglVersion", "Mojang"));
+ settings().registerSetting(new Setting("IntendedJarVersion", ""));
+ settings().registerSetting(new Setting("lastLaunchTime", 0));
+
+ // Java Settings
+ settings().registerSetting(new OverrideSetting("JavaPath", globalSettings->getSetting("JavaPath")));
+ settings().registerSetting(new OverrideSetting("JvmArgs", globalSettings->getSetting("JvmArgs")));
+
+ // Custom Commands
+ settings().registerSetting(new OverrideSetting("PreLaunchCommand",
+ globalSettings->getSetting("PreLaunchCommand")));
+ settings().registerSetting(new OverrideSetting("PostExitCommand",
+ globalSettings->getSetting("PostExitCommand")));
+
+ // Memory
+ settings().registerSetting(new OverrideSetting("MinMemAlloc", globalSettings->getSetting("MinMemAlloc")));
+ settings().registerSetting(new OverrideSetting("MaxMemAlloc", globalSettings->getSetting("MaxMemAlloc")));
+
+ // Auto login
+ settings().registerSetting(new OverrideSetting("AutoLogin", globalSettings->getSetting("AutoLogin")));
+}
+
+QString Instance::id() const
+{
+ return QFileInfo(rootDir()).fileName();
+}
+
+QString Instance::rootDir() const
+{
+ return m_rootDir;
+}
+
+InstanceList *Instance::instList() const
+{
+ if (parent()->inherits("InstanceList"))
+ return (InstanceList *)parent();
+ else
+ return NULL;
+}
+
+QString Instance::minecraftDir() const
+{
+ QFileInfo mcDir(PathCombine(rootDir(), "minecraft"));
+ QFileInfo dotMCDir(PathCombine(rootDir(), ".minecraft"));
+
+ if (dotMCDir.exists() && !mcDir.exists())
+ return dotMCDir.filePath();
+ else
+ return mcDir.filePath();
+}
+
+QString Instance::binDir() const
+{
+ return PathCombine(minecraftDir(), "bin");
+}
+
+QString Instance::savesDir() const
+{
+ return PathCombine(minecraftDir(), "saves");
+}
+
+QString Instance::mlModsDir() const
+{
+ return PathCombine(minecraftDir(), "mods");
+}
+
+QString Instance::coreModsDir() const
+{
+ return PathCombine(minecraftDir(), "coremods");
+}
+
+QString Instance::resourceDir() const
+{
+ return PathCombine(minecraftDir(), "resources");
+}
+
+QString Instance::screenshotsDir() const
+{
+ return PathCombine(minecraftDir(), "screenshots");
+}
+
+QString Instance::texturePacksDir() const
+{
+ return PathCombine(minecraftDir(), "texturepacks");
+}
+
+QString Instance::mcJar() const
+{
+ return PathCombine(binDir(), "minecraft.jar");
+}
+
+SettingsObject &Instance::settings() const
+{
+ return *m_settings;
+}
diff --git a/libmultimc/src/instancelist.cpp b/libmultimc/src/instancelist.cpp
new file mode 100644
index 00000000..3b0b668f
--- /dev/null
+++ b/libmultimc/src/instancelist.cpp
@@ -0,0 +1,87 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/instancelist.h"
+
+#include "siglist_impl.h"
+
+#include <QDir>
+#include <QFile>
+#include <QDirIterator>
+
+#include "include/instance.h"
+#include "include/instanceloader.h"
+
+#include "pathutils.h"
+
+
+InstanceList::InstanceList(const QString &instDir, QObject *parent) :
+ QObject(parent), m_instDir(instDir)
+{
+
+}
+
+InstanceList::InstListError InstanceList::loadList()
+{
+ QDir dir(m_instDir);
+ QDirIterator iter(dir);
+
+ while (iter.hasNext())
+ {
+ QString subDir = iter.next();
+ if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists())
+ {
+ Instance *instPtr = NULL;
+
+ InstanceLoader::InstTypeError error = InstanceLoader::get().
+ loadInstance(instPtr, subDir);
+
+ if (error != InstanceLoader::NoError &&
+ error != InstanceLoader::NotAnInstance)
+ {
+ QString errorMsg = QString("Failed to load instance %1: ").
+ arg(QFileInfo(subDir).baseName()).toUtf8();
+
+ switch (error)
+ {
+ case InstanceLoader::TypeNotRegistered:
+ errorMsg += "Instance type not found.";
+ break;
+
+ default:
+ errorMsg += QString("Unknown instance loader error %1").
+ arg(error);
+ break;
+ }
+ qDebug(errorMsg.toUtf8());
+ }
+ else if (!instPtr)
+ {
+ qDebug(QString("Error loading instance %1. Instance loader returned null.").
+ arg(QFileInfo(subDir).baseName()).toUtf8());
+ }
+ else
+ {
+ QSharedPointer<Instance> inst(instPtr);
+
+ qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8());
+ inst->setParent(this);
+ append(QSharedPointer<Instance>(inst));
+ }
+ }
+ }
+
+ return NoError;
+}
diff --git a/libmultimc/src/instanceloader.cpp b/libmultimc/src/instanceloader.cpp
new file mode 100644
index 00000000..9d98230f
--- /dev/null
+++ b/libmultimc/src/instanceloader.cpp
@@ -0,0 +1,109 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/instanceloader.h"
+
+#include <QFileInfo>
+
+#include "include/instancetypeinterface.h"
+
+#include "inifile.h"
+
+#include "pathutils.h"
+
+InstanceLoader InstanceLoader::loader;
+
+InstanceLoader::InstanceLoader() :
+ QObject(NULL)
+{
+
+}
+
+
+InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceTypeInterface *type)
+{
+ // Check to see if the type ID exists.
+ if (m_typeMap.contains(type->typeID()))
+ return TypeIDExists;
+
+ // Set the parent to this.
+ // ((QObject *)type)->setParent(this);
+
+ // Add it to the map.
+ m_typeMap.insert(type->typeID(), type);
+
+ qDebug(QString("Registered instance type %1.").
+ arg(type->typeID()).toUtf8());
+ return NoError;
+}
+
+InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *&inst,
+ const InstanceTypeInterface *type,
+ const QString &instDir)
+{
+ // Check if the type is registered.
+ if (!type || findType(type->typeID()) != type)
+ return TypeNotRegistered;
+
+ // Create the instance.
+ return type->createInstance(inst, instDir);
+}
+
+InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *&inst,
+ const InstanceTypeInterface *type,
+ const QString &instDir)
+{
+ // Check if the type is registered.
+ if (!type || findType(type->typeID()) != type)
+ return TypeNotRegistered;
+
+ return type->loadInstance(inst, instDir);
+}
+
+InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *&inst,
+ const QString &instDir)
+{
+ QFileInfo instConfig(PathCombine(instDir, "instance.cfg"));
+
+ if (!instConfig.exists())
+ return NotAnInstance;
+
+ INIFile ini;
+ ini.loadFile(instConfig.path());
+ QString typeName = ini.get("type", "net.forkk.MultiMC.StdInstance").toString();
+ const InstanceTypeInterface *type = findType(typeName);
+
+ return loadInstance(inst, type, instDir);
+}
+
+const InstanceTypeInterface *InstanceLoader::findType(const QString &id)
+{
+ if (!m_typeMap.contains(id))
+ return NULL;
+ else
+ return m_typeMap[id];
+}
+
+InstTypeList InstanceLoader::typeList()
+{
+ InstTypeList typeList;
+
+ for (QMap<QString, InstanceTypeInterface *>::iterator iter = m_typeMap.begin(); iter != m_typeMap.end(); iter++)
+ {
+ typeList.append(*iter);
+ }
+
+ return typeList;
+}
diff --git a/libmultimc/src/instversion.cpp b/libmultimc/src/instversion.cpp
new file mode 100644
index 00000000..cedb61df
--- /dev/null
+++ b/libmultimc/src/instversion.cpp
@@ -0,0 +1,32 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/instversion.h"
+#include "include/instversionlist.h"
+
+InstVersion::InstVersion(InstVersionList *parent) :
+ QObject(parent)
+{
+
+}
+
+InstVersionList *InstVersion::versionList() const
+{
+ // Parent should *always* be an InstVersionList
+ if (!parent() || !parent()->inherits("InstVersionList"))
+ return NULL;
+ else
+ return (InstVersionList *)parent();
+}
diff --git a/libmultimc/src/instversionlist.cpp b/libmultimc/src/instversionlist.cpp
new file mode 100644
index 00000000..e171cfa5
--- /dev/null
+++ b/libmultimc/src/instversionlist.cpp
@@ -0,0 +1,21 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "include/instversionlist.h"
+
+InstVersionList::InstVersionList() :
+ QObject(NULL)
+{
+}
diff --git a/libmultimc/src/loginresponse.cpp b/libmultimc/src/loginresponse.cpp
new file mode 100644
index 00000000..99a618ad
--- /dev/null
+++ b/libmultimc/src/loginresponse.cpp
@@ -0,0 +1,69 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "loginresponse.h"
+
+LoginResponse::LoginResponse(const QString& username, const QString& sessionID,
+ qint64 latestVersion, QObject *parent) :
+ QObject(parent)
+{
+ this->m_username = username;
+ this->m_sessionID = sessionID;
+ this->m_latestVersion = latestVersion;
+}
+
+LoginResponse::LoginResponse()
+{
+ this->m_username = "";
+ this->m_sessionID = "";
+ this->m_latestVersion = 0;
+}
+
+LoginResponse::LoginResponse(const LoginResponse &other)
+{
+ this->m_username = other.username();
+ this->m_sessionID = other.sessionID();
+ this->m_latestVersion = other.latestVersion();
+}
+
+QString LoginResponse::username() const
+{
+ return m_username;
+}
+
+void LoginResponse::setUsername(const QString& username)
+{
+ this->m_username = username;
+}
+
+QString LoginResponse::sessionID() const
+{
+ return m_sessionID;
+}
+
+void LoginResponse::setSessionID(const QString& sessionID)
+{
+ this->m_sessionID = sessionID;
+}
+
+qint64 LoginResponse::latestVersion() const
+{
+ return m_latestVersion;
+}
+
+void LoginResponse::setLatestVersion(qint64 v)
+{
+ this->m_latestVersion = v;
+}
diff --git a/libmultimc/src/logintask.cpp b/libmultimc/src/logintask.cpp
new file mode 100644
index 00000000..71075630
--- /dev/null
+++ b/libmultimc/src/logintask.cpp
@@ -0,0 +1,121 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "logintask.h"
+
+#include <QStringList>
+
+#include <QtNetwork/QNetworkAccessManager>
+#include <QtNetwork/QNetworkReply>
+#include <QtNetwork/QNetworkRequest>
+
+#include <QUrl>
+#include <QUrlQuery>
+
+LoginTask::LoginTask(const UserInfo &uInfo, QObject *parent) :
+ Task(parent), uInfo(uInfo)
+{
+
+}
+
+void LoginTask::executeTask()
+{
+ setStatus("Logging in...");
+
+ QNetworkAccessManager netMgr;
+ connect(&netMgr, SIGNAL(finished(QNetworkReply*)),
+ SLOT(processNetReply(QNetworkReply*)));
+
+ QUrl loginURL("https://login.minecraft.net/");
+ QNetworkRequest netRequest(loginURL);
+ netRequest.setHeader(QNetworkRequest::ContentTypeHeader,
+ "application/x-www-form-urlencoded");
+
+ QUrlQuery params;
+ params.addQueryItem("user", uInfo.username());
+ params.addQueryItem("password", uInfo.password());
+ params.addQueryItem("version", "13");
+
+ netReply = netMgr.post(netRequest, params.query(QUrl::EncodeSpaces).toUtf8());
+ exec();
+}
+
+void LoginTask::processNetReply(QNetworkReply *reply)
+{
+ // Check for errors.
+ switch (reply->error())
+ {
+ case QNetworkReply::NoError:
+ {
+ // Check the response code.
+ int responseCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
+
+ if (responseCode == 200)
+ {
+ QString responseStr(reply->readAll());
+
+ QStringList strings = responseStr.split(":");
+ if (strings.count() >= 4)
+ {
+ bool parseSuccess;
+ qint64 latestVersion = strings[0].toLongLong(&parseSuccess);
+ if (parseSuccess)
+ {
+ // strings[1] is the download ticket. It isn't used anymore.
+ QString username = strings[2];
+ QString sessionID = strings[3];
+
+ LoginResponse response(username, sessionID, latestVersion);
+ emit loginComplete(response);
+ }
+ else
+ {
+ emit loginFailed("Failed to parse Minecraft version string.");
+ }
+ }
+ else
+ {
+ if (responseStr.toLower() == "bad login")
+ emit loginFailed("Invalid username or password.");
+ else if (responseStr.toLower() == "old version")
+ emit loginFailed("Launcher outdated, please update.");
+ else
+ emit loginFailed("Login failed: " + responseStr);
+ }
+ }
+ else if (responseCode == 503)
+ {
+ emit loginFailed("The login servers are currently unavailable. "
+ "Check http://help.mojang.com/ for more info.");
+ }
+ else
+ {
+ emit loginFailed(QString("Login failed: Unknown HTTP error %1 occurred.").
+ arg(QString::number(responseCode)));
+ }
+ break;
+ }
+
+ case QNetworkReply::OperationCanceledError:
+ emit loginFailed("Login canceled.");
+ break;
+
+ default:
+ emit loginFailed("Login failed: " + reply->errorString());
+ break;
+ }
+
+ quit();
+}
diff --git a/libmultimc/src/minecraftprocess.cpp b/libmultimc/src/minecraftprocess.cpp
new file mode 100644
index 00000000..943d76b1
--- /dev/null
+++ b/libmultimc/src/minecraftprocess.cpp
@@ -0,0 +1,248 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Authors: Orochimarufan <orochimarufan.x3@gmail.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "minecraftprocess.h"
+
+#include <QDataStream>
+#include <QFile>
+#include <QDir>
+//#include <QImage>
+#include <QProcessEnvironment>
+
+#include "instance.h"
+
+#include "osutils.h"
+#include "pathutils.h"
+
+#define LAUNCHER_FILE "MultiMCLauncher.jar"
+#define IBUS "@im=ibus"
+
+// 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;
+}
+
+// prepare tools
+inline void MinecraftProcess::extractIcon(InstancePtr inst, QString destination)
+{
+// QImage(":/icons/instances/" + inst->iconKey()).save(destination);
+}
+
+inline void MinecraftProcess::extractLauncher(QString 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"));
+}
+
+// constructor
+MinecraftProcess::MinecraftProcess(InstancePtr inst, QString user, QString session) :
+ m_instance(inst), m_user(user), m_session(session)
+{
+ 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, ""));
+#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()));
+}
+
+// console window
+void MinecraftProcess::on_stdErr()
+{
+// if (m_console != nullptr)
+// m_console->write(readAllStandardError(), ConsoleWindow::ERROR);
+}
+
+void MinecraftProcess::on_stdOut()
+{
+// 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));
+}
+
+// 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->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->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->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);
+#endif
+
+ // 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/libmultimc/src/pluginmanager.cpp b/libmultimc/src/pluginmanager.cpp
new file mode 100644
index 00000000..2f066293
--- /dev/null
+++ b/libmultimc/src/pluginmanager.cpp
@@ -0,0 +1,105 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "pluginmanager.h"
+
+#include <QDir>
+#include <QDirIterator>
+#include <QFileInfo>
+#include <QVariant>
+
+#include <QJsonObject>
+
+#include <QtPlugin>
+
+#include "instancetypeinterface.h"
+
+// MultiMC's API version. This must match the "api" field in each plugin's
+// metadata or MultiMC won't consider them valid MultiMC plugin.
+#define MMC_API_VERSION "MultiMC5-API-1"
+
+PluginManager PluginManager::manager;
+
+PluginManager::PluginManager() :
+ QObject(NULL)
+{
+
+}
+
+bool PluginManager::loadPlugins(QString pluginDir)
+{
+ // Delete the loaded plugins and clear the list.
+ for (int i = 0; i < m_plugins.count(); i++)
+ {
+ delete m_plugins[i];
+ }
+ m_plugins.clear();
+
+ qDebug(QString("Loading plugins from directory: %1").
+ arg(pluginDir).toUtf8());
+
+ QDir dir(pluginDir);
+ QDirIterator iter(dir);
+
+ while (iter.hasNext())
+ {
+ QFileInfo pluginFile(dir.absoluteFilePath(iter.next()));
+
+ if (pluginFile.exists() && pluginFile.isFile())
+ {
+ qDebug(QString("Attempting to load plugin: %1").
+ arg(pluginFile.canonicalFilePath()).toUtf8());
+
+ QPluginLoader *pluginLoader = new QPluginLoader(pluginFile.absoluteFilePath());
+
+ QJsonObject pluginInfo = pluginLoader->metaData();
+ QJsonObject pluginMetadata = pluginInfo.value("MetaData").toObject();
+
+ if (pluginMetadata.value("api").toString("") != MMC_API_VERSION)
+ {
+ // If "api" is not specified, it's not a MultiMC plugin.
+ qDebug(QString("Not loading plugin %1. Not a valid MultiMC plugin. "
+ "API: %2").
+ arg(pluginFile.canonicalFilePath(), pluginMetadata.value("api").toString("")).toUtf8());
+ continue;
+ }
+
+ qDebug(QString("Loaded plugin: %1").
+ arg(pluginInfo.value("IID").toString()).toUtf8());
+ m_plugins.push_back(pluginLoader);
+ }
+ }
+
+ return true;
+}
+
+QPluginLoader *PluginManager::getPlugin(int index)
+{
+ return m_plugins[index];
+}
+
+void PluginManager::initInstanceTypes()
+{
+ for (int i = 0; i < m_plugins.count(); i++)
+ {
+ InstanceTypeInterface *instType = qobject_cast<InstanceTypeInterface *>(m_plugins[i]->instance());
+
+ if (instType)
+ {
+ // TODO: Handle errors
+ InstanceLoader::get().registerInstanceType(instType);
+ }
+ }
+}
diff --git a/libmultimc/src/task.cpp b/libmultimc/src/task.cpp
new file mode 100644
index 00000000..d581a1dd
--- /dev/null
+++ b/libmultimc/src/task.cpp
@@ -0,0 +1,56 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "task.h"
+
+Task::Task(QObject *parent) :
+ QThread(parent)
+{
+
+}
+
+QString Task::getStatus() const
+{
+ return status;
+}
+
+void Task::setStatus(const QString &status)
+{
+ this->status = status;
+ emit statusChanged(status);
+}
+
+int Task::getProgress() const
+{
+ return progress;
+}
+
+void Task::setProgress(int progress)
+{
+ this->progress = progress;
+ emit progressChanged(progress);
+}
+
+void Task::startTask()
+{
+ start();
+}
+
+void Task::run()
+{
+ emit taskStarted(this);
+ executeTask();
+ emit taskEnded(this);
+}
diff --git a/libmultimc/src/userinfo.cpp b/libmultimc/src/userinfo.cpp
new file mode 100644
index 00000000..0bb5da11
--- /dev/null
+++ b/libmultimc/src/userinfo.cpp
@@ -0,0 +1,49 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "userinfo.h"
+
+UserInfo::UserInfo(const QString &username, const QString &password, QObject *parent) :
+ QObject(parent)
+{
+ this->m_username = username;
+ this->m_password = password;
+}
+
+UserInfo::UserInfo(const UserInfo &other)
+{
+ this->m_username = other.m_username;
+ this->m_password = other.m_password;
+}
+
+QString UserInfo::username() const
+{
+ return m_username;
+}
+
+void UserInfo::setUsername(const QString &username)
+{
+ this->m_username = username;
+}
+
+QString UserInfo::password() const
+{
+ return m_password;
+}
+
+void UserInfo::setPassword(const QString &password)
+{
+ this->m_password = password;
+}
diff --git a/libmultimc/src/version.cpp b/libmultimc/src/version.cpp
new file mode 100644
index 00000000..eec50e13
--- /dev/null
+++ b/libmultimc/src/version.cpp
@@ -0,0 +1,46 @@
+/* Copyright 2013 MultiMC Contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "version.h"
+
+#include "config.h"
+
+Version Version::current(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD);
+
+Version::Version(int major, int minor, int revision, int build, QObject *parent) :
+ QObject(parent)
+{
+ this->major = major;
+ this->minor = minor;
+ this->revision = revision;
+ this->build = build;
+}
+
+Version::Version(const Version& ver)
+{
+ this->major = ver.major;
+ this->minor = ver.minor;
+ this->revision = ver.revision;
+ this->build = ver.build;
+}
+
+QString Version::toString() const
+{
+ return QString("%1.%2.%3.%4").arg(
+ QString::number(major),
+ QString::number(minor),
+ QString::number(revision),
+ QString::number(build));
+}