Split MultiMC up into a few separate libraries.

Fixed plugin system.

Tons of other stuff...
This commit is contained in:
Andrew 2013-02-20 19:10:09 -06:00
parent f71479ec33
commit dd2e836b4c
42 changed files with 404 additions and 300 deletions

View File

@ -4,6 +4,7 @@ project(MultiMC)
set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_INCLUDE_CURRENT_DIR ON)
SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR})
#### Check for machine endianness #### #### Check for machine endianness ####
INCLUDE(TestBigEndian) INCLUDE(TestBigEndian)
@ -32,9 +33,22 @@ add_subdirectory(quazip)
add_subdirectory(patchlib) add_subdirectory(patchlib)
include_directories(patchlib) include_directories(patchlib)
# add the java launcher # Add the java launcher
add_subdirectory(launcher) add_subdirectory(launcher)
# Add the util library.
add_subdirectory(libutil)
include_directories(${LIBMMCUTIL_INCLUDE_DIR})
# Add the settings library.
add_subdirectory(libsettings)
include_directories(${LIBMMCSETTINGS_INCLUDE_DIR})
# Add the instance library.
add_subdirectory(libinstance)
include_directories(${LIBMMCINST_INCLUDE_DIR})
# Add the stdinstance plugin. # Add the stdinstance plugin.
add_subdirectory(plugins/stdinstance) add_subdirectory(plugins/stdinstance)
@ -97,43 +111,6 @@ message(STATUS "Job URL: ${MultiMC_JOB_URL}")
configure_file("${PROJECT_SOURCE_DIR}/config.h.in" configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h") "${PROJECT_BINARY_DIR}/config.h")
SET(MULTIMC_SOURCES
main.cpp
data/appsettings.cpp
data/inifile.cpp
data/version.cpp
data/userinfo.cpp
data/loginresponse.cpp
data/inst/instanceloader.cpp
data/inst/instancetype.cpp
data/inst/instance.cpp
data/inst/instancelist.cpp
data/plugin/pluginmanager.cpp
data/version/instversion.cpp
data/version/instversionlist.cpp
gui/mainwindow.cpp
gui/modeditwindow.cpp
gui/settingsdialog.cpp
gui/newinstancedialog.cpp
gui/logindialog.cpp
gui/taskdialog.cpp
util/pathutils.cpp
util/osutils.cpp
java/javautils.cpp
java/annotations.cpp
tasks/task.cpp
tasks/logintask.cpp
)
SET(MULTIMC_HEADERS SET(MULTIMC_HEADERS
gui/mainwindow.h gui/mainwindow.h
gui/modeditwindow.h gui/modeditwindow.h
@ -142,28 +119,11 @@ gui/newinstancedialog.h
gui/logindialog.h gui/logindialog.h
gui/taskdialog.h gui/taskdialog.h
data/appsettings.h
data/inifile.h
data/version.h data/version.h
data/userinfo.h data/userinfo.h
data/loginresponse.h data/loginresponse.h
data/siglist.h
data/siglist_impl.h
data/inst/instanceloader.h
data/inst/instancetype.h
data/inst/instance.h
data/inst/instancelist.h
data/plugin/pluginmanager.h data/plugin/pluginmanager.h
data/plugin/instancetypeplugin.h
data/version/instversion.h
data/version/instversionlist.h
util/apputils.h
util/pathutils.h
util/osutils.h
multimc_pragma.h multimc_pragma.h
@ -179,6 +139,29 @@ tasks/task.h
tasks/logintask.h tasks/logintask.h
) )
SET(MULTIMC_SOURCES
main.cpp
data/version.cpp
data/userinfo.cpp
data/loginresponse.cpp
data/plugin/pluginmanager.cpp
gui/mainwindow.cpp
gui/modeditwindow.cpp
gui/settingsdialog.cpp
gui/newinstancedialog.cpp
gui/logindialog.cpp
gui/taskdialog.cpp
java/javautils.cpp
java/annotations.cpp
tasks/task.cpp
tasks/logintask.cpp
)
SET(MULTIMC5_UIS SET(MULTIMC5_UIS
gui/mainwindow.ui gui/mainwindow.ui
gui/modeditwindow.ui gui/modeditwindow.ui
@ -214,8 +197,10 @@ QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc)
add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC}) add_executable(MultiMC MACOSX_BUNDLE WIN32 ${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC})
qt5_use_modules(MultiMC Widgets Network) qt5_use_modules(MultiMC Widgets Network)
target_link_libraries(MultiMC quazip patchlib stdinstance ${MultiMC_LINK_ADDITIONAL_LIBS}) target_link_libraries(MultiMC quazip patchlib
add_dependencies(MultiMC MultiMCLauncher) libmmcutil libmmcsettings libmmcinst
${MultiMC_LINK_ADDITIONAL_LIBS})
add_dependencies(MultiMC MultiMCLauncher libmmcutil libmmcsettings libmmcinst)
################ Dirs ################ ################ Dirs ################
@ -225,9 +210,9 @@ SET(QTCONF_DEST_DIR bin)
SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC") SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC")
IF(WIN32) IF(WIN32)
#SET(PLUGIN_DEST_DIR .) SET(PLUGIN_DEST_DIR .)
#SET(QTCONF_DEST_DIR .) SET(QTCONF_DEST_DIR .)
SET(APPS "\${CMAKE_INSTALL_PREFIX}/bin/MultiMC.exe") SET(APPS "\${CMAKE_INSTALL_PREFIX}/MultiMC.exe")
ENDIF() ENDIF()
IF(APPLE) IF(APPLE)
SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS) SET(PLUGIN_DEST_DIR MultiMC.app/Contents/MacOS)
@ -255,7 +240,7 @@ ENDIF(APPLE)
IF(WIN32) IF(WIN32)
INSTALL(TARGETS MultiMC INSTALL(TARGETS MultiMC
BUNDLE DESTINATION . COMPONENT Runtime BUNDLE DESTINATION . COMPONENT Runtime
RUNTIME DESTINATION bin COMPONENT Runtime RUNTIME DESTINATION . COMPONENT Runtime
) )
ENDIF() ENDIF()
IF(UNIX) IF(UNIX)
@ -287,7 +272,11 @@ INSTALL(CODE "
# Dirs to look for dependencies. # Dirs to look for dependencies.
SET(DIRS ${QT_LIBRARY_DIRS}) SET(DIRS "${QT_LIBRARY_DIRS}
${CMAKE_BINARY_DIR}/libutil
${CMAKE_BINARY_DIR}/libsettings
${CMAKE_BINARY_DIR}/libinstance")
message(STATUS "${DIRS}")
INSTALL(CODE " INSTALL(CODE "
file(GLOB_RECURSE QTPLUGINS file(GLOB_RECURSE QTPLUGINS

View File

@ -1,41 +0,0 @@
/* 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 INSTANCETYPEPLUGIN_H
#define INSTANCETYPEPLUGIN_H
#include <QList>
#include "data/inst/instancetype.h"
/*!
* \brief Interface for plugins that want to provide custom instance types.
*/
class InstanceTypePlugin
{
public:
/*!
* \brief Gets a QList containing the instance types that this plugin provides.
* These instance types are then registered with the InstanceLoader.
* The InstanceType objects should \e not be deleted by the plugin. Once they
* are registered, they belong to the InstanceLoader.
* \return A QList containing this plugin's instance types.
*/
virtual QList<InstanceType *> getInstanceTypes() = 0;
};
Q_DECLARE_INTERFACE(InstanceTypePlugin, "net.forkk.MultiMC.InstanceTypePlugin/0.1")
#endif // INSTANCETYPEPLUGIN_H

View File

@ -18,10 +18,17 @@
#include <QDir> #include <QDir>
#include <QDirIterator> #include <QDirIterator>
#include <QFileInfo> #include <QFileInfo>
#include <QVariant>
#include <QJsonObject>
#include <QtPlugin> #include <QtPlugin>
#include "data/plugin/instancetypeplugin.h" #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::manager;
@ -33,8 +40,16 @@ PluginManager::PluginManager() :
bool PluginManager::loadPlugins(QString pluginDir) 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(); m_plugins.clear();
qDebug(QString("Loading plugins from directory: %1").
arg(pluginDir).toUtf8());
QDir dir(pluginDir); QDir dir(pluginDir);
QDirIterator iter(dir); QDirIterator iter(dir);
@ -44,53 +59,47 @@ bool PluginManager::loadPlugins(QString pluginDir)
if (pluginFile.exists() && pluginFile.isFile()) if (pluginFile.exists() && pluginFile.isFile())
{ {
QPluginLoader pluginLoader(pluginFile.absoluteFilePath()); qDebug(QString("Attempting to load plugin: %1").
pluginLoader.load(); arg(pluginFile.canonicalFilePath()).toUtf8());
QObject *plugin = pluginLoader.instance();
if (plugin) QPluginLoader *pluginLoader = new QPluginLoader(pluginFile.absoluteFilePath());
QJsonObject pluginInfo = pluginLoader->metaData();
QJsonObject pluginMetadata = pluginInfo.value("MetaData").toObject();
if (pluginMetadata.value("api").toString("") != MMC_API_VERSION)
{ {
qDebug(QString("Loaded plugin %1."). // If "api" is not specified, it's not a MultiMC plugin.
arg(pluginFile.baseName()).toUtf8()); qDebug(QString("Not loading plugin %1. Not a valid MultiMC plugin. "
m_plugins.push_back(plugin); "API: %2").
} arg(pluginFile.canonicalFilePath(), pluginMetadata.value("api").toString("")).toUtf8());
else continue;
{
qWarning(QString("Error loading plugin %1. Not a valid plugin.").
arg(pluginFile.baseName()).toUtf8());
} }
qDebug(QString("Loaded plugin: %1").
arg(pluginInfo.value("IID").toString()).toUtf8());
m_plugins.push_back(pluginLoader);
} }
} }
return true; return true;
} }
bool PluginManager::initInstanceTypes() QPluginLoader *PluginManager::getPlugin(int index)
{
for (int i = 0; i < m_plugins.count(); i++)
{
InstanceTypePlugin *plugin = qobject_cast<InstanceTypePlugin *>(m_plugins[i]);
if (plugin)
{
QList<InstanceType *> instanceTypes = plugin->getInstanceTypes();
for (int i = 0; i < instanceTypes.count(); i++)
{
InstanceLoader::InstTypeError error =
InstanceLoader::loader.registerInstanceType(instanceTypes[i]);
switch (error)
{
case InstanceLoader::TypeIDExists:
qWarning(QString("Instance type %1 already registered.").
arg(instanceTypes[i]->typeID()).toUtf8());
}
}
}
}
return true;
}
QObject *PluginManager::getPlugin(int index)
{ {
return m_plugins[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);
}
}
}

