Working 1.6 modding (currently only forge)

This commit is contained in:
Petr Mrázek 2013-09-22 04:21:36 +02:00
parent c2c7293083
commit ceca6959d2
35 changed files with 996 additions and 673 deletions

24
.clang-format Normal file
View File

@ -0,0 +1,24 @@
UseTab: true
IndentWidth: 4
TabWidth: 4
ConstructorInitializerIndentWidth: 4
AccessModifierOffset: -4
IndentCaseLabels: false
IndentFunctionDeclarationAfterType: false
NamespaceIndentation: None
BreakBeforeBraces: Allman
AllowShortIfStatementsOnASingleLine: false
ColumnLimit: 96
MaxEmptyLinesToKeep: 1
Standard: Cpp11
Cpp11BracedListStyle: true
SpacesInParentheses: false
SpaceInEmptyParentheses: false
SpacesInCStyleCastParentheses: false
SpaceAfterControlStatementKeyword: true
AlignTrailingComments: true
SpacesBeforeTrailingComments: 1

View File

@ -147,165 +147,143 @@ ADD_DEFINITIONS(-DLIBGROUPVIEW_STATIC)
################################ FILES ################################ ################################ FILES ################################
######## Headers ######## ######## Sources and headers ########
SET(MULTIMC_HEADERS SET(MULTIMC_SOURCES
# Application base
MultiMC.h MultiMC.h
MultiMC.cpp
MultiMCVersion.h MultiMCVersion.h
# GUI
gui/mainwindow.h gui/mainwindow.h
gui/mainwindow.cpp
gui/settingsdialog.h gui/settingsdialog.h
gui/settingsdialog.cpp
gui/newinstancedialog.h gui/newinstancedialog.h
gui/newinstancedialog.cpp
gui/logindialog.h gui/logindialog.h
gui/logindialog.cpp
gui/ProgressDialog.h gui/ProgressDialog.h
gui/ProgressDialog.cpp
gui/aboutdialog.h gui/aboutdialog.h
gui/aboutdialog.cpp
gui/consolewindow.h gui/consolewindow.h
gui/consolewindow.cpp
gui/instancedelegate.h gui/instancedelegate.h
gui/instancedelegate.cpp
gui/versionselectdialog.h gui/versionselectdialog.h
gui/versionselectdialog.cpp
gui/lwjglselectdialog.h gui/lwjglselectdialog.h
gui/lwjglselectdialog.cpp
gui/instancesettings.h gui/instancesettings.h
gui/instancesettings.cpp
gui/IconPickerDialog.h gui/IconPickerDialog.h
gui/IconPickerDialog.cpp
gui/LegacyModEditDialog.h gui/LegacyModEditDialog.h
gui/LegacyModEditDialog.cpp
gui/OneSixModEditDialog.h gui/OneSixModEditDialog.h
gui/OneSixModEditDialog.cpp
gui/ModEditDialogCommon.h gui/ModEditDialogCommon.h
gui/ModEditDialogCommon.cpp
gui/ModListView.h gui/ModListView.h
gui/ModListView.cpp
gui/LabeledToolButton.h gui/LabeledToolButton.h
gui/LabeledToolButton.cpp
gui/EditNotesDialog.h gui/EditNotesDialog.h
gui/EditNotesDialog.cpp
# Base classes and infrastructure # Base classes and infrastructure
logic/BaseVersion.h logic/BaseVersion.h
logic/MinecraftVersion.h logic/MinecraftVersion.h
logic/InstanceFactory.h logic/InstanceFactory.h
logic/InstanceFactory.cpp
logic/BaseUpdate.h logic/BaseUpdate.h
logic/BaseUpdate.cpp
logic/BaseInstance.h logic/BaseInstance.h
logic/BaseInstance.cpp
logic/BaseInstance_p.h logic/BaseInstance_p.h
logic/MinecraftProcess.h logic/MinecraftProcess.h
logic/MinecraftProcess.cpp
logic/Mod.h logic/Mod.h
logic/Mod.cpp
logic/ModList.h logic/ModList.h
logic/ModList.cpp
# Basic instance launcher for starting from terminal # Basic instance launcher for starting from terminal
logic/InstanceLauncher.h logic/InstanceLauncher.h
logic/InstanceLauncher.cpp
# network stuffs # network stuffs
logic/net/Download.h logic/net/Download.h
logic/net/FileDownload.h logic/net/FileDownload.h
logic/net/ByteArrayDownload.h
logic/net/CacheDownload.h
logic/net/DownloadJob.h
logic/net/HttpMetaCache.h
# legacy instances
logic/LegacyInstance.h
logic/LegacyInstance_p.h
logic/LegacyUpdate.h
logic/LegacyForge.h
# 1.6 instances
logic/OneSixAssets.h
logic/OneSixInstance.h
logic/OneSixInstance_p.h
logic/OneSixUpdate.h
logic/OneSixVersion.h
logic/OneSixLibrary.h
logic/OneSixRule.h
logic/VersionFactory.h
logic/OpSys.h
# Nostalgia
logic/NostalgiaInstance.h
# Lists
logic/lists/InstanceList.h
logic/lists/IconList.h
logic/lists/BaseVersionList.h
logic/lists/MinecraftVersionList.h
logic/lists/LwjglVersionList.h
logic/lists/ForgeVersionList.h
# misc model/view
logic/EnabledItemFilter.h
# Tasks
logic/tasks/Task.h
logic/tasks/LoginTask.h
logic/tasks/ProgressProvider.h
)
######## Sources ########
SET(MULTIMC_SOURCES
MultiMC.cpp
gui/mainwindow.cpp
gui/settingsdialog.cpp
gui/newinstancedialog.cpp
gui/logindialog.cpp
gui/aboutdialog.cpp
gui/consolewindow.cpp
gui/instancedelegate.cpp
gui/versionselectdialog.cpp
gui/lwjglselectdialog.cpp
gui/instancesettings.cpp
gui/ProgressDialog.cpp
gui/IconPickerDialog.cpp
gui/LegacyModEditDialog.cpp
gui/OneSixModEditDialog.cpp
gui/ModEditDialogCommon.cpp
gui/ModListView.cpp
gui/LabeledToolButton.cpp
gui/EditNotesDialog.cpp
# Base classes and infrastructure
logic/InstanceFactory.cpp
logic/BaseUpdate.cpp
logic/BaseInstance.cpp
logic/MinecraftProcess.cpp
logic/Mod.cpp
logic/ModList.cpp
# Basic instance launcher for starting from terminal
logic/InstanceLauncher.cpp
# network stuffs - to be moved into a depend lib ~_~
logic/net/FileDownload.cpp logic/net/FileDownload.cpp
logic/net/ByteArrayDownload.h
logic/net/ByteArrayDownload.cpp logic/net/ByteArrayDownload.cpp
logic/net/CacheDownload.h
logic/net/CacheDownload.cpp logic/net/CacheDownload.cpp
logic/net/DownloadJob.h
logic/net/DownloadJob.cpp logic/net/DownloadJob.cpp
logic/net/HttpMetaCache.h
logic/net/HttpMetaCache.cpp logic/net/HttpMetaCache.cpp
# legacy instances # legacy instances
logic/LegacyInstance.h
logic/LegacyInstance.cpp logic/LegacyInstance.cpp
logic/LegacyInstance_p.h
logic/LegacyUpdate.h
logic/LegacyUpdate.cpp logic/LegacyUpdate.cpp
logic/LegacyForge.h
logic/LegacyForge.cpp logic/LegacyForge.cpp
# 1.6 instances # 1.6 instances
logic/OneSixAssets.h
logic/OneSixAssets.cpp logic/OneSixAssets.cpp
logic/OneSixInstance.h
logic/OneSixInstance.cpp logic/OneSixInstance.cpp
logic/OneSixInstance_p.h
logic/OneSixUpdate.h
logic/OneSixUpdate.cpp logic/OneSixUpdate.cpp
logic/OneSixVersion.h
logic/OneSixVersion.cpp logic/OneSixVersion.cpp
logic/OneSixLibrary.h
logic/OneSixLibrary.cpp logic/OneSixLibrary.cpp
logic/OneSixRule.h
logic/OneSixRule.cpp logic/OneSixRule.cpp
logic/VersionFactory.cpp logic/OpSys.h
logic/OpSys.cpp logic/OpSys.cpp
logic/ForgeInstaller.h
logic/ForgeInstaller.cpp
# Nostalgia # Nostalgia
logic/NostalgiaInstance.h
logic/NostalgiaInstance.cpp logic/NostalgiaInstance.cpp
# Lists # Lists
logic/lists/InstanceList.h
logic/lists/InstanceList.cpp logic/lists/InstanceList.cpp
logic/lists/IconList.h
logic/lists/IconList.cpp logic/lists/IconList.cpp
logic/lists/BaseVersionList.h
logic/lists/BaseVersionList.cpp logic/lists/BaseVersionList.cpp
logic/lists/MinecraftVersionList.h
logic/lists/MinecraftVersionList.cpp logic/lists/MinecraftVersionList.cpp
logic/lists/LwjglVersionList.h
logic/lists/LwjglVersionList.cpp logic/lists/LwjglVersionList.cpp
logic/lists/ForgeVersionList.h
logic/lists/ForgeVersionList.cpp logic/lists/ForgeVersionList.cpp
# misc model/view # misc model/view
logic/EnabledItemFilter.h
logic/EnabledItemFilter.cpp logic/EnabledItemFilter.cpp
# Tasks # Tasks
logic/tasks/ProgressProvider.h
logic/tasks/Task.h
logic/tasks/Task.cpp logic/tasks/Task.cpp
logic/tasks/LoginTask.h
logic/tasks/LoginTask.cpp logic/tasks/LoginTask.cpp
) )
@ -328,7 +306,7 @@ gui/OneSixModEditDialog.ui
gui/EditNotesDialog.ui gui/EditNotesDialog.ui
) )
set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${MULTIMC_SOURCES} ${MULTIMC_UIS} ${MULTIMC_HEADERS}) set (FILES_TO_TRANSLATE ${FILES_TO_TRANSLATE} ${MULTIMC_SOURCES} ${MULTIMC_UIS})
######## Windows resource files ######## ######## Windows resource files ########
@ -362,7 +340,7 @@ QT5_ADD_RESOURCES(MULTIMC_QRC multimc.qrc)
# Add executable # Add executable
ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32 ADD_EXECUTABLE(MultiMC MACOSX_BUNDLE WIN32
${MULTIMC_SOURCES} ${MULTIMC_HEADERS} ${MULTIMC_UI} ${MULTIMC_QRC} ${MULTIMC_RCS}) ${MULTIMC_SOURCES} ${MULTIMC_UI} ${MULTIMC_QRC} ${MULTIMC_RCS})
# Link # Link
QT5_USE_MODULES(MultiMC Widgets Network Xml) QT5_USE_MODULES(MultiMC Widgets Network Xml)

View File

