summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libmultimc/include/instance.h263
-rw-r--r--libmultimc/include/instancetypeinterface.h10
-rw-r--r--libmultimc/include/instversion.h33
-rw-r--r--libmultimc/include/instversionlist.h37
-rw-r--r--libmultimc/include/task.h9
-rw-r--r--libmultimc/src/instance.cpp24
-rw-r--r--libmultimc/src/instversionlist.cpp17
-rw-r--r--libmultimc/src/task.cpp5
-rw-r--r--plugins/stdinstance/CMakeLists.txt7
-rw-r--r--plugins/stdinstance/stdinstance.cpp17
-rw-r--r--plugins/stdinstance/stdinstance.h9
-rw-r--r--plugins/stdinstance/stdinstancetype.cpp10
-rw-r--r--plugins/stdinstance/stdinstancetype.h3
-rw-r--r--plugins/stdinstance/stdinstversion.cpp147
-rw-r--r--plugins/stdinstance/stdinstversion.h82
-rw-r--r--plugins/stdinstance/stdinstversionlist.cpp509
-rw-r--r--plugins/stdinstance/stdinstversionlist.h99
17 files changed, 1110 insertions, 171 deletions
diff --git a/libmultimc/include/instance.h b/libmultimc/include/instance.h
index 7de61343..c41e6718 100644
--- a/libmultimc/include/instance.h
+++ b/libmultimc/include/instance.h
@@ -22,6 +22,8 @@
#include <settingsobject.h>
#include "inifile.h"
+#include "instancetypeinterface.h"
+#include "instversionlist.h"
#include "libmmc_config.h"
@@ -38,33 +40,124 @@ class InstanceList;
class LIBMULTIMC_EXPORT Instance : public QObject
{
Q_OBJECT
+
+ // Properties
+ /*!
+ * 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.
+ */
+ Q_PROPERTY(QString id READ id STORED false)
+
+ //! Path to the instance's root directory.
+ Q_PROPERTY(QString rootDir READ rootDir)
+
+ //! The name of the instance that is displayed to the user.
+ Q_PROPERTY(QString name READ name WRITE setName)
+
+ //! The instance's icon key.
+ Q_PROPERTY(QString iconKey READ iconKey WRITE setIconKey)
+
+ //! The instance's notes.
+ Q_PROPERTY(QString notes READ notes WRITE setNotes)
+
+ /*!
+ * Whether or not the instance's minecraft.jar needs to be rebuilt.
+ * If this is true, when the instance launches, its jar mods will be
+ * re-added to a fresh minecraft.jar file.
+ */
+ Q_PROPERTY(bool shouldRebuild READ shouldRebuild WRITE setShouldRebuild)
+
+
+ /*!
+ * The instance's current version.
+ * This value represents the instance's current version. If this value is
+ * different from the intendedVersion, the instance should be updated.
+ * \warning Don't change this value unless you know what you're doing.
+ */
+ Q_PROPERTY(QString currentVersion READ currentVersion WRITE setCurrentVersion)
+
+ /*!
+ * The version that the user has set for this instance to use.
+ * If this is not the same as currentVersion, the instance's game updater
+ * will be run on launch.
+ */
+ Q_PROPERTY(QString intendedVersion READ intendedVersion WRITE setIntendedVersion)
+
+ //! The version of LWJGL that this instance uses.
+ Q_PROPERTY(QString lwjglVersion READ lwjglVersion WRITE setLWJGLVersion)
+
+
+ /*!
+ * Gets the time that the instance was last launched.
+ * Stored in milliseconds since epoch.
+ * This value is usually used for things like sorting instances by the time
+ * they were last launched.
+ */
+ Q_PROPERTY(qint64 lastLaunch READ lastLaunch WRITE setLastLaunch)
+
+
+
+ // Dirs
+ //! Path to the instance's .minecraft folder.
+ Q_PROPERTY(QString minecraftDir READ minecraftDir STORED false)
+
+ //! Path to the instance's instMods folder.
+ Q_PROPERTY(QString instModsDir READ instModsDir STORED false)
+
+ //! Path to the instance's bin folder.
+ Q_PROPERTY(QString binDir READ binDir STORED false)
+
+ //! Path to the instance's saves folder.
+ Q_PROPERTY(QString savesDir READ savesDir STORED false)
+
+ //! Path to the instance's mods folder (.minecraft/mods)
+ Q_PROPERTY(QString mlModsDir READ mlModsDir STORED false)
+
+ //! Path to the instance's coremods folder.
+ Q_PROPERTY(QString coreModsDir READ coreModsDir STORED false)
+
+ //! Path to the instance's resources folder.
+ Q_PROPERTY(QString resourceDir READ resourceDir STORED false)
+
+ //! Path to the instance's screenshots folder.
+ Q_PROPERTY(QString screenshotsDir READ screenshotsDir STORED false)
+
+ //! Path to the instance's texturepacks folder.
+ Q_PROPERTY(QString texturePacksDir READ texturePacksDir STORED false)
+
+
+ // Files
+ //! Path to the instance's minecraft.jar
+ Q_PROPERTY(QString mcJar READ mcJar STORED false)
+
+ //! Path to the instance's mcbackup.jar
+ Q_PROPERTY(QString mcBackup READ mcBackup STORED false)
+
+ //! Path to the instance's config file.
+ Q_PROPERTY(QString configFile READ configFile STORED false)
+
+ //! Path to the instance's modlist file.
+ Q_PROPERTY(QString modListFile READ modListFile STORED false)
+
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.
+ // As a side-note, doxygen processes comments for accessor functions and
+ // properties separately, so please document properties in the massive block of
+ // Q_PROPERTY declarations above rather than documenting their accessors.
//////// 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;
/*!
@@ -79,178 +172,76 @@ public:
//////// 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;
+ //////// LISTS, LISTS, AND MORE LISTS ////////
+ /*!
+ * \brief Gets a pointer to this instance's version list.
+ * \return A pointer to the available version list for this instance.
+ */
+ virtual InstVersionList *versionList() const = 0;
+
+
+
+ //////// INSTANCE TYPE STUFF ////////
+
+ /*!
+ * \brief Returns a pointer to this instance's type.
+ * \return A pointer to this instance's type interface.
+ */
+ virtual const InstanceTypeInterface *instanceType() const = 0;
+
+
//////// OTHER FUNCTIONS ////////
//// Version System ////
diff --git a/libmultimc/include/instancetypeinterface.h b/libmultimc/include/instancetypeinterface.h
index 30a12d99..ba13f820 100644
--- a/libmultimc/include/instancetypeinterface.h
+++ b/libmultimc/include/instancetypeinterface.h
@@ -20,6 +20,8 @@
#include "instanceloader.h"
+class InstVersionList;
+
//! The InstanceTypeInterface's interface ID.
#define InstanceTypeInterface_IID "net.forkk.MultiMC.InstanceTypeInterface/0.1"
@@ -56,7 +58,13 @@ public:
* \brief Gets a longer, more detailed description of this instance type.
* \return The instance type's description.
*/
- virtual QString description() const = 0;
+ virtual QString description() const = 0;
+
+ /*!
+ * \brief Gets the version list for this instance type.
+ * \return A pointer to this instance type's version list.
+ */
+ virtual InstVersionList *versionList() const = 0;
protected:
/*!
diff --git a/libmultimc/include/instversion.h b/libmultimc/include/instversion.h
index 3c6b7ac9..7de83966 100644
--- a/libmultimc/include/instversion.h
+++ b/libmultimc/include/instversion.h
@@ -26,27 +26,32 @@ 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.
+ /*!
+ * \brief 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.
+ */
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;
+ //! Gets the string used to identify this version in config files.
+ virtual QString descriptor() const = 0;
+
+ /*!
+ * \breif 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.
+ */
- // 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.
+ /*!
+ * \brief 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.
+ //! Returns the version list that this InstVersion is a part of.
virtual InstVersionList *versionList() const;
};
diff --git a/libmultimc/include/instversionlist.h b/libmultimc/include/instversionlist.h
index d64a286f..4345aaaa 100644
--- a/libmultimc/include/instversionlist.h
+++ b/libmultimc/include/instversionlist.h
@@ -21,25 +21,44 @@
#include "libmmc_config.h"
class InstVersion;
+class Task;
-// 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.
+/*!
+ * \brief 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. Before using the version list, you
+ * should check to see if it has been loaded yet and if not, load the list.
+ */
class LIBMULTIMC_EXPORT InstVersionList : public QObject
{
Q_OBJECT
public:
- explicit InstVersionList();
+ explicit InstVersionList(QObject *parent = 0);
+
+ /*!
+ * \brief Gets a task that will reload the version list.
+ * Simply execute the task to load the list.
+ * \return A pointer to a task that reloads the version list.
+ */
+ virtual Task *getLoadTask() = 0;
- // Reloads the version list.
- virtual void loadVersionList() = 0;
+ //! Checks whether or not the list is loaded. If this returns false, the list should be loaded.
+ virtual bool isLoaded() = 0;
- // Gets the version at the given index.
+ //! Gets the version at the given index.
virtual const InstVersion *at(int i) const = 0;
- // Returns the number of versions in the list.
+ //! Returns the number of versions in the list.
virtual int count() const = 0;
+
+ /*!
+ * \brief Finds a version by its descriptor.
+ * \param The descriptor of the version to find.
+ * \return A const pointer to the version with the given descriptor. NULL if
+ * one doesn't exist.
+ */
+ virtual const InstVersion *findVersion(const QString &descriptor);
};
#endif // INSTVERSIONLIST_H
diff --git a/libmultimc/include/task.h b/libmultimc/include/task.h
index b1a3052d..fc5b1d25 100644
--- a/libmultimc/include/task.h
+++ b/libmultimc/include/task.h
@@ -34,6 +34,15 @@ public:
QString getStatus() const;
int getProgress() const;
+ /*!
+ * \brief Calculates and sets the task's progress based on the number of parts completed out of the total number to complete.
+ * This is essentially just shorthand for setProgress((parts / whole) * 100);
+ * \param parts The parts out of the whole completed. This parameter should
+ * be less than whole. If it is greater than whole, progress is set to 100.
+ * \param whole The total number of things that need to be completed.
+ */
+ void calcProgress(int parts, int whole);
+
public slots:
void setStatus(const QString& status);
void setProgress(int progress);
diff --git a/libmultimc/src/instance.cpp b/libmultimc/src/instance.cpp
index 377acd32..1af359d1 100644
--- a/libmultimc/src/instance.cpp
+++ b/libmultimc/src/instance.cpp
@@ -27,7 +27,7 @@ Instance::Instance(const QString &rootDir, QObject *parent) :
QObject(parent)
{
m_rootDir = rootDir;
- m_settings = new INISettingsObject(PathCombine(rootDir, "instance.cfg"), this);
+ m_settings = new INISettingsObject(configFile(), this);
settings().registerSetting(new Setting("name", "Unnamed Instance"));
settings().registerSetting(new Setting("iconKey", "default"));
@@ -82,7 +82,12 @@ QString Instance::minecraftDir() const
if (dotMCDir.exists() && !mcDir.exists())
return dotMCDir.filePath();
else
- return mcDir.filePath();
+ return mcDir.filePath();
+}
+
+QString Instance::instModsDir() const
+{
+ return PathCombine(rootDir(), "instMods");
}
QString Instance::binDir() const
@@ -125,6 +130,21 @@ QString Instance::mcJar() const
return PathCombine(binDir(), "minecraft.jar");
}
+QString Instance::mcBackup() const
+{
+ return PathCombine(binDir(), "mcbackup.jar");
+}
+
+QString Instance::configFile() const
+{
+ return PathCombine(rootDir(), "instance.cfg");
+}
+
+QString Instance::modListFile() const
+{
+ return PathCombine(rootDir(), "modlist");
+}
+
SettingsObject &Instance::settings() const
{
return *m_settings;
diff --git a/libmultimc/src/instversionlist.cpp b/libmultimc/src/instversionlist.cpp
index e171cfa5..301b9969 100644
--- a/libmultimc/src/instversionlist.cpp
+++ b/libmultimc/src/instversionlist.cpp
@@ -13,9 +13,20 @@
* limitations under the License.
*/
-#include "include/instversionlist.h"
+#include "instversionlist.h"
+#include "instversion.h"
-InstVersionList::InstVersionList() :
- QObject(NULL)
+InstVersionList::InstVersionList(QObject *parent) :
+ QObject(parent)
{
}
+
+const InstVersion *InstVersionList::findVersion(const QString &descriptor)
+{
+ for (int i = 0; i < count(); i++)
+ {
+ if (at(i)->descriptor() == descriptor)
+ return at(i);
+ }
+ return NULL;
+}
diff --git a/libmultimc/src/task.cpp b/libmultimc/src/task.cpp
index d581a1dd..3e30827b 100644
--- a/libmultimc/src/task.cpp
+++ b/libmultimc/src/task.cpp
@@ -37,6 +37,11 @@ int Task::getProgress() const
return progress;
}
+void Task::calcProgress(int parts, int whole)
+{
+ setProgress((int)((((float)parts) / ((float)whole))*100)); // Not sure if C++ or LISP...
+}
+
void Task::setProgress(int progress)
{
this->progress = progress;
diff --git a/plugins/stdinstance/CMakeLists.txt b/plugins/stdinstance/CMakeLists.txt
index 7b1ff192..deebf812 100644
--- a/plugins/stdinstance/CMakeLists.txt
+++ b/plugins/stdinstance/CMakeLists.txt
@@ -5,6 +5,7 @@ ADD_DEFINITIONS(-DQT_PLUGIN)
# Find Qt
find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
+find_package(Qt5Xml REQUIRED)
# Include Qt headers.
include_directories(${Qt5Base_INCLUDE_DIRS})
@@ -25,11 +26,15 @@ include_directories(${CMAKE_SOURCE_DIR}libinstance/include)
SET(STDINST_HEADERS
stdinstancetype.h
stdinstance.h
+stdinstversionlist.h
+stdinstversion.h
)
SET(STDINST_SOURCES
stdinstancetype.cpp
stdinstance.cpp
+stdinstversionlist.cpp
+stdinstversion.cpp
)
add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS})
@@ -41,7 +46,7 @@ IF(UNIX)
set_target_properties(stdinstance PROPERTIES LIBRARY_OUTPUT_DIRECTORY "..")
ENDIF()
-qt5_use_modules(stdinstance Core Network)
+qt5_use_modules(stdinstance Core Network Xml)
target_link_libraries(stdinstance
quazip
patchlib
diff --git a/plugins/stdinstance/stdinstance.cpp b/plugins/stdinstance/stdinstance.cpp
index 217514a3..e5d87d23 100644
--- a/plugins/stdinstance/stdinstance.cpp
+++ b/plugins/stdinstance/stdinstance.cpp
@@ -21,11 +21,14 @@
#include <javautils.h>
-StdInstance::StdInstance(const QString &rootDir, QObject *parent) :
+#include "stdinstversionlist.h"
+
+StdInstance::StdInstance(const QString &rootDir, const InstanceTypeInterface *iType, QObject *parent) :
Instance(rootDir, parent)
{
- settings().registerSetting(new Setting("lastVersionUpdate", 0));
+ m_instType = iType;
+ settings().registerSetting(new Setting("lastVersionUpdate", 0));
}
bool StdInstance::shouldUpdateCurrentVersion()
@@ -55,3 +58,13 @@ void StdInstance::updateCurrentVersion(bool keepCurrent)
setCurrentVersion(newVersion);
}
}
+
+const InstanceTypeInterface *StdInstance::instanceType() const
+{
+ return m_instType;
+}
+
+InstVersionList *StdInstance::versionList() const
+{
+ return &vList;
+}
diff --git a/plugins/stdinstance/stdinstance.h b/plugins/stdinstance/stdinstance.h
index d657d9aa..2058453b 100644
--- a/plugins/stdinstance/stdinstance.h
+++ b/plugins/stdinstance/stdinstance.h
@@ -22,15 +22,22 @@ class StdInstance : public Instance
{
Q_OBJECT
public:
- explicit StdInstance(const QString &rootDir, QObject *parent = 0);
+ explicit StdInstance(const QString &rootDir, const InstanceTypeInterface *iType, QObject *parent = 0);
virtual bool shouldUpdateCurrentVersion();
virtual void updateCurrentVersion(bool keepCurrent);
+ virtual const InstanceTypeInterface *instanceType() const;
+
+ virtual InstVersionList *versionList() const;
+
////// TIMESTAMPS //////
virtual qint64 lastVersionUpdate() { return settings().get("lastVersionUpdate").value<qint64>(); }
virtual void setLastVersionUpdate(qint64 val) { settings().set("lastVersionUpdate", val); }
+
+protected:
+ const InstanceTypeInterface *m_instType;
};
#endif // STDINSTANCE_H
diff --git a/plugins/stdinstance/stdinstancetype.cpp b/plugins/stdinstance/stdinstancetype.cpp
index 5a3a6649..8ad7fd40 100644
--- a/plugins/stdinstance/stdinstancetype.cpp
+++ b/plugins/stdinstance/stdinstancetype.cpp
@@ -19,6 +19,7 @@
#include <QFileInfo>
#include "stdinstance.h"
+#include "stdinstversionlist.h"
StdInstanceType::StdInstanceType(QObject *parent) :
QObject(parent)
@@ -26,6 +27,11 @@ StdInstanceType::StdInstanceType(QObject *parent) :
}
+InstVersionList *StdInstanceType::versionList() const
+{
+ return &vList;
+}
+
InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *&inst,
const QString &instDir) const
{
@@ -36,7 +42,7 @@ InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *&inst,
return InstanceLoader::CantCreateDir;
}
- StdInstance *stdInst = new StdInstance(instDir);
+ StdInstance *stdInst = new StdInstance(instDir, this);
// TODO: Verify that the instance is valid.
@@ -48,7 +54,7 @@ InstanceLoader::InstTypeError StdInstanceType::createInstance(Instance *&inst,
InstanceLoader::InstTypeError StdInstanceType::loadInstance(Instance *&inst,
const QString &instDir) const
{
- StdInstance *stdInst = new StdInstance(instDir);
+ StdInstance *stdInst = new StdInstance(instDir, this);
// TODO: Verify that the instance is valid.
diff --git a/plugins/stdinstance/stdinstancetype.h b/plugins/stdinstance/stdinstancetype.h
index b8382a97..4840ab51 100644
--- a/plugins/stdinstance/stdinstancetype.h
+++ b/plugins/stdinstance/stdinstancetype.h
@@ -34,6 +34,9 @@ public:
virtual QString description() const { return "A standard Minecraft instance."; }
+ virtual InstVersionList *versionList() const;
+
+protected:
virtual InstanceLoader::InstTypeError createInstance(Instance *&inst, const QString &instDir) const;
virtual InstanceLoader::InstTypeError loadInstance(Instance *&inst, const QString &instDir) const;
diff --git a/plugins/stdinstance/stdinstversion.cpp b/plugins/stdinstance/stdinstversion.cpp
new file mode 100644
index 00000000..0e582ffc
--- /dev/null
+++ b/plugins/stdinstance/stdinstversion.cpp
@@ -0,0 +1,147 @@
+/* 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 "stdinstversion.h"
+
+StdInstVersion::StdInstVersion(QString descriptor,
+ QString name,
+ qint64 timestamp,
+ QString dlUrl,
+ bool hasLWJGL,
+ QString etag,
+ InstVersionList *parent) :
+ InstVersion(parent), m_descriptor(descriptor), m_name(name), m_timestamp(timestamp),
+ m_dlUrl(dlUrl), m_hasLWJGL(hasLWJGL), m_etag(etag)
+{
+ m_linkedVersion = NULL;
+}
+
+StdInstVersion::StdInstVersion(StdInstVersion *linkedVersion)
+{
+ m_linkedVersion = linkedVersion;
+}
+
+StdInstVersion::StdInstVersion()
+{
+ m_timestamp = 0;
+ m_hasLWJGL = false;
+ m_linkedVersion = NULL;
+}
+
+StdInstVersion *StdInstVersion::mcnVersion(QString rawName, QString niceName)
+{
+ StdInstVersion *version = new StdInstVersion;
+ version->m_descriptor = rawName;
+ version->m_name = niceName;
+ version->setVersionType(MCNostalgia);
+ return version;
+}
+
+QString StdInstVersion::descriptor() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->descriptor();
+ return m_descriptor;
+}
+
+QString StdInstVersion::name() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->name();
+ return m_name;
+}
+
+QString StdInstVersion::type() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->type();
+
+ switch (versionType())
+ {
+ case OldSnapshot:
+ return "Old Snapshot";
+
+ case Stable:
+ return "Stable";
+
+ case CurrentStable:
+ return "Current Stable";
+
+ case Snapshot:
+ return "Snapshot";
+
+ case MCNostalgia:
+ return "MCNostalgia";
+
+ case MetaCustom:
+ // Not really sure what this does, but it was in the code for v4,
+ // so it must be important... Right?
+ return "Custom Meta Version";
+
+ case MetaLatestSnapshot:
+ return "Latest Snapshot";
+
+ case MetaLatestStable:
+ return "Latest Stable";
+
+ default:
+ return QString("Unknown Type %1").arg(versionType());
+ }
+}
+
+qint64 StdInstVersion::timestamp() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->timestamp();
+ return m_timestamp;
+}
+
+QString StdInstVersion::downloadURL() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->downloadURL();
+ return m_dlUrl;
+}
+
+bool StdInstVersion::hasLWJGL() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->hasLWJGL();
+ return m_hasLWJGL;
+}
+
+QString StdInstVersion::etag() const
+{
+ if (m_linkedVersion)
+ return m_linkedVersion->etag();
+ return m_etag;
+}
+
+StdInstVersion::VersionType StdInstVersion::versionType() const
+{
+ return m_type;
+}
+
+void StdInstVersion::setVersionType(StdInstVersion::VersionType type)
+{
+ m_type = type;
+}
+
+bool StdInstVersion::isMeta() const
+{
+ return versionType() == MetaCustom ||
+ versionType() == MetaLatestSnapshot ||
+ versionType() == MetaLatestStable;
+}
diff --git a/plugins/stdinstance/stdinstversion.h b/plugins/stdinstance/stdinstversion.h
new file mode 100644
index 00000000..3f03ae83
--- /dev/null
+++ b/plugins/stdinstance/stdinstversion.h
@@ -0,0 +1,82 @@
+/* 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 STDINSTVERSION_H
+#define STDINSTVERSION_H
+
+#include "instversion.h"
+
+/*!
+ * \brief Implements a standard Minecraft instance version.
+ * This class also supports meta versions (i.e. versions that are essentially
+ * aliases of other versions).
+ */
+class StdInstVersion : public InstVersion
+{
+ Q_OBJECT
+public:
+ explicit StdInstVersion(QString descriptor,
+ QString name,
+ qint64 timestamp,
+ QString dlUrl,
+ bool hasLWJGL,
+ QString etag,
+ InstVersionList *parent);
+
+ explicit StdInstVersion(StdInstVersion *linkedVersion);
+
+ StdInstVersion();
+
+ static StdInstVersion *mcnVersion(QString rawName, QString niceName);
+
+ enum VersionType
+ {
+ OldSnapshot,
+ Stable,
+ CurrentStable,
+ Snapshot,
+ MCNostalgia,
+ MetaCustom,
+ MetaLatestSnapshot,
+ MetaLatestStable
+ };
+
+ virtual QString descriptor() const;
+ virtual QString name() const;
+ virtual QString type() const;
+ virtual qint64 timestamp() const;
+ virtual QString downloadURL() const;
+ virtual bool hasLWJGL() const;
+ virtual QString etag() const;
+
+ virtual VersionType versionType() const;
+ virtual void setVersionType(VersionType type);
+
+ virtual bool isMeta() const;
+
+
+protected:
+ QString m_descriptor;
+ QString m_name;
+ qint64 m_timestamp;
+ QString m_dlUrl;
+ bool m_hasLWJGL;
+ QString m_etag;
+ VersionType m_type;
+
+ StdInstVersion *m_linkedVersion;
+};
+
+#endif // STDINSTVERSION_H
diff --git a/plugins/stdinstance/stdinstversionlist.cpp b/plugins/stdinstance/stdinstversionlist.cpp
new file mode 100644
index 00000000..4ad4c52f
--- /dev/null
+++ b/plugins/stdinstance/stdinstversionlist.cpp
@@ -0,0 +1,509 @@
+/* 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 "stdinstversionlist.h"
+
+#include <QNetworkAccessManager>
+#include <QNetworkRequest>
+#include <QNetworkReply>
+
+#include <QtXml/QDomDocument>
+
+#include <QJsonDocument>
+#include <QJsonObject>
+#include <QJsonArray>
+#include <QJsonParseError>
+
+#include <QDateTime>
+#include <QMap>
+#include <QMapIterator>
+#include <QStringList>
+#include <QUrl>
+
+#include <QRegExp>
+
+#include <QDebug>
+
+#include <instversion.h>
+
+#include "stdinstversion.h"
+
+#define MCDL_URLBASE "http://assets.minecraft.net/"
+#define ASSETS_URLBASE "http://s3.amazonaws.com/MinecraftDownload/"
+#define MCN_URLBASE "http://sonicrules.org/mcnweb.py"
+
+// When this is defined, prints the entire version list to qDebug() after loading.
+#define PRINT_VERSIONS
+
+
+StdInstVersionList vList;
+
+StdInstVersionList::StdInstVersionList(QObject *parent) :
+ InstVersionList(parent)
+{
+ loaded = false;
+}
+
+Task *StdInstVersionList::getLoadTask()
+{
+ return new StdInstVListLoadTask(this);
+}
+
+bool StdInstVersionList::isLoaded()
+{
+ return loaded;
+}
+
+const InstVersion *StdInstVersionList::at(int i) const
+{
+ return m_vlist.at(i);
+}
+
+int StdInstVersionList::count() const
+{
+ return m_vlist.count();
+}
+
+void StdInstVersionList::printToStdOut()
+{
+ qDebug() << "---------------- Version List ----------------";
+
+ for (int i = 0; i < m_vlist.count(); i++)
+ {
+ StdInstVersion *version = qobject_cast<StdInstVersion *>(m_vlist.at(i));
+
+ if (!version)
+ continue;
+
+ qDebug() << "Version " << version->name();
+ qDebug() << "\tDownload: " << version->downloadURL();
+ qDebug() << "\tTimestamp: " << version->timestamp();
+ qDebug() << "\tType: " << version->type();
+ qDebug() << "----------------------------------------------";
+ }
+}
+
+
+StdInstVListLoadTask::StdInstVListLoadTask(StdInstVersionList *vlist) :
+ Task(vlist)
+{
+ m_list = vlist;
+ processedMCDLReply = false;
+ processedAssetsReply = false;
+ processedMCNReply = false;
+
+ currentStable = NULL;
+ foundCurrentInAssets = false;
+}
+
+void StdInstVListLoadTask::executeTask()
+{
+ setSubStatus();
+
+ // Initialize the network access manager.
+ QNetworkAccessManager netMgr;
+
+ mcdlReply = netMgr.get(QNetworkRequest(QUrl(ASSETS_URLBASE)));
+ assetsReply = netMgr.get(QNetworkRequest(QUrl(MCDL_URLBASE)));
+ mcnReply = netMgr.get(QNetworkRequest(QUrl(QString(MCN_URLBASE) + "?pversion=1&list=True")));
+
+ connect(mcdlReply, SIGNAL(finished()),
+ SLOT(processMCDLReply()));
+ connect(mcnReply, SIGNAL(finished()),
+ SLOT(processMCNReply()));
+
+ exec();
+ finalize();
+}
+
+void StdInstVListLoadTask::finalize()
+{
+ // First, we need to do some cleanup. We loaded MCNostalgia versions into
+ // mcnList and all the others into tempList. MCNostalgia provides some versions
+ // that are on assets.minecraft.net and we want to ignore those, so we remove
+ // and delete them from mcnList.
+
+ // To start, we get a list of the descriptors in tmpList.
+ QStringList tlistDescriptors;
+ for (int i = 0; i < tempList.count(); i++)
+ tlistDescriptors.append(tempList.at(i)->descriptor());
+
+ // Now, we go through our MCNostalgia version list and remove anything with
+ // a descriptor that matches one we already have in tempList.
+ // We'll need a list of items we're going to remove.
+ for (int i = 0; i < mcnList.count(); i++)
+ if (tlistDescriptors.contains(mcnList.at(i)->descriptor()))
+ delete mcnList.takeAt(i--); // We need to decrement here because we're removing an item.
+
+ // Now that the duplicates are gone, we need to merge the two lists. This is
+ // simple enough.
+ tempList.append(mcnList);
+
+ // We're done with mcnList now, but the items have been moved over to
+ // tempList, so we don't need to delete them.
+
+ // Now we swap the list we loaded into the actual version list.
+ // This applies our changes to the version list immediately and still gives us
+ // access to the old list so that we can delete the objects in it and free their memory.
+ // By doing this, we cause the version list to update immediately.
+ m_list->m_vlist.swap(tempList);
+
+ // We called swap, so all the data that was in the version list previously is now in
+ // tempList (and vice-versa). Now we just free the memory.
+ while (!tempList.isEmpty())
+ delete tempList.takeFirst();
+
+#ifdef PRINT_VERSIONS
+ m_list->printToStdOut();
+#endif
+}
+
+inline QDomElement getDomElementByTagName(QDomElement parent, QString tagname)
+{
+ QDomNodeList elementList = parent.elementsByTagName(tagname);
+ if (elementList.count())
+ return elementList.at(0).toElement();
+ else
+ return QDomElement();
+}
+
+inline QDateTime timeFromS3Time(QString str)
+{
+ const QString fmt("yyyy-MM-dd'T'HH:mm:ss'.000Z'");
+ return QDateTime::fromString(str, fmt);
+}
+
+void StdInstVListLoadTask::processMCDLReply()
+{
+ switch (mcdlReply->error())
+ {
+ case QNetworkReply::NoError:
+ {
+ // Get the XML string.
+ QString xmlString = mcdlReply->readAll();
+
+ QString xmlErrorMsg;
+
+ QDomDocument doc;
+ if (!doc.setContent(xmlString, false, &xmlErrorMsg))
+ {
+ // TODO: Display error message to the user.
+ qDebug(QString("Failed to process Minecraft download site. XML error: %s").
+ arg(xmlErrorMsg).toUtf8());
+ }
+
+ QDomNodeList contents = doc.elementsByTagName("Contents");
+
+ for (int i = 0; i < contents.length(); i++)
+ {
+ QDomElement element = contents.at(i).toElement();
+
+ if (element.isNull())
+ continue;
+
+ QDomElement keyElement = getDomElementByTagName(element, "Key");
+ QDomElement lastmodElement = getDomElementByTagName(element, "LastModified");
+ QDomElement etagElement = getDomElementByTagName(element, "ETag");
+
+ if (keyElement.isNull() || lastmodElement.isNull() || etagElement.isNull())
+ continue;
+
+ QString key = keyElement.text();
+ QString lastModStr = lastmodElement.text();
+ QString etagStr = etagElement.text();
+ QString dlUrl = "http://s3.amazonaws.com/MinecraftDownload/";
+
+ if (key != "minecraft.jar")
+ continue;
+
+ QDateTime versionTimestamp = timeFromS3Time(lastModStr);
+ if (!versionTimestamp.isValid())
+ {
+ qDebug(QString("Failed to parse timestamp for current stable version %1").
+ arg(lastModStr).toUtf8());
+ versionTimestamp = QDateTime::currentDateTime();
+ }
+
+ currentStable = new StdInstVersion("LatestStable", "Current",
+ versionTimestamp.toMSecsSinceEpoch(),
+ "http://s3.amazonaws.com/MinecraftDownload/",
+ true, etagStr, m_list);
+
+ setSubStatus("Loaded latest version info.");
+ }
+ break;
+ }
+
+ default:
+ // TODO: Network error handling.
+ break;
+ }
+
+ if (!currentStable)
+ qDebug("Failed to get current stable version.");
+
+
+ processedMCDLReply = true;
+ updateStuff();
+
+ // If the assets request isn't finished yet, connect the slot to allow it
+ // to process when the request is done. Otherwise, simply call the
+ // processAssetsReply slot directly.
+ if (!assetsReply->isFinished())
+ connect(assetsReply, SIGNAL(finished()),
+ SLOT(processAssetsReply()));
+ else if (!processedAssetsReply)
+ processAssetsReply();
+}
+
+void StdInstVListLoadTask::processAssetsReply()
+{
+ switch (assetsReply->error())
+ {
+ case QNetworkReply::NoError:
+ {
+ // Get the XML string.
+ QString xmlString = assetsReply->readAll();
+
+ QString xmlErrorMsg;
+
+ QDomDocument doc;
+ if (!doc.setContent(xmlString, false, &xmlErrorMsg))
+ {
+ // TODO: Display error message to the user.
+ qDebug(QString("Failed to process assets.minecraft.net. XML error: %s").
+ arg(xmlErrorMsg).toUtf8());
+ }
+
+ QDomNodeList contents = doc.elementsByTagName("Contents");
+
+ QRegExp mcRegex("/minecraft.jar$");
+ QRegExp snapshotRegex("[0-9][0-9]w[0-9][0-9][a-z]|pre|rc");
+
+ for (int i = 0; i < contents.length(); i++)
+ {
+ QDomElement element = contents.at(i).toElement();
+
+ if (element.isNull())
+ continue;
+
+ QDomElement keyElement = getDomElementByTagName(element, "Key");
+ QDomElement lastmodElement = getDomElementByTagName(element, "LastModified");
+ QDomElement etagElement = getDomElementByTagName(element, "ETag");
+
+ if (keyElement.isNull() || lastmodElement.isNull() || etagElement.isNull())
+ continue;
+
+ QString key = keyElement.text();
+ QString lastModStr = lastmodElement.text();
+ QString etagStr = etagElement.text();
+
+ if (!key.contains(mcRegex))
+ continue;
+
+ QString versionDirName = key.left(key.length() - 14);
+ QString dlUrl = QString("http://assets.minecraft.net/%1/").arg(versionDirName);
+
+ QString versionName = versionDirName.replace("_", ".");
+
+ QDateTime versionTimestamp = timeFromS3Time(lastModStr);
+ if (!versionTimestamp.isValid())
+ {
+ qDebug(QString("Failed to parse timestamp for version %1 %2").
+ arg(versionName, lastModStr).toUtf8());
+ versionTimestamp = QDateTime::currentDateTime();
+ }
+
+ if (currentStable)
+ {
+ if (etagStr == currentStable->etag())
+ {
+ StdInstVersion *version = new StdInstVersion(
+ versionName, versionName,
+ versionTimestamp.toMSecsSinceEpoch(),
+ currentStable->downloadURL(), true, etagStr, m_list);
+ version->setVersionType(StdInstVersion::CurrentStable);
+ tempList.push_back(version);
+ foundCurrentInAssets = true;
+ }
+ else
+ {
+ bool older = versionTimestamp.toMSecsSinceEpoch() < currentStable->timestamp();
+ bool newer = versionTimestamp.toMSecsSinceEpoch() > currentStable->timestamp();
+ bool isSnapshot = versionName.contains(snapshotRegex);
+
+ StdInstVersion *version = new StdInstVersion(
+ versionName, versionName,
+ versionTimestamp.toMSecsSinceEpoch(),
+ dlUrl, false, etagStr, m_list);
+
+ if (newer)
+ {
+ version->setVersionType(StdInstVersion::Snapshot);
+ }
+ else if (older && isSnapshot)
+ {
+ version->setVersionType(StdInstVersion::OldSnapshot);
+ }
+ else if (older)
+ {
+ version->setVersionType(StdInstVersion::Stable);
+ }
+ else
+ {
+ // Shouldn't happen, but just in case...
+ version->setVersionType(StdInstVersion::CurrentStable);
+ }
+
+ tempList.push_back(version);
+ }
+ }
+ else // If there isn't a current stable version.
+ {
+ bool isSnapshot = versionName.contains(snapshotRegex);
+
+ StdInstVersion *version = new StdInstVersion(
+ versionName, versionName,
+ versionTimestamp.toMSecsSinceEpoch(),
+ dlUrl, false, etagStr, m_list);
+ version->setVersionType(isSnapshot? StdInstVersion::Snapshot :
+ StdInstVersion::Stable);
+ tempList.push_back(version);
+ }
+ }
+
+ setSubStatus("Loaded assets.minecraft.net");
+ break;
+ }
+
+ default:
+ // TODO: Network error handling.
+ break;
+ }
+
+ processedAssetsReply = true;
+ updateStuff();
+}
+
+
+QString mcnToAssetsVersion(QString mcnVersion);
+
+void StdInstVListLoadTask::processMCNReply()
+{
+ switch (assetsReply->error())
+ {
+ case QNetworkReply::NoError:
+ {
+ QJsonParseError pError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(mcnReply->readAll(), &pError);
+
+ if (pError.error != QJsonParseError::NoError)
+ {
+ // Handle errors.
+ qDebug() << "Failed to parse MCNostalgia response. JSON parser error: " <<
+ pError.errorString();
+ break;
+ }
+
+
+ // Load data.
+ QRegExp indevRegex("in(f)?dev");
+ QJsonArray vlistArray = jsonDoc.object().value("order").toArray();
+
+ for (int i = 0; i < vlistArray.size(); i++)
+ {
+ QString rawVersion = vlistArray.at(i).toString();
+ if (rawVersion.isEmpty() || rawVersion.contains(indevRegex))
+ continue;
+
+ QString niceVersion = mcnToAssetsVersion(rawVersion);
+ if (niceVersion.isEmpty())
+ continue;
+
+ StdInstVersion *version = StdInstVersion::mcnVersion(rawVersion, niceVersion);
+ mcnList.prepend(version);
+ }
+
+ setSubStatus("Loaded MCNostalgia");
+ break;
+ }
+
+ default:
+ // TODO: Network error handling.
+ break;
+ }
+
+
+ processedMCNReply = true;
+ updateStuff();
+}
+
+void StdInstVListLoadTask::setSubStatus(const QString &msg)
+{
+ if (msg.isEmpty())
+ setStatus("Loading instance version list...");
+ else
+ setStatus("Loading instance version list: " + msg);
+}
+
+void StdInstVListLoadTask::updateStuff()
+{
+ const int totalReqs = 3;
+ int reqsComplete = 0;
+
+ if (processedMCDLReply)
+ reqsComplete++;
+ if (processedAssetsReply)
+ reqsComplete++;
+ if (processedMCNReply)
+ reqsComplete++;
+
+ calcProgress(reqsComplete, totalReqs);
+
+ if (reqsComplete >= totalReqs)
+ {
+ quit();
+ }
+}
+
+class MCNostalgiaVNameMap
+{
+public:
+ QMap <QString, QString> mapping;
+ MCNostalgiaVNameMap()
+ {
+ // An empty string means that it should be ignored
+ mapping["1.4.6_pre"] = "";
+ mapping["1.4.5_pre"] = "";
+ mapping["1.4.3_pre"] = "1.4.3";
+ mapping["1.4.2_pre"] = "";
+ mapping["1.4.1_pre"] = "1.4.1";
+ mapping["1.4_pre"] = "1.4";
+ mapping["1.3.2_pre"] = "";
+ mapping["1.3.1_pre"] = "";
+ mapping["1.3_pre"] = "";
+ mapping["1.2_pre"] = "1.2";
+ }
+} mcnVNMap;
+
+QString mcnToAssetsVersion(QString mcnVersion)
+{
+ QMap<QString, QString>::iterator iter = mcnVNMap.mapping.find(mcnVersion);
+ if (iter != mcnVNMap.mapping.end())
+ {
+ return iter.value();
+ }
+ return mcnVersion;
+}
diff --git a/plugins/stdinstance/stdinstversionlist.h b/plugins/stdinstance/stdinstversionlist.h
new file mode 100644
index 00000000..1fad48c2
--- /dev/null
+++ b/plugins/stdinstance/stdinstversionlist.h
@@ -0,0 +1,99 @@
+/* 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 STDINSTVERSIONLIST_H
+#define STDINSTVERSIONLIST_H
+
+#include <instversionlist.h>
+
+#include <task.h>
+
+class QNetworkReply;
+
+class StdInstVListLoadTask;
+class StdInstVersion;
+
+class StdInstVersionList : public InstVersionList
+{
+ Q_OBJECT
+public:
+ friend class StdInstVListLoadTask;
+
+ explicit StdInstVersionList(QObject *parent = 0);
+
+ virtual Task *getLoadTask();
+
+ virtual bool isLoaded();
+
+ virtual const InstVersion *at(int i) const;
+
+ virtual int count() const;
+
+ //! Prints the list to stdout. This is mainly for debugging.
+ virtual void printToStdOut();
+
+protected:
+ QList<InstVersion *> m_vlist;
+
+ bool loaded;
+};
+
+class StdInstVListLoadTask : public Task
+{
+Q_OBJECT
+public:
+ StdInstVListLoadTask(StdInstVersionList *vlist);
+
+ virtual void executeTask();
+
+ //! Performs some final processing when the task is finished.
+ virtual void finalize();
+
+protected slots:
+ //! Slot connected to the finished signal for mcdlReply.
+ virtual void processMCDLReply();
+
+ //! Slot connected to the finished signal for assetsReply.
+ virtual void processAssetsReply();
+
+ //! Slot connected to the finished signal for mcnReply.
+ virtual void processMCNReply();
+
+protected:
+ void setSubStatus(const QString &msg = "");
+
+ StdInstVersionList *m_list;
+ QList<InstVersion *> tempList; //! < List of loaded versions.
+ QList<InstVersion *> mcnList; //! < List of MCNostalgia versions.
+
+ QNetworkReply *assetsReply; //! < The reply from assets.minecraft.net
+ QNetworkReply *mcdlReply; //! < The reply from s3.amazonaws.com/MinecraftDownload
+ QNetworkReply *mcnReply; //! < The reply from MCNostalgia.
+
+ bool processedAssetsReply;
+ bool processedMCDLReply;
+ bool processedMCNReply;
+
+ //! Checks if the task is finished processing replies and, if so, exits the task's event loop.
+ void updateStuff();
+
+ StdInstVersion *currentStable;
+
+ bool foundCurrentInAssets;
+};
+
+extern StdInstVersionList vList;
+
+#endif // STDINSTVERSIONLIST_H