View File

@ -41,12 +41,6 @@ public:
*/ */
bool loadPlugins(QString pluginDir); bool loadPlugins(QString pluginDir);
/*!
* \brief Initializes the instance type plugins.
* \return True if successful. False on failure.
*/
bool initInstanceTypes();
/*! /*!
* \brief Checks how many plugins are loaded. * \brief Checks how many plugins are loaded.
* \return The number of plugins. * \return The number of plugins.
@ -58,12 +52,19 @@ public:
* \param index The index of the plugin to get. * \param index The index of the plugin to get.
* \return The plugin at the given index. * \return The plugin at the given index.
*/ */
QObject *getPlugin(int 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: private:
PluginManager(); PluginManager();
QList<QObject *> m_plugins; QList<QPluginLoader *> m_plugins;
static PluginManager manager; static PluginManager manager;
}; };

View File

@ -21,20 +21,25 @@
#include <QDesktopServices> #include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include <QFileInfo>
#include "util/osutils.h" #include "osutils.h"
#include "gui/settingsdialog.h" #include "gui/settingsdialog.h"
#include "gui/newinstancedialog.h" #include "gui/newinstancedialog.h"
#include "gui/logindialog.h" #include "gui/logindialog.h"
#include "gui/taskdialog.h" #include "gui/taskdialog.h"
#include "data/inst/instancelist.h" #include "instancelist.h"
#include "data/appsettings.h" #include "appsettings.h"
#include "data/version.h" #include "data/version.h"
#include "tasks/logintask.h" #include "tasks/logintask.h"
// Opens the given file in the default application.
// TODO: Move this somewhere.
void openInDefaultProgram(QString filename);
MainWindow::MainWindow(QWidget *parent) : MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), QMainWindow(parent),
ui(new Ui::MainWindow), ui(new Ui::MainWindow),
@ -156,3 +161,8 @@ void MainWindow::onLoginComplete(LoginResponse response)
QString("Logged in as %1 with session ID %2."). QString("Logged in as %1 with session ID %2.").
arg(response.getUsername(), response.getSessionID())); arg(response.getUsername(), response.getSessionID()));
} }
void openInDefaultProgram(QString filename)
{
QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath());
}