@ -123,7 +123,7 @@ MultiMC::MultiMC ( int& argc, char** argv )
initGlobalSettings(); initGlobalSettings();
// and instances // and instances
m_instances = new InstanceList(m_settings->get("InstanceDir").toString(),this); m_instances.reset(new InstanceList(m_settings->get("InstanceDir").toString(),this));
std::cout << "Loading Instances..." << std::endl; std::cout << "Loading Instances..." << std::endl;
m_instances->loadList(); m_instances->loadList();
@ -131,7 +131,7 @@ MultiMC::MultiMC ( int& argc, char** argv )
initHttpMetaCache(); initHttpMetaCache();
// create the global network manager // create the global network manager
m_qnam = new QNetworkAccessManager(this); m_qnam.reset(new QNetworkAccessManager(this));
// Register meta types. // Register meta types.
qRegisterMetaType<LoginResponse>("LoginResponse"); qRegisterMetaType<LoginResponse>("LoginResponse");
@ -152,80 +152,59 @@ MultiMC::~MultiMC()
{ {
if(m_mmc_translator) if(m_mmc_translator)
{ {
removeTranslator(m_mmc_translator); removeTranslator(m_mmc_translator.data());
delete m_mmc_translator;
m_mmc_translator = nullptr;
} }
if(m_qt_translator) if(m_qt_translator)
{ {
removeTranslator(m_qt_translator); removeTranslator(m_qt_translator.data());
delete m_qt_translator;
m_qt_translator = nullptr;
} }
if(m_icons)
{
delete m_icons;
m_icons = nullptr;
}
if(m_lwjgllist)
{
delete m_lwjgllist;
m_lwjgllist = nullptr;
}
if(m_minecraftlist)
{
delete m_minecraftlist;
m_minecraftlist = nullptr;
}
delete m_settings;
delete m_metacache;
} }
void MultiMC::initTranslations() void MultiMC::initTranslations()
{ {
m_qt_translator = new QTranslator(); m_qt_translator.reset(new QTranslator());
if(m_qt_translator->load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath))) if(m_qt_translator->load("qt_" + QLocale::system().name(), QLibraryInfo::location(QLibraryInfo::TranslationsPath)))
{ {
std::cout std::cout
<< "Loading Qt Language File for " << "Loading Qt Language File for "
<< QLocale::system().name().toLocal8Bit().constData() << QLocale::system().name().toLocal8Bit().constData()
<< "..."; << "...";
if(!installTranslator(m_qt_translator)) if(!installTranslator(m_qt_translator.data()))
{ {
std::cout << " failed."; std::cout << " failed.";
m_qt_translator.reset();
} }
std::cout << std::endl; std::cout << std::endl;
} }
else else
{ {
delete m_qt_translator; m_qt_translator.reset();
m_qt_translator = nullptr;
} }
m_mmc_translator = new QTranslator(); m_mmc_translator.reset(new QTranslator());
if(m_mmc_translator->load("mmc_" + QLocale::system().name(), QDir("translations").absolutePath())) if(m_mmc_translator->load("mmc_" + QLocale::system().name(), QDir("translations").absolutePath()))
{ {
std::cout std::cout
<< "Loading MMC Language File for " << "Loading MMC Language File for "
<< QLocale::system().name().toLocal8Bit().constData() << QLocale::system().name().toLocal8Bit().constData()
<< "..."; << "...";
if(!installTranslator(m_mmc_translator)) if(!installTranslator(m_mmc_translator.data()))
{ {
std::cout << " failed."; std::cout << " failed.";
m_mmc_translator.reset();
} }
std::cout << std::endl; std::cout << std::endl;
} }
else else
{ {
delete m_mmc_translator; m_mmc_translator.reset();
m_mmc_translator = nullptr;
} }
} }
void MultiMC::initGlobalSettings() void MultiMC::initGlobalSettings()
{ {
m_settings = new INISettingsObject("multimc.cfg", this); m_settings.reset(new INISettingsObject("multimc.cfg", this));
// Updates // Updates
m_settings->registerSetting(new Setting("UseDevBuilds", false)); m_settings->registerSetting(new Setting("UseDevBuilds", false));
m_settings->registerSetting(new Setting("AutoUpdate", true)); m_settings->registerSetting(new Setting("AutoUpdate", true));
@ -278,7 +257,7 @@ void MultiMC::initGlobalSettings()
void MultiMC::initHttpMetaCache() void MultiMC::initHttpMetaCache()
{ {
m_metacache = new HttpMetaCache("metacache"); m_metacache.reset(new HttpMetaCache("metacache"));
m_metacache->addBase("assets", QDir("assets").absolutePath()); m_metacache->addBase("assets", QDir("assets").absolutePath());
m_metacache->addBase("versions", QDir("versions").absolutePath()); m_metacache->addBase("versions", QDir("versions").absolutePath());
m_metacache->addBase("libraries", QDir("libraries").absolutePath()); m_metacache->addBase("libraries", QDir("libraries").absolutePath());
@ -287,37 +266,38 @@ void MultiMC::initHttpMetaCache()
} }
IconList* MultiMC::icons() QSharedPointer<IconList> MultiMC::icons()
{ {
if ( !m_icons ) if ( !m_icons )
{ {
m_icons = new IconList; m_icons.reset(new IconList);
} }
return m_icons; return m_icons;
} }
LWJGLVersionList* MultiMC::lwjgllist() QSharedPointer<LWJGLVersionList> MultiMC::lwjgllist()
{ {
if ( !m_lwjgllist ) if ( !m_lwjgllist )
{ {
m_lwjgllist = new LWJGLVersionList(); m_lwjgllist.reset(new LWJGLVersionList());
} }
return m_lwjgllist; return m_lwjgllist;
} }
ForgeVersionList* MultiMC::forgelist()
QSharedPointer<ForgeVersionList> MultiMC::forgelist()
{ {
if ( !m_forgelist ) if ( !m_forgelist )
{ {
m_forgelist = new ForgeVersionList(); m_forgelist.reset(new ForgeVersionList());
} }
return m_forgelist; return m_forgelist;
} }
MinecraftVersionList* MultiMC::minecraftlist() QSharedPointer<MinecraftVersionList> MultiMC::minecraftlist()
{ {
if ( !m_minecraftlist ) if ( !m_minecraftlist )
{ {
m_minecraftlist = new MinecraftVersionList(); m_minecraftlist.reset(new MinecraftVersionList());
} }
return m_minecraftlist; return m_minecraftlist;
} }
@ -345,4 +325,6 @@ int main(int argc, char *argv[])
} }
} }
#include "MultiMC.moc" #include "MultiMC.moc"

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <QApplication> #include <QApplication>
#include <QSharedPointer>
#include "MultiMCVersion.h" #include "MultiMCVersion.h"
#include "config.h" #include "config.h"
@ -33,17 +34,17 @@ public:
MultiMC ( int& argc, char** argv ); MultiMC ( int& argc, char** argv );
virtual ~MultiMC(); virtual ~MultiMC();
SettingsObject * settings() QSharedPointer<SettingsObject> settings()
{ {
return m_settings; return m_settings;
}; };
InstanceList * instances() QSharedPointer<InstanceList> instances()
{ {
return m_instances; return m_instances;
}; };
IconList * icons(); QSharedPointer<IconList> icons();
Status status() Status status()
{ {
@ -55,21 +56,21 @@ public:
return m_version; return m_version;
} }
QNetworkAccessManager * qnam() QSharedPointer<QNetworkAccessManager> qnam()
{ {
return m_qnam; return m_qnam;
} }
HttpMetaCache * metacache() QSharedPointer<HttpMetaCache> metacache()
{ {
return m_metacache; return m_metacache;
} }
LWJGLVersionList * lwjgllist(); QSharedPointer<LWJGLVersionList> lwjgllist();
ForgeVersionList * forgelist(); QSharedPointer<ForgeVersionList> forgelist();
MinecraftVersionList * minecraftlist(); QSharedPointer<MinecraftVersionList> minecraftlist();
private: private:
void initGlobalSettings(); void initGlobalSettings();
@ -77,17 +78,17 @@ private:
void initTranslations(); void initTranslations();
private: private:
QTranslator * m_qt_translator = nullptr; QSharedPointer<QTranslator> m_qt_translator;
QTranslator * m_mmc_translator = nullptr; QSharedPointer<QTranslator> m_mmc_translator;
SettingsObject * m_settings = nullptr; QSharedPointer<SettingsObject> m_settings;
InstanceList * m_instances = nullptr; QSharedPointer<InstanceList> m_instances;
IconList * m_icons = nullptr; QSharedPointer<IconList> m_icons;
QNetworkAccessManager * m_qnam = nullptr; QSharedPointer<QNetworkAccessManager> m_qnam;
HttpMetaCache * m_metacache = nullptr; QSharedPointer<HttpMetaCache> m_metacache;
Status m_status = MultiMC::Failed; QSharedPointer<LWJGLVersionList> m_lwjgllist;
LWJGLVersionList * m_lwjgllist = nullptr; QSharedPointer<ForgeVersionList> m_forgelist;
ForgeVersionList * m_forgelist = nullptr; QSharedPointer<MinecraftVersionList> m_minecraftlist;
MinecraftVersionList * m_minecraftlist = nullptr;
Status m_status = MultiMC::Failed;
MultiMCVersion m_version = {VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD}; MultiMCVersion m_version = {VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD};
}; };

View File

@ -39,7 +39,7 @@ IconPickerDialog::IconPickerDialog(QWidget *parent) :
contentsWidget->installEventFilter(this); contentsWidget->installEventFilter(this);
contentsWidget->setModel(MMC->icons()); contentsWidget->setModel(MMC->icons().data());
auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"),QDialogButtonBox::ResetRole); auto buttonAdd = ui->buttonBox->addButton(tr("Add Icon"),QDialogButtonBox::ResetRole);
auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"),QDialogButtonBox::ResetRole); auto buttonRemove = ui->buttonBox->addButton(tr("Remove Icon"),QDialogButtonBox::ResetRole);
@ -119,7 +119,7 @@ void IconPickerDialog::selectionChanged ( QItemSelection selected, QItemSelectio
int IconPickerDialog::exec ( QString selection ) int IconPickerDialog::exec ( QString selection )
{ {
IconList * list = MMC->icons(); auto list = MMC->icons();
auto contentsWidget = ui->iconView; auto contentsWidget = ui->iconView;
selectedIconKey = selection; selectedIconKey = selection;

View File

@ -199,7 +199,7 @@ void LegacyModEditDialog::on_addCoreBtn_clicked()
} }
void LegacyModEditDialog::on_addForgeBtn_clicked() void LegacyModEditDialog::on_addForgeBtn_clicked()
{ {
VersionSelectDialog vselect(MMC->forgelist(), this); VersionSelectDialog vselect(MMC->forgelist().data(), this);
vselect.setFilter(1, m_inst->intendedVersionId()); vselect.setFilter(1, m_inst->intendedVersionId());
if (vselect.exec() && vselect.selectedVersion()) if (vselect.exec() && vselect.selectedVersion())
{ {

View File

@ -1,9 +1,9 @@
/* Copyright 2013 MultiMC Contributors /* Copyright 2013 MultiMC Contributors
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
@ -20,6 +20,7 @@
#include "logic/OneSixVersion.h" #include "logic/OneSixVersion.h"
#include "logic/EnabledItemFilter.h" #include "logic/EnabledItemFilter.h"
#include "logic/lists/ForgeVersionList.h" #include "logic/lists/ForgeVersionList.h"
#include <logic/ForgeInstaller.h>
#include "gui/versionselectdialog.h" #include "gui/versionselectdialog.h"
#include "ProgressDialog.h" #include "ProgressDialog.h"
@ -30,30 +31,33 @@
#include <QEvent> #include <QEvent>
#include <QKeyEvent> #include <QKeyEvent>
OneSixModEditDialog::OneSixModEditDialog(OneSixInstance * inst, QWidget *parent): OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent)
m_inst(inst), : m_inst(inst), QDialog(parent), ui(new Ui::OneSixModEditDialog)
QDialog(parent),
ui(new Ui::OneSixModEditDialog)
{ {
ui->setupUi(this); ui->setupUi(this);
//libraries! // libraries!
m_version = m_inst->getFullVersion();
if (m_version)
{ {
m_version = m_inst->getFullVersion();
main_model = new EnabledItemFilter(this); main_model = new EnabledItemFilter(this);
main_model->setActive(true); main_model->setActive(true);
main_model->setSourceModel(m_version.data()); main_model->setSourceModel(m_version.data());
ui->libraryTreeView->setModel(main_model); ui->libraryTreeView->setModel(main_model);
ui->libraryTreeView->installEventFilter( this ); ui->libraryTreeView->installEventFilter(this);
ui->mainClassEdit->setText(m_version->mainClass); ui->mainClassEdit->setText(m_version->mainClass);
updateButtons(); updateVersionControls();
}
else
{
disableVersionControls();
} }
// Loader mods // Loader mods
{ {
ensureFolderPathExists(m_inst->loaderModsDir()); ensureFolderPathExists(m_inst->loaderModsDir());
m_mods = m_inst->loaderModList(); m_mods = m_inst->loaderModList();
ui->loaderModTreeView->setModel(m_mods.data()); ui->loaderModTreeView->setModel(m_mods.data());
ui->loaderModTreeView->installEventFilter( this ); ui->loaderModTreeView->installEventFilter(this);
m_mods->startWatching(); m_mods->startWatching();
} }
// resource packs // resource packs
@ -61,7 +65,7 @@ OneSixModEditDialog::OneSixModEditDialog(OneSixInstance * inst, QWidget *parent)
ensureFolderPathExists(m_inst->resourcePacksDir()); ensureFolderPathExists(m_inst->resourcePacksDir());
m_resourcepacks = m_inst->resourcePackList(); m_resourcepacks = m_inst->resourcePackList();
ui->resPackTreeView->setModel(m_resourcepacks.data()); ui->resPackTreeView->setModel(m_resourcepacks.data());
ui->resPackTreeView->installEventFilter( this ); ui->resPackTreeView->installEventFilter(this);
m_resourcepacks->startWatching(); m_resourcepacks->startWatching();
} }
} }
@ -73,48 +77,62 @@ OneSixModEditDialog::~OneSixModEditDialog()
delete ui; delete ui;
} }
void OneSixModEditDialog::updateButtons() void OneSixModEditDialog::updateVersionControls()
{ {
bool customVersion = m_inst->versionIsCustom(); bool customVersion = m_inst->versionIsCustom();
ui->customizeBtn->setEnabled(!customVersion); ui->customizeBtn->setEnabled(!customVersion);
ui->revertBtn->setEnabled(customVersion); ui->revertBtn->setEnabled(customVersion);
ui->forgeBtn->setEnabled(true);
} }
void OneSixModEditDialog::disableVersionControls()
{
ui->customizeBtn->setEnabled(false);
ui->revertBtn->setEnabled(false);
ui->forgeBtn->setEnabled(false);
}
void OneSixModEditDialog::on_customizeBtn_clicked() void OneSixModEditDialog::on_customizeBtn_clicked()
{ {
if(m_inst->customizeVersion()) if (m_inst->customizeVersion())
{ {
m_version = m_inst->getFullVersion(); m_version = m_inst->getFullVersion();
main_model->setSourceModel(m_version.data()); main_model->setSourceModel(m_version.data());
updateButtons(); updateVersionControls();
} }
} }
void OneSixModEditDialog::on_revertBtn_clicked() void OneSixModEditDialog::on_revertBtn_clicked()
{ {
auto reply = QMessageBox::question(this, tr("Revert?"), tr("Do you want to revert the version of this instance to its original configuration?"),QMessageBox::Yes|QMessageBox::No); auto reply = QMessageBox::question(
this, tr("Revert?"), tr("Do you want to revert the "
"version of this instance to its original configuration?"),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes)
{ {
if(m_inst->revertCustomVersion()) if (m_inst->revertCustomVersion())
{ {
m_version = m_inst->getFullVersion(); m_version = m_inst->getFullVersion();
main_model->setSourceModel(m_version.data()); main_model->setSourceModel(m_version.data());
updateButtons(); updateVersionControls();
} }
} }
} }
void OneSixModEditDialog::on_forgeBtn_clicked() void OneSixModEditDialog::on_forgeBtn_clicked()
{ {
VersionSelectDialog vselect(MMC->forgelist(), this); VersionSelectDialog vselect(MMC->forgelist().data(), this);
vselect.setFilter(1, m_inst->currentVersionId()); vselect.setFilter(1, m_inst->currentVersionId());
if (vselect.exec() && vselect.selectedVersion()) if (vselect.exec() && vselect.selectedVersion())
{ {
if(m_inst->versionIsCustom()) if (m_inst->versionIsCustom())
{ {
auto reply = QMessageBox::question(this, tr("Revert?"), tr("This will revert any changes you did to the version up to this point. Is that OK?"),QMessageBox::Yes|QMessageBox::No); auto reply = QMessageBox::question(
this, tr("Revert?"),
tr("This will revert any "
"changes you did to the version up to this point. Is that "
"OK?"),
QMessageBox::Yes | QMessageBox::No);
if (reply == QMessageBox::Yes) if (reply == QMessageBox::Yes)
{ {
m_inst->revertCustomVersion(); m_inst->revertCustomVersion();
@ -122,24 +140,38 @@ void OneSixModEditDialog::on_forgeBtn_clicked()
{ {
m_version = m_inst->getFullVersion(); m_version = m_inst->getFullVersion();
main_model->setSourceModel(m_version.data()); main_model->setSourceModel(m_version.data());
updateButtons(); updateVersionControls();
} }
} }
else return; else
return;
} }
ForgeVersionPtr forge = vselect.selectedVersion().dynamicCast<ForgeVersion>(); else
if(!forge)
return;
auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename);
if(entry->stale)
{ {
DownloadJob * fjob = new DownloadJob("Forge download"); m_inst->customizeVersion();
fjob->add(forge->universal_url, entry); m_version = m_inst->getFullVersion();
main_model->setSourceModel(m_version.data());
updateVersionControls();
}
ForgeVersionPtr forgeVersion = vselect.selectedVersion().dynamicCast<ForgeVersion>();
if (!forgeVersion)
return;
auto entry = MMC->metacache()->resolveEntry("minecraftforge", forgeVersion->filename);
if (entry->stale)
{
DownloadJob *fjob = new DownloadJob("Forge download");
fjob->add(forgeVersion->installer_url, entry);
ProgressDialog dlg(this); ProgressDialog dlg(this);
dlg.exec(fjob); dlg.exec(fjob);
if(dlg.result() == QDialog::Accepted) if (dlg.result() == QDialog::Accepted)
{ {
// install // install
QString forgePath = entry->getFullPath();
ForgeInstaller forge(forgePath, forgeVersion->universal_url);
if (!forge.apply(m_version))
{
// failure notice
}
} }
else else
{ {
@ -149,55 +181,60 @@ void OneSixModEditDialog::on_forgeBtn_clicked()
else else
{ {
// install // install
QString forgePath = entry->getFullPath();
ForgeInstaller forge(forgePath, forgeVersion->universal_url);
if (!forge.apply(m_version))
{
// failure notice
}
} }
} }
} }
bool OneSixModEditDialog::loaderListFilter ( QKeyEvent* keyEvent ) bool OneSixModEditDialog::loaderListFilter(QKeyEvent *keyEvent)
{ {
switch(keyEvent->key()) switch (keyEvent->key())
{ {
case Qt::Key_Delete: case Qt::Key_Delete:
on_rmModBtn_clicked(); on_rmModBtn_clicked();
return true; return true;
case Qt::Key_Plus: case Qt::Key_Plus:
on_addModBtn_clicked(); on_addModBtn_clicked();
return true; return true;
default: default:
break; break;
} }
return QDialog::eventFilter( ui->loaderModTreeView, keyEvent ); return QDialog::eventFilter(ui->loaderModTreeView, keyEvent);
} }
bool OneSixModEditDialog::resourcePackListFilter ( QKeyEvent* keyEvent ) bool OneSixModEditDialog::resourcePackListFilter(QKeyEvent *keyEvent)
{ {
switch(keyEvent->key()) switch (keyEvent->key())
{ {
case Qt::Key_Delete: case Qt::Key_Delete:
on_rmResPackBtn_clicked(); on_rmResPackBtn_clicked();
return true; return true;
case Qt::Key_Plus: case Qt::Key_Plus:
on_addResPackBtn_clicked(); on_addResPackBtn_clicked();
return true; return true;
default: default:
break; break;
} }
return QDialog::eventFilter( ui->resPackTreeView, keyEvent ); return QDialog::eventFilter(ui->resPackTreeView, keyEvent);
} }
bool OneSixModEditDialog::eventFilter(QObject *obj, QEvent *ev)
bool OneSixModEditDialog::eventFilter ( QObject* obj, QEvent* ev )
{ {
if (ev->type() != QEvent::KeyPress) if (ev->type() != QEvent::KeyPress)
{ {
return QDialog::eventFilter( obj, ev ); return QDialog::eventFilter(obj, ev);
} }
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(ev); QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev);
if(obj == ui->loaderModTreeView) if (obj == ui->loaderModTreeView)
return loaderListFilter(keyEvent); return loaderListFilter(keyEvent);
if(obj == ui->resPackTreeView) if (obj == ui->resPackTreeView)
return resourcePackListFilter(keyEvent); return resourcePackListFilter(keyEvent);
return QDialog::eventFilter( obj, ev ); return QDialog::eventFilter(obj, ev);
} }
void OneSixModEditDialog::on_buttonBox_rejected() void OneSixModEditDialog::on_buttonBox_rejected()
@ -207,8 +244,9 @@ void OneSixModEditDialog::on_buttonBox_rejected()
void OneSixModEditDialog::on_addModBtn_clicked() void OneSixModEditDialog::on_addModBtn_clicked()
{ {
QStringList fileNames = QFileDialog::getOpenFileNames(this, QApplication::translate("LegacyModEditDialog", "Select Loader Mods")); QStringList fileNames = QFileDialog::getOpenFileNames(
for(auto filename:fileNames) this, QApplication::translate("LegacyModEditDialog", "Select Loader Mods"));
for (auto filename : fileNames)
{ {
m_mods->stopWatching(); m_mods->stopWatching();
m_mods->installMod(QFileInfo(filename)); m_mods->installMod(QFileInfo(filename));
@ -219,8 +257,8 @@ void OneSixModEditDialog::on_rmModBtn_clicked()
{ {
int first, last; int first, last;
auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); auto list = ui->loaderModTreeView->selectionModel()->selectedRows();
if(!lastfirst(list, first, last)) if (!lastfirst(list, first, last))
return; return;
m_mods->stopWatching(); m_mods->stopWatching();
m_mods->deleteMods(first, last); m_mods->deleteMods(first, last);
@ -231,11 +269,11 @@ void OneSixModEditDialog::on_viewModBtn_clicked()
openDirInDefaultProgram(m_inst->loaderModsDir(), true); openDirInDefaultProgram(m_inst->loaderModsDir(), true);
} }
void OneSixModEditDialog::on_addResPackBtn_clicked() void OneSixModEditDialog::on_addResPackBtn_clicked()
{ {
QStringList fileNames = QFileDialog::getOpenFileNames(this, QApplication::translate("LegacyModEditDialog", "Select Resource Packs")); QStringList fileNames = QFileDialog::getOpenFileNames(
for(auto filename:fileNames) this, QApplication::translate("LegacyModEditDialog", "Select Resource Packs"));
for (auto filename : fileNames)
{ {
m_resourcepacks->stopWatching(); m_resourcepacks->stopWatching();
m_resourcepacks->installMod(QFileInfo(filename)); m_resourcepacks->installMod(QFileInfo(filename));
@ -246,8 +284,8 @@ void OneSixModEditDialog::on_rmResPackBtn_clicked()
{ {
int first, last; int first, last;
auto list = ui->resPackTreeView->selectionModel()->selectedRows(); auto list = ui->resPackTreeView->selectionModel()->selectedRows();
if(!lastfirst(list, first, last)) if (!lastfirst(list, first, last))
return; return;
m_resourcepacks->stopWatching(); m_resourcepacks->stopWatching();
m_resourcepacks->deleteMods(first, last); m_resourcepacks->deleteMods(first, last);
@ -257,4 +295,3 @@ void OneSixModEditDialog::on_viewResPackBtn_clicked()
{ {
openDirInDefaultProgram(m_inst->resourcePacksDir(), true); openDirInDefaultProgram(m_inst->resourcePacksDir(), true);
} }

View File

@ -44,7 +44,8 @@ private slots:
void on_forgeBtn_clicked(); void on_forgeBtn_clicked();
void on_customizeBtn_clicked(); void on_customizeBtn_clicked();
void on_revertBtn_clicked(); void on_revertBtn_clicked();
void updateButtons(); void updateVersionControls();
void disableVersionControls();
protected: protected:
bool eventFilter(QObject *obj, QEvent *ev); bool eventFilter(QObject *obj, QEvent *ev);
bool loaderListFilter( QKeyEvent* ev ); bool loaderListFilter( QKeyEvent* ev );

View File

@ -9,4 +9,4 @@ public:
protected: protected:
void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; void paint ( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const; QSize sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const;
}; };

View File

@ -26,10 +26,10 @@ LWJGLSelectDialog::LWJGLSelectDialog(QWidget *parent) :
ui->setupUi(this); ui->setupUi(this);
ui->labelStatus->setVisible(false); ui->labelStatus->setVisible(false);
auto lwjgllist = MMC->lwjgllist(); auto lwjgllist = MMC->lwjgllist();
ui->lwjglListView->setModel(lwjgllist); ui->lwjglListView->setModel(lwjgllist.data());
connect(lwjgllist, SIGNAL(loadingStateUpdated(bool)), SLOT(loadingStateUpdated(bool))); connect(lwjgllist.data(), SIGNAL(loadingStateUpdated(bool)), SLOT(loadingStateUpdated(bool)));
connect(lwjgllist, SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString))); connect(lwjgllist.data(), SIGNAL(loadListFailed(QString)), SLOT(loadingFailed(QString)));
loadingStateUpdated(lwjgllist->isLoading()); loadingStateUpdated(lwjgllist->isLoading());
} }

View File

@ -124,7 +124,7 @@ MainWindow::MainWindow ( QWidget *parent )
//proxymodel->setDynamicSortFilter ( true ); //proxymodel->setDynamicSortFilter ( true );
// FIXME: instList should be global-ish, or at least not tied to the main window... maybe the application itself? // FIXME: instList should be global-ish, or at least not tied to the main window... maybe the application itself?
proxymodel->setSourceModel ( MMC->instances() ); proxymodel->setSourceModel ( MMC->instances().data() );
proxymodel->sort ( 0 ); proxymodel->sort ( 0 );
view->setFrameShape ( QFrame::NoFrame ); view->setFrameShape ( QFrame::NoFrame );
view->setModel ( proxymodel ); view->setModel ( proxymodel );
@ -149,7 +149,7 @@ MainWindow::MainWindow ( QWidget *parent )
); );
// model reset -> selection is invalid. All the instance pointers are wrong. // model reset -> selection is invalid. All the instance pointers are wrong.
// FIXME: stop using POINTERS everywhere // FIXME: stop using POINTERS everywhere
connect(MMC->instances() ,SIGNAL(dataIsInvalid()),SLOT(selectionBad())); connect(MMC->instances().data() ,SIGNAL(dataIsInvalid()),SLOT(selectionBad()));
// run the things that load and download other things... FIXME: this is NOT the place // run the things that load and download other things... FIXME: this is NOT the place
// FIXME: invisible actions in the background = NOPE. // FIXME: invisible actions in the background = NOPE.
@ -601,7 +601,7 @@ void MainWindow::on_actionChangeInstMCVersion_triggered()
if (view->selectionModel()->selectedIndexes().count() < 1) if (view->selectionModel()->selectedIndexes().count() < 1)
return; return;
VersionSelectDialog vselect(m_selectedInstance->versionList(), this); VersionSelectDialog vselect(m_selectedInstance->versionList().data(), this);
if (vselect.exec() && vselect.selectedVersion()) if (vselect.exec() && vselect.selectedVersion())
{ {
m_selectedInstance->setIntendedVersionId(vselect.selectedVersion()->descriptor()); m_selectedInstance->setIntendedVersionId(vselect.selectedVersion()->descriptor());

View File

@ -440,7 +440,7 @@
<string>Meow</string> <string>Meow</string>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; color:#ff0004;&quot;&gt;Catnatok!&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Or just a cat with a ball of yarn?&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;WHO KNOWS?!&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;:/icons/instances/tnt&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string> <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-weight:600; color:#ff0004;&quot;&gt;Catnarok!&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;Or just a cat with a ball of yarn?&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;span style=&quot; font-style:italic;&quot;&gt;WHO KNOWS?!&lt;/span&gt;&lt;/p&gt;&lt;p align=&quot;center&quot;&gt;&lt;img src=&quot;:/icons/instances/tnt&quot;/&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property> </property>
</action> </action>
</widget> </widget>

View File

@ -96,7 +96,7 @@ BaseVersionPtr NewInstanceDialog::selectedVersion() const
void NewInstanceDialog::on_btnChangeVersion_clicked() void NewInstanceDialog::on_btnChangeVersion_clicked()
{ {
VersionSelectDialog vselect(MMC->minecraftlist(), this); VersionSelectDialog vselect(MMC->minecraftlist().data(), this);
vselect.exec(); vselect.exec();
if (vselect.result() == QDialog::Accepted) if (vselect.result() == QDialog::Accepted)
{ {

View File

@ -27,7 +27,7 @@ SettingsDialog::SettingsDialog(QWidget *parent) :
{ {
ui->setupUi(this); ui->setupUi(this);
loadSettings(MMC->settings()); loadSettings(MMC->settings().data());
updateCheckboxStuff(); updateCheckboxStuff();
} }
@ -85,7 +85,7 @@ void SettingsDialog::on_maximizedCheckBox_clicked(bool checked)
void SettingsDialog::on_buttonBox_accepted() void SettingsDialog::on_buttonBox_accepted()
{ {
applySettings(MMC->settings()); applySettings(MMC->settings().data());
} }
void SettingsDialog::applySettings(SettingsObject *s) void SettingsDialog::applySettings(SettingsObject *s)

View File

@ -132,7 +132,7 @@ InstanceList *BaseInstance::instList() const
return NULL; return NULL;
} }
BaseVersionList *BaseInstance::versionList() const QSharedPointer<BaseVersionList> BaseInstance::versionList() const
{ {
return MMC->minecraftlist(); return MMC->minecraftlist();
} }

View File

@ -134,7 +134,7 @@ public:
* \brief Gets a pointer to this instance's version list. * \brief Gets a pointer to this instance's version list.
* \return A pointer to the available version list for this instance. * \return A pointer to the available version list for this instance.
*/ */
virtual BaseVersionList *versionList() const; virtual QSharedPointer<BaseVersionList> versionList() const;
/*! /*!
* \brief Gets this instance's settings object. * \brief Gets this instance's settings object.

125
logic/ForgeInstaller.cpp Normal file
View File

@ -0,0 +1,125 @@
#include "ForgeInstaller.h"
#include "OneSixVersion.h"
#include "OneSixLibrary.h"
#include <quazip.h>
#include <quazipfile.h>
#include <pathutils.h>
#include <QStringList>
ForgeInstaller::ForgeInstaller(QString filename, QString universal_url)
{
QSharedPointer<OneSixVersion> newVersion;
m_universal_url = universal_url;
QuaZip zip(filename);
if (!zip.open(QuaZip::mdUnzip))
return;
QuaZipFile file(&zip);
// read the install profile
if (!zip.setCurrentFile("install_profile.json"))
return;
QJsonParseError jsonError;
if (!file.open(QIODevice::ReadOnly))
return;
QJsonDocument jsonDoc = QJsonDocument::fromJson(file.readAll(), &jsonError);
file.close();
if (jsonError.error != QJsonParseError::NoError)
return;
if (!jsonDoc.isObject())
return;
QJsonObject root = jsonDoc.object();
auto installVal = root.value("install");
auto versionInfoVal = root.value("versionInfo");
if (!installVal.isObject() || !versionInfoVal.isObject())
return;
// read the forge version info
{
newVersion = OneSixVersion::fromJson(versionInfoVal.toObject());
if (!newVersion)
return;
}
QJsonObject installObj = installVal.toObject();
QString libraryName = installObj.value("path").toString();
internalPath = installObj.value("filePath").toString();
// where do we put the library? decode the mojang path
OneSixLibrary lib(libraryName);
lib.finalize();
finalPath = "libraries/" + lib.storagePath();
if (!ensureFilePathExists(finalPath))
return;
if (!zip.setCurrentFile(internalPath))
return;
if (!file.open(QIODevice::ReadOnly))
return;
{
QByteArray data = file.readAll();
// extract file
QSaveFile extraction(finalPath);
if (!extraction.open(QIODevice::WriteOnly))
return;
if (extraction.write(data) != data.size())
return;
if (!extraction.commit())
return;
}
file.close();
m_forge_version = newVersion;
realVersionId = m_forge_version->id = installObj.value("minecraft").toString();
}
bool ForgeInstaller::apply(QSharedPointer<OneSixVersion> to)
{
if (!m_forge_version)
return false;
to->externalUpdateStart();
int sliding_insert_window = 0;
{
// for each library in the version we are adding (except for the blacklisted)
QSet<QString> blacklist{"lwjgl", "lwjgl_util", "lwjgl-platform"};
for (auto lib : m_forge_version->libraries)
{
QString libName = lib->name();
// if this is the actual forge lib, set an absolute url for the download
if(libName.contains("minecraftforge"))
{
lib->setAbsoluteUrl(m_universal_url);
}
if (blacklist.contains(libName))
continue;
// find an entry that matches this one
bool found = false;
for (auto tolib : to->libraries)
{
if (tolib->name() != libName)
continue;
found = true;
// replace lib
tolib = lib;
break;
}
if (!found)
{
// add lib
to->libraries.insert(sliding_insert_window, lib);
sliding_insert_window++;
}
}
to->mainClass = m_forge_version->mainClass;
to->minecraftArguments = m_forge_version->minecraftArguments;
to->processArguments = m_forge_version->processArguments;
}
to->externalUpdateFinish();
return to->toOriginalFile();
}

25
logic/ForgeInstaller.h Normal file
View File

@ -0,0 +1,25 @@
#pragma once
#include <QString>
#include <QSharedPointer>
class OneSixVersion;
class ForgeInstaller
{
public:
ForgeInstaller(QString filename, QString universal_url);
bool apply(QSharedPointer<OneSixVersion> to);
private:
// the version, read from the installer
QSharedPointer<OneSixVersion> m_forge_version;
QString internalPath;
QString finalPath;
QString realVersionId;
QString m_universal_url;
};

View File

@ -60,7 +60,7 @@ void LegacyUpdate::lwjglStart()
m_reply = QSharedPointer<QNetworkReply> (rep, &QObject::deleteLater); m_reply = QSharedPointer<QNetworkReply> (rep, &QObject::deleteLater);
connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); connect(rep, SIGNAL(downloadProgress(qint64,qint64)), SIGNAL(progress(qint64,qint64)));
connect(worker, SIGNAL(finished(QNetworkReply*)), SLOT(lwjglFinished(QNetworkReply*))); connect(worker.data(), SIGNAL(finished(QNetworkReply*)), SLOT(lwjglFinished(QNetworkReply*)));
//connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError))); //connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), SLOT(downloadError(QNetworkReply::NetworkError)));
} }
@ -77,7 +77,7 @@ void LegacyUpdate::lwjglFinished(QNetworkReply* reply)
"\nSometimes you have to wait a bit if you download many LWJGL versions in a row. YMMV"); "\nSometimes you have to wait a bit if you download many LWJGL versions in a row. YMMV");
return; return;
} }
auto *worker = MMC->qnam(); auto worker = MMC->qnam();
//Here i check if there is a cookie for me in the reply and extract it //Here i check if there is a cookie for me in the reply and extract it
QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader)); QList<QNetworkCookie> cookies = qvariant_cast<QList<QNetworkCookie>>(reply->header(QNetworkRequest::SetCookieHeader));
if(cookies.count() != 0) if(cookies.count() != 0)

View File

@ -112,3 +112,6 @@ protected:
QString m_list_id; QString m_list_id;
QList<Mod> mods; QList<Mod> mods;
}; };

View File

@ -2,7 +2,7 @@
#include "OneSixInstance_p.h" #include "OneSixInstance_p.h"
#include "OneSixUpdate.h" #include "OneSixUpdate.h"
#include "MinecraftProcess.h" #include "MinecraftProcess.h"
#include "VersionFactory.h" #include "OneSixVersion.h"
#include <setting.h> #include <setting.h>
#include <pathutils.h> #include <pathutils.h>
@ -10,8 +10,9 @@
#include <JlCompress.h> #include <JlCompress.h>
#include <gui/OneSixModEditDialog.h> #include <gui/OneSixModEditDialog.h>
OneSixInstance::OneSixInstance ( const QString& rootDir, SettingsObject* setting_obj, QObject* parent ) OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *setting_obj,
: BaseInstance ( new OneSixInstancePrivate(), rootDir, setting_obj, parent ) QObject *parent)
: BaseInstance(new OneSixInstancePrivate(), rootDir, setting_obj, parent)
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
d->m_settings->registerSetting(new Setting("IntendedVersion", "")); d->m_settings->registerSetting(new Setting("IntendedVersion", ""));
@ -19,7 +20,7 @@ OneSixInstance::OneSixInstance ( const QString& rootDir, SettingsObject* setting
reloadFullVersion(); reloadFullVersion();
} }
BaseUpdate* OneSixInstance::doUpdate() BaseUpdate *OneSixInstance::doUpdate()
{ {
return new OneSixUpdate(this); return new OneSixUpdate(this);
} }
@ -34,10 +35,10 @@ QString replaceTokensIn(QString text, QMap<QString, QString> with)
int head = 0; int head = 0;
while ((head = token_regexp.indexIn(text, head)) != -1) while ((head = token_regexp.indexIn(text, head)) != -1)
{ {
result.append(text.mid(tail, head-tail)); result.append(text.mid(tail, head - tail));
QString key = token_regexp.cap(1); QString key = token_regexp.cap(1);
auto iter = with.find(key); auto iter = with.find(key);
if(iter != with.end()) if (iter != with.end())
{ {
result.append(*iter); result.append(*iter);
} }
@ -48,26 +49,26 @@ QString replaceTokensIn(QString text, QMap<QString, QString> with)
return result; return result;
} }
QStringList OneSixInstance::processMinecraftArgs( QString user, QString session ) QStringList OneSixInstance::processMinecraftArgs(QString user, QString session)
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
auto version = d->version; auto version = d->version;
QString args_pattern = version->minecraftArguments; QString args_pattern = version->minecraftArguments;
QMap<QString, QString> token_mapping; QMap<QString, QString> token_mapping;
token_mapping["auth_username"] = user; token_mapping["auth_username"] = user;
token_mapping["auth_session"] = session; token_mapping["auth_session"] = session;
//FIXME: user and player name are DIFFERENT! // FIXME: user and player name are DIFFERENT!
token_mapping["auth_player_name"] = user; token_mapping["auth_player_name"] = user;
//FIXME: WTF is this. I just plugged in a random UUID here. // FIXME: WTF is this. I just plugged in a random UUID here.
token_mapping["auth_uuid"] = "7d4bacf0-fd62-11e2-b778-0800200c9a66"; // obviously fake. token_mapping["auth_uuid"] = "7d4bacf0-fd62-11e2-b778-0800200c9a66"; // obviously fake.
// this is for offline: // this is for offline:
/* /*
map["auth_player_name"] = "Player"; map["auth_player_name"] = "Player";
map["auth_player_name"] = "00000000-0000-0000-0000-000000000000"; map["auth_player_name"] = "00000000-0000-0000-0000-000000000000";
*/ */
token_mapping["profile_name"] = name(); token_mapping["profile_name"] = name();
token_mapping["version_name"] = version->id; token_mapping["version_name"] = version->id;
@ -75,8 +76,8 @@ QStringList OneSixInstance::processMinecraftArgs( QString user, QString session
token_mapping["game_directory"] = absRootDir; token_mapping["game_directory"] = absRootDir;
QString absAssetsDir = QDir("assets/").absolutePath(); QString absAssetsDir = QDir("assets/").absolutePath();
token_mapping["game_assets"] = absAssetsDir; token_mapping["game_assets"] = absAssetsDir;
QStringList parts = args_pattern.split(' ',QString::SkipEmptyParts); QStringList parts = args_pattern.split(' ', QString::SkipEmptyParts);
for (int i = 0; i < parts.length(); i++) for (int i = 0; i < parts.length(); i++)
{ {
parts[i] = replaceTokensIn(parts[i], token_mapping); parts[i] = replaceTokensIn(parts[i], token_mapping);
@ -84,27 +85,28 @@ QStringList OneSixInstance::processMinecraftArgs( QString user, QString session
return parts; return parts;
} }
MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString session ) MinecraftProcess *OneSixInstance::prepareForLaunch(QString user, QString session)
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
cleanupAfterRun(); cleanupAfterRun();
auto version = d->version; auto version = d->version;
if(!version) if (!version)
return nullptr; return nullptr;
auto libs_to_extract = version->getActiveNativeLibs(); auto libs_to_extract = version->getActiveNativeLibs();
QString natives_dir_raw = PathCombine(instanceRoot(), "natives/"); QString natives_dir_raw = PathCombine(instanceRoot(), "natives/");
bool success = ensureFolderPathExists(natives_dir_raw); bool success = ensureFolderPathExists(natives_dir_raw);
if(!success) if (!success)
{ {
// FIXME: handle errors // FIXME: handle errors
return nullptr; return nullptr;
} }
for(auto lib: libs_to_extract) for (auto lib : libs_to_extract)
{ {
QString path = "libraries/" + lib->storagePath(); QString path = "libraries/" + lib->storagePath();
qDebug() << "Will extract " << path.toLocal8Bit(); qDebug() << "Will extract " << path.toLocal8Bit();
if(JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes).isEmpty()) if (JlCompress::extractWithExceptions(path, natives_dir_raw, lib->extract_excludes)
.isEmpty())
{ {
return nullptr; return nullptr;
} }
@ -116,11 +118,11 @@ MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString sessi
args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt()); args << QString("-Xmx%1m").arg(settings().get("MaxMemAlloc").toInt());
args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt()); args << QString("-XX:PermSize=%1m").arg(settings().get("PermGen").toInt());
QDir natives_dir(natives_dir_raw); QDir natives_dir(natives_dir_raw);
args << QString("-Djava.library.path=%1").arg( natives_dir.absolutePath() ); args << QString("-Djava.library.path=%1").arg(natives_dir.absolutePath());
QString classPath; QString classPath;
{ {
auto libs = version->getActiveNormalLibs(); auto libs = version->getActiveNormalLibs();
for (auto lib: libs) for (auto lib : libs)
{ {
QFileInfo fi(QString("libraries/") + lib->storagePath()); QFileInfo fi(QString("libraries/") + lib->storagePath());
classPath.append(fi.absoluteFilePath()); classPath.append(fi.absoluteFilePath());
@ -134,16 +136,16 @@ MinecraftProcess* OneSixInstance::prepareForLaunch ( QString user, QString sessi
QFileInfo fi(targetstr); QFileInfo fi(targetstr);
classPath.append(fi.absoluteFilePath()); classPath.append(fi.absoluteFilePath());
} }
if(classPath.size()) if (classPath.size())
{ {
args << "-cp"; args << "-cp";
args << classPath; args << classPath;
} }
args << version->mainClass; args << version->mainClass;
args.append(processMinecraftArgs(user, session)); args.append(processMinecraftArgs(user, session));
// create the process and set its parameters // create the process and set its parameters
MinecraftProcess * proc = new MinecraftProcess(this); MinecraftProcess *proc = new MinecraftProcess(this);
proc->setMinecraftArguments(args); proc->setMinecraftArguments(args);
proc->setMinecraftWorkdir(minecraftRoot()); proc->setMinecraftWorkdir(minecraftRoot());
return proc; return proc;
@ -156,10 +158,10 @@ void OneSixInstance::cleanupAfterRun()
dir.removeRecursively(); dir.removeRecursively();
} }
QSharedPointer< ModList > OneSixInstance::loaderModList() QSharedPointer<ModList> OneSixInstance::loaderModList()
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
if(!d->loader_mod_list) if (!d->loader_mod_list)
{ {
d->loader_mod_list.reset(new ModList(loaderModsDir())); d->loader_mod_list.reset(new ModList(loaderModsDir()));
} }
@ -168,10 +170,10 @@ QSharedPointer< ModList > OneSixInstance::loaderModList()
return d->loader_mod_list; return d->loader_mod_list;
} }
QSharedPointer< ModList > OneSixInstance::resourcePackList() QSharedPointer<ModList> OneSixInstance::resourcePackList()
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
if(!d->resource_pack_list) if (!d->resource_pack_list)
{ {
d->resource_pack_list.reset(new ModList(resourcePacksDir())); d->resource_pack_list.reset(new ModList(resourcePacksDir()));
} }
@ -180,13 +182,12 @@ QSharedPointer< ModList > OneSixInstance::resourcePackList()
return d->resource_pack_list; return d->resource_pack_list;
} }
QDialog *OneSixInstance::createModEditDialog(QWidget *parent)
QDialog * OneSixInstance::createModEditDialog ( QWidget* parent )
{ {
return new OneSixModEditDialog(this, parent); return new OneSixModEditDialog(this, parent);
} }
bool OneSixInstance::setIntendedVersionId ( QString version ) bool OneSixInstance::setIntendedVersionId(QString version)
{ {
settings().set("IntendedVersion", version); settings().set("IntendedVersion", version);
setShouldUpdate(true); setShouldUpdate(true);
@ -198,16 +199,16 @@ QString OneSixInstance::intendedVersionId() const
return settings().get("IntendedVersion").toString(); return settings().get("IntendedVersion").toString();
} }
void OneSixInstance::setShouldUpdate ( bool val ) void OneSixInstance::setShouldUpdate(bool val)
{ {
settings().set ( "ShouldUpdate", val ); settings().set("ShouldUpdate", val);
} }
bool OneSixInstance::shouldUpdate() const bool OneSixInstance::shouldUpdate() const
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
QVariant var = settings().get ( "ShouldUpdate" ); QVariant var = settings().get("ShouldUpdate");
if ( !var.isValid() || var.toBool() == false ) if (!var.isValid() || var.toBool() == false)
{ {
return intendedVersionId() != currentVersionId(); return intendedVersionId() != currentVersionId();
} }
@ -228,56 +229,51 @@ QString OneSixInstance::currentVersionId() const
bool OneSixInstance::customizeVersion() bool OneSixInstance::customizeVersion()
{ {
if(!versionIsCustom()) if (!versionIsCustom())
{ {
auto pathCustom = PathCombine(instanceRoot(), "custom.json"); auto pathCustom = PathCombine(instanceRoot(), "custom.json");
auto pathOrig = PathCombine(instanceRoot(), "version.json"); auto pathOrig = PathCombine(instanceRoot(), "version.json");
QFile::copy(pathOrig, pathCustom); QFile::copy(pathOrig, pathCustom);
return reloadFullVersion(); return reloadFullVersion();
} }
else return true; else
return true;
} }
bool OneSixInstance::revertCustomVersion() bool OneSixInstance::revertCustomVersion()
{ {
if(versionIsCustom()) if (versionIsCustom())
{ {
auto path = PathCombine(instanceRoot(), "custom.json"); auto path = PathCombine(instanceRoot(), "custom.json");
QFile::remove(path); QFile::remove(path);
return reloadFullVersion(); return reloadFullVersion();
} }
else return true; else
return true;
} }
bool OneSixInstance::reloadFullVersion() bool OneSixInstance::reloadFullVersion()
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
QString verpath = PathCombine(instanceRoot(), "version.json"); QString verpath = PathCombine(instanceRoot(), "version.json");
{ {
QString verpath_custom = PathCombine(instanceRoot(), "custom.json"); QString verpath_custom = PathCombine(instanceRoot(), "custom.json");
QFile versionfile(verpath_custom); QFile versionfile(verpath_custom);
if(versionfile.exists()) if (versionfile.exists())
verpath = verpath_custom; verpath = verpath_custom;
} }
QFile versionfile(verpath); auto version = OneSixVersion::fromFile(verpath);
if(versionfile.exists() && versionfile.open(QIODevice::ReadOnly)) if (version)
{ {
FullVersionFactory fvf; d->version = version;
auto version = fvf.parse(versionfile.readAll()); return true;
versionfile.close(); }
if(version)
{
d->version = version;
return true;
}
};
return false; return false;
} }
QSharedPointer< OneSixVersion > OneSixInstance::getFullVersion() QSharedPointer<OneSixVersion> OneSixInstance::getFullVersion()
{ {
I_D(OneSixInstance); I_D(OneSixInstance);
return d->version; return d->version;
@ -293,9 +289,9 @@ QString OneSixInstance::defaultCustomBaseJar() const
return PathCombine(instanceRoot(), "custom.jar"); return PathCombine(instanceRoot(), "custom.jar");
} }
bool OneSixInstance::menuActionEnabled ( QString action_name ) const bool OneSixInstance::menuActionEnabled(QString action_name) const
{ {
if(action_name == "actionChangeInstLWJGLVersion") if (action_name == "actionChangeInstLWJGLVersion")
return false; return false;
return true; return true;
} }
@ -303,7 +299,7 @@ bool OneSixInstance::menuActionEnabled ( QString action_name ) const
QString OneSixInstance::getStatusbarDescription() QString OneSixInstance::getStatusbarDescription()
{ {
QString descr = "One Six : " + intendedVersionId(); QString descr = "One Six : " + intendedVersionId();
if(versionIsCustom()) if (versionIsCustom())
{ {
descr + " (custom)"; descr + " (custom)";
} }

View File

@ -1,18 +1,19 @@
#include "OneSixLibrary.h" #include "OneSixLibrary.h"
#include "OneSixRule.h" #include "OneSixRule.h"
#include "OpSys.h" #include "OpSys.h"
#include <QJsonArray>
void OneSixLibrary::finalize() void OneSixLibrary::finalize()
{ {
QStringList parts = m_name.split ( ':' ); QStringList parts = m_name.split(':');
QString relative = parts[0]; QString relative = parts[0];
relative.replace ( '.','/' ); relative.replace('.', '/');
relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2]; relative += '/' + parts[1] + '/' + parts[2] + '/' + parts[1] + '-' + parts[2];
if ( !m_is_native ) if (!m_is_native)
relative += ".jar"; relative += ".jar";
else else
{ {
if ( m_native_suffixes.contains ( currentSystem ) ) if (m_native_suffixes.contains(currentSystem))
{ {
relative += "-" + m_native_suffixes[currentSystem] + ".jar"; relative += "-" + m_native_suffixes[currentSystem] + ".jar";
} }
@ -22,30 +23,30 @@ void OneSixLibrary::finalize()
relative += ".jar"; relative += ".jar";
} }
} }
m_decentname = parts[1]; m_decentname = parts[1];
m_decentversion = parts[2]; m_decentversion = parts[2];
m_storage_path = relative; m_storage_path = relative;
m_download_path = m_base_url + relative; m_download_url = m_base_url + relative;
if ( m_rules.empty() ) if (m_rules.empty())
{ {
m_is_active = true; m_is_active = true;
} }
else else
{ {
RuleAction result = Disallow; RuleAction result = Disallow;
for ( auto rule: m_rules ) for (auto rule : m_rules)
{ {
RuleAction temp = rule->apply ( this ); RuleAction temp = rule->apply(this);
if ( temp != Defer ) if (temp != Defer)
result = temp; result = temp;
} }
m_is_active = ( result == Allow ); m_is_active = (result == Allow);
} }
if ( m_is_native ) if (m_is_native)
{ {
m_is_active = m_is_active && m_native_suffixes.contains ( currentSystem ); m_is_active = m_is_active && m_native_suffixes.contains(currentSystem);
m_decenttype = "Native"; m_decenttype = "Native";
} }
else else
@ -54,11 +55,11 @@ void OneSixLibrary::finalize()
} }
} }
void OneSixLibrary::setName ( QString name ) void OneSixLibrary::setName(QString name)
{ {
m_name = name; m_name = name;
} }
void OneSixLibrary::setBaseUrl ( QString base_url ) void OneSixLibrary::setBaseUrl(QString base_url)
{ {
m_base_url = base_url; m_base_url = base_url;
} }
@ -66,12 +67,12 @@ void OneSixLibrary::setIsNative()
{ {
m_is_native = true; m_is_native = true;
} }
void OneSixLibrary::addNative ( OpSys os, QString suffix ) void OneSixLibrary::addNative(OpSys os, QString suffix)
{ {
m_is_native = true; m_is_native = true;
m_native_suffixes[os] = suffix; m_native_suffixes[os] = suffix;
} }
void OneSixLibrary::setRules ( QList< QSharedPointer< Rule > > rules ) void OneSixLibrary::setRules(QList<QSharedPointer<Rule>> rules)
{ {
m_rules = rules; m_rules = rules;
} }
@ -83,11 +84,66 @@ bool OneSixLibrary::isNative()
{ {
return m_is_native; return m_is_native;
} }
QString OneSixLibrary::downloadPath() QString OneSixLibrary::downloadUrl()
{ {
return m_download_path; if(m_absolute_url.size())
return m_absolute_url;
return m_download_url;
} }
QString OneSixLibrary::storagePath() QString OneSixLibrary::storagePath()
{ {
return m_storage_path; return m_storage_path;
} }
void OneSixLibrary::setAbsoluteUrl(QString absolute_url)
{
m_absolute_url = absolute_url;
}
QString OneSixLibrary::absoluteUrl()
{
return m_absolute_url;
}
QJsonObject OneSixLibrary::toJson()
{
QJsonObject libRoot;
libRoot.insert("name", m_name);
if(m_absolute_url.size())
libRoot.insert("MMC-absulute_url", m_absolute_url);
if(m_base_url != "https://s3.amazonaws.com/Minecraft.Download/libraries/")
libRoot.insert("url", m_base_url);
if (isNative() && m_native_suffixes.size())
{
QJsonObject nativeList;
auto iter = m_native_suffixes.begin();
while (iter != m_native_suffixes.end())
{
nativeList.insert(OpSys_toString(iter.key()), iter.value());
iter++;
}
libRoot.insert("natives", nativeList);
}
if (isNative() && extract_excludes.size())
{
QJsonArray excludes;
QJsonObject extract;
for (auto exclude : extract_excludes)
{
excludes.append(exclude);
}
extract.insert("exclude", excludes);
libRoot.insert("extract", extract);
}
if (m_rules.size())
{
QJsonArray allRules;
for (auto &rule : m_rules)
{
QJsonObject ruleObj = rule->toJson();
allRules.append(ruleObj);
}
libRoot.insert("rules", allRules);
}
return libRoot;
}