View File

@ -18,7 +18,7 @@
#include <QMainWindow> #include <QMainWindow>
#include "data/inst/instancelist.h" #include "instancelist.h"
#include "data/loginresponse.h" #include "data/loginresponse.h"
namespace Ui namespace Ui

View File

@ -16,7 +16,7 @@
#include "settingsdialog.h" #include "settingsdialog.h"
#include "ui_settingsdialog.h" #include "ui_settingsdialog.h"
#include "data/appsettings.h" #include "appsettings.h"
#include <QFileDialog> #include <QFileDialog>
#include <QMessageBox> #include <QMessageBox>

View File

@ -1,31 +1,47 @@
project(stdinstance) project(libmmcinst)
ADD_DEFINITIONS(-DQT_PLUGIN) set(CMAKE_AUTOMOC ON)
# Find Qt # Find Qt
find_package(Qt5Core REQUIRED) find_package(Qt5Core REQUIRED)
find_package(Qt5Network REQUIRED)
# Include Qt headers. # Include Qt headers.
include_directories(${Qt5Base_INCLUDE_DIRS}) include_directories(${Qt5Base_INCLUDE_DIRS})
include_directories(${Qt5Network_INCLUDE_DIRS}) include_directories(${Qt5Network_INCLUDE_DIRS})
# Include MultiMC's headers. # Include utility library.
include_directories(../../) include_directories(${CMAKE_SOURCE_DIR}/libutil/include)
SET(STDINST_HEADERS # Include utility library.
stdinstplugin.h include_directories(${CMAKE_SOURCE_DIR}/libsettings/include)
stdinstancetype.h
stdinstance.h SET(LIBINST_HEADERS
include/libinstance_config.h
include/instancetypeinterface.h
include/instance.h
include/instancelist.h
include/instanceloader.h
include/instversion.h
include/instversionlist.h
) )
SET(STDINST_SOURCES SET(LIBINST_SOURCES
stdinstplugin.cpp src/instance.cpp
stdinstancetype.cpp src/instancelist.cpp
stdinstance.cpp src/instanceloader.cpp
src/instversion.cpp
src/instversionlist.cpp
) )
add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) # Set the include dir path.
set_target_properties(stdinstance PROPERTIES PREFIX "") SET(LIBMMCINST_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
qt5_use_modules(stdinstance Core Network)
target_link_libraries(stdinstance quazip patchlib) add_definitions(-DLIBMMCINST_LIBRARY)
add_library(libmmcinst SHARED ${LIBINST_SOURCES} ${LIBINST_HEADERS})
qt5_use_modules(libmmcinst Core)
target_link_libraries(libmmcinst libmmcutil libmmcsettings)

View File

@ -19,8 +19,10 @@
#include <QObject> #include <QObject>
#include <QDateTime> #include <QDateTime>
#include "data/appsettings.h" #include "appsettings.h"
#include "data/inifile.h" #include "inifile.h"
#include "libinstance_config.h"
#define DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, cfgEntryName, typeName) \ #define DEFINE_OVERRIDDEN_SETTING_ADVANCED(funcName, cfgEntryName, typeName) \
typeName get ## funcName() const { return getField(cfgEntryName, settings->get ## funcName()).value<typeName>(); } typeName get ## funcName() const { return getField(cfgEntryName, settings->get ## funcName()).value<typeName>(); }
@ -38,7 +40,7 @@ class InstanceList;
* To create a new instance type, create a new class inheriting from this class * To create a new instance type, create a new class inheriting from this class
* and implement the pure virtual functions. * and implement the pure virtual functions.
*/ */
class Instance : public SettingsBase class LIBMMCINST_EXPORT Instance : public SettingsBase
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -62,13 +64,13 @@ public:
* *
* \return The instance's ID. * \return The instance's ID.
*/ */
virtual QString id(); virtual QString id() const;
/*! /*!
* \brief Gets the path to the instance's root directory. * \brief Gets the path to the instance's root directory.
* \return The path to the instance's root directory. * \return The path to the instance's root directory.
*/ */
virtual QString rootDir(); virtual QString rootDir() const;
/*! /*!
* \brief Gets the instance list that this instance is a part of. * \brief Gets the instance list that this instance is a part of.
@ -76,7 +78,7 @@ public:
* (the parent is not an InstanceList). * (the parent is not an InstanceList).
* \return A pointer to the InstanceList containing this instance. * \return A pointer to the InstanceList containing this instance.
*/ */
virtual InstanceList *instList(); virtual InstanceList *instList() const;
//////// FIELDS AND SETTINGS //////// //////// FIELDS AND SETTINGS ////////

View File

@ -20,11 +20,13 @@
#include <QSharedPointer> #include <QSharedPointer>
#include "data/siglist.h" #include "siglist.h"
#include "libinstance_config.h"
class Instance; class Instance;
class InstanceList : public QObject, public SigList<QSharedPointer<Instance>> class LIBMMCINST_EXPORT InstanceList : public QObject, public SigList<QSharedPointer<Instance>>
{ {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -20,21 +20,26 @@
#include <QMap> #include <QMap>
#include <QList> #include <QList>
class InstanceType; #include "libinstance_config.h"
class InstanceTypeInterface;
class Instance; class Instance;
typedef QList<const InstanceType *> InstTypeList; typedef QList<const InstanceTypeInterface *> InstTypeList;
/*! /*!
* \brief The InstanceLoader is a singleton that manages all of the instance types and handles loading and creating instances. * \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. * 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 * Creating instances is done through the InstanceLoader's createInstance() function. This function takes
*/ */
class InstanceLoader : public QObject class LIBMMCINST_EXPORT InstanceLoader : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
static InstanceLoader loader; /*!
* \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. * \brief Error codes returned by functions in the InstanceLoader and InstanceType classes.
@ -62,15 +67,12 @@ public:
/*! /*!
* \brief Registers the given InstanceType with the instance loader. * \brief Registers the given InstanceType with the instance loader.
* This causes the instance loader to take ownership of the given
* instance type (meaning the instance type's parent will be set to
* the instance loader).
* *
* \param type The InstanceType to register. * \param type The InstanceType to register.
* \return An InstTypeError error code. * \return An InstTypeError error code.
* - TypeIDExists if the given type's is already registered to another instance type. * - TypeIDExists if the given type's is already registered to another instance type.
*/ */
InstTypeError registerInstanceType(InstanceType *type); InstTypeError registerInstanceType(InstanceTypeInterface *type);
/*! /*!
* \brief Creates an instance with the given type and stores it in inst. * \brief Creates an instance with the given type and stores it in inst.
@ -82,7 +84,7 @@ public:
* - TypeNotRegistered if the given type is not registered with the InstanceLoader. * - TypeNotRegistered if the given type is not registered with the InstanceLoader.
* - InstExists if the given instance directory is already an instance. * - InstExists if the given instance directory is already an instance.
*/ */
InstTypeError createInstance(Instance *inst, const InstanceType *type, const QString &instDir); InstTypeError createInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir);
/*! /*!
* \brief Loads an instance from the given directory. * \brief Loads an instance from the given directory.
@ -95,7 +97,7 @@ public:
* - NotAnInstance if the given instance directory isn't a valid instance. * - 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. * - WrongInstType if the given instance directory's type isn't the same as the given type.
*/ */
InstTypeError loadInstance(Instance *inst, const InstanceType *type, const QString &instDir); InstTypeError loadInstance(Instance *inst, const InstanceTypeInterface *type, const QString &instDir);
/*! /*!
* \brief Loads an instance from the given directory. * \brief Loads an instance from the given directory.
@ -115,7 +117,7 @@ public:
* \param id The ID of the type to find. * \param id The ID of the type to find.
* \return The type with the given ID. NULL if none were found. * \return The type with the given ID. NULL if none were found.
*/ */
const InstanceType *findType(const QString &id); const InstanceTypeInterface *findType(const QString &id);
/*! /*!
* \brief Gets a list of the registered instance types. * \brief Gets a list of the registered instance types.
@ -127,7 +129,9 @@ public:
private: private:
InstanceLoader(); InstanceLoader();
QMap<QString, InstanceType *> m_typeMap; QMap<QString, InstanceTypeInterface *> m_typeMap;
static InstanceLoader loader;
}; };
#endif // INSTANCELOADER_H #endif // INSTANCELOADER_H

View File

@ -20,20 +20,21 @@
#include "instanceloader.h" #include "instanceloader.h"
//! The InstanceTypeInterface's interface ID.
#define InstanceTypeInterface_IID "net.forkk.MultiMC.InstanceTypeInterface/0.1"
/*! /*!
* \brief The InstanceType class is a base class for all instance types. * \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 * 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 * one of these for each type of instance and they should be registered with the
* InstanceLoader. * InstanceLoader.
* To create an instance, the InstanceLoader calls the type's createInstance() * To create an instance, the InstanceLoader calls the type's createInstance()
* function. Loading is done through the loadInstance() function. * function. Loading is done through the loadInstance() function.
*/ */
class InstanceType : public QObject class InstanceTypeInterface
{ {
Q_OBJECT
public: public:
explicit InstanceType(QObject *parent = 0);
friend class InstanceLoader; friend class InstanceLoader;
/*! /*!
@ -80,4 +81,6 @@ protected:
virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const = 0; virtual InstanceLoader::InstTypeError loadInstance(Instance *inst, const QString &instDir) const = 0;
}; };
Q_DECLARE_INTERFACE(InstanceTypeInterface, InstanceTypeInterface_IID)
#endif // INSTANCETYPE_H #endif // INSTANCETYPE_H

View File

@ -18,9 +18,11 @@
#include <QObject> #include <QObject>
#include "libinstance_config.h"
class InstVersionList; class InstVersionList;
class InstVersion : public QObject class LIBMMCINST_EXPORT InstVersion : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -18,13 +18,15 @@
#include <QObject> #include <QObject>
#include "libinstance_config.h"
class InstVersion; class InstVersion;
// Class that each instance type's version list derives from. Version lists are // 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. // 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 // This list will not be loaded on startup. It will be loaded when the list's
// load function is called. // load function is called.
class InstVersionList : public QObject class LIBMMCINST_EXPORT InstVersionList : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:

View File

@ -13,9 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instancetype.h" //#ifndef LIBINSTANCE_CONFIG_H
//#define LIBINSTANCE_CONFIG_H
InstanceType::InstanceType(QObject *parent) : #include <QtCore/QtGlobal>
QObject(parent)
{ #ifdef LIBMMCINST_LIBRARY
} # define LIBMMCINST_EXPORT Q_DECL_EXPORT
#else
# define LIBMMCINST_EXPORT Q_DECL_IMPORT
#endif
//#endif // LIBINSTANCE_CONFIG_H

View File

@ -13,11 +13,11 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instance.h" #include "include/instance.h"
#include <QFileInfo> #include <QFileInfo>
#include "util/pathutils.h" #include "pathutils.h"
Instance::Instance(const QString &rootDir, QObject *parent) : Instance::Instance(const QString &rootDir, QObject *parent) :
SettingsBase(parent) SettingsBase(parent)
@ -26,17 +26,17 @@ Instance::Instance(const QString &rootDir, QObject *parent) :
config.loadFile(PathCombine(rootDir, "instance.cfg")); config.loadFile(PathCombine(rootDir, "instance.cfg"));
} }
QString Instance::id() QString Instance::id() const
{ {
return QFileInfo(rootDir()).baseName(); return QFileInfo(rootDir()).baseName();
} }
QString Instance::rootDir() QString Instance::rootDir() const
{ {
return m_rootDir; return m_rootDir;
} }
InstanceList *Instance::instList() InstanceList *Instance::instList() const
{ {
if (parent()->inherits("InstanceList")) if (parent()->inherits("InstanceList"))
return (InstanceList *)parent(); return (InstanceList *)parent();

View File

@ -13,18 +13,18 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instancelist.h" #include "include/instancelist.h"
#include "data/siglist_impl.h" #include "siglist_impl.h"
#include <QDir> #include <QDir>
#include <QFile> #include <QFile>
#include <QDirIterator> #include <QDirIterator>
#include "instance.h" #include "include/instance.h"
#include "instanceloader.h" #include "include/instanceloader.h"
#include "util/pathutils.h" #include "pathutils.h"
InstanceList::InstanceList(const QString &instDir, QObject *parent) : InstanceList::InstanceList(const QString &instDir, QObject *parent) :
@ -44,16 +44,11 @@ InstanceList::InstListError InstanceList::loadList()
if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists()) if (QFileInfo(PathCombine(subDir, "instance.cfg")).exists())
{ {
QSharedPointer<Instance> inst; QSharedPointer<Instance> inst;
InstanceLoader::InstTypeError error = InstanceLoader::loader. InstanceLoader::InstTypeError error = InstanceLoader::get().
loadInstance(inst.data(), subDir); loadInstance(inst.data(), subDir);
if (inst.data() && error == InstanceLoader::NoError) if (error != InstanceLoader::NoError &&
{ error != InstanceLoader::NotAnInstance)
qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8());
inst->setParent(this);
append(QSharedPointer<Instance>(inst));
}
else if (error != InstanceLoader::NotAnInstance)
{ {
QString errorMsg = QString("Failed to load instance %1: "). QString errorMsg = QString("Failed to load instance %1: ").
arg(QFileInfo(subDir).baseName()).toUtf8(); arg(QFileInfo(subDir).baseName()).toUtf8();
@ -63,6 +58,11 @@ InstanceList::InstListError InstanceList::loadList()
case InstanceLoader::TypeNotRegistered: case InstanceLoader::TypeNotRegistered:
errorMsg += "Instance type not found."; errorMsg += "Instance type not found.";
break; break;
default:
errorMsg += QString("Unknown instance loader error %1").
arg(error);
break;
} }
qDebug(errorMsg.toUtf8()); qDebug(errorMsg.toUtf8());
} }
@ -71,6 +71,12 @@ InstanceList::InstListError InstanceList::loadList()
qDebug(QString("Error loading instance %1. Instance loader returned null."). qDebug(QString("Error loading instance %1. Instance loader returned null.").
arg(QFileInfo(subDir).baseName()).toUtf8()); arg(QFileInfo(subDir).baseName()).toUtf8());
} }
else
{
qDebug(QString("Loaded instance %1").arg(inst->name()).toUtf8());
inst->setParent(this);
append(QSharedPointer<Instance>(inst));
}
} }
} }

View File

@ -13,15 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instanceloader.h" #include "include/instanceloader.h"
#include <QFileInfo> #include <QFileInfo>
#include "instancetype.h" #include "include/instancetypeinterface.h"
#include "data/inifile.h" #include "inifile.h"
#include "util/pathutils.h" #include "pathutils.h"
InstanceLoader InstanceLoader::loader; InstanceLoader InstanceLoader::loader;
@ -32,22 +32,25 @@ InstanceLoader::InstanceLoader() :
} }
InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceType *type) InstanceLoader::InstTypeError InstanceLoader::registerInstanceType(InstanceTypeInterface *type)
{ {
// Check to see if the type ID exists. // Check to see if the type ID exists.
if (m_typeMap.contains(type->typeID())) if (m_typeMap.contains(type->typeID()))
return TypeIDExists; return TypeIDExists;
// Set the parent to this. // Set the parent to this.
type->setParent(this); // ((QObject *)type)->setParent(this);
// Add it to the map. // Add it to the map.
m_typeMap.insert(type->typeID(), type); m_typeMap.insert(type->typeID(), type);
qDebug(QString("Registered instance type %1.").
arg(type->typeID()).toUtf8());
return NoError; return NoError;
} }
InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst, InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst,
const InstanceType *type, const InstanceTypeInterface *type,
const QString &instDir) const QString &instDir)
{ {
// Check if the type is registered. // Check if the type is registered.
@ -59,7 +62,7 @@ InstanceLoader::InstTypeError InstanceLoader::createInstance(Instance *inst,
} }
InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst, InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst,
const InstanceType *type, const InstanceTypeInterface *type,
const QString &instDir) const QString &instDir)
{ {
// Check if the type is registered. // Check if the type is registered.
@ -79,13 +82,13 @@ InstanceLoader::InstTypeError InstanceLoader::loadInstance(Instance *inst,
INIFile ini; INIFile ini;
ini.loadFile(instConfig.path()); ini.loadFile(instConfig.path());
QString typeName = ini.get("type", "StdInstance").toString(); QString typeName = ini.get("type", "net.forkk.MultiMC.StdInstance").toString();
const InstanceType *type = findType(typeName); const InstanceTypeInterface *type = findType(typeName);
return loadInstance(inst, type, instDir); return loadInstance(inst, type, instDir);
} }
const InstanceType *InstanceLoader::findType(const QString &id) const InstanceTypeInterface *InstanceLoader::findType(const QString &id)
{ {
if (!m_typeMap.contains(id)) if (!m_typeMap.contains(id))
return NULL; return NULL;

View File

@ -13,8 +13,8 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instversion.h" #include "include/instversion.h"
#include "instversionlist.h" #include "include/instversionlist.h"
InstVersion::InstVersion(InstVersionList *parent) : InstVersion::InstVersion(InstVersionList *parent) :
QObject(parent) QObject(parent)

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "instversionlist.h" #include "include/instversionlist.h"
InstVersionList::InstVersionList() : InstVersionList::InstVersionList() :
QObject(NULL) QObject(NULL)

View File

@ -0,0 +1,30 @@
project(libmmcsettings)
# Find Qt
find_package(Qt5Core REQUIRED)
# Include Qt headers.
include_directories(${Qt5Base_INCLUDE_DIRS})
include_directories(${Qt5Network_INCLUDE_DIRS})
# Include utils library headers.
include_directories(${CMAKE_SOURCE_DIR}/libutil/include)
SET(LIBSETTINGS_HEADERS
include/libsettings_config.h
include/appsettings.h
)
SET(LIBSETTINGS_SOURCES
src/appsettings.cpp
)
# Set the include dir path.
SET(LIBMMCSETTINGS_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
add_definitions(-DLIBMMCSETTINGS_LIBRARY)
add_library(libmmcsettings SHARED ${LIBSETTINGS_SOURCES} ${LIBSETTINGS_HEADERS})
qt5_use_modules(libmmcsettings Core)
target_link_libraries(libmmcsettings libmmcutil)

View File

@ -18,11 +18,13 @@
#include <QObject> #include <QObject>
#include <QSettings> #include <QSettings>
#include <QColor> //#include <QColor>
#include <QPoint> #include <QPoint>
#include "util/apputils.h" #include <apputils.h>
#include "util/osutils.h" #include <osutils.h>
#include "libsettings_config.h"
#if WINDOWS #if WINDOWS
#define JPATHKEY "JavaPathWindows" #define JPATHKEY "JavaPathWindows"
@ -40,7 +42,7 @@
DEFINE_SETTING_ADVANCED(name, STR_VAL(name), valType, defVal) DEFINE_SETTING_ADVANCED(name, STR_VAL(name), valType, defVal)
class SettingsBase : public QObject class LIBMMCSETTINGS_EXPORT SettingsBase : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -64,9 +66,10 @@ public:
DEFINE_SETTING(InstanceToolbarPosition, QPoint, QPoint()) DEFINE_SETTING(InstanceToolbarPosition, QPoint, QPoint())
// Console Colors // Console Colors
DEFINE_SETTING(SysMessageColor, QColor, QColor(Qt::blue)) // Currently commented out because QColor is a part of QtGUI
DEFINE_SETTING(StdOutColor, QColor, QColor(Qt::black)) // DEFINE_SETTING(SysMessageColor, QColor, QColor(Qt::blue))
DEFINE_SETTING(StdErrColor, QColor, QColor(Qt::red)) // DEFINE_SETTING(StdOutColor, QColor, QColor(Qt::black))
// DEFINE_SETTING(StdErrColor, QColor, QColor(Qt::red))
// Window Size // Window Size
DEFINE_SETTING(LaunchCompatMode, bool, false) DEFINE_SETTING(LaunchCompatMode, bool, false)
@ -93,7 +96,7 @@ public:
virtual void setValue(const QString& name, QVariant val) = 0; virtual void setValue(const QString& name, QVariant val) = 0;
}; };
class AppSettings : public SettingsBase class LIBMMCSETTINGS_EXPORT AppSettings : public SettingsBase
{ {
Q_OBJECT Q_OBJECT
public: public:
@ -111,6 +114,6 @@ protected:
#undef DEFINE_SETTING_ADVANCED #undef DEFINE_SETTING_ADVANCED
#undef DEFINE_SETTING #undef DEFINE_SETTING
extern AppSettings* settings; LIBMMCSETTINGS_EXPORT extern AppSettings* settings;
#endif // APPSETTINGS_H #endif // APPSETTINGS_H

View File

@ -13,21 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#ifndef STDINSTPLUGIN_H #ifndef LIBINSTANCE_CONFIG_H
#define STDINSTPLUGIN_H #define LIBINSTANCE_CONFIG_H
#include <QObject> #include <QtCore/QtGlobal>
#include <data/plugin/instancetypeplugin.h> #ifdef LIBMMCSETTINGS_LIBRARY
# define LIBMMCSETTINGS_EXPORT Q_DECL_EXPORT
#else
# define LIBMMCSETTINGS_EXPORT Q_DECL_IMPORT
#endif
class StdInstPlugin : public QObject, InstanceTypePlugin #endif // LIBINSTANCE_CONFIG_H
{
Q_OBJECT
Q_INTERFACES(InstanceTypePlugin)
Q_PLUGIN_METADATA(IID "net.forkk.MultiMC.Plugins.StdInstance")
public:
virtual QList<InstanceType *> getInstanceTypes();
};
#endif // STDINSTPLUGIN_H

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "appsettings.h" #include "include/appsettings.h"
AppSettings* settings; AppSettings* settings;

38
libutil/CMakeLists.txt Normal file
View File

@ -0,0 +1,38 @@
project(libmmcutil)
# Find Qt
find_package(Qt5Core REQUIRED)
# Include Qt headers.
include_directories(${Qt5Base_INCLUDE_DIRS})
include_directories(${Qt5Network_INCLUDE_DIRS})
SET(LIBUTIL_HEADERS
include/libutil_config.h
include/apputils.h
include/pathutils.h
include/osutils.h
include/inifile.h
include/siglist.h
include/siglist_impl.h
)
SET(LIBUTIL_SOURCES
src/pathutils.cpp
src/osutils.cpp
src/inifile.cpp
)
# Set the include dir path.
SET(LIBMMCUTIL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
add_definitions(-DLIBMMCUTIL_LIBRARY)
add_library(libmmcutil SHARED ${LIBUTIL_SOURCES} ${LIBUTIL_HEADERS})
qt5_use_modules(libmmcutil Core)
target_link_libraries(libmmcutil)

View File

@ -20,8 +20,10 @@
#include <QString> #include <QString>
#include <QVariant> #include <QVariant>
#include "libutil_config.h"
// Sectionless INI parser (for instance config files) // Sectionless INI parser (for instance config files)
class INIFile : public QMap<QString, QVariant> class LIBMMCUTIL_EXPORT INIFile : public QMap<QString, QVariant>
{ {
public: public:
explicit INIFile(); explicit INIFile();

View File

@ -13,15 +13,15 @@
* limitations under the License. * limitations under the License.
*/ */
#include "stdinstplugin.h" #ifndef LIBUTIL_CONFIG_H
#define LIBUTIL_CONFIG_H
#include <QtPlugin> #include <QtCore/QtGlobal>
#include "stdinstancetype.h" #ifdef LIBMMCUTIL_LIBRARY
# define LIBMMCUTIL_EXPORT Q_DECL_EXPORT
#else
# define LIBMMCUTIL_EXPORT Q_DECL_IMPORT
#endif
QList<InstanceType *> StdInstPlugin::getInstanceTypes() #endif // LIBUTIL_CONFIG_H
{
QList<InstanceType *> types;
types.push_back(new StdInstanceType(this));
return types;
}

View File

@ -26,7 +26,4 @@
#define LINUX 1 #define LINUX 1
#endif #endif
// Opens the given file in the default application.
void openInDefaultProgram(QString filename);
#endif // OSUTILS_H #endif // OSUTILS_H

View File

@ -18,9 +18,11 @@
#include <QString> #include <QString>
QString PathCombine(QString path1, QString path2); #include "libutil_config.h"
QString PathCombine(QString path1, QString path2, QString path3);
QString AbsolutePath(QString path); LIBMMCUTIL_EXPORT QString PathCombine(QString path1, QString path2);
LIBMMCUTIL_EXPORT QString PathCombine(QString path1, QString path2, QString path3);
LIBMMCUTIL_EXPORT QString AbsolutePath(QString path);
#endif // PATHUTILS_H #endif // PATHUTILS_H

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "inifile.h" #include "include/inifile.h"
#include <QFile> #include <QFile>
#include <QTextStream> #include <QTextStream>

View File

@ -13,13 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "osutils.h" #include "include/osutils.h"
#include <QDesktopServices>
#include <QUrl> #include <QUrl>
#include <QFileInfo> #include <QFileInfo>
void openInDefaultProgram(QString filename)
{
QDesktopServices::openUrl("file:///" + QFileInfo(filename).absolutePath());
}

View File

@ -13,7 +13,7 @@
* limitations under the License. * limitations under the License.
*/ */
#include "pathutils.h" #include "include/pathutils.h"
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>

View File

@ -17,12 +17,12 @@
#include "gui/mainwindow.h" #include "gui/mainwindow.h"
#include <QApplication> #include <QApplication>
#include "data/appsettings.h" #include "appsettings.h"
#include "data/loginresponse.h" #include "data/loginresponse.h"
#include "data/plugin/pluginmanager.h" #include "data/plugin/pluginmanager.h"
#include "util/pathutils.h" #include "pathutils.h"
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {

View File

@ -10,22 +10,40 @@ find_package(Qt5Network REQUIRED)
include_directories(${Qt5Base_INCLUDE_DIRS}) include_directories(${Qt5Base_INCLUDE_DIRS})
include_directories(${Qt5Network_INCLUDE_DIRS}) include_directories(${Qt5Network_INCLUDE_DIRS})
# Include MultiMC's headers. # Include the Java library.
include_directories(../../) include_directories(${CMAKE_SOURCE_DIR}/java)
# Include utils library headers.
include_directories(${CMAKE_SOURCE_DIR}/libutil/include)
# Include settings library headers.
include_directories(${CMAKE_SOURCE_DIR}/libsettings/include)
# Include instance library headers.
include_directories(${CMAKE_SOURCE_DIR}libinstance/include)
SET(STDINST_HEADERS SET(STDINST_HEADERS
stdinstplugin.h
stdinstancetype.h stdinstancetype.h
stdinstance.h stdinstance.h
) )
SET(STDINST_SOURCES SET(STDINST_SOURCES
stdinstplugin.cpp
stdinstancetype.cpp stdinstancetype.cpp
stdinstance.cpp stdinstance.cpp
) )
add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS}) add_library(stdinstance SHARED ${STDINST_SOURCES} ${STDINST_HEADERS})
set_target_properties(stdinstance PROPERTIES PREFIX "") set_target_properties(stdinstance PROPERTIES PREFIX "")
set_target_properties(stdinstance PROPERTIES RUNTIME_OUTPUT_DIRECTORY "..")
qt5_use_modules(stdinstance Core Network) qt5_use_modules(stdinstance Core Network)
target_link_libraries(stdinstance quazip patchlib) target_link_libraries(stdinstance
quazip
patchlib
# Link the util, settings, and instance libraries.
libmmcutil
libmmcsettings
libmmcinst
)

View File

@ -17,7 +17,7 @@
#include <QFileInfo> #include <QFileInfo>
#include <java/javautils.h> #include <javautils.h>
StdInstance::StdInstance(const QString &rootDir, QObject *parent) : StdInstance::StdInstance(const QString &rootDir, QObject *parent) :
Instance(rootDir, parent) Instance(rootDir, parent)
@ -47,7 +47,8 @@ void StdInstance::updateCurrentVersion(bool keepCurrent)
setLastVersionUpdate(time); setLastVersionUpdate(time);
if (!keepCurrent) if (!keepCurrent)
{ {
QString newVersion = javautils::GetMinecraftJarVersion(jar.absoluteFilePath()); // TODO: Implement GetMinecraftJarVersion function.
QString newVersion = "Unknown";//javautils::GetMinecraftJarVersion(jar.absoluteFilePath());
setCurrentVersion(newVersion); setCurrentVersion(newVersion);
} }
} }

View File

@ -16,7 +16,7 @@
#ifndef STDINSTANCE_H #ifndef STDINSTANCE_H
#define STDINSTANCE_H #define STDINSTANCE_H
#include <data/inst/instance.h> #include <instance.h>
class StdInstance : public Instance class StdInstance : public Instance
{ {

View File

@ -1 +1,8 @@
{} {
"api": "MultiMC5-API-1",
"name": "Standard Instance Plugin",
"summary": "A plugin that provides standard Minecraft instances.",
"description": "This is a built-in plugin that provides the standard Minecraft instance.",
"version": "0.1"
}

View File

@ -16,7 +16,7 @@
#include "stdinstancetype.h" #include "stdinstancetype.h"
StdInstanceType::StdInstanceType(QObject *parent) : StdInstanceType::StdInstanceType(QObject *parent) :
InstanceType(parent) QObject(parent)
{ {
} }

View File

@ -16,11 +16,15 @@
#ifndef STDINSTANCETYPE_H #ifndef STDINSTANCETYPE_H
#define STDINSTANCETYPE_H #define STDINSTANCETYPE_H
#include <data/inst/instancetype.h> #include <instancetypeinterface.h>
class StdInstanceType : public InstanceType #define StdInstanceType_IID "net.forkk.MultiMC.StdInstanceType/0.1"
class StdInstanceType : public QObject, InstanceTypeInterface
{ {
Q_OBJECT Q_OBJECT
Q_PLUGIN_METADATA(IID StdInstanceType_IID FILE "stdinstance.json")
Q_INTERFACES(InstanceTypeInterface)
public: public:
explicit StdInstanceType(QObject *parent = 0); explicit StdInstanceType(QObject *parent = 0);