View File

@ -3,6 +3,7 @@
#include <QStringList> #include <QStringList>
#include <QMap> #include <QMap>
#include <QSharedPointer> #include <QSharedPointer>
#include <QJsonObject>
#include "OpSys.h" #include "OpSys.h"
class Rule; class Rule;
@ -12,9 +13,13 @@ class OneSixLibrary
private: private:
// basic values used internally (so far) // basic values used internally (so far)
QString m_name; QString m_name;
QString m_base_url; QString m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/";
QList<QSharedPointer<Rule> > m_rules; QList<QSharedPointer<Rule> > m_rules;
// custom values
/// absolute URL. takes precedence over m_download_path, if defined
QString m_absolute_url;
// derived values used for real things // derived values used for real things
/// a decent name fit for display /// a decent name fit for display
QString m_decentname; QString m_decentname;
@ -25,11 +30,11 @@ private:
/// where to store the lib locally /// where to store the lib locally
QString m_storage_path; QString m_storage_path;
/// where to download the lib from /// where to download the lib from
QString m_download_path; QString m_download_url;
/// is this lib actually active on the current OS? /// is this lib actually active on the current OS?
bool m_is_active; bool m_is_active = false;
/// is the library a native? /// is the library a native?
bool m_is_native; bool m_is_native = false;
/// native suffixes per OS /// native suffixes per OS
QMap<OpSys, QString> m_native_suffixes; QMap<OpSys, QString> m_native_suffixes;
public: public:
@ -39,12 +44,11 @@ public:
/// Constructor /// Constructor
OneSixLibrary(QString name) OneSixLibrary(QString name)
{ {
m_is_native = false;
m_is_active = false;
m_name = name; m_name = name;
m_base_url = "https://s3.amazonaws.com/Minecraft.Download/libraries/";
} }
QJsonObject toJson();
/** /**
* finalize the library, processing the input values into derived values and state * finalize the library, processing the input values into derived values and state
* *
@ -84,7 +88,11 @@ public:
/// Returns true if the library is native /// Returns true if the library is native
bool isNative(); bool isNative();
/// Get the URL to download the library from /// Get the URL to download the library from
QString downloadPath(); QString downloadUrl();
/// Get the relative path where the library should be saved /// Get the relative path where the library should be saved
QString storagePath(); QString storagePath();
/// set an absolute URL for the library. This is an MMC extension.
void setAbsoluteUrl(QString absolute_url);
QString absoluteUrl();
}; };

View File

@ -1,10 +1,72 @@
#include "OneSixRule.h" #include "OneSixRule.h"
#include <QJsonObject>
#include <QJsonArray>
QList<QSharedPointer<Rule>> rulesFromJsonV4(QJsonObject &objectWithRules)
{
QList<QSharedPointer<Rule>> rules;
auto rulesVal = objectWithRules.value("rules");
if (!rulesVal.isArray())
return rules;
QJsonArray ruleList = rulesVal.toArray();
for (auto ruleVal : ruleList)
{
QSharedPointer<Rule> rule;
if (!ruleVal.isObject())
continue;
auto ruleObj = ruleVal.toObject();
auto actionVal = ruleObj.value("action");
if (!actionVal.isString())
continue;
auto action = RuleAction_fromString(actionVal.toString());
if (action == Defer)
continue;
auto osVal = ruleObj.value("os");
if (!osVal.isObject())
{
// add a new implicit action rule
rules.append(ImplicitRule::create(action));
continue;
}
auto osObj = osVal.toObject();
auto osNameVal = osObj.value("name");
if (!osNameVal.isString())
continue;
OpSys requiredOs = OpSys_fromString(osNameVal.toString());
QString versionRegex = osObj.value("version").toString();
// add a new OS rule
rules.append(OsRule::create(action, requiredOs, versionRegex));
}
}
QJsonObject ImplicitRule::toJson()
{
QJsonObject ruleObj;
ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
return ruleObj;
}
QJsonObject OsRule::toJson()
{
QJsonObject ruleObj;
ruleObj.insert("action", m_result == Allow ? QString("allow") : QString("disallow"));
QJsonObject osObj;
{
osObj.insert("name", OpSys_toString(m_system));
osObj.insert("version", m_version_regexp);
}
ruleObj.insert("os", osObj);
return ruleObj;
}
RuleAction RuleAction_fromString(QString name) RuleAction RuleAction_fromString(QString name)
{ {
if(name == "allow") if (name == "allow")
return Allow; return Allow;
if(name == "disallow") if (name == "disallow")
return Disallow; return Disallow;
return Defer; return Defer;
} }

View File

@ -1,8 +1,6 @@
#pragma once #pragma once
#include <QString> #include <QString>
#include <QSharedPointer> #include <QSharedPointer>
class OneSixLibrary;
#include "OneSixLibrary.h" #include "OneSixLibrary.h"
enum RuleAction enum RuleAction
@ -13,6 +11,7 @@ enum RuleAction
}; };
RuleAction RuleAction_fromString(QString); RuleAction RuleAction_fromString(QString);
QList<QSharedPointer<Rule>> rulesFromJsonV4(QJsonObject &objectWithRules);
class Rule class Rule
{ {
@ -23,6 +22,7 @@ public:
Rule(RuleAction result) Rule(RuleAction result)
:m_result(result) {} :m_result(result) {}
virtual ~Rule(){}; virtual ~Rule(){};
virtual QJsonObject toJson() = 0;
RuleAction apply(OneSixLibrary * parent) RuleAction apply(OneSixLibrary * parent)
{ {
if(applies(parent)) if(applies(parent))
@ -47,6 +47,7 @@ protected:
OsRule(RuleAction result, OpSys system, QString version_regexp) OsRule(RuleAction result, OpSys system, QString version_regexp)
: Rule(result), m_system(system), m_version_regexp(version_regexp) {} : Rule(result), m_system(system), m_version_regexp(version_regexp) {}
public: public:
virtual QJsonObject toJson();
static QSharedPointer<OsRule> create(RuleAction result, OpSys system, QString version_regexp) static QSharedPointer<OsRule> create(RuleAction result, OpSys system, QString version_regexp)
{ {
return QSharedPointer<OsRule> (new OsRule(result, system, version_regexp)); return QSharedPointer<OsRule> (new OsRule(result, system, version_regexp));
@ -63,6 +64,7 @@ protected:
ImplicitRule(RuleAction result) ImplicitRule(RuleAction result)
: Rule(result) {} : Rule(result) {}
public: public:
virtual QJsonObject toJson();
static QSharedPointer<ImplicitRule> create(RuleAction result) static QSharedPointer<ImplicitRule> create(RuleAction result)
{ {
return QSharedPointer<ImplicitRule> (new ImplicitRule(result)); return QSharedPointer<ImplicitRule> (new ImplicitRule(result));

View File

@ -3,7 +3,7 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
@ -26,20 +26,20 @@
#include "BaseInstance.h" #include "BaseInstance.h"
#include "lists/MinecraftVersionList.h" #include "lists/MinecraftVersionList.h"
#include "VersionFactory.h"
#include "OneSixVersion.h" #include "OneSixVersion.h"
#include "OneSixLibrary.h" #include "OneSixLibrary.h"
#include "OneSixInstance.h" #include "OneSixInstance.h"
#include "pathutils.h" #include "pathutils.h"
OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent) : BaseUpdate(inst, parent)
OneSixUpdate::OneSixUpdate(BaseInstance *inst, QObject *parent):BaseUpdate(inst, parent){} {
}
void OneSixUpdate::executeTask() void OneSixUpdate::executeTask()
{ {
QString intendedVersion = m_inst->intendedVersionId(); QString intendedVersion = m_inst->intendedVersionId();
// Make directories // Make directories
QDir mcDir(m_inst->minecraftRoot()); QDir mcDir(m_inst->minecraftRoot());
if (!mcDir.exists() && !mcDir.mkpath(".")) if (!mcDir.exists() && !mcDir.mkpath("."))
@ -47,17 +47,18 @@ void OneSixUpdate::executeTask()
emitFailed("Failed to create bin folder."); emitFailed("Failed to create bin folder.");
return; return;
} }
// Get a pointer to the version object that corresponds to the instance's version. // Get a pointer to the version object that corresponds to the instance's version.
targetVersion = MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast<MinecraftVersion>(); targetVersion =
if(targetVersion == nullptr) MMC->minecraftlist()->findVersion(intendedVersion).dynamicCast<MinecraftVersion>();
if (targetVersion == nullptr)
{ {
// don't do anything if it was invalid // don't do anything if it was invalid
emitSucceeded(); emitSucceeded();
return; return;
} }
if(m_inst->shouldUpdate()) if (m_inst->shouldUpdate())
{ {
versionFileStart(); versionFileStart();
} }
@ -70,62 +71,65 @@ void OneSixUpdate::executeTask()
void OneSixUpdate::versionFileStart() void OneSixUpdate::versionFileStart()
{ {
setStatus("Getting the version files from Mojang."); setStatus("Getting the version files from Mojang.");
QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json"; urlstr += targetVersion->descriptor() + "/" + targetVersion->descriptor() + ".json";
auto job = new DownloadJob("Version index"); auto job = new DownloadJob("Version index");
job->add(QUrl(urlstr)); job->add(QUrl(urlstr));
specificVersionDownloadJob.reset(job); specificVersionDownloadJob.reset(job);
connect(specificVersionDownloadJob.data(), SIGNAL(succeeded()), SLOT(versionFileFinished())); connect(specificVersionDownloadJob.data(), SIGNAL(succeeded()),
SLOT(versionFileFinished()));
connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed())); connect(specificVersionDownloadJob.data(), SIGNAL(failed()), SLOT(versionFileFailed()));
connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); connect(specificVersionDownloadJob.data(), SIGNAL(progress(qint64, qint64)),
SIGNAL(progress(qint64, qint64)));
specificVersionDownloadJob->start(); specificVersionDownloadJob->start();
} }
void OneSixUpdate::versionFileFinished() void OneSixUpdate::versionFileFinished()
{ {
DownloadPtr DlJob = specificVersionDownloadJob->first(); DownloadPtr DlJob = specificVersionDownloadJob->first();
OneSixInstance * inst = (OneSixInstance *) m_inst; OneSixInstance *inst = (OneSixInstance *)m_inst;
QString version_id = targetVersion->descriptor(); QString version_id = targetVersion->descriptor();
QString inst_dir = m_inst->instanceRoot(); QString inst_dir = m_inst->instanceRoot();
// save the version file in $instanceId/version.json // save the version file in $instanceId/version.json
{ {
QString version1 = PathCombine(inst_dir, "/version.json"); QString version1 = PathCombine(inst_dir, "/version.json");
ensureFilePathExists(version1); ensureFilePathExists(version1);
// FIXME: detect errors here, download to a temp file, swap // FIXME: detect errors here, download to a temp file, swap
QSaveFile vfile1 (version1); QSaveFile vfile1(version1);
if(!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly )) if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
{ {
emitFailed("Can't open " + version1 + " for writing."); emitFailed("Can't open " + version1 + " for writing.");
return; return;
} }
auto data = DlJob.dynamicCast<ByteArrayDownload>()->m_data; auto data = DlJob.dynamicCast<ByteArrayDownload>()->m_data;
qint64 actual = 0; qint64 actual = 0;
if((actual = vfile1.write(data)) != data.size()) if ((actual = vfile1.write(data)) != data.size())
{ {
emitFailed("Failed to write into " + version1 + ". Written " + actual + " out of " + data.size() + '.'); emitFailed("Failed to write into " + version1 + ". Written " + actual + " out of " +
data.size() + '.');
return; return;
} }
if(!vfile1.commit()) if (!vfile1.commit())
{ {
emitFailed("Can't commit changes to " + version1); emitFailed("Can't commit changes to " + version1);
return; return;
} }
} }
// the version is downloaded safely. update is 'done' at this point // the version is downloaded safely. update is 'done' at this point
m_inst->setShouldUpdate(false); m_inst->setShouldUpdate(false);
// delete any custom version inside the instance (it's no longer relevant, we did an update) // delete any custom version inside the instance (it's no longer relevant, we did an update)
QString custom = PathCombine(inst_dir, "/custom.json"); QString custom = PathCombine(inst_dir, "/custom.json");
QFile finfo(custom); QFile finfo(custom);
if(finfo.exists()) if (finfo.exists())
{ {
finfo.remove(); finfo.remove();
} }
inst->reloadFullVersion(); inst->reloadFullVersion();
jarlibStart(); jarlibStart();
} }
@ -136,42 +140,44 @@ void OneSixUpdate::versionFileFailed()
void OneSixUpdate::jarlibStart() void OneSixUpdate::jarlibStart()
{ {
OneSixInstance * inst = (OneSixInstance *) m_inst; OneSixInstance *inst = (OneSixInstance *)m_inst;
bool successful = inst->reloadFullVersion(); bool successful = inst->reloadFullVersion();
if(!successful) if (!successful)
{ {
emitFailed("Failed to load the version description file (version.json). It might be corrupted, missing or simply too new."); emitFailed("Failed to load the version description file (version.json). It might be "
"corrupted, missing or simply too new.");
return; return;
} }
QSharedPointer<OneSixVersion> version = inst->getFullVersion(); QSharedPointer<OneSixVersion> version = inst->getFullVersion();
// download the right jar, save it in versions/$version/$version.jar // download the right jar, save it in versions/$version/$version.jar
QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/"); QString urlstr("http://s3.amazonaws.com/Minecraft.Download/versions/");
urlstr += version->id + "/" + version->id + ".jar"; urlstr += version->id + "/" + version->id + ".jar";
QString targetstr ("versions/"); QString targetstr("versions/");
targetstr += version->id + "/" + version->id + ".jar"; targetstr += version->id + "/" + version->id + ".jar";
auto job = new DownloadJob("Libraries for instance " + inst->name()); auto job = new DownloadJob("Libraries for instance " + inst->name());
job->add(QUrl(urlstr), targetstr); job->add(QUrl(urlstr), targetstr);
jarlibDownloadJob.reset(job); jarlibDownloadJob.reset(job);
auto libs = version->getActiveNativeLibs(); auto libs = version->getActiveNativeLibs();
libs.append(version->getActiveNormalLibs()); libs.append(version->getActiveNormalLibs());
auto metacache = MMC->metacache(); auto metacache = MMC->metacache();
for(auto lib: libs) for (auto lib : libs)
{ {
QString download_path = lib->downloadPath(); QString download_path = lib->downloadUrl();
auto entry = metacache->resolveEntry("libraries", lib->storagePath()); auto entry = metacache->resolveEntry("libraries", lib->storagePath());
if(entry->stale) if (entry->stale)
{ {
jarlibDownloadJob->add(download_path, entry); jarlibDownloadJob->add(download_path, entry);
} }
} }
connect(jarlibDownloadJob.data(), SIGNAL(succeeded()), SLOT(jarlibFinished())); connect(jarlibDownloadJob.data(), SIGNAL(succeeded()), SLOT(jarlibFinished()));
connect(jarlibDownloadJob.data(), SIGNAL(failed()), SLOT(jarlibFailed())); connect(jarlibDownloadJob.data(), SIGNAL(failed()), SLOT(jarlibFailed()));
connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64,qint64)), SIGNAL(progress(qint64,qint64))); connect(jarlibDownloadJob.data(), SIGNAL(progress(qint64, qint64)),
SIGNAL(progress(qint64, qint64)));
jarlibDownloadJob->start(); jarlibDownloadJob->start();
} }
@ -185,4 +191,3 @@ void OneSixUpdate::jarlibFailed()
{ {
emitFailed("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE"); emitFailed("Failed to download the binary garbage. Try again. Maybe. IF YOU DARE");
} }

View File

@ -1,10 +1,201 @@
#include "OneSixVersion.h" #include "OneSixVersion.h"
#include "OneSixLibrary.h" #include "OneSixLibrary.h"
#include "OneSixRule.h"
QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNormalLibs() QSharedPointer<OneSixVersion> fromJsonV4(QJsonObject root,
QSharedPointer<OneSixVersion> fullVersion)
{ {
QList<QSharedPointer<OneSixLibrary> > output; fullVersion->id = root.value("id").toString();
for ( auto lib: libraries )
fullVersion->mainClass = root.value("mainClass").toString();
auto procArgsValue = root.value("processArguments");
if (procArgsValue.isString())
{
fullVersion->processArguments = procArgsValue.toString();
QString toCompare = fullVersion->processArguments.toLower();
if (toCompare == "legacy")
{
fullVersion->minecraftArguments = " ${auth_player_name} ${auth_session}";
}
else if (toCompare == "username_session")
{
fullVersion->minecraftArguments =
"--username ${auth_player_name} --session ${auth_session}";
}
else if (toCompare == "username_session_version")
{
fullVersion->minecraftArguments = "--username ${auth_player_name} "
"--session ${auth_session} "
"--version ${profile_name}";
}
}
auto minecraftArgsValue = root.value("minecraftArguments");
if (minecraftArgsValue.isString())
{
fullVersion->minecraftArguments = minecraftArgsValue.toString();
}
auto minecraftTypeValue = root.value("type");
if (minecraftTypeValue.isString())
{
fullVersion->type = minecraftTypeValue.toString();
}
fullVersion->releaseTime = root.value("releaseTime").toString();
fullVersion->time = root.value("time").toString();
// Iterate through the list, if it's a list.
auto librariesValue = root.value("libraries");
if (!librariesValue.isArray())
return fullVersion;
QJsonArray libList = root.value("libraries").toArray();
for (auto libVal : libList)
{
if (!libVal.isObject())
{
continue;
}
QJsonObject libObj = libVal.toObject();
// Library name
auto nameVal = libObj.value("name");
if (!nameVal.isString())
continue;
QSharedPointer<OneSixLibrary> library(new OneSixLibrary(nameVal.toString()));
auto urlVal = libObj.value("url");
if (urlVal.isString())
{
library->setBaseUrl(urlVal.toString());
}
auto urlAbsVal = libObj.value("MMC-absulute_url");
if (urlAbsVal.isString())
{
library->setAbsoluteUrl(urlAbsVal.toString());
}
// Extract excludes (if any)
auto extractVal = libObj.value("extract");
if (extractVal.isObject())
{
QStringList excludes;
auto extractObj = extractVal.toObject();
auto excludesVal = extractObj.value("exclude");
if (excludesVal.isArray())
{
auto excludesList = excludesVal.toArray();
for (auto excludeVal : excludesList)
{
if (excludeVal.isString())
excludes.append(excludeVal.toString());
}
library->extract_excludes = excludes;
}
}
auto nativesVal = libObj.value("natives");
if (nativesVal.isObject())
{
library->setIsNative();
auto nativesObj = nativesVal.toObject();
auto iter = nativesObj.begin();
while (iter != nativesObj.end())
{
auto osType = OpSys_fromString(iter.key());
if (osType == Os_Other)
continue;
if (!iter.value().isString())
continue;
library->addNative(osType, iter.value().toString());
iter++;
}
}
library->setRules(rulesFromJsonV4(libObj));
library->finalize();
fullVersion->libraries.append(library);
}
return fullVersion;
}
QSharedPointer<OneSixVersion> OneSixVersion::fromJson(QJsonObject root)
{
QSharedPointer<OneSixVersion> readVersion(new OneSixVersion());
int launcher_ver = readVersion->minimumLauncherVersion =
root.value("minimumLauncherVersion").toDouble();
// ADD MORE HERE :D
if (launcher_ver > 0 && launcher_ver <= 7)
return fromJsonV4(root, readVersion);
else
{
return QSharedPointer<OneSixVersion>();
}
}
QSharedPointer<OneSixVersion> OneSixVersion::fromFile(QString filepath)
{
QFile file(filepath);
if (!file.open(QIODevice::ReadOnly))
{
return QSharedPointer<OneSixVersion>();
}
auto data = file.readAll();
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
if (jsonError.error != QJsonParseError::NoError)
{
return QSharedPointer<OneSixVersion>();
}
if (!jsonDoc.isObject())
{
return QSharedPointer<OneSixVersion>();
}
QJsonObject root = jsonDoc.object();
auto version = fromJson(root);
version->original_file = filepath;
return version;
}
bool OneSixVersion::toOriginalFile()
{
if (original_file.isEmpty())
return false;
QSaveFile file(original_file);
if (!file.open(QIODevice::WriteOnly))
{
return false;
}
// serialize base attributes (those we care about anyway)
QJsonObject root;
root.insert("minecraftArguments", minecraftArguments);
root.insert("mainClass", mainClass);
root.insert("minimumLauncherVersion", minimumLauncherVersion);
root.insert("time", time);
root.insert("id", id);
root.insert("type", type);
// screw processArguments
root.insert("releaseTime", releaseTime);
QJsonArray libarray;
for(const auto & lib: libraries)
{
libarray.append(lib->toJson());
}
if(libarray.count())
root.insert("libraries", libarray);
QJsonDocument doc(root);
file.write(doc.toJson());
return file.commit();
}
QList<QSharedPointer<OneSixLibrary>> OneSixVersion::getActiveNormalLibs()
{
QList<QSharedPointer<OneSixLibrary>> output;
for (auto lib : libraries)
{ {
if (lib->isActive() && !lib->isNative()) if (lib->isActive() && !lib->isNative())
{ {
@ -14,10 +205,10 @@ QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNormalLibs()
return output; return output;
} }
QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNativeLibs() QList<QSharedPointer<OneSixLibrary>> OneSixVersion::getActiveNativeLibs()
{ {
QList<QSharedPointer<OneSixLibrary> > output; QList<QSharedPointer<OneSixLibrary>> output;
for ( auto lib: libraries ) for (auto lib : libraries)
{ {
if (lib->isActive() && lib->isNative()) if (lib->isActive() && lib->isNative())
{ {
@ -27,41 +218,50 @@ QList<QSharedPointer<OneSixLibrary> > OneSixVersion::getActiveNativeLibs()
return output; return output;
} }
void OneSixVersion::externalUpdateStart()
QVariant OneSixVersion::data(const QModelIndex& index, int role) const
{ {
if(!index.isValid()) beginResetModel();
}
void OneSixVersion::externalUpdateFinish()
{
endResetModel();
}
QVariant OneSixVersion::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant(); return QVariant();
int row = index.row(); int row = index.row();
int column = index.column(); int column = index.column();
if(row < 0 || row >= libraries.size()) if (row < 0 || row >= libraries.size())
return QVariant(); return QVariant();
if(role == Qt::DisplayRole) if (role == Qt::DisplayRole)
{ {
switch(column) switch (column)
{ {
case 0: case 0:
return libraries[row]->name(); return libraries[row]->name();
case 1: case 1:
return libraries[row]->type(); return libraries[row]->type();
case 2: case 2:
return libraries[row]->version(); return libraries[row]->version();
default: default:
return QVariant(); return QVariant();
} }
} }
return QVariant(); return QVariant();
} }
Qt::ItemFlags OneSixVersion::flags(const QModelIndex& index) const Qt::ItemFlags OneSixVersion::flags(const QModelIndex &index) const
{ {
if(!index.isValid()) if (!index.isValid())
return Qt::NoItemFlags; return Qt::NoItemFlags;
int row = index.row(); int row = index.row();
if(libraries[row]->isActive()) if (libraries[row]->isActive())
{ {
return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren; return Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemNeverHasChildren;
} }
@ -69,11 +269,10 @@ Qt::ItemFlags OneSixVersion::flags(const QModelIndex& index) const
{ {
return Qt::ItemNeverHasChildren; return Qt::ItemNeverHasChildren;
} }
//return QAbstractListModel::flags(index); // return QAbstractListModel::flags(index);
} }
QVariant OneSixVersion::headerData(int section, Qt::Orientation orientation, int role) const
QVariant OneSixVersion::headerData ( int section, Qt::Orientation orientation, int role ) const
{ {
if (role != Qt::DisplayRole || orientation != Qt::Horizontal) if (role != Qt::DisplayRole || orientation != Qt::Horizontal)
return QVariant(); return QVariant();
@ -90,12 +289,12 @@ QVariant OneSixVersion::headerData ( int section, Qt::Orientation orientation, i
} }
} }
int OneSixVersion::rowCount(const QModelIndex& parent) const int OneSixVersion::rowCount(const QModelIndex &parent) const
{ {
return libraries.size(); return libraries.size();
} }
int OneSixVersion::columnCount(const QModelIndex& parent) const int OneSixVersion::columnCount(const QModelIndex &parent) const
{ {
return 3; return 3;
} }

View File

@ -4,13 +4,33 @@ class OneSixLibrary;
class OneSixVersion : public QAbstractListModel class OneSixVersion : public QAbstractListModel
{ {
// Things required to implement the Qt list model
public: public:
virtual QVariant data ( const QModelIndex& index, int role = Qt::DisplayRole ) const; virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
virtual int rowCount ( const QModelIndex& parent = QModelIndex() ) const; virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const; virtual QVariant headerData(int section, Qt::Orientation orientation,
virtual int columnCount ( const QModelIndex& parent ) const; int role = Qt::DisplayRole) const;
virtual Qt::ItemFlags flags(const QModelIndex& index) const; virtual int columnCount(const QModelIndex &parent) const;
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
// serialization/deserialization
public: public:
bool toOriginalFile();
static QSharedPointer<OneSixVersion> fromJson(QJsonObject root);
static QSharedPointer<OneSixVersion> fromFile(QString filepath);
public:
QList<QSharedPointer<OneSixLibrary>> getActiveNormalLibs();
QList<QSharedPointer<OneSixLibrary>> getActiveNativeLibs();
// called when something starts/stops messing with the object
// FIXME: these are ugly in every possible way.
void externalUpdateStart();
void externalUpdateFinish();
// data members
public:
/// file this was read from. blank, if none
QString original_file;
/// the ID - determines which jar to use! ACTUALLY IMPORTANT! /// the ID - determines which jar to use! ACTUALLY IMPORTANT!
QString id; QString id;
/// Last updated time - as a string /// Last updated time - as a string
@ -23,26 +43,27 @@ public:
* DEPRECATED: Old versions of the new vanilla launcher used this * DEPRECATED: Old versions of the new vanilla launcher used this
* ex: "username_session_version" * ex: "username_session_version"
*/ */
QString processArguments; QString processArguments;
/** /**
* arguments that should be used for launching minecraft * arguments that should be used for launching minecraft
* *
* ex: "--username ${auth_player_name} --session ${auth_session} * ex: "--username ${auth_player_name} --session ${auth_session}
* --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}" * --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}"
*/ */
QString minecraftArguments; QString minecraftArguments;
/** /**
* the minimum launcher version required by this version ... current is 4 (at point of writing) * the minimum launcher version required by this version ... current is 4 (at point of
* writing)
*/ */
int minimumLauncherVersion; int minimumLauncherVersion = 0xDEADBEEF;
/** /**
* The main class to load first * The main class to load first
*/ */
QString mainClass; QString mainClass;
/// the list of libs - both active and inactive, native and java /// the list of libs - both active and inactive, native and java
QList<QSharedPointer<OneSixLibrary> > libraries; QList<QSharedPointer<OneSixLibrary>> libraries;
/* /*
FIXME: add support for those rules here? Looks like a pile of quick hacks to me though. FIXME: add support for those rules here? Looks like a pile of quick hacks to me though.
@ -58,18 +79,11 @@ public:
} }
} }
], ],
"incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX 10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!" "incompatibilityReason": "There is a bug in LWJGL which makes it incompatible with OSX
10.5.8. Please go to New Profile and use 1.5.2 for now. Sorry!"
} }
*/ */
// QList<Rule> rules; // QList<Rule> rules;
public:
OneSixVersion()
{
minimumLauncherVersion = 0xDEADBEEF;
}
QList<QSharedPointer<OneSixLibrary> > getActiveNormalLibs();
QList<QSharedPointer<OneSixLibrary> > getActiveNativeLibs();
}; };

View File

@ -9,4 +9,15 @@ OpSys OpSys_fromString(QString name)
if(name == "osx") if(name == "osx")
return Os_OSX; return Os_OSX;
return Os_Other; return Os_Other;
}
QString OpSys_toString(OpSys name)
{
switch(name)
{
case Os_Linux: return "linux";
case Os_OSX: return "osx";
case Os_Windows: return "windows";
default: return "other";
}
} }

View File

@ -9,6 +9,7 @@ enum OpSys
}; };
OpSys OpSys_fromString(QString); OpSys OpSys_fromString(QString);
QString OpSys_toString(OpSys);
#ifdef Q_OS_WIN32 #ifdef Q_OS_WIN32
#define currentSystem Os_Windows #define currentSystem Os_Windows

View File

@ -1,196 +0,0 @@
#include "VersionFactory.h"
#include "OneSixVersion.h"
#include "OneSixRule.h"
// Library rules (if any)
QList<QSharedPointer<Rule> > FullVersionFactory::parse4rules(QJsonObject & baseObj)
{
QList<QSharedPointer<Rule> > rules;
auto rulesVal = baseObj.value("rules");
if(rulesVal.isArray())
{
QJsonArray ruleList = rulesVal.toArray();
for(auto ruleVal : ruleList)
{
QSharedPointer<Rule> rule;
if(!ruleVal.isObject())
continue;
auto ruleObj = ruleVal.toObject();
auto actionVal = ruleObj.value("action");
if(!actionVal.isString())
continue;
auto action = RuleAction_fromString(actionVal.toString());
if(action == Defer)
continue;
auto osVal = ruleObj.value("os");
if(!osVal.isObject())
{
// add a new implicit action rule
rules.append(ImplicitRule::create(action));
}
else
{
auto osObj = osVal.toObject();
auto osNameVal = osObj.value("name");
if(!osNameVal.isString())
continue;
OpSys requiredOs = OpSys_fromString(osNameVal.toString());
QString versionRegex = osObj.value("version").toString();
// add a new OS rule
rules.append(OsRule::create(action, requiredOs, versionRegex));
}
}
}
return rules;
}
QSharedPointer<OneSixVersion> FullVersionFactory::parse4(QJsonObject root, QSharedPointer<OneSixVersion> fullVersion)
{
fullVersion->id = root.value("id").toString();
fullVersion->mainClass = root.value("mainClass").toString();
auto procArgsValue = root.value("processArguments");
if(procArgsValue.isString())
{
fullVersion->processArguments = procArgsValue.toString();
QString toCompare = fullVersion->processArguments.toLower();
if(toCompare == "legacy")
{
fullVersion->minecraftArguments = " ${auth_player_name} ${auth_session}";
}
else if(toCompare == "username_session")
{
fullVersion->minecraftArguments = "--username ${auth_player_name} --session ${auth_session}";
}
else if(toCompare == "username_session_version")
{
fullVersion->minecraftArguments = "--username ${auth_player_name} --session ${auth_session} --version ${profile_name}";
}
}
auto minecraftArgsValue = root.value("minecraftArguments");
if(minecraftArgsValue.isString())
{
fullVersion->minecraftArguments = minecraftArgsValue.toString();
}
auto minecraftTypeValue = root.value("type");
if(minecraftTypeValue.isString())
{
fullVersion->type = minecraftTypeValue.toString();
}
fullVersion->releaseTime = root.value("releaseTime").toString();
fullVersion->time = root.value("time").toString();
// Iterate through the list, if it's a list.
auto librariesValue = root.value("libraries");
if(!librariesValue.isArray())
return fullVersion;
QJsonArray libList = root.value("libraries").toArray();
for (auto libVal : libList)
{
if (!libVal.isObject())
{
continue;
}
QJsonObject libObj = libVal.toObject();
// Library name
auto nameVal = libObj.value("name");
if(!nameVal.isString())
continue;
QSharedPointer<OneSixLibrary> library(new OneSixLibrary(nameVal.toString()));
auto urlVal = libObj.value("url");
if(urlVal.isString())
{
library->setBaseUrl(urlVal.toString());
}
// Extract excludes (if any)
auto extractVal = libObj.value("extract");
if(extractVal.isObject())
{
QStringList excludes;
auto extractObj = extractVal.toObject();
auto excludesVal = extractObj.value("exclude");
if(!excludesVal.isArray())
goto SKIP_EXTRACTS;
auto excludesList = excludesVal.toArray();
for(auto excludeVal : excludesList)
{
if(excludeVal.isString())
excludes.append(excludeVal.toString());
}
library->extract_excludes = excludes;
}
SKIP_EXTRACTS:
auto nativesVal = libObj.value("natives");
if(nativesVal.isObject())
{
library->setIsNative();
auto nativesObj = nativesVal.toObject();
auto iter = nativesObj.begin();
while(iter != nativesObj.end())
{
auto osType = OpSys_fromString(iter.key());
if(osType == Os_Other)
continue;
if(!iter.value().isString())
continue;
library->addNative(osType, iter.value().toString());
iter++;
}
}
library->setRules(parse4rules(libObj));
library->finalize();
fullVersion->libraries.append(library);
}
return fullVersion;
}
QSharedPointer<OneSixVersion> FullVersionFactory::parse(QByteArray data)
{
QSharedPointer<OneSixVersion> readVersion(new OneSixVersion());
QJsonParseError jsonError;
QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
if (jsonError.error != QJsonParseError::NoError)
{
error_string = QString( "Error reading version file :") + " " + jsonError.errorString();
m_error = FullVersionFactory::ParseError;
return QSharedPointer<OneSixVersion>();
}
if(!jsonDoc.isObject())
{
error_string = "Error reading version file.";
m_error = FullVersionFactory::ParseError;
return QSharedPointer<OneSixVersion>();
}
QJsonObject root = jsonDoc.object();
int launcher_ver = readVersion->minimumLauncherVersion = root.value("minimumLauncherVersion").toDouble();
// ADD MORE HERE :D
if(launcher_ver > 0 && launcher_ver <= 7)
return parse4(root, readVersion);
else
{
error_string = "Version file was for an unrecognized launcher version. RIP";
m_error = FullVersionFactory::UnsupportedVersion;
return QSharedPointer<OneSixVersion>();
}
}
FullVersionFactory::FullVersionFactory()
{
m_error = FullVersionFactory::AllOK;
}

View File

@ -1,24 +0,0 @@
#pragma once
#include <QtCore>
struct OneSixVersion;
class Rule;
class FullVersionFactory
{
public:
enum Error
{
AllOK, // all parsed OK
ParseError, // the file was corrupted somehow
UnsupportedVersion // the file was meant for a launcher version we don't support (yet)
} m_error;
QString error_string;
public:
FullVersionFactory();
QSharedPointer<OneSixVersion> parse(QByteArray data);
private:
QSharedPointer<OneSixVersion> parse4(QJsonObject root, QSharedPointer<OneSixVersion> product);
QList<QSharedPointer<Rule> > parse4rules(QJsonObject & baseObj);
};

View File

@ -260,8 +260,10 @@ void ForgeListLoadTask::list_downloaded()
fVersion->installer_url = installer_url; fVersion->installer_url = installer_url;
fVersion->jobbuildver = jobbuildver; fVersion->jobbuildver = jobbuildver;
fVersion->mcver = mcver; fVersion->mcver = mcver;
fVersion->filename = filename; if(installer_filename.isEmpty())
fVersion->filename = installer_filename; fVersion->filename = filename;
else
fVersion->filename = installer_filename;
fVersion->m_buildnr = build_nr; fVersion->m_buildnr = build_nr;
tempList.append(fVersion); tempList.append(fVersion);
} }
@ -271,3 +273,8 @@ void ForgeListLoadTask::list_downloaded()
emitSucceeded(); emitSucceeded();
return; return;
} }

View File

@ -3,7 +3,7 @@
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
* *
* http://www.apache.org/licenses/LICENSE-2.0 * http://www.apache.org/licenses/LICENSE-2.0
* *
* Unless required by applicable law or agreed to in writing, software * Unless required by applicable law or agreed to in writing, software
@ -33,19 +33,22 @@ struct ForgeVersion : public BaseVersion
virtual QString descriptor() virtual QString descriptor()
{ {
return filename; return filename;
}; }
;
virtual QString name() virtual QString name()
{ {
return "Forge " + jobbuildver; return "Forge " + jobbuildver;
}; }
;
virtual QString typeString() const virtual QString typeString() const
{ {
if(installer_url.isEmpty()) if (installer_url.isEmpty())
return "Universal"; return "Universal";
else else
return "Installer"; return "Installer";
}; }
;
int m_buildnr = 0; int m_buildnr = 0;
QString universal_url; QString universal_url;
QString changelog_url; QString changelog_url;
@ -60,42 +63,45 @@ class ForgeVersionList : public BaseVersionList
Q_OBJECT Q_OBJECT
public: public:
friend class ForgeListLoadTask; friend class ForgeListLoadTask;
explicit ForgeVersionList(QObject *parent = 0); explicit ForgeVersionList(QObject *parent = 0);
virtual Task *getLoadTask(); virtual Task *getLoadTask();
virtual bool isLoaded(); virtual bool isLoaded();
virtual const BaseVersionPtr at(int i) const; virtual const BaseVersionPtr at(int i) const;
virtual int count() const; virtual int count() const;
virtual void sort(); virtual void sort();
virtual BaseVersionPtr getLatestStable() const; virtual BaseVersionPtr getLatestStable() const;
virtual QVariant data(const QModelIndex& index, int role) const; virtual QVariant data(const QModelIndex &index, int role) const;
virtual QVariant headerData(int section, Qt::Orientation orientation, int role) const; virtual QVariant headerData(int section, Qt::Orientation orientation,
virtual int columnCount(const QModelIndex& parent) const; int role) const;
virtual int columnCount(const QModelIndex &parent) const;
protected: protected:
QList<BaseVersionPtr> m_vlist; QList<BaseVersionPtr> m_vlist;
bool m_loaded; bool m_loaded;
protected slots: protected
virtual void updateListData(QList<BaseVersionPtr > versions); slots:
virtual void updateListData(QList<BaseVersionPtr> versions);
}; };
class ForgeListLoadTask : public Task class ForgeListLoadTask : public Task
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit ForgeListLoadTask(ForgeVersionList *vlist); explicit ForgeListLoadTask(ForgeVersionList *vlist);
virtual void executeTask(); virtual void executeTask();
protected slots: protected
slots:
void list_downloaded(); void list_downloaded();
protected: protected:
DownloadJobPtr listJob; DownloadJobPtr listJob;
ForgeVersionList *m_list; ForgeVersionList *m_list;

View File

@ -30,7 +30,7 @@ void LoginTask::executeTask()
{ {
setStatus(tr("Logging in...")); setStatus(tr("Logging in..."));
auto worker = MMC->qnam(); auto worker = MMC->qnam();
connect(worker, SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetReply(QNetworkReply*))); connect(worker.data(), SIGNAL(finished(QNetworkReply*)), this, SLOT(processNetReply(QNetworkReply*)));
QUrl loginURL("https://login.minecraft.net/"); QUrl loginURL("https://login.minecraft.net/");
QNetworkRequest netRequest(loginURL); QNetworkRequest netRequest(loginURL);