Begin the transformation!
Nuke all the things.
This commit is contained in:
		| @@ -309,12 +309,8 @@ SET(MULTIMC_SOURCES | ||||
| 	gui/dialogs/InstanceSettings.cpp | ||||
| 	gui/dialogs/IconPickerDialog.h | ||||
| 	gui/dialogs/IconPickerDialog.cpp | ||||
| 	gui/dialogs/LegacyModEditDialog.h | ||||
| 	gui/dialogs/LegacyModEditDialog.cpp | ||||
| 	gui/dialogs/OneSixModEditDialog.h | ||||
| 	gui/dialogs/OneSixModEditDialog.cpp | ||||
| 	gui/dialogs/ModEditDialogCommon.h | ||||
| 	gui/dialogs/ModEditDialogCommon.cpp | ||||
| 	gui/dialogs/InstanceEditDialog.h | ||||
| 	gui/dialogs/InstanceEditDialog.cpp | ||||
| 	gui/dialogs/EditNotesDialog.h | ||||
| 	gui/dialogs/EditNotesDialog.cpp | ||||
| 	gui/dialogs/CustomMessageBox.h | ||||
| @@ -395,10 +391,6 @@ SET(MULTIMC_SOURCES | ||||
| 	logic/net/ByteArrayDownload.cpp | ||||
| 	logic/net/CacheDownload.h | ||||
| 	logic/net/CacheDownload.cpp | ||||
| 	logic/net/ForgeMirrors.h | ||||
| 	logic/net/ForgeMirrors.cpp | ||||
| 	logic/net/ForgeXzDownload.h | ||||
| 	logic/net/ForgeXzDownload.cpp | ||||
| 	logic/net/NetJob.h | ||||
| 	logic/net/NetJob.cpp | ||||
| 	logic/net/HttpMetaCache.h | ||||
| @@ -449,9 +441,6 @@ SET(MULTIMC_SOURCES | ||||
| 	logic/LegacyUpdate.h | ||||
| 	logic/LegacyUpdate.cpp | ||||
|  | ||||
| 	logic/LegacyForge.h | ||||
| 	logic/LegacyForge.cpp | ||||
|  | ||||
| 	# OneSix instances | ||||
| 	logic/OneSixUpdate.h | ||||
| 	logic/OneSixUpdate.cpp | ||||
| @@ -476,14 +465,6 @@ SET(MULTIMC_SOURCES | ||||
| 	# Mod installers | ||||
| 	logic/BaseInstaller.h | ||||
| 	logic/BaseInstaller.cpp | ||||
| 	logic/ForgeInstaller.h | ||||
| 	logic/ForgeInstaller.cpp | ||||
| 	logic/LiteLoaderInstaller.h | ||||
| 	logic/LiteLoaderInstaller.cpp | ||||
|  | ||||
| 	# Nostalgia | ||||
| 	logic/NostalgiaInstance.h | ||||
| 	logic/NostalgiaInstance.cpp | ||||
|  | ||||
| 	# FTB | ||||
| 	logic/OneSixFTBInstance.h | ||||
| @@ -500,12 +481,8 @@ SET(MULTIMC_SOURCES | ||||
| 	logic/lists/MinecraftVersionList.cpp | ||||
| 	logic/lists/LwjglVersionList.h | ||||
| 	logic/lists/LwjglVersionList.cpp | ||||
| 	logic/lists/ForgeVersionList.h | ||||
| 	logic/lists/ForgeVersionList.cpp | ||||
| 	logic/lists/JavaVersionList.h | ||||
| 	logic/lists/JavaVersionList.cpp | ||||
| 	logic/lists/LiteLoaderVersionList.h | ||||
| 	logic/lists/LiteLoaderVersionList.cpp | ||||
|  | ||||
| 	# the screenshots feature | ||||
| 	logic/screenshots/Screenshot.h | ||||
| @@ -566,6 +543,29 @@ SET(MULTIMC_SOURCES | ||||
| 	logic/tools/JProfiler.cpp | ||||
| 	logic/tools/JVisualVM.h | ||||
| 	logic/tools/JVisualVM.cpp | ||||
| 	 | ||||
| 	# Forge and all things forge related | ||||
| 	logic/forge/ForgeData.h | ||||
| 	logic/forge/ForgeData.cpp | ||||
| 	logic/forge/ForgeVersion.h | ||||
| 	logic/forge/ForgeVersion.cpp | ||||
| 	logic/forge/ForgeVersionList.h | ||||
| 	logic/forge/ForgeVersionList.cpp | ||||
| 	logic/forge/ForgeMirror.h | ||||
| 	logic/forge/ForgeMirrors.h | ||||
| 	logic/forge/ForgeMirrors.cpp | ||||
| 	logic/forge/ForgeXzDownload.h | ||||
| 	logic/forge/ForgeXzDownload.cpp | ||||
| 	logic/forge/LegacyForge.h | ||||
| 	logic/forge/LegacyForge.cpp | ||||
| 	logic/forge/ForgeInstaller.h | ||||
| 	logic/forge/ForgeInstaller.cpp | ||||
| 	 | ||||
| 	# Liteloader and related things | ||||
| 	logic/liteloader/LiteLoaderInstaller.h | ||||
| 	logic/liteloader/LiteLoaderInstaller.cpp | ||||
| 	logic/liteloader/LiteLoaderVersionList.h | ||||
| 	logic/liteloader/LiteLoaderVersionList.cpp | ||||
| ) | ||||
|  | ||||
|  | ||||
| @@ -585,8 +585,7 @@ SET(MULTIMC_UIS | ||||
| 	gui/dialogs/InstanceSettings.ui | ||||
| 	gui/dialogs/ProgressDialog.ui | ||||
| 	gui/dialogs/IconPickerDialog.ui | ||||
| 	gui/dialogs/LegacyModEditDialog.ui | ||||
| 	gui/dialogs/OneSixModEditDialog.ui | ||||
| 	gui/dialogs/InstanceEditDialog.ui | ||||
| 	gui/dialogs/EditNotesDialog.ui | ||||
| 	gui/dialogs/AccountListDialog.ui | ||||
| 	gui/dialogs/AccountSelectDialog.ui | ||||
|   | ||||
| @@ -17,8 +17,9 @@ | ||||
| #include "logic/icons/IconList.h" | ||||
| #include "logic/lists/LwjglVersionList.h" | ||||
| #include "logic/lists/MinecraftVersionList.h" | ||||
| #include "logic/lists/ForgeVersionList.h" | ||||
| #include "logic/lists/LiteLoaderVersionList.h" | ||||
| #include "logic/liteloader/LiteLoaderVersionList.h" | ||||
|  | ||||
| #include "logic/forge/ForgeVersionList.h" | ||||
|  | ||||
| #include "logic/news/NewsChecker.h" | ||||
|  | ||||
|   | ||||
| @@ -1032,7 +1032,7 @@ void MainWindow::on_actionViewSelectedInstFolder_triggered() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::on_actionEditInstMods_triggered() | ||||
| void MainWindow::on_actionEditInstance_triggered() | ||||
| { | ||||
| 	if (m_selectedInstance) | ||||
| 	{ | ||||
| @@ -1339,99 +1339,12 @@ void MainWindow::startTask(Task *task) | ||||
| 	task->start(); | ||||
| } | ||||
|  | ||||
| // Create A Desktop Shortcut | ||||
| void MainWindow::on_actionMakeDesktopShortcut_triggered() | ||||
| { | ||||
| 	QString name("Test"); | ||||
| 	name = QInputDialog::getText(this, tr("MultiMC Shortcut"), tr("Enter a Shortcut Name."), | ||||
| 								 QLineEdit::Normal, name); | ||||
|  | ||||
| 	Util::createShortCut(Util::getDesktopDir(), QApplication::instance()->applicationFilePath(), | ||||
| 						 QStringList() << "-dl" << QDir::currentPath() << "test", name, | ||||
| 						 "application-x-octet-stream"); | ||||
|  | ||||
| 	CustomMessageBox::selectable( | ||||
| 		this, tr("Not useful"), | ||||
| 		tr("A Dummy Shortcut was created. it will not do anything productive"), | ||||
| 		QMessageBox::Warning)->show(); | ||||
| } | ||||
|  | ||||
| // BrowserDialog | ||||
| void MainWindow::openWebPage(QUrl url) | ||||
| { | ||||
| 	QDesktopServices::openUrl(url); | ||||
| } | ||||
|  | ||||
| void MainWindow::on_actionChangeInstMCVersion_triggered() | ||||
| { | ||||
| 	if (view->selectionModel()->selectedIndexes().count() < 1) | ||||
| 		return; | ||||
|  | ||||
| 	VersionSelectDialog vselect(m_selectedInstance->versionList().get(), | ||||
| 								tr("Change Minecraft version"), this); | ||||
| 	vselect.setFuzzyFilter(1, "*OneSix*"); | ||||
| 	if (!vselect.exec() || !vselect.selectedVersion()) | ||||
| 		return; | ||||
|  | ||||
| 	if (!MMC->accounts()->anyAccountIsValid()) | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable( | ||||
| 			this, tr("Error"), | ||||
| 			tr("MultiMC cannot download Minecraft or update instances unless you have at least " | ||||
| 			   "one account added.\nPlease add your Mojang or Minecraft account."), | ||||
| 			QMessageBox::Warning)->show(); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (m_selectedInstance->versionIsCustom()) | ||||
| 	{ | ||||
| 		auto result = CustomMessageBox::selectable( | ||||
| 			this, tr("Are you sure?"), | ||||
| 			tr("This will remove any library/version customization you did previously. " | ||||
| 			   "This includes things like Forge install and similar."), | ||||
| 			QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Abort, | ||||
| 			QMessageBox::Abort)->exec(); | ||||
|  | ||||
| 		if (result != QMessageBox::Ok) | ||||
| 			return; | ||||
| 	} | ||||
| 	m_selectedInstance->setIntendedVersionId(vselect.selectedVersion()->descriptor()); | ||||
|  | ||||
| 	auto updateTask = m_selectedInstance->doUpdate(); | ||||
| 	if (!updateTask) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 	ProgressDialog tDialog(this); | ||||
| 	connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); | ||||
| 	tDialog.exec(updateTask.get()); | ||||
| } | ||||
|  | ||||
| void MainWindow::on_actionChangeInstLWJGLVersion_triggered() | ||||
| { | ||||
| 	if (!m_selectedInstance) | ||||
| 		return; | ||||
|  | ||||
| 	LWJGLSelectDialog lselect(this); | ||||
| 	lselect.exec(); | ||||
| 	if (lselect.result() == QDialog::Accepted) | ||||
| 	{ | ||||
|         auto ptr = std::dynamic_pointer_cast<LegacyInstance>(m_selectedInstance); | ||||
|         if(ptr) | ||||
|             ptr->setLWJGLVersion(lselect.selectedVersion()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void MainWindow::on_actionInstanceSettings_triggered() | ||||
| { | ||||
| 	if (view->selectionModel()->selectedIndexes().count() < 1) | ||||
| 		return; | ||||
|  | ||||
| 	InstanceSettings settings(&m_selectedInstance->settings(), this); | ||||
| 	settings.setWindowTitle(tr("Instance settings")); | ||||
| 	settings.exec(); | ||||
| } | ||||
|  | ||||
| void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex &previous) | ||||
| { | ||||
|     if(!current.isValid()) | ||||
| @@ -1446,12 +1359,8 @@ void MainWindow::instanceChanged(const QModelIndex ¤t, const QModelIndex & | ||||
| 	{ | ||||
| 		ui->instanceToolBar->setEnabled(m_selectedInstance->canLaunch()); | ||||
| 		renameButton->setText(m_selectedInstance->name()); | ||||
| 		ui->actionChangeInstLWJGLVersion->setEnabled( | ||||
| 			m_selectedInstance->menuActionEnabled("actionChangeInstLWJGLVersion")); | ||||
| 		ui->actionEditInstMods->setEnabled( | ||||
| 			m_selectedInstance->menuActionEnabled("actionEditInstMods")); | ||||
| 		ui->actionChangeInstMCVersion->setEnabled( | ||||
| 			m_selectedInstance->menuActionEnabled("actionChangeInstMCVersion")); | ||||
| 		ui->actionEditInstance->setEnabled( | ||||
| 			m_selectedInstance->menuActionEnabled("actionEditInstance")); | ||||
| 		m_statusLeft->setText(m_selectedInstance->getStatusbarDescription()); | ||||
| 		updateInstanceToolIcon(m_selectedInstance->iconKey()); | ||||
|  | ||||
|   | ||||
| @@ -103,11 +103,7 @@ slots: | ||||
|  | ||||
| 	void on_actionRenameInstance_triggered(); | ||||
|  | ||||
| 	void on_actionMakeDesktopShortcut_triggered(); | ||||
|  | ||||
| 	void on_actionChangeInstMCVersion_triggered(); | ||||
|  | ||||
| 	void on_actionEditInstMods_triggered(); | ||||
| 	void on_actionEditInstance_triggered(); | ||||
|  | ||||
| 	void on_actionEditInstNotes_triggered(); | ||||
|  | ||||
| @@ -135,12 +131,8 @@ slots: | ||||
| 	void taskStart(); | ||||
| 	void taskEnd(); | ||||
|  | ||||
| 	void on_actionChangeInstLWJGLVersion_triggered(); | ||||
|  | ||||
| 	void instanceEnded(); | ||||
|  | ||||
| 	void on_actionInstanceSettings_triggered(); | ||||
|  | ||||
| 	// called when an icon is changed in the icon model. | ||||
| 	void iconUpdated(QString); | ||||
|  | ||||
|   | ||||
| @@ -74,7 +74,7 @@ | ||||
|    <addaction name="actionReportBug"/> | ||||
|    <addaction name="actionAbout"/> | ||||
|    <addaction name="separator"/> | ||||
|    <addaction name="actionPatreon"/>    | ||||
|    <addaction name="actionPatreon"/> | ||||
|    <addaction name="actionCAT"/> | ||||
|   </widget> | ||||
|   <widget class="QStatusBar" name="statusBar"/> | ||||
| @@ -115,10 +115,7 @@ | ||||
|    <addaction name="separator"/> | ||||
|    <addaction name="actionScreenshots"/> | ||||
|    <addaction name="separator"/> | ||||
|    <addaction name="actionInstanceSettings"/> | ||||
|    <addaction name="actionChangeInstMCVersion"/> | ||||
|    <addaction name="actionChangeInstLWJGLVersion"/> | ||||
|    <addaction name="actionEditInstMods"/> | ||||
|    <addaction name="actionEditInstance"/> | ||||
|    <addaction name="actionViewSelectedInstFolder"/> | ||||
|    <addaction name="actionConfig_Folder"/> | ||||
|    <addaction name="separator"/> | ||||
| @@ -284,7 +281,7 @@ | ||||
|    <property name="statusTip"> | ||||
|     <string>Open the MultiMC Patreon page.</string> | ||||
|    </property> | ||||
|   </action>   | ||||
|   </action> | ||||
|   <action name="actionMoreNews"> | ||||
|    <property name="icon"> | ||||
|     <iconset theme="news"> | ||||
| @@ -388,82 +385,18 @@ | ||||
|     <string>Edit the notes for the selected instance.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionInstanceSettings"> | ||||
|    <property name="enabled"> | ||||
|     <bool>true</bool> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Settings</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Change settings for the selected instance.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Change settings for the selected instance.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionMakeDesktopShortcut"> | ||||
|    <property name="enabled"> | ||||
|     <bool>false</bool> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Make Shortcut</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Make a shortcut on the desktop for the selected instance.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Make a shortcut on the desktop for the selected instance.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionManageInstSaves"> | ||||
|    <property name="enabled"> | ||||
|     <bool>false</bool> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Manage Saves</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Manage saves for the selected instance.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Manage saves for the selected instance.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionEditInstMods"> | ||||
|   <action name="actionEditInstance"> | ||||
|    <property name="text"> | ||||
|     <string>Edit Mods</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Edit the mods for the selected instance.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Edit the mods for the selected instance.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionChangeInstMCVersion"> | ||||
|    <property name="text"> | ||||
|     <string>Change Version</string> | ||||
|    <property name="iconText"> | ||||
|     <string>Edit Instance</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Change the selected instance's Minecraft version.</string> | ||||
|     <string>Change the instance settings, mods and versions.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Change the selected instance's Minecraft version.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionChangeInstLWJGLVersion"> | ||||
|    <property name="enabled"> | ||||
|     <bool>false</bool> | ||||
|    </property> | ||||
|    <property name="text"> | ||||
|     <string>Change LWJGL</string> | ||||
|    </property> | ||||
|    <property name="toolTip"> | ||||
|     <string>Change the version of LWJGL for the selected instance to use.</string> | ||||
|    </property> | ||||
|    <property name="statusTip"> | ||||
|     <string>Change the version of LWJGL for the selected instance to use.</string> | ||||
|     <string>Change the instance settings, mods and versions.</string> | ||||
|    </property> | ||||
|   </action> | ||||
|   <action name="actionViewSelectedInstFolder"> | ||||
|   | ||||
| @@ -23,27 +23,74 @@ | ||||
| #include <QKeyEvent> | ||||
| #include <QDesktopServices> | ||||
| 
 | ||||
| #include "OneSixModEditDialog.h" | ||||
| #include "ModEditDialogCommon.h" | ||||
| #include "ui_OneSixModEditDialog.h" | ||||
| #include "InstanceEditDialog.h" | ||||
| #include "ui_InstanceEditDialog.h" | ||||
| 
 | ||||
| #include "gui/Platform.h" | ||||
| #include "gui/dialogs/CustomMessageBox.h" | ||||
| #include "gui/dialogs/VersionSelectDialog.h" | ||||
| 
 | ||||
| #include "gui/dialogs/ProgressDialog.h" | ||||
| #include "InstanceSettings.h" | ||||
| 
 | ||||
| #include "logic/ModList.h" | ||||
| #include "logic/VersionFinal.h" | ||||
| #include "logic/EnabledItemFilter.h" | ||||
| #include "logic/lists/ForgeVersionList.h" | ||||
| #include "logic/lists/LiteLoaderVersionList.h" | ||||
| #include "logic/ForgeInstaller.h" | ||||
| #include "logic/LiteLoaderInstaller.h" | ||||
| #include "logic/forge/ForgeVersionList.h" | ||||
| #include "logic/forge/ForgeInstaller.h" | ||||
| #include "logic/liteloader/LiteLoaderVersionList.h" | ||||
| #include "logic/liteloader/LiteLoaderInstaller.h" | ||||
| #include "logic/OneSixVersionBuilder.h" | ||||
| #include "logic/auth/MojangAccountList.h" | ||||
| 
 | ||||
| OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) | ||||
| 	: QDialog(parent), ui(new Ui::OneSixModEditDialog), m_inst(inst) | ||||
| #include <QAbstractItemModel> | ||||
| #include <logic/Mod.h> | ||||
| 
 | ||||
| #include "CustomMessageBox.h" | ||||
| #include <QDesktopServices> | ||||
| #include <QMessageBox> | ||||
| #include <QString> | ||||
| #include <QUrl> | ||||
| 
 | ||||
| bool lastfirst(QModelIndexList &list, int &first, int &last) | ||||
| { | ||||
| 	if (!list.size()) | ||||
| 		return false; | ||||
| 	first = last = list[0].row(); | ||||
| 	for (auto item : list) | ||||
| 	{ | ||||
| 		int row = item.row(); | ||||
| 		if (row < first) | ||||
| 			first = row; | ||||
| 		if (row > last) | ||||
| 			last = row; | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| void showWebsiteForMod(QWidget *parentDlg, Mod &m) | ||||
| { | ||||
| 	QString url = m.homeurl(); | ||||
| 	if (url.size()) | ||||
| 	{ | ||||
| 		// catch the cases where the protocol is missing
 | ||||
| 		if (!url.startsWith("http")) | ||||
| 		{ | ||||
| 			url = "http://" + url; | ||||
| 		} | ||||
| 		QDesktopServices::openUrl(url); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable( | ||||
| 			parentDlg, QObject::tr("How sad!"), | ||||
| 			QObject::tr("The mod author didn't provide a website link for this mod."), | ||||
| 			QMessageBox::Warning); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| InstanceEditDialog::InstanceEditDialog(OneSixInstance *inst, QWidget *parent) | ||||
| 	: QDialog(parent), ui(new Ui::InstanceEditDialog), m_inst(inst) | ||||
| { | ||||
| 	MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	ui->setupUi(this); | ||||
| @@ -58,7 +105,7 @@ OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) | ||||
| 		ui->libraryTreeView->setModel(main_model); | ||||
| 		ui->libraryTreeView->installEventFilter(this); | ||||
| 		connect(ui->libraryTreeView->selectionModel(), &QItemSelectionModel::currentChanged, | ||||
| 				this, &OneSixModEditDialog::versionCurrent); | ||||
| 				this, &InstanceEditDialog::versionCurrent); | ||||
| 		updateVersionControls(); | ||||
| 	} | ||||
| 	else | ||||
| @@ -76,6 +123,17 @@ OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) | ||||
| 		connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), | ||||
| 				SLOT(loaderCurrent(QModelIndex, QModelIndex))); | ||||
| 	} | ||||
| 	// Core mods
 | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->coreModsDir()); | ||||
| 		m_coremods = m_inst->coreModList(); | ||||
| 		ui->coreModsTreeView->setModel(m_coremods.get()); | ||||
| 		ui->coreModsTreeView->installEventFilter(this); | ||||
| 		m_coremods->startWatching(); | ||||
| 		auto smodel = ui->coreModsTreeView->selectionModel(); | ||||
| 		connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), | ||||
| 				SLOT(coreCurrent(QModelIndex, QModelIndex))); | ||||
| 	} | ||||
| 	// resource packs
 | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->resourcePacksDir()); | ||||
| @@ -86,23 +144,24 @@ OneSixModEditDialog::OneSixModEditDialog(OneSixInstance *inst, QWidget *parent) | ||||
| 	} | ||||
| 
 | ||||
| 	connect(m_inst, &OneSixInstance::versionReloaded, this, | ||||
| 			&OneSixModEditDialog::updateVersionControls); | ||||
| 			&InstanceEditDialog::updateVersionControls); | ||||
| } | ||||
| 
 | ||||
| OneSixModEditDialog::~OneSixModEditDialog() | ||||
| InstanceEditDialog::~InstanceEditDialog() | ||||
| { | ||||
| 	m_mods->stopWatching(); | ||||
| 	m_resourcepacks->stopWatching(); | ||||
| 	m_coremods->stopWatching(); | ||||
| 	delete ui; | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::updateVersionControls() | ||||
| void InstanceEditDialog::updateVersionControls() | ||||
| { | ||||
| 	ui->forgeBtn->setEnabled(true); | ||||
| 	ui->liteloaderBtn->setEnabled(true); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::disableVersionControls() | ||||
| void InstanceEditDialog::disableVersionControls() | ||||
| { | ||||
| 	ui->forgeBtn->setEnabled(false); | ||||
| 	ui->liteloaderBtn->setEnabled(false); | ||||
| @@ -110,7 +169,7 @@ void OneSixModEditDialog::disableVersionControls() | ||||
| 	ui->removeLibraryBtn->setEnabled(false); | ||||
| } | ||||
| 
 | ||||
| bool OneSixModEditDialog::reloadInstanceVersion() | ||||
| bool InstanceEditDialog::reloadInstanceVersion() | ||||
| { | ||||
| 	try | ||||
| 	{ | ||||
| @@ -131,12 +190,19 @@ bool OneSixModEditDialog::reloadInstanceVersion() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_reloadLibrariesBtn_clicked() | ||||
| void InstanceEditDialog::on_settingsBtn_clicked() | ||||
| { | ||||
| 	InstanceSettings settings(&m_inst->settings(), this); | ||||
| 	settings.setWindowTitle(tr("Instance settings")); | ||||
| 	settings.exec(); | ||||
| } | ||||
| 
 | ||||
| void InstanceEditDialog::on_reloadLibrariesBtn_clicked() | ||||
| { | ||||
| 	reloadInstanceVersion(); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_removeLibraryBtn_clicked() | ||||
| void InstanceEditDialog::on_removeLibraryBtn_clicked() | ||||
| { | ||||
| 	if (ui->libraryTreeView->currentIndex().isValid()) | ||||
| 	{ | ||||
| @@ -148,7 +214,7 @@ void OneSixModEditDialog::on_removeLibraryBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_resetLibraryOrderBtn_clicked() | ||||
| void InstanceEditDialog::on_resetLibraryOrderBtn_clicked() | ||||
| { | ||||
| 	try | ||||
| 	{ | ||||
| @@ -160,7 +226,7 @@ void OneSixModEditDialog::on_resetLibraryOrderBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_moveLibraryUpBtn_clicked() | ||||
| void InstanceEditDialog::on_moveLibraryUpBtn_clicked() | ||||
| { | ||||
| 	if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) | ||||
| 	{ | ||||
| @@ -178,7 +244,7 @@ void OneSixModEditDialog::on_moveLibraryUpBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_moveLibraryDownBtn_clicked() | ||||
| void InstanceEditDialog::on_moveLibraryDownBtn_clicked() | ||||
| { | ||||
| 	if (ui->libraryTreeView->selectionModel()->selectedRows().isEmpty()) | ||||
| 	{ | ||||
| @@ -196,7 +262,106 @@ void OneSixModEditDialog::on_moveLibraryDownBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_forgeBtn_clicked() | ||||
| // FIXME: use this for legacy forge... or abstract away.
 | ||||
| /*
 | ||||
| void LegacyModEditDialog::on_addForgeBtn_clicked() | ||||
| { | ||||
| 	VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); | ||||
| 	vselect.setFilter(1, m_inst->intendedVersionId()); | ||||
| 	if (vselect.exec() && vselect.selectedVersion()) | ||||
| 	{ | ||||
| 		ForgeVersionPtr forge = | ||||
| 			std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); | ||||
| 		if (!forge) | ||||
| 			return; | ||||
| 		auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename); | ||||
| 		if (entry->stale) | ||||
| 		{ | ||||
| 			NetJob *fjob = new NetJob("Forge download"); | ||||
| 			fjob->addNetAction(CacheDownload::make(forge->universal_url, entry)); | ||||
| 			ProgressDialog dlg(this); | ||||
| 			dlg.exec(fjob); | ||||
| 			if (dlg.result() == QDialog::Accepted) | ||||
| 			{ | ||||
| 				m_jarmods->stopWatching(); | ||||
| 				m_jarmods->installMod(QFileInfo(entry->getFullPath())); | ||||
| 				m_jarmods->startWatching(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// failed to download forge :/
 | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_jarmods->stopWatching(); | ||||
| 			m_jarmods->installMod(QFileInfo(entry->getFullPath())); | ||||
| 			m_jarmods->startWatching(); | ||||
| 		} | ||||
| 	} | ||||
| }*/ | ||||
| 
 | ||||
| void InstanceEditDialog::on_changeMCVersionBtn_clicked() | ||||
| { | ||||
| 	VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"), this); | ||||
| 	if (!vselect.exec() || !vselect.selectedVersion()) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!MMC->accounts()->anyAccountIsValid()) | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable( | ||||
| 			this, tr("Error"), | ||||
| 			tr("MultiMC cannot download Minecraft or update instances unless you have at least " | ||||
| 			   "one account added.\nPlease add your Mojang or Minecraft account."), | ||||
| 			QMessageBox::Warning)->show(); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	if (m_inst->versionIsCustom()) | ||||
| 	{ | ||||
| 		auto result = CustomMessageBox::selectable( | ||||
| 			this, tr("Are you sure?"), | ||||
| 			tr("This will remove any library/version customization you did previously. " | ||||
| 			   "This includes things like Forge install and similar."), | ||||
| 			QMessageBox::Warning, QMessageBox::Ok | QMessageBox::Abort, | ||||
| 			QMessageBox::Abort)->exec(); | ||||
| 
 | ||||
| 		if (result != QMessageBox::Ok) | ||||
| 			return; | ||||
| 		m_version->revertToVanilla(); | ||||
| 		reloadInstanceVersion(); | ||||
| 	} | ||||
| 	m_inst->setIntendedVersionId(vselect.selectedVersion()->descriptor()); | ||||
| 
 | ||||
| 	auto updateTask = m_inst->doUpdate(); | ||||
| 	if (!updateTask) | ||||
| 	{ | ||||
| 		return; | ||||
| 	} | ||||
| 	ProgressDialog tDialog(this); | ||||
| 	connect(updateTask.get(), SIGNAL(failed(QString)), SLOT(onGameUpdateError(QString))); | ||||
| 	tDialog.exec(updateTask.get()); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
| void MainWindow::on_actionChangeInstLWJGLVersion_triggered() | ||||
| { | ||||
| 	if (!m_selectedInstance) | ||||
| 		return; | ||||
| 
 | ||||
| 	LWJGLSelectDialog lselect(this); | ||||
| 	lselect.exec(); | ||||
| 	if (lselect.result() == QDialog::Accepted) | ||||
| 	{ | ||||
|         auto ptr = std::dynamic_pointer_cast<LegacyInstance>(m_selectedInstance); | ||||
|         if(ptr) | ||||
|             ptr->setLWJGLVersion(lselect.selectedVersion()); | ||||
| 	} | ||||
| } | ||||
| */ | ||||
| 
 | ||||
| 
 | ||||
| void InstanceEditDialog::on_forgeBtn_clicked() | ||||
| { | ||||
| 	// FIXME: use actual model, not reloading. Move logic to model.
 | ||||
| 	if (m_version->hasFtbPack()) | ||||
| @@ -210,7 +375,7 @@ void OneSixModEditDialog::on_forgeBtn_clicked() | ||||
| 		m_version->removeFtbPack(); | ||||
| 		reloadInstanceVersion(); | ||||
| 	} | ||||
| 	if (m_version->isCustom()) | ||||
| 	if (m_version->usesLegacyCustomJson()) | ||||
| 	{ | ||||
| 		if (QMessageBox::question(this, tr("Revert?"), | ||||
| 								  tr("This action will remove your custom.json. Continue?")) != | ||||
| @@ -218,7 +383,7 @@ void OneSixModEditDialog::on_forgeBtn_clicked() | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		m_version->revertToBase(); | ||||
| 		m_version->revertToVanilla(); | ||||
| 		reloadInstanceVersion(); | ||||
| 	} | ||||
| 	VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); | ||||
| @@ -232,7 +397,7 @@ void OneSixModEditDialog::on_forgeBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_liteloaderBtn_clicked() | ||||
| void InstanceEditDialog::on_liteloaderBtn_clicked() | ||||
| { | ||||
| 	if (m_version->hasFtbPack()) | ||||
| 	{ | ||||
| @@ -245,7 +410,7 @@ void OneSixModEditDialog::on_liteloaderBtn_clicked() | ||||
| 		m_version->removeFtbPack(); | ||||
| 		reloadInstanceVersion(); | ||||
| 	} | ||||
| 	if (m_version->isCustom()) | ||||
| 	if (m_version->usesLegacyCustomJson()) | ||||
| 	{ | ||||
| 		if (QMessageBox::question(this, tr("Revert?"), | ||||
| 								  tr("This action will remove your custom.json. Continue?")) != | ||||
| @@ -253,7 +418,7 @@ void OneSixModEditDialog::on_liteloaderBtn_clicked() | ||||
| 		{ | ||||
| 			return; | ||||
| 		} | ||||
| 		m_version->revertToBase(); | ||||
| 		m_version->revertToVanilla(); | ||||
| 		reloadInstanceVersion(); | ||||
| 	} | ||||
| 	VersionSelectDialog vselect(MMC->liteloaderlist().get(), tr("Select LiteLoader version"), | ||||
| @@ -268,7 +433,7 @@ void OneSixModEditDialog::on_liteloaderBtn_clicked() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| bool OneSixModEditDialog::loaderListFilter(QKeyEvent *keyEvent) | ||||
| bool InstanceEditDialog::loaderListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| @@ -284,7 +449,23 @@ bool OneSixModEditDialog::loaderListFilter(QKeyEvent *keyEvent) | ||||
| 	return QDialog::eventFilter(ui->loaderModTreeView, keyEvent); | ||||
| } | ||||
| 
 | ||||
| bool OneSixModEditDialog::resourcePackListFilter(QKeyEvent *keyEvent) | ||||
| bool InstanceEditDialog::coreListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| 	case Qt::Key_Delete: | ||||
| 		on_rmCoreBtn_clicked(); | ||||
| 		return true; | ||||
| 	case Qt::Key_Plus: | ||||
| 		on_addCoreBtn_clicked(); | ||||
| 		return true; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return QDialog::eventFilter(ui->coreModsTreeView, keyEvent); | ||||
| } | ||||
| 
 | ||||
| bool InstanceEditDialog::resourcePackListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| @@ -300,7 +481,7 @@ bool OneSixModEditDialog::resourcePackListFilter(QKeyEvent *keyEvent) | ||||
| 	return QDialog::eventFilter(ui->resPackTreeView, keyEvent); | ||||
| } | ||||
| 
 | ||||
| bool OneSixModEditDialog::eventFilter(QObject *obj, QEvent *ev) | ||||
| bool InstanceEditDialog::eventFilter(QObject *obj, QEvent *ev) | ||||
| { | ||||
| 	if (ev->type() != QEvent::KeyPress) | ||||
| 	{ | ||||
| @@ -309,20 +490,22 @@ bool OneSixModEditDialog::eventFilter(QObject *obj, QEvent *ev) | ||||
| 	QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev); | ||||
| 	if (obj == ui->loaderModTreeView) | ||||
| 		return loaderListFilter(keyEvent); | ||||
| 	if (obj == ui->coreModsTreeView) | ||||
| 		return coreListFilter(keyEvent); | ||||
| 	if (obj == ui->resPackTreeView) | ||||
| 		return resourcePackListFilter(keyEvent); | ||||
| 	return QDialog::eventFilter(obj, ev); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_buttonBox_rejected() | ||||
| void InstanceEditDialog::on_buttonBox_rejected() | ||||
| { | ||||
| 	close(); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_addModBtn_clicked() | ||||
| void InstanceEditDialog::on_addModBtn_clicked() | ||||
| { | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames( | ||||
| 		this, QApplication::translate("LegacyModEditDialog", "Select Loader Mods")); | ||||
| 		this, QApplication::translate("InstanceEditDialog", "Select Loader Mods")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_mods->stopWatching(); | ||||
| @@ -330,7 +513,7 @@ void OneSixModEditDialog::on_addModBtn_clicked() | ||||
| 		m_mods->startWatching(); | ||||
| 	} | ||||
| } | ||||
| void OneSixModEditDialog::on_rmModBtn_clicked() | ||||
| void InstanceEditDialog::on_rmModBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); | ||||
| @@ -341,15 +524,44 @@ void OneSixModEditDialog::on_rmModBtn_clicked() | ||||
| 	m_mods->deleteMods(first, last); | ||||
| 	m_mods->startWatching(); | ||||
| } | ||||
| void OneSixModEditDialog::on_viewModBtn_clicked() | ||||
| void InstanceEditDialog::on_viewModBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->loaderModsDir(), true); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::on_addResPackBtn_clicked() | ||||
| void InstanceEditDialog::on_addCoreBtn_clicked() | ||||
| { | ||||
| 	//: Title of core mod selection dialog
 | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Core Mods")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_coremods->stopWatching(); | ||||
| 		m_coremods->installMod(QFileInfo(filename)); | ||||
| 		m_coremods->startWatching(); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void InstanceEditDialog::on_rmCoreBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->coreModsTreeView->selectionModel()->selectedRows(); | ||||
| 
 | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_coremods->stopWatching(); | ||||
| 	m_coremods->deleteMods(first, last); | ||||
| 	m_coremods->startWatching(); | ||||
| } | ||||
| 
 | ||||
| void InstanceEditDialog::on_viewCoreBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->coreModsDir(), true); | ||||
| } | ||||
| 
 | ||||
| void InstanceEditDialog::on_addResPackBtn_clicked() | ||||
| { | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames( | ||||
| 		this, QApplication::translate("LegacyModEditDialog", "Select Resource Packs")); | ||||
| 		this, QApplication::translate("InstanceEditDialog", "Select Resource Packs")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_resourcepacks->stopWatching(); | ||||
| @@ -357,7 +569,7 @@ void OneSixModEditDialog::on_addResPackBtn_clicked() | ||||
| 		m_resourcepacks->startWatching(); | ||||
| 	} | ||||
| } | ||||
| void OneSixModEditDialog::on_rmResPackBtn_clicked() | ||||
| void InstanceEditDialog::on_rmResPackBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->resPackTreeView->selectionModel()->selectedRows(); | ||||
| @@ -368,12 +580,12 @@ void OneSixModEditDialog::on_rmResPackBtn_clicked() | ||||
| 	m_resourcepacks->deleteMods(first, last); | ||||
| 	m_resourcepacks->startWatching(); | ||||
| } | ||||
| void OneSixModEditDialog::on_viewResPackBtn_clicked() | ||||
| void InstanceEditDialog::on_viewResPackBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->resourcePacksDir(), true); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous) | ||||
| void InstanceEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
| @@ -385,7 +597,7 @@ void OneSixModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previou | ||||
| 	ui->frame->updateWithMod(m); | ||||
| } | ||||
| 
 | ||||
| void OneSixModEditDialog::versionCurrent(const QModelIndex ¤t, | ||||
| void InstanceEditDialog::versionCurrent(const QModelIndex ¤t, | ||||
| 										 const QModelIndex &previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| @@ -397,3 +609,15 @@ void OneSixModEditDialog::versionCurrent(const QModelIndex ¤t, | ||||
| 		ui->removeLibraryBtn->setEnabled(m_version->canRemove(current.row())); | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| void InstanceEditDialog::coreCurrent(QModelIndex current, QModelIndex previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
| 		ui->coreMIFrame->clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	int row = current.row(); | ||||
| 	Mod &m = m_coremods->operator[](row); | ||||
| 	ui->coreMIFrame->updateWithMod(m); | ||||
| } | ||||
| @@ -17,59 +17,81 @@ | ||||
| #include <QDialog> | ||||
| 
 | ||||
| #include <logic/OneSixInstance.h> | ||||
| #include <logic/net/NetJob.h> | ||||
| 
 | ||||
| class EnabledItemFilter; | ||||
| namespace Ui | ||||
| { | ||||
| class OneSixModEditDialog; | ||||
| class InstanceEditDialog; | ||||
| } | ||||
| 
 | ||||
| class OneSixModEditDialog : public QDialog | ||||
| class InstanceEditDialog : public QDialog | ||||
| { | ||||
| 	Q_OBJECT | ||||
| 
 | ||||
| public: | ||||
| 	explicit OneSixModEditDialog(OneSixInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~OneSixModEditDialog(); | ||||
| 	explicit InstanceEditDialog(OneSixInstance *inst, QWidget *parent = 0); | ||||
| 	virtual ~InstanceEditDialog(); | ||||
| 
 | ||||
| private | ||||
| slots: | ||||
| 	void on_addModBtn_clicked(); | ||||
| 	void on_rmModBtn_clicked(); | ||||
| 	void on_viewModBtn_clicked(); | ||||
| 
 | ||||
| 	void on_addResPackBtn_clicked(); | ||||
| 	void on_rmResPackBtn_clicked(); | ||||
| 	void on_viewResPackBtn_clicked(); | ||||
| 	// Questionable: SettingsDialog doesn't need this for some reason?
 | ||||
| 	void on_buttonBox_rejected(); | ||||
| 	// version tab
 | ||||
| 	void on_forgeBtn_clicked(); | ||||
| 	void on_liteloaderBtn_clicked(); | ||||
| 	void on_reloadLibrariesBtn_clicked(); | ||||
| 	void on_removeLibraryBtn_clicked(); | ||||
| 	void on_resetLibraryOrderBtn_clicked(); | ||||
| 	void on_settingsBtn_clicked(); | ||||
| 	void on_moveLibraryUpBtn_clicked(); | ||||
| 	void on_moveLibraryDownBtn_clicked(); | ||||
| 
 | ||||
| 	// loader mod tab
 | ||||
| 	void on_addModBtn_clicked(); | ||||
| 	void on_rmModBtn_clicked(); | ||||
| 	void on_viewModBtn_clicked(); | ||||
| 
 | ||||
| 	// core mod tab
 | ||||
| 	void on_addCoreBtn_clicked(); | ||||
| 	void on_rmCoreBtn_clicked(); | ||||
| 	void on_viewCoreBtn_clicked(); | ||||
| 
 | ||||
| 	// resource pack tab
 | ||||
| 	void on_addResPackBtn_clicked(); | ||||
| 	void on_rmResPackBtn_clicked(); | ||||
| 	void on_viewResPackBtn_clicked(); | ||||
| 
 | ||||
| 	 | ||||
| 	// Questionable: SettingsDialog doesn't need this for some reason?
 | ||||
| 	void on_buttonBox_rejected(); | ||||
| 	 | ||||
| 	void updateVersionControls(); | ||||
| 	void disableVersionControls(); | ||||
| 
 | ||||
| 	void on_changeMCVersionBtn_clicked(); | ||||
| 	 | ||||
| protected: | ||||
| 	bool eventFilter(QObject *obj, QEvent *ev); | ||||
| 	bool jarListFilter(QKeyEvent *ev); | ||||
| 	bool loaderListFilter(QKeyEvent *ev); | ||||
| 	bool coreListFilter(QKeyEvent *ev); | ||||
| 	bool resourcePackListFilter(QKeyEvent *ev); | ||||
| 	/// FIXME: this shouldn't be necessary!
 | ||||
| 	bool reloadInstanceVersion(); | ||||
| 
 | ||||
| private: | ||||
| 	Ui::OneSixModEditDialog *ui; | ||||
| 	Ui::InstanceEditDialog *ui; | ||||
| 	std::shared_ptr<VersionFinal> m_version; | ||||
| 	std::shared_ptr<ModList> m_mods; | ||||
| 	std::shared_ptr<ModList> m_coremods; | ||||
| 	std::shared_ptr<ModList> m_jarmods; | ||||
| 	std::shared_ptr<ModList> m_resourcepacks; | ||||
| 	EnabledItemFilter *main_model; | ||||
| 	OneSixInstance *m_inst; | ||||
| 	NetJobPtr forgeJob; | ||||
| 
 | ||||
| public | ||||
| slots: | ||||
| 	void loaderCurrent(QModelIndex current, QModelIndex previous); | ||||
| 	void versionCurrent(const QModelIndex ¤t, const QModelIndex &previous); | ||||
| 	void coreCurrent(QModelIndex current, QModelIndex previous); | ||||
| }; | ||||
| @@ -1,19 +1,29 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>OneSixModEditDialog</class> | ||||
|  <widget class="QDialog" name="OneSixModEditDialog"> | ||||
|  <class>InstanceEditDialog</class> | ||||
|  <widget class="QDialog" name="InstanceEditDialog"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>555</width> | ||||
|     <height>463</height> | ||||
|     <width>593</width> | ||||
|     <height>568</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Manage Mods</string> | ||||
|    <string>Edit Instance</string> | ||||
|   </property> | ||||
|   <layout class="QGridLayout" name="gridLayout"> | ||||
|    <item row="1" column="0"> | ||||
|     <widget class="QDialogButtonBox" name="buttonBox"> | ||||
|      <property name="autoFillBackground"> | ||||
|       <bool>false</bool> | ||||
|      </property> | ||||
|      <property name="standardButtons"> | ||||
|       <set>QDialogButtonBox::Close</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item row="0" column="0"> | ||||
|     <widget class="QTabWidget" name="tabWidget"> | ||||
|      <property name="enabled"> | ||||
| @@ -52,6 +62,13 @@ | ||||
|        </item> | ||||
|        <item> | ||||
|         <layout class="QVBoxLayout" name="verticalLayout_4"> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="changeMCVersionBtn"> | ||||
|            <property name="text"> | ||||
|             <string>Change version</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="forgeBtn"> | ||||
|            <property name="toolTip"> | ||||
| @@ -69,6 +86,13 @@ | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="jarmodBtn"> | ||||
|            <property name="text"> | ||||
|             <string>Add jar mod</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="Line" name="line"> | ||||
|            <property name="orientation"> | ||||
| @@ -127,6 +151,20 @@ | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="Line" name="line_3"> | ||||
|            <property name="orientation"> | ||||
|             <enum>Qt::Horizontal</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="settingsBtn"> | ||||
|            <property name="text"> | ||||
|             <string>Settings</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <spacer name="verticalSpacer_7"> | ||||
|            <property name="orientation"> | ||||
| @@ -144,6 +182,72 @@ | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|      <widget class="QWidget" name="coreTab"> | ||||
|       <attribute name="title"> | ||||
|        <string>Core Mods</string> | ||||
|       </attribute> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||||
|          <item> | ||||
|           <widget class="ModListView" name="coreModsTreeView"> | ||||
|            <property name="dragDropMode"> | ||||
|             <enum>QAbstractItemView::DropOnly</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <layout class="QVBoxLayout" name="coreModsButtonBox"> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="addCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Add</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="rmCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Remove</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <spacer name="coreModsButtonSpacer"> | ||||
|              <property name="orientation"> | ||||
|               <enum>Qt::Vertical</enum> | ||||
|              </property> | ||||
|              <property name="sizeHint" stdset="0"> | ||||
|               <size> | ||||
|                <width>20</width> | ||||
|                <height>40</height> | ||||
|               </size> | ||||
|              </property> | ||||
|             </spacer> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="viewCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&View Folder</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|        <item> | ||||
|         <widget class="MCModInfoFrame" name="coreMIFrame"> | ||||
|          <property name="frameShape"> | ||||
|           <enum>QFrame::StyledPanel</enum> | ||||
|          </property> | ||||
|          <property name="frameShadow"> | ||||
|           <enum>QFrame::Raised</enum> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|      <widget class="QWidget" name="modTab"> | ||||
|       <attribute name="title"> | ||||
|        <string>Loader Mods</string> | ||||
| @@ -280,16 +384,6 @@ | ||||
|      </widget> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item row="1" column="0"> | ||||
|     <widget class="QDialogButtonBox" name="buttonBox"> | ||||
|      <property name="autoFillBackground"> | ||||
|       <bool>false</bool> | ||||
|      </property> | ||||
|      <property name="standardButtons"> | ||||
|       <set>QDialogButtonBox::Close</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <customwidgets> | ||||
| @@ -1,393 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #include "MultiMC.h" | ||||
| #include "LegacyModEditDialog.h" | ||||
| #include "ModEditDialogCommon.h" | ||||
| #include "VersionSelectDialog.h" | ||||
| #include "ProgressDialog.h" | ||||
| #include "ui_LegacyModEditDialog.h" | ||||
| #include "logic/ModList.h" | ||||
| #include "logic/lists/ForgeVersionList.h" | ||||
| #include "gui/Platform.h" | ||||
|  | ||||
| #include <pathutils.h> | ||||
| #include <QFileDialog> | ||||
| //#include <QMessageBox> | ||||
| #include <QDebug> | ||||
| #include <QEvent> | ||||
| #include <QKeyEvent> | ||||
|  | ||||
| LegacyModEditDialog::LegacyModEditDialog(LegacyInstance *inst, QWidget *parent) | ||||
| 	: QDialog(parent), ui(new Ui::LegacyModEditDialog), m_inst(inst) | ||||
| { | ||||
| 	MultiMCPlatform::fixWM_CLASS(this); | ||||
| 	ui->setupUi(this); | ||||
|  | ||||
| 	// Jar mods | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->jarModsDir()); | ||||
| 		m_jarmods = m_inst->jarModList(); | ||||
| 		ui->jarModsTreeView->setModel(m_jarmods.get()); | ||||
| #ifndef Q_OS_LINUX | ||||
| 		// FIXME: internal DnD causes segfaults later | ||||
| 		ui->jarModsTreeView->setDragDropMode(QAbstractItemView::DragDrop); | ||||
| 		// FIXME: DnD is glitched with contiguous (we move only first item in selection) | ||||
| 		ui->jarModsTreeView->setSelectionMode(QAbstractItemView::SingleSelection); | ||||
| #endif | ||||
| 		ui->jarModsTreeView->installEventFilter(this); | ||||
| 		m_jarmods->startWatching(); | ||||
| 		auto smodel = ui->jarModsTreeView->selectionModel(); | ||||
| 		connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), | ||||
| 				SLOT(jarCurrent(QModelIndex, QModelIndex))); | ||||
| 	} | ||||
| 	// Core mods | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->coreModsDir()); | ||||
| 		m_coremods = m_inst->coreModList(); | ||||
| 		ui->coreModsTreeView->setModel(m_coremods.get()); | ||||
| 		ui->coreModsTreeView->installEventFilter(this); | ||||
| 		m_coremods->startWatching(); | ||||
| 		auto smodel = ui->coreModsTreeView->selectionModel(); | ||||
| 		connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), | ||||
| 				SLOT(coreCurrent(QModelIndex, QModelIndex))); | ||||
| 	} | ||||
| 	// Loader mods | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->loaderModsDir()); | ||||
| 		m_mods = m_inst->loaderModList(); | ||||
| 		ui->loaderModTreeView->setModel(m_mods.get()); | ||||
| 		ui->loaderModTreeView->installEventFilter(this); | ||||
| 		m_mods->startWatching(); | ||||
| 		auto smodel = ui->loaderModTreeView->selectionModel(); | ||||
| 		connect(smodel, SIGNAL(currentChanged(QModelIndex, QModelIndex)), | ||||
| 				SLOT(loaderCurrent(QModelIndex, QModelIndex))); | ||||
| 	} | ||||
| 	// texture packs | ||||
| 	{ | ||||
| 		ensureFolderPathExists(m_inst->texturePacksDir()); | ||||
| 		m_texturepacks = m_inst->texturePackList(); | ||||
| 		ui->texPackTreeView->setModel(m_texturepacks.get()); | ||||
| 		ui->texPackTreeView->installEventFilter(this); | ||||
| 		m_texturepacks->startWatching(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| LegacyModEditDialog::~LegacyModEditDialog() | ||||
| { | ||||
| 	m_mods->stopWatching(); | ||||
| 	m_coremods->stopWatching(); | ||||
| 	m_jarmods->stopWatching(); | ||||
| 	m_texturepacks->stopWatching(); | ||||
| 	delete ui; | ||||
| } | ||||
|  | ||||
| bool LegacyModEditDialog::coreListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| 	case Qt::Key_Delete: | ||||
| 		on_rmCoreBtn_clicked(); | ||||
| 		return true; | ||||
| 	case Qt::Key_Plus: | ||||
| 		on_addCoreBtn_clicked(); | ||||
| 		return true; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return QDialog::eventFilter(ui->coreModsTreeView, keyEvent); | ||||
| } | ||||
|  | ||||
| bool LegacyModEditDialog::jarListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| 	case Qt::Key_Up: | ||||
| 	{ | ||||
| 		if (keyEvent->modifiers() & Qt::ControlModifier) | ||||
| 		{ | ||||
| 			on_moveJarUpBtn_clicked(); | ||||
| 			return true; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	case Qt::Key_Down: | ||||
| 	{ | ||||
| 		if (keyEvent->modifiers() & Qt::ControlModifier) | ||||
| 		{ | ||||
| 			on_moveJarDownBtn_clicked(); | ||||
| 			return true; | ||||
| 		} | ||||
| 		break; | ||||
| 	} | ||||
| 	case Qt::Key_Delete: | ||||
| 		on_rmJarBtn_clicked(); | ||||
| 		return true; | ||||
| 	case Qt::Key_Plus: | ||||
| 		on_addJarBtn_clicked(); | ||||
| 		return true; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return QDialog::eventFilter(ui->jarModsTreeView, keyEvent); | ||||
| } | ||||
|  | ||||
| bool LegacyModEditDialog::loaderListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| 	case Qt::Key_Delete: | ||||
| 		on_rmModBtn_clicked(); | ||||
| 		return true; | ||||
| 	case Qt::Key_Plus: | ||||
| 		on_addModBtn_clicked(); | ||||
| 		return true; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return QDialog::eventFilter(ui->loaderModTreeView, keyEvent); | ||||
| } | ||||
|  | ||||
| bool LegacyModEditDialog::texturePackListFilter(QKeyEvent *keyEvent) | ||||
| { | ||||
| 	switch (keyEvent->key()) | ||||
| 	{ | ||||
| 	case Qt::Key_Delete: | ||||
| 		on_rmTexPackBtn_clicked(); | ||||
| 		return true; | ||||
| 	case Qt::Key_Plus: | ||||
| 		on_addTexPackBtn_clicked(); | ||||
| 		return true; | ||||
| 	default: | ||||
| 		break; | ||||
| 	} | ||||
| 	return QDialog::eventFilter(ui->texPackTreeView, keyEvent); | ||||
| } | ||||
|  | ||||
| bool LegacyModEditDialog::eventFilter(QObject *obj, QEvent *ev) | ||||
| { | ||||
| 	if (ev->type() != QEvent::KeyPress) | ||||
| 	{ | ||||
| 		return QDialog::eventFilter(obj, ev); | ||||
| 	} | ||||
| 	QKeyEvent *keyEvent = static_cast<QKeyEvent *>(ev); | ||||
| 	if (obj == ui->jarModsTreeView) | ||||
| 		return jarListFilter(keyEvent); | ||||
| 	if (obj == ui->coreModsTreeView) | ||||
| 		return coreListFilter(keyEvent); | ||||
| 	if (obj == ui->loaderModTreeView) | ||||
| 		return loaderListFilter(keyEvent); | ||||
| 	if (obj == ui->texPackTreeView) | ||||
| 		return texturePackListFilter(keyEvent); | ||||
| 	return QDialog::eventFilter(obj, ev); | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::on_addCoreBtn_clicked() | ||||
| { | ||||
| 	//: Title of core mod selection dialog | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Core Mods")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_coremods->stopWatching(); | ||||
| 		m_coremods->installMod(QFileInfo(filename)); | ||||
| 		m_coremods->startWatching(); | ||||
| 	} | ||||
| } | ||||
| void LegacyModEditDialog::on_addForgeBtn_clicked() | ||||
| { | ||||
| 	VersionSelectDialog vselect(MMC->forgelist().get(), tr("Select Forge version"), this); | ||||
| 	vselect.setExactFilter(1, m_inst->intendedVersionId()); | ||||
| 	if (vselect.exec() && vselect.selectedVersion()) | ||||
| 	{ | ||||
| 		ForgeVersionPtr forge = | ||||
| 			std::dynamic_pointer_cast<ForgeVersion>(vselect.selectedVersion()); | ||||
| 		if (!forge) | ||||
| 			return; | ||||
| 		auto entry = MMC->metacache()->resolveEntry("minecraftforge", forge->filename); | ||||
| 		if (entry->stale) | ||||
| 		{ | ||||
| 			NetJob *fjob = new NetJob("Forge download"); | ||||
| 			fjob->addNetAction(CacheDownload::make(forge->universal_url, entry)); | ||||
| 			ProgressDialog dlg(this); | ||||
| 			dlg.exec(fjob); | ||||
| 			if (dlg.result() == QDialog::Accepted) | ||||
| 			{ | ||||
| 				m_jarmods->stopWatching(); | ||||
| 				m_jarmods->installMod(QFileInfo(entry->getFullPath())); | ||||
| 				m_jarmods->startWatching(); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				// failed to download forge :/ | ||||
| 			} | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_jarmods->stopWatching(); | ||||
| 			m_jarmods->installMod(QFileInfo(entry->getFullPath())); | ||||
| 			m_jarmods->startWatching(); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| void LegacyModEditDialog::on_addJarBtn_clicked() | ||||
| { | ||||
| 	//: Title of jar mod selection dialog | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Jar Mods")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_jarmods->stopWatching(); | ||||
| 		m_jarmods->installMod(QFileInfo(filename)); | ||||
| 		m_jarmods->startWatching(); | ||||
| 	} | ||||
| } | ||||
| void LegacyModEditDialog::on_addModBtn_clicked() | ||||
| { | ||||
| 	//: Title of regular mod selection dialog | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Loader Mods")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_mods->stopWatching(); | ||||
| 		m_mods->installMod(QFileInfo(filename)); | ||||
| 		m_mods->startWatching(); | ||||
| 	} | ||||
| } | ||||
| void LegacyModEditDialog::on_addTexPackBtn_clicked() | ||||
| { | ||||
| 	//: Title of texture pack selection dialog | ||||
| 	QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Select Texture Packs")); | ||||
| 	for (auto filename : fileNames) | ||||
| 	{ | ||||
| 		m_texturepacks->stopWatching(); | ||||
| 		m_texturepacks->installMod(QFileInfo(filename)); | ||||
| 		m_texturepacks->startWatching(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::on_moveJarDownBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
|  | ||||
| 	m_jarmods->moveModsDown(first, last); | ||||
| } | ||||
| void LegacyModEditDialog::on_moveJarUpBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_jarmods->moveModsUp(first, last); | ||||
| } | ||||
| void LegacyModEditDialog::on_rmCoreBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->coreModsTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_coremods->stopWatching(); | ||||
| 	m_coremods->deleteMods(first, last); | ||||
| 	m_coremods->startWatching(); | ||||
| } | ||||
| void LegacyModEditDialog::on_rmJarBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->jarModsTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_jarmods->stopWatching(); | ||||
| 	m_jarmods->deleteMods(first, last); | ||||
| 	m_jarmods->startWatching(); | ||||
| } | ||||
| void LegacyModEditDialog::on_rmModBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->loaderModTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_mods->stopWatching(); | ||||
| 	m_mods->deleteMods(first, last); | ||||
| 	m_mods->startWatching(); | ||||
| } | ||||
| void LegacyModEditDialog::on_rmTexPackBtn_clicked() | ||||
| { | ||||
| 	int first, last; | ||||
| 	auto list = ui->texPackTreeView->selectionModel()->selectedRows(); | ||||
|  | ||||
| 	if (!lastfirst(list, first, last)) | ||||
| 		return; | ||||
| 	m_texturepacks->stopWatching(); | ||||
| 	m_texturepacks->deleteMods(first, last); | ||||
| 	m_texturepacks->startWatching(); | ||||
| } | ||||
| void LegacyModEditDialog::on_viewCoreBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->coreModsDir(), true); | ||||
| } | ||||
| void LegacyModEditDialog::on_viewModBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->loaderModsDir(), true); | ||||
| } | ||||
| void LegacyModEditDialog::on_viewTexPackBtn_clicked() | ||||
| { | ||||
| 	openDirInDefaultProgram(m_inst->texturePacksDir(), true); | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::on_buttonBox_rejected() | ||||
| { | ||||
| 	close(); | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::jarCurrent(QModelIndex current, QModelIndex previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
| 		ui->jarMIFrame->clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	int row = current.row(); | ||||
| 	Mod &m = m_jarmods->operator[](row); | ||||
| 	ui->jarMIFrame->updateWithMod(m); | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::coreCurrent(QModelIndex current, QModelIndex previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
| 		ui->coreMIFrame->clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	int row = current.row(); | ||||
| 	Mod &m = m_coremods->operator[](row); | ||||
| 	ui->coreMIFrame->updateWithMod(m); | ||||
| } | ||||
|  | ||||
| void LegacyModEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous) | ||||
| { | ||||
| 	if (!current.isValid()) | ||||
| 	{ | ||||
| 		ui->loaderMIFrame->clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	int row = current.row(); | ||||
| 	Mod &m = m_mods->operator[](row); | ||||
| 	ui->loaderMIFrame->updateWithMod(m); | ||||
| } | ||||
| @@ -1,78 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <QDialog> | ||||
| #include "logic/LegacyInstance.h" | ||||
| #include <logic/net/NetJob.h> | ||||
|  | ||||
| namespace Ui | ||||
| { | ||||
| class LegacyModEditDialog; | ||||
| } | ||||
|  | ||||
| class LegacyModEditDialog : public QDialog | ||||
| { | ||||
| 	Q_OBJECT | ||||
|  | ||||
| public: | ||||
| 	explicit LegacyModEditDialog(LegacyInstance *inst, QWidget *parent = 0); | ||||
| 	~LegacyModEditDialog(); | ||||
|  | ||||
| private | ||||
| slots: | ||||
|  | ||||
| 	void on_addJarBtn_clicked(); | ||||
| 	void on_rmJarBtn_clicked(); | ||||
| 	void on_addForgeBtn_clicked(); | ||||
| 	void on_moveJarUpBtn_clicked(); | ||||
| 	void on_moveJarDownBtn_clicked(); | ||||
|  | ||||
| 	void on_addCoreBtn_clicked(); | ||||
| 	void on_rmCoreBtn_clicked(); | ||||
| 	void on_viewCoreBtn_clicked(); | ||||
|  | ||||
| 	void on_addModBtn_clicked(); | ||||
| 	void on_rmModBtn_clicked(); | ||||
| 	void on_viewModBtn_clicked(); | ||||
|  | ||||
| 	void on_addTexPackBtn_clicked(); | ||||
| 	void on_rmTexPackBtn_clicked(); | ||||
| 	void on_viewTexPackBtn_clicked(); | ||||
|  | ||||
| 	// Questionable: SettingsDialog doesn't need this for some reason? | ||||
| 	void on_buttonBox_rejected(); | ||||
|  | ||||
| 	void jarCurrent(QModelIndex current, QModelIndex previous); | ||||
| 	void coreCurrent(QModelIndex current, QModelIndex previous); | ||||
| 	void loaderCurrent(QModelIndex current, QModelIndex previous); | ||||
|  | ||||
| protected: | ||||
| 	bool eventFilter(QObject *obj, QEvent *ev); | ||||
| 	bool jarListFilter(QKeyEvent *ev); | ||||
| 	bool coreListFilter(QKeyEvent *ev); | ||||
| 	bool loaderListFilter(QKeyEvent *ev); | ||||
| 	bool texturePackListFilter(QKeyEvent *ev); | ||||
|  | ||||
| private: | ||||
| 	Ui::LegacyModEditDialog *ui; | ||||
| 	std::shared_ptr<ModList> m_mods; | ||||
| 	std::shared_ptr<ModList> m_coremods; | ||||
| 	std::shared_ptr<ModList> m_jarmods; | ||||
| 	std::shared_ptr<ModList> m_texturepacks; | ||||
| 	LegacyInstance *m_inst; | ||||
| 	NetJobPtr forgeJob; | ||||
| }; | ||||
| @@ -1,321 +0,0 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <ui version="4.0"> | ||||
|  <class>LegacyModEditDialog</class> | ||||
|  <widget class="QDialog" name="LegacyModEditDialog"> | ||||
|   <property name="geometry"> | ||||
|    <rect> | ||||
|     <x>0</x> | ||||
|     <y>0</y> | ||||
|     <width>540</width> | ||||
|     <height>420</height> | ||||
|    </rect> | ||||
|   </property> | ||||
|   <property name="windowTitle"> | ||||
|    <string>Edit Mods</string> | ||||
|   </property> | ||||
|   <layout class="QVBoxLayout" name="verticalLayout"> | ||||
|    <item> | ||||
|     <widget class="QTabWidget" name="tabWidget"> | ||||
|      <property name="currentIndex"> | ||||
|       <number>0</number> | ||||
|      </property> | ||||
|      <widget class="QWidget" name="jarTab"> | ||||
|       <attribute name="title"> | ||||
|        <string>Jar Mods</string> | ||||
|       </attribute> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_2"> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout"> | ||||
|          <item> | ||||
|           <widget class="ModListView" name="jarModsTreeView"> | ||||
|            <property name="verticalScrollBarPolicy"> | ||||
|             <enum>Qt::ScrollBarAlwaysOn</enum> | ||||
|            </property> | ||||
|            <property name="horizontalScrollBarPolicy"> | ||||
|             <enum>Qt::ScrollBarAlwaysOff</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <layout class="QVBoxLayout" name="jarModsButtonBox"> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="addJarBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Add</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="rmJarBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Remove</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="addForgeBtn"> | ||||
|              <property name="text"> | ||||
|               <string>MCForge</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <spacer name="jarModsButtonSpacer"> | ||||
|              <property name="orientation"> | ||||
|               <enum>Qt::Vertical</enum> | ||||
|              </property> | ||||
|              <property name="sizeHint" stdset="0"> | ||||
|               <size> | ||||
|                <width>20</width> | ||||
|                <height>40</height> | ||||
|               </size> | ||||
|              </property> | ||||
|             </spacer> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="moveJarUpBtn"> | ||||
|              <property name="text"> | ||||
|               <string>Move &Up</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="moveJarDownBtn"> | ||||
|              <property name="text"> | ||||
|               <string>Move &Down</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|        <item> | ||||
|         <widget class="MCModInfoFrame" name="jarMIFrame"> | ||||
|          <property name="frameShadow"> | ||||
|           <enum>QFrame::Plain</enum> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|      <widget class="QWidget" name="coreTab"> | ||||
|       <attribute name="title"> | ||||
|        <string>Core Mods</string> | ||||
|       </attribute> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_3"> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout_3"> | ||||
|          <item> | ||||
|           <widget class="ModListView" name="coreModsTreeView"> | ||||
|            <property name="dragDropMode"> | ||||
|             <enum>QAbstractItemView::DropOnly</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <layout class="QVBoxLayout" name="coreModsButtonBox"> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="addCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Add</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="rmCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Remove</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <spacer name="coreModsButtonSpacer"> | ||||
|              <property name="orientation"> | ||||
|               <enum>Qt::Vertical</enum> | ||||
|              </property> | ||||
|              <property name="sizeHint" stdset="0"> | ||||
|               <size> | ||||
|                <width>20</width> | ||||
|                <height>40</height> | ||||
|               </size> | ||||
|              </property> | ||||
|             </spacer> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="viewCoreBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&View Folder</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|        <item> | ||||
|         <widget class="MCModInfoFrame" name="coreMIFrame"> | ||||
|          <property name="frameShape"> | ||||
|           <enum>QFrame::StyledPanel</enum> | ||||
|          </property> | ||||
|          <property name="frameShadow"> | ||||
|           <enum>QFrame::Raised</enum> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|      <widget class="QWidget" name="modTab"> | ||||
|       <attribute name="title"> | ||||
|        <string>Loader Mods</string> | ||||
|       </attribute> | ||||
|       <layout class="QVBoxLayout" name="verticalLayout_4"> | ||||
|        <item> | ||||
|         <layout class="QHBoxLayout" name="horizontalLayout_2"> | ||||
|          <item> | ||||
|           <widget class="ModListView" name="loaderModTreeView"> | ||||
|            <property name="acceptDrops"> | ||||
|             <bool>true</bool> | ||||
|            </property> | ||||
|            <property name="dragDropMode"> | ||||
|             <enum>QAbstractItemView::DropOnly</enum> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <layout class="QVBoxLayout" name="mlModsButtonBox"> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="addModBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Add</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="rmModBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&Remove</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|            <item> | ||||
|             <spacer name="mlModsButtonSpacer"> | ||||
|              <property name="orientation"> | ||||
|               <enum>Qt::Vertical</enum> | ||||
|              </property> | ||||
|              <property name="sizeHint" stdset="0"> | ||||
|               <size> | ||||
|                <width>20</width> | ||||
|                <height>40</height> | ||||
|               </size> | ||||
|              </property> | ||||
|             </spacer> | ||||
|            </item> | ||||
|            <item> | ||||
|             <widget class="QPushButton" name="viewModBtn"> | ||||
|              <property name="text"> | ||||
|               <string>&View Folder</string> | ||||
|              </property> | ||||
|             </widget> | ||||
|            </item> | ||||
|           </layout> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|        <item> | ||||
|         <widget class="MCModInfoFrame" name="loaderMIFrame"> | ||||
|          <property name="frameShape"> | ||||
|           <enum>QFrame::StyledPanel</enum> | ||||
|          </property> | ||||
|          <property name="frameShadow"> | ||||
|           <enum>QFrame::Raised</enum> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|      <widget class="QWidget" name="texPackTab"> | ||||
|       <property name="acceptDrops"> | ||||
|        <bool>false</bool> | ||||
|       </property> | ||||
|       <attribute name="title"> | ||||
|        <string>Texture Packs</string> | ||||
|       </attribute> | ||||
|       <layout class="QHBoxLayout" name="horizontalLayout_4"> | ||||
|        <item> | ||||
|         <widget class="ModListView" name="texPackTreeView"> | ||||
|          <property name="acceptDrops"> | ||||
|           <bool>true</bool> | ||||
|          </property> | ||||
|          <property name="dragDropMode"> | ||||
|           <enum>QAbstractItemView::DropOnly</enum> | ||||
|          </property> | ||||
|         </widget> | ||||
|        </item> | ||||
|        <item> | ||||
|         <layout class="QVBoxLayout" name="texturePacksButtonBox"> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="addTexPackBtn"> | ||||
|            <property name="text"> | ||||
|             <string>&Add</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="rmTexPackBtn"> | ||||
|            <property name="text"> | ||||
|             <string>&Remove</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|          <item> | ||||
|           <spacer name="texturePacksButtonSpacer"> | ||||
|            <property name="orientation"> | ||||
|             <enum>Qt::Vertical</enum> | ||||
|            </property> | ||||
|            <property name="sizeHint" stdset="0"> | ||||
|             <size> | ||||
|              <width>20</width> | ||||
|              <height>40</height> | ||||
|             </size> | ||||
|            </property> | ||||
|           </spacer> | ||||
|          </item> | ||||
|          <item> | ||||
|           <widget class="QPushButton" name="viewTexPackBtn"> | ||||
|            <property name="text"> | ||||
|             <string>&View Folder</string> | ||||
|            </property> | ||||
|           </widget> | ||||
|          </item> | ||||
|         </layout> | ||||
|        </item> | ||||
|       </layout> | ||||
|      </widget> | ||||
|     </widget> | ||||
|    </item> | ||||
|    <item> | ||||
|     <widget class="QDialogButtonBox" name="buttonBox"> | ||||
|      <property name="standardButtons"> | ||||
|       <set>QDialogButtonBox::Close</set> | ||||
|      </property> | ||||
|     </widget> | ||||
|    </item> | ||||
|   </layout> | ||||
|  </widget> | ||||
|  <customwidgets> | ||||
|   <customwidget> | ||||
|    <class>ModListView</class> | ||||
|    <extends>QTreeView</extends> | ||||
|    <header>gui/widgets/ModListView.h</header> | ||||
|   </customwidget> | ||||
|   <customwidget> | ||||
|    <class>MCModInfoFrame</class> | ||||
|    <extends>QFrame</extends> | ||||
|    <header>gui/widgets/MCModInfoFrame.h</header> | ||||
|    <container>1</container> | ||||
|   </customwidget> | ||||
|  </customwidgets> | ||||
|  <resources/> | ||||
|  <connections/> | ||||
| </ui> | ||||
| @@ -1,57 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #include "ModEditDialogCommon.h" | ||||
| #include "CustomMessageBox.h" | ||||
| #include <QDesktopServices> | ||||
| #include <QMessageBox> | ||||
| #include <QString> | ||||
| #include <QUrl> | ||||
| bool lastfirst(QModelIndexList &list, int &first, int &last) | ||||
| { | ||||
| 	if (!list.size()) | ||||
| 		return false; | ||||
| 	first = last = list[0].row(); | ||||
| 	for (auto item : list) | ||||
| 	{ | ||||
| 		int row = item.row(); | ||||
| 		if (row < first) | ||||
| 			first = row; | ||||
| 		if (row > last) | ||||
| 			last = row; | ||||
| 	} | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| void showWebsiteForMod(QWidget *parentDlg, Mod &m) | ||||
| { | ||||
| 	QString url = m.homeurl(); | ||||
| 	if (url.size()) | ||||
| 	{ | ||||
| 		// catch the cases where the protocol is missing | ||||
| 		if (!url.startsWith("http")) | ||||
| 		{ | ||||
| 			url = "http://" + url; | ||||
| 		} | ||||
| 		QDesktopServices::openUrl(url); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		CustomMessageBox::selectable( | ||||
| 			parentDlg, QObject::tr("How sad!"), | ||||
| 			QObject::tr("The mod author didn't provide a website link for this mod."), | ||||
| 			QMessageBox::Warning); | ||||
| 	} | ||||
| } | ||||
| @@ -1,22 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
| #include <QAbstractItemModel> | ||||
| #include <logic/Mod.h> | ||||
|  | ||||
| bool lastfirst(QModelIndexList &list, int &first, int &last); | ||||
|  | ||||
| void showWebsiteForMod(QWidget *parentDlg, Mod &m); | ||||
| @@ -29,7 +29,7 @@ class BaseInstaller | ||||
| { | ||||
| public: | ||||
| 	BaseInstaller(); | ||||
|  | ||||
| 	virtual ~BaseInstaller(){}; | ||||
| 	bool isApplied(OneSixInstance *on); | ||||
|  | ||||
| 	virtual bool add(OneSixInstance *to); | ||||
|   | ||||
| @@ -16,6 +16,8 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include <memory> | ||||
| #include <QString> | ||||
| #include <QMetaType> | ||||
|  | ||||
| /*! | ||||
|  * An abstract base class for versions. | ||||
| @@ -52,4 +54,4 @@ struct BaseVersion | ||||
|  | ||||
| typedef std::shared_ptr<BaseVersion> BaseVersionPtr; | ||||
|  | ||||
| Q_DECLARE_METATYPE(BaseVersionPtr) | ||||
| Q_DECLARE_METATYPE(BaseVersionPtr) | ||||
|   | ||||
| @@ -23,7 +23,6 @@ | ||||
| #include "LegacyFTBInstance.h" | ||||
| #include "OneSixInstance.h" | ||||
| #include "OneSixFTBInstance.h" | ||||
| #include "NostalgiaInstance.h" | ||||
| #include "OneSixInstance.h" | ||||
| #include "BaseVersion.h" | ||||
| #include "MinecraftVersion.h" | ||||
| @@ -51,7 +50,7 @@ InstanceFactory::InstLoadError InstanceFactory::loadInstance(InstancePtr &inst, | ||||
| 	QString inst_type = m_settings->get("InstanceType").toString(); | ||||
|  | ||||
| 	// FIXME: replace with a map lookup, where instance classes register their types | ||||
| 	if (inst_type == "OneSix") | ||||
| 	if (inst_type == "OneSix" || inst_type == "Nostalgia") | ||||
| 	{ | ||||
| 		inst.reset(new OneSixInstance(instDir, m_settings, this)); | ||||
| 	} | ||||
| @@ -59,10 +58,6 @@ InstanceFactory::InstLoadError InstanceFactory::loadInstance(InstancePtr &inst, | ||||
| 	{ | ||||
| 		inst.reset(new LegacyInstance(instDir, m_settings, this)); | ||||
| 	} | ||||
| 	else if (inst_type == "Nostalgia") | ||||
| 	{ | ||||
| 		inst.reset(new NostalgiaInstance(instDir, m_settings, this)); | ||||
| 	} | ||||
| 	else if (inst_type == "LegacyFTB") | ||||
| 	{ | ||||
| 		inst.reset(new LegacyFTBInstance(instDir, m_settings, this)); | ||||
| @@ -98,55 +93,26 @@ InstanceFactory::InstCreateError InstanceFactory::createInstance(InstancePtr &in | ||||
|  | ||||
| 	if (type == NormalInst) | ||||
| 	{ | ||||
| 		switch (mcVer->type) | ||||
| 		{ | ||||
| 		case MinecraftVersion::Legacy: | ||||
| 			// TODO new instance type | ||||
| 			m_settings->set("InstanceType", "Legacy"); | ||||
| 			inst.reset(new LegacyInstance(instDir, m_settings, this)); | ||||
| 			inst->setIntendedVersionId(version->descriptor()); | ||||
| 			inst->setShouldUseCustomBaseJar(false); | ||||
| 			break; | ||||
| 		case MinecraftVersion::OneSix: | ||||
| 			m_settings->set("InstanceType", "OneSix"); | ||||
| 			inst.reset(new OneSixInstance(instDir, m_settings, this)); | ||||
| 			inst->setIntendedVersionId(version->descriptor()); | ||||
| 			inst->setShouldUseCustomBaseJar(false); | ||||
| 			break; | ||||
| 		case MinecraftVersion::Nostalgia: | ||||
| 			m_settings->set("InstanceType", "Nostalgia"); | ||||
| 			inst.reset(new NostalgiaInstance(instDir, m_settings, this)); | ||||
| 			inst->setIntendedVersionId(version->descriptor()); | ||||
| 			inst->setShouldUseCustomBaseJar(false); | ||||
| 			break; | ||||
| 		default: | ||||
| 		{ | ||||
| 			delete m_settings; | ||||
| 			return InstanceFactory::NoSuchVersion; | ||||
| 		} | ||||
| 		} | ||||
| 		m_settings->set("InstanceType", "OneSix"); | ||||
| 		inst.reset(new OneSixInstance(instDir, m_settings, this)); | ||||
| 		inst->setIntendedVersionId(version->descriptor()); | ||||
| 		inst->setShouldUseCustomBaseJar(false); | ||||
| 	} | ||||
| 	else if (type == FTBInstance) | ||||
| 	{ | ||||
| 		switch (mcVer->type) | ||||
| 		if(mcVer->usesLegacyLauncher()) | ||||
| 		{ | ||||
| 		case MinecraftVersion::Legacy: | ||||
| 			m_settings->set("InstanceType", "LegacyFTB"); | ||||
| 			inst.reset(new LegacyFTBInstance(instDir, m_settings, this)); | ||||
| 			inst->setIntendedVersionId(version->descriptor()); | ||||
| 			inst->setShouldUseCustomBaseJar(false); | ||||
| 			break; | ||||
| 		case MinecraftVersion::OneSix: | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			m_settings->set("InstanceType", "OneSixFTB"); | ||||
| 			inst.reset(new OneSixFTBInstance(instDir, m_settings, this)); | ||||
| 			inst->setIntendedVersionId(version->descriptor()); | ||||
| 			inst->setShouldUseCustomBaseJar(false); | ||||
| 			break; | ||||
| 		default: | ||||
| 		{ | ||||
| 			delete m_settings; | ||||
| 			return InstanceFactory::NoSuchVersion; | ||||
| 		} | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
|   | ||||
| @@ -29,8 +29,6 @@ | ||||
| #include "logic/LegacyUpdate.h" | ||||
| #include "logic/icons/IconList.h" | ||||
|  | ||||
| #include "gui/dialogs/LegacyModEditDialog.h" | ||||
|  | ||||
| LegacyInstance::LegacyInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 							   QObject *parent) | ||||
| 	: BaseInstance(new LegacyInstancePrivate(), rootDir, settings, parent) | ||||
| @@ -138,7 +136,7 @@ std::shared_ptr<ModList> LegacyInstance::texturePackList() | ||||
|  | ||||
| QDialog *LegacyInstance::createModEditDialog(QWidget *parent) | ||||
| { | ||||
| 	return new LegacyModEditDialog(this, parent); | ||||
| 	return nullptr; | ||||
| } | ||||
|  | ||||
| QString LegacyInstance::jarModsDir() const | ||||
| @@ -280,10 +278,7 @@ QString LegacyInstance::getStatusbarDescription() | ||||
| { | ||||
| 	if (flags().contains(VersionBrokenFlag)) | ||||
| 	{ | ||||
| 		return "Legacy : " + intendedVersionId() + " (broken)"; | ||||
| 		return tr("Legacy : %1 (broken)").arg(intendedVersionId()); | ||||
| 	} | ||||
| 	if (shouldUpdate()) | ||||
| 		return "Legacy : " + currentVersionId() + " -> " + intendedVersionId(); | ||||
| 	else | ||||
| 		return "Legacy : " + currentVersionId(); | ||||
| 	return tr("Legacy : %1").arg(intendedVersionId()); | ||||
| } | ||||
|   | ||||
| @@ -30,52 +30,6 @@ | ||||
|  | ||||
| LegacyUpdate::LegacyUpdate(BaseInstance *inst, QObject *parent) : Task(parent), m_inst(inst) | ||||
| { | ||||
| 	// 1.3 - 1.3.2 | ||||
| 	auto libs13 = QList<FMLlib>{ | ||||
| 		{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false}, | ||||
| 		{"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false}, | ||||
| 		{"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.3.2"] = libs13; | ||||
|  | ||||
| 	auto libs14 = QList<FMLlib>{ | ||||
| 		{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false}, | ||||
| 		{"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false}, | ||||
| 		{"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}, | ||||
| 		{"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.4"] = libs14; | ||||
| 	fmlLibsMapping["1.4.1"] = libs14; | ||||
| 	fmlLibsMapping["1.4.2"] = libs14; | ||||
| 	fmlLibsMapping["1.4.3"] = libs14; | ||||
| 	fmlLibsMapping["1.4.4"] = libs14; | ||||
| 	fmlLibsMapping["1.4.5"] = libs14; | ||||
| 	fmlLibsMapping["1.4.6"] = libs14; | ||||
| 	fmlLibsMapping["1.4.7"] = libs14; | ||||
|  | ||||
| 	fmlLibsMapping["1.5"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.5.1"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.5.2"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
| } | ||||
|  | ||||
| void LegacyUpdate::executeTask() | ||||
| @@ -110,6 +64,7 @@ void LegacyUpdate::fmllibsStart() | ||||
| 	bool forge_present = false; | ||||
|  | ||||
| 	QString version = inst->intendedVersionId(); | ||||
| 	auto & fmlLibsMapping = g_forgeData.fmlLibsMapping; | ||||
| 	if (!fmlLibsMapping.contains(version)) | ||||
| 	{ | ||||
| 		lwjglStart(); | ||||
| @@ -152,7 +107,7 @@ void LegacyUpdate::fmllibsStart() | ||||
| 	// now check the lib folder inside the instance for files. | ||||
| 	for (auto &lib : libList) | ||||
| 	{ | ||||
| 		QFileInfo libInfo(PathCombine(inst->libDir(), lib.name)); | ||||
| 		QFileInfo libInfo(PathCombine(inst->libDir(), lib.filename)); | ||||
| 		if (libInfo.exists()) | ||||
| 			continue; | ||||
| 		fmlLibsToProcess.append(lib); | ||||
| @@ -171,9 +126,9 @@ void LegacyUpdate::fmllibsStart() | ||||
| 	auto metacache = MMC->metacache(); | ||||
| 	for (auto &lib : fmlLibsToProcess) | ||||
| 	{ | ||||
| 		auto entry = metacache->resolveEntry("fmllibs", lib.name); | ||||
| 		QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.name | ||||
| 									 : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.name; | ||||
| 		auto entry = metacache->resolveEntry("fmllibs", lib.filename); | ||||
| 		QString urlString = lib.ours ? URLConstants::FMLLIBS_OUR_BASE_URL + lib.filename | ||||
| 									 : URLConstants::FMLLIBS_FORGE_BASE_URL + lib.filename; | ||||
| 		dljob->addNetAction(CacheDownload::make(QUrl(urlString), entry)); | ||||
| 	} | ||||
|  | ||||
| @@ -196,16 +151,16 @@ void LegacyUpdate::fmllibsFinished() | ||||
| 		for (auto &lib : fmlLibsToProcess) | ||||
| 		{ | ||||
| 			progress(index, fmlLibsToProcess.size()); | ||||
| 			auto entry = metacache->resolveEntry("fmllibs", lib.name); | ||||
| 			auto path = PathCombine(inst->libDir(), lib.name); | ||||
| 			auto entry = metacache->resolveEntry("fmllibs", lib.filename); | ||||
| 			auto path = PathCombine(inst->libDir(), lib.filename); | ||||
| 			if(!ensureFilePathExists(path)) | ||||
| 			{ | ||||
| 				emitFailed(tr("Failed creating FML library folder inside the instance.")); | ||||
| 				return; | ||||
| 			} | ||||
| 			if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.name))) | ||||
| 			if (!QFile::copy(entry->getFullPath(), PathCombine(inst->libDir(), lib.filename))) | ||||
| 			{ | ||||
| 				emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.name)); | ||||
| 				emitFailed(tr("Failed copying Forge/FML library: %1.").arg(lib.filename)); | ||||
| 				return; | ||||
| 			} | ||||
| 			index++; | ||||
| @@ -265,8 +220,6 @@ void LegacyUpdate::lwjglStart() | ||||
| 	connect(rep, SIGNAL(downloadProgress(qint64, qint64)), SIGNAL(progress(qint64, qint64))); | ||||
| 	connect(worker.get(), SIGNAL(finished(QNetworkReply *)), | ||||
| 			SLOT(lwjglFinished(QNetworkReply *))); | ||||
| 	// connect(rep, SIGNAL(error(QNetworkReply::NetworkError)), | ||||
| 	// SLOT(downloadError(QNetworkReply::NetworkError))); | ||||
| } | ||||
|  | ||||
| void LegacyUpdate::lwjglFinished(QNetworkReply *reply) | ||||
|   | ||||
| @@ -21,19 +21,13 @@ | ||||
|  | ||||
| #include "logic/net/NetJob.h" | ||||
| #include "logic/tasks/Task.h" | ||||
| #include "logic/forge/ForgeData.h" | ||||
|  | ||||
| class MinecraftVersion; | ||||
| class BaseInstance; | ||||
| class QuaZip; | ||||
| class Mod; | ||||
|  | ||||
| struct FMLlib | ||||
| { | ||||
| 	QString name; | ||||
| 	QString checksum; | ||||
| 	bool ours; | ||||
| }; | ||||
|  | ||||
| class LegacyUpdate : public Task | ||||
| { | ||||
| 	Q_OBJECT | ||||
| @@ -84,5 +78,4 @@ private: | ||||
| 	NetJobPtr legacyDownloadJob; | ||||
| 	BaseInstance *m_inst = nullptr; | ||||
| 	QList<FMLlib> fmlLibsToProcess; | ||||
| 	QMap<QString, QList<FMLlib>> fmlLibsMapping; | ||||
| }; | ||||
|   | ||||
| @@ -17,6 +17,7 @@ | ||||
|  | ||||
| #include "BaseVersion.h" | ||||
| #include <QStringList> | ||||
| #include <QSet> | ||||
|  | ||||
| struct MinecraftVersion : public BaseVersion | ||||
| { | ||||
| @@ -29,13 +30,8 @@ struct MinecraftVersion : public BaseVersion | ||||
| 	/// The URL that this version will be downloaded from. maybe. | ||||
| 	QString download_url; | ||||
|  | ||||
| 	/// This version's type. Used internally to identify what kind of version this is. | ||||
| 	enum VersionType | ||||
| 	{ | ||||
| 		OneSix, | ||||
| 		Legacy, | ||||
| 		Nostalgia | ||||
| 	} type; | ||||
| 	/// extra features enabled for this Minecraft version. Mostly for compatibility | ||||
| 	QSet <QString> features; | ||||
|  | ||||
| 	/// is this the latest version? | ||||
| 	bool is_latest = false; | ||||
| @@ -47,6 +43,11 @@ struct MinecraftVersion : public BaseVersion | ||||
|  | ||||
| 	QString m_descriptor; | ||||
|  | ||||
| 	bool usesLegacyLauncher() | ||||
| 	{ | ||||
| 		return features.contains("legacy"); | ||||
| 	} | ||||
| 	 | ||||
| 	virtual QString descriptor() | ||||
| 	{ | ||||
| 		return m_descriptor; | ||||
| @@ -59,31 +60,21 @@ struct MinecraftVersion : public BaseVersion | ||||
|  | ||||
| 	virtual QString typeString() const | ||||
| 	{ | ||||
| 		QStringList pre_final; | ||||
| 		if (is_latest == true) | ||||
| 		if (is_latest && is_snapshot) | ||||
| 		{ | ||||
| 			pre_final.append("Latest"); | ||||
| 			return QObject::tr("Latest snapshot"); | ||||
| 		} | ||||
| 		switch (type) | ||||
| 		else if(is_latest) | ||||
| 		{ | ||||
| 		case OneSix: | ||||
| 			pre_final.append("OneSix"); | ||||
| 			break; | ||||
| 		case Legacy: | ||||
| 			pre_final.append("Legacy"); | ||||
| 			break; | ||||
| 		case Nostalgia: | ||||
| 			pre_final.append("Nostalgia"); | ||||
| 			break; | ||||
|  | ||||
| 		default: | ||||
| 			pre_final.append(QString("Type(%1)").arg(type)); | ||||
| 			break; | ||||
| 			return QObject::tr("Latest release"); | ||||
| 		} | ||||
| 		if (is_snapshot == true) | ||||
| 		else if(is_snapshot) | ||||
| 		{ | ||||
| 			pre_final.append("Snapshot"); | ||||
| 			return QObject::tr("Old snapshot"); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			return QObject::tr("Regular release"); | ||||
| 		} | ||||
| 		return pre_final.join(' '); | ||||
| 	} | ||||
| }; | ||||
|   | ||||
| @@ -1,36 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #include "NostalgiaInstance.h" | ||||
|  | ||||
| NostalgiaInstance::NostalgiaInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 									 QObject *parent) | ||||
| 	: OneSixInstance(rootDir, settings, parent) | ||||
| { | ||||
| } | ||||
|  | ||||
| QString NostalgiaInstance::getStatusbarDescription() | ||||
| { | ||||
| 	if (flags().contains(VersionBrokenFlag)) | ||||
| 	{ | ||||
| 		return "Nostalgia : " + intendedVersionId() + " (broken)"; | ||||
| 	} | ||||
| 	return "Nostalgia : " + intendedVersionId(); | ||||
| } | ||||
|  | ||||
| bool NostalgiaInstance::menuActionEnabled(QString action_name) const | ||||
| { | ||||
| 	return false; | ||||
| } | ||||
| @@ -1,29 +0,0 @@ | ||||
| /* Copyright 2013 MultiMC Contributors | ||||
|  * | ||||
|  * Licensed under the Apache License, Version 2.0 (the "License"); | ||||
|  * you may not use this file except in compliance with the License. | ||||
|  * You may obtain a copy of the License at | ||||
|  * | ||||
|  *     http://www.apache.org/licenses/LICENSE-2.0 | ||||
|  * | ||||
|  * Unless required by applicable law or agreed to in writing, software | ||||
|  * distributed under the License is distributed on an "AS IS" BASIS, | ||||
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
|  * See the License for the specific language governing permissions and | ||||
|  * limitations under the License. | ||||
|  */ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "OneSixInstance.h" | ||||
|  | ||||
| class NostalgiaInstance : public OneSixInstance | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	explicit NostalgiaInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 							   QObject *parent = 0); | ||||
| 	virtual ~NostalgiaInstance() {}; | ||||
| 	virtual QString getStatusbarDescription(); | ||||
| 	virtual bool menuActionEnabled(QString action_name) const; | ||||
| }; | ||||
| @@ -3,8 +3,8 @@ | ||||
| #include "VersionFinal.h" | ||||
| #include "OneSixLibrary.h" | ||||
| #include "tasks/SequentialTask.h" | ||||
| #include "ForgeInstaller.h" | ||||
| #include "lists/ForgeVersionList.h" | ||||
| #include "forge/ForgeInstaller.h" | ||||
| #include "forge/ForgeVersionList.h" | ||||
| #include "OneSixInstance_p.h" | ||||
| #include "OneSixVersionBuilder.h" | ||||
| #include "MultiMC.h" | ||||
|   | ||||
| @@ -26,7 +26,7 @@ | ||||
| #include "MultiMC.h" | ||||
| #include "icons/IconList.h" | ||||
| #include "MinecraftProcess.h" | ||||
| #include "gui/dialogs/OneSixModEditDialog.h" | ||||
| #include "gui/dialogs/InstanceEditDialog.h" | ||||
| #include <MMCError.h> | ||||
|  | ||||
| OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, QObject *parent) | ||||
| @@ -36,7 +36,6 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings, | ||||
| 	d->m_settings->registerSetting("IntendedVersion", ""); | ||||
| 	d->m_settings->registerSetting("ShouldUpdate", false); | ||||
| 	d->version.reset(new VersionFinal(this, this)); | ||||
| 	d->vanillaVersion.reset(new VersionFinal(this, this)); | ||||
| } | ||||
|  | ||||
| void OneSixInstance::init() | ||||
| @@ -260,6 +259,17 @@ std::shared_ptr<ModList> OneSixInstance::loaderModList() | ||||
| 	return d->loader_mod_list; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<ModList> OneSixInstance::coreModList() | ||||
| { | ||||
| 	I_D(OneSixInstance); | ||||
| 	if (!d->core_mod_list) | ||||
| 	{ | ||||
| 		d->core_mod_list.reset(new ModList(coreModsDir())); | ||||
| 	} | ||||
| 	d->core_mod_list->update(); | ||||
| 	return d->core_mod_list; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<ModList> OneSixInstance::resourcePackList() | ||||
| { | ||||
| 	I_D(OneSixInstance); | ||||
| @@ -273,7 +283,7 @@ std::shared_ptr<ModList> OneSixInstance::resourcePackList() | ||||
|  | ||||
| QDialog *OneSixInstance::createModEditDialog(QWidget *parent) | ||||
| { | ||||
| 	return new OneSixModEditDialog(this, parent); | ||||
| 	return new InstanceEditDialog(this, parent); | ||||
| } | ||||
|  | ||||
| bool OneSixInstance::setIntendedVersionId(QString version) | ||||
| @@ -307,10 +317,13 @@ bool OneSixInstance::shouldUpdate() const | ||||
|  | ||||
| bool OneSixInstance::versionIsCustom() | ||||
| { | ||||
| 	QDir patches(PathCombine(instanceRoot(), "patches/")); | ||||
| 	return (patches.exists() && patches.count() >= 0) | ||||
| 			|| QFile::exists(PathCombine(instanceRoot(), "custom.json")) | ||||
| 			|| QFile::exists(PathCombine(instanceRoot(), "user.json")); | ||||
| 	I_D(const OneSixInstance); | ||||
| 	auto ver = d->version; | ||||
| 	if(ver) | ||||
| 	{ | ||||
| 		return !ver->isVanilla(); | ||||
| 	} | ||||
| 	return false; | ||||
| } | ||||
|  | ||||
| bool OneSixInstance::versionIsFTBPack() | ||||
| @@ -335,15 +348,13 @@ void OneSixInstance::reloadVersion() | ||||
|  | ||||
| 	try | ||||
| 	{ | ||||
| 		d->version->reload(false, externalPatches()); | ||||
| 		d->vanillaVersion->reload(true, externalPatches()); | ||||
| 		d->version->reload(externalPatches()); | ||||
| 		d->m_flags.remove(VersionBrokenFlag); | ||||
| 		emit versionReloaded(); | ||||
| 	} | ||||
| 	catch(MMCError & error) | ||||
| 	{ | ||||
| 		d->version->clear(); | ||||
| 		d->vanillaVersion->clear(); | ||||
| 		d->m_flags.insert(VersionBrokenFlag); | ||||
| 		//TODO: rethrow to show some error message(s)? | ||||
| 		emit versionReloaded(); | ||||
| @@ -355,7 +366,6 @@ void OneSixInstance::clearVersion() | ||||
| { | ||||
| 	I_D(OneSixInstance); | ||||
| 	d->version->clear(); | ||||
| 	d->vanillaVersion->clear(); | ||||
| 	emit versionReloaded(); | ||||
| } | ||||
|  | ||||
| @@ -365,12 +375,6 @@ std::shared_ptr<VersionFinal> OneSixInstance::getFullVersion() const | ||||
| 	return d->version; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<VersionFinal> OneSixInstance::getVanillaVersion() const | ||||
| { | ||||
| 	I_D(const OneSixInstance); | ||||
| 	return d->vanillaVersion; | ||||
| } | ||||
|  | ||||
| QString OneSixInstance::defaultBaseJar() const | ||||
| { | ||||
| 	return "versions/" + intendedVersionId() + "/" + intendedVersionId() + ".jar"; | ||||
| @@ -396,16 +400,24 @@ bool OneSixInstance::menuActionEnabled(QString action_name) const | ||||
|  | ||||
| QString OneSixInstance::getStatusbarDescription() | ||||
| { | ||||
| 	QString descr = "OneSix : " + intendedVersionId(); | ||||
| 	QStringList traits; | ||||
| 	if (versionIsCustom()) | ||||
| 	{ | ||||
| 		descr += " (custom)"; | ||||
| 		traits.append(tr("custom")); | ||||
| 	} | ||||
| 	if (flags().contains(VersionBrokenFlag)) | ||||
| 	{ | ||||
| 		descr += " (broken)"; | ||||
| 		traits.append(tr("broken")); | ||||
| 	} | ||||
| 	 | ||||
| 	if(traits.size()) | ||||
| 	{ | ||||
| 		return tr("Minecraft %1 (%2)").arg(intendedVersionId()).arg(traits.join(", ")); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		return tr("Minecraft %1").arg(intendedVersionId()); | ||||
| 	} | ||||
| 	return descr; | ||||
| } | ||||
|  | ||||
| QDir OneSixInstance::librariesPath() const | ||||
| @@ -449,6 +461,11 @@ QString OneSixInstance::loaderModsDir() const | ||||
| 	return PathCombine(minecraftRoot(), "mods"); | ||||
| } | ||||
|  | ||||
| QString OneSixInstance::coreModsDir() const | ||||
| { | ||||
| 	return PathCombine(minecraftRoot(), "coremods"); | ||||
| } | ||||
|  | ||||
| QString OneSixInstance::resourcePacksDir() const | ||||
| { | ||||
| 	return PathCombine(minecraftRoot(), "resourcepacks"); | ||||
| @@ -458,3 +475,8 @@ QString OneSixInstance::instanceConfigFolder() const | ||||
| { | ||||
| 	return PathCombine(minecraftRoot(), "config"); | ||||
| } | ||||
|  | ||||
| QString OneSixInstance::jarModsDir() const | ||||
| { | ||||
| 	return PathCombine(instanceRoot(), "jarmods"); | ||||
| } | ||||
|   | ||||
| @@ -32,11 +32,14 @@ public: | ||||
|  | ||||
| 	//////  Mod Lists  ////// | ||||
| 	std::shared_ptr<ModList> loaderModList(); | ||||
| 	std::shared_ptr<ModList> coreModList(); | ||||
| 	std::shared_ptr<ModList> resourcePackList(); | ||||
|  | ||||
| 	////// Directories ////// | ||||
| 	////// Directories and files ////// | ||||
| 	QString jarModsDir() const; | ||||
| 	QString resourcePacksDir() const; | ||||
| 	QString loaderModsDir() const; | ||||
| 	QString coreModsDir() const; | ||||
| 	virtual QString instanceConfigFolder() const override; | ||||
|  | ||||
| 	virtual std::shared_ptr<Task> doUpdate() override; | ||||
| @@ -60,14 +63,16 @@ public: | ||||
| 	 * throws various exceptions :3 | ||||
| 	 */ | ||||
| 	void reloadVersion(); | ||||
| 	 | ||||
| 	/// clears all version information in preparation for an update | ||||
| 	void clearVersion(); | ||||
| 	 | ||||
| 	/// get the current full version info | ||||
| 	std::shared_ptr<VersionFinal> getFullVersion() const; | ||||
| 	/// gets the current version info, but only for version.json | ||||
| 	std::shared_ptr<VersionFinal> getVanillaVersion() const; | ||||
| 	 | ||||
| 	/// is the current version original, or custom? | ||||
| 	virtual bool versionIsCustom() override; | ||||
| 	 | ||||
| 	/// does this instance have an FTB pack patch inside? | ||||
| 	bool versionIsFTBPack(); | ||||
|  | ||||
|   | ||||
| @@ -24,7 +24,8 @@ class OneSixInstancePrivate : public BaseInstancePrivate | ||||
| public: | ||||
| 	virtual ~OneSixInstancePrivate() {}; | ||||
| 	std::shared_ptr<VersionFinal> version; | ||||
| 	std::shared_ptr<VersionFinal> vanillaVersion; | ||||
| 	std::shared_ptr<ModList> jar_mod_list; | ||||
| 	std::shared_ptr<ModList> loader_mod_list; | ||||
| 	std::shared_ptr<ModList> core_mod_list; | ||||
| 	std::shared_ptr<ModList> resource_pack_list; | ||||
| }; | ||||
|   | ||||
| @@ -41,7 +41,7 @@ private: | ||||
| 	// custom values | ||||
| 	/// absolute URL. takes precedence over m_download_path, if defined | ||||
| 	QString m_absolute_url; | ||||
| 	/// download hint - how to actually get the library | ||||
| 	/// type hint - modifies how the library is treated | ||||
| 	QString m_hint; | ||||
|  | ||||
| 	// derived values used for real things | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
| #include "VersionFinal.h" | ||||
| #include "OneSixLibrary.h" | ||||
| #include "OneSixInstance.h" | ||||
| #include "net/ForgeMirrors.h" | ||||
| #include "logic/forge/ForgeMirrors.h" | ||||
| #include "net/URLConstants.h" | ||||
| #include "assets/AssetsUtils.h" | ||||
|  | ||||
|   | ||||
| @@ -38,13 +38,12 @@ OneSixVersionBuilder::OneSixVersionBuilder() | ||||
| { | ||||
| } | ||||
|  | ||||
| void OneSixVersionBuilder::build(VersionFinal *version, OneSixInstance *instance, | ||||
| 								 const bool onlyVanilla, const QStringList &external) | ||||
| void OneSixVersionBuilder::build(VersionFinal *version, OneSixInstance *instance, const QStringList &external) | ||||
| { | ||||
| 	OneSixVersionBuilder builder; | ||||
| 	builder.m_version = version; | ||||
| 	builder.m_instance = instance; | ||||
| 	builder.buildInternal(onlyVanilla, external); | ||||
| 	builder.buildInternal(external); | ||||
| } | ||||
|  | ||||
| void OneSixVersionBuilder::readJsonAndApplyToVersion(VersionFinal *version, | ||||
| @@ -56,7 +55,7 @@ void OneSixVersionBuilder::readJsonAndApplyToVersion(VersionFinal *version, | ||||
| 	builder.readJsonAndApply(obj); | ||||
| } | ||||
|  | ||||
| void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringList &external) | ||||
| void OneSixVersionBuilder::buildInternal(const QStringList &external) | ||||
| { | ||||
| 	m_version->versionFiles.clear(); | ||||
|  | ||||
| @@ -111,9 +110,6 @@ void OneSixVersionBuilder::buildInternal(const bool onlyVanilla, const QStringLi | ||||
| 			// QObject::tr("Error while applying %1. Please check MultiMC-0.log for more | ||||
| 			// info.").arg(root.absoluteFilePath("version.json"))); | ||||
|  | ||||
| 			if (onlyVanilla) | ||||
| 				break; | ||||
|  | ||||
| 			// patches/ | ||||
| 			// load all, put into map for ordering, apply in the right order | ||||
|  | ||||
|   | ||||
| @@ -28,8 +28,7 @@ class OneSixVersionBuilder | ||||
| { | ||||
| 	OneSixVersionBuilder(); | ||||
| public: | ||||
| 	static void build(VersionFinal *version, OneSixInstance *instance, const bool onlyVanilla, | ||||
| 					  const QStringList &external); | ||||
| 	static void build(VersionFinal *version, OneSixInstance *instance, const QStringList &external); | ||||
| 	static void readJsonAndApplyToVersion(VersionFinal *version, const QJsonObject &obj); | ||||
|  | ||||
| 	static QMap<QString, int> readOverrideOrders(OneSixInstance *instance); | ||||
| @@ -39,7 +38,7 @@ private: | ||||
| 	VersionFinal *m_version; | ||||
| 	OneSixInstance *m_instance; | ||||
|  | ||||
| 	void buildInternal(const bool onlyVanilla, const QStringList &external); | ||||
| 	void buildInternal(const QStringList& external); | ||||
| 	void readJsonAndApply(const QJsonObject &obj); | ||||
|  | ||||
| 	VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, | ||||
|   | ||||
| @@ -13,6 +13,43 @@ using namespace MMCJson; | ||||
|  | ||||
| #define CURRENT_MINIMUM_LAUNCHER_VERSION 14 | ||||
|  | ||||
| JarmodPtr Jarmod::fromJson(const QJsonObject &libObj, const QString &filename) | ||||
| { | ||||
| 	JarmodPtr out(new Jarmod()); | ||||
| 	if (!libObj.contains("name")) | ||||
| 	{ | ||||
| 		throw JSONValidationError(filename + | ||||
| 								  "contains a jarmod that doesn't have a 'name' field"); | ||||
| 	} | ||||
| 	out->name = libObj.value("name").toString(); | ||||
|  | ||||
| 	auto readString = [libObj, filename](const QString & key, QString & variable) | ||||
| 	{ | ||||
| 		if (libObj.contains(key)) | ||||
| 		{ | ||||
| 			QJsonValue val = libObj.value(key); | ||||
| 			if (!val.isString()) | ||||
| 			{ | ||||
| 				QLOG_WARN() << key << "is not a string in" << filename << "(skipping)"; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				variable = val.toString(); | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	readString("url", out->baseurl); | ||||
| 	readString("MMC-absoluteUrl", out->absoluteUrl); | ||||
| 	if(!out->baseurl.isEmpty() && out->absoluteUrl.isEmpty()) | ||||
| 	{ | ||||
| 		out->absoluteUrl = out->baseurl + out->name; | ||||
| 	} | ||||
| 	return out; | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| RawLibraryPtr RawLibrary::fromJson(const QJsonObject &libObj, const QString &filename) | ||||
| { | ||||
| 	RawLibraryPtr out(new RawLibrary()); | ||||
| @@ -165,6 +202,14 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("+traits")) | ||||
| 	{ | ||||
| 		for (auto tweakerVal : ensureArray(root.value("+traits"))) | ||||
| 		{ | ||||
| 			out->traits.insert(ensureString(tweakerVal)); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("libraries")) | ||||
| 	{ | ||||
| 		// FIXME: This should be done when applying. | ||||
| @@ -188,6 +233,18 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("+jarMods")) | ||||
| 	{ | ||||
| 		for (auto libVal : ensureArray(root.value("+jarMods"))) | ||||
| 		{ | ||||
| 			QJsonObject libObj = ensureObject(libVal); | ||||
| 			// parse the jarmod | ||||
| 			auto lib = Jarmod::fromJson(libObj, filename); | ||||
| 			// and add to jar mods | ||||
| 			out->jarMods.append(lib); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("+libraries")) | ||||
| 	{ | ||||
| 		for (auto libVal : ensureArray(root.value("+libraries"))) | ||||
| @@ -258,6 +315,7 @@ VersionFilePtr VersionFile::fromJson(const QJsonDocument &doc, const QString &fi | ||||
| 			out->addLibs.append(lib); | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (root.contains("-libraries")) | ||||
| 	{ | ||||
| 		for (auto libVal : ensureArray(root.value("-libraries"))) | ||||
| @@ -309,6 +367,16 @@ int VersionFile::findLibrary(QList<OneSixLibraryPtr> haystack, const QString &ne | ||||
| 	return retval; | ||||
| } | ||||
|  | ||||
| bool VersionFile::isVanilla() | ||||
| { | ||||
| 	return fileId == "org.multimc.version.json"; | ||||
| } | ||||
|  | ||||
| bool VersionFile::hasJarMods() | ||||
| { | ||||
| 	return !jarMods.isEmpty(); | ||||
| } | ||||
|  | ||||
| void VersionFile::applyTo(VersionFinal *version) | ||||
| { | ||||
| 	if (minimumLauncherVersion != -1) | ||||
| @@ -338,6 +406,10 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 	} | ||||
| 	if (!processArguments.isNull()) | ||||
| 	{ | ||||
| 		if(isVanilla()) | ||||
| 		{ | ||||
| 			version->vanillaProcessArguments = processArguments; | ||||
| 		} | ||||
| 		version->processArguments = processArguments; | ||||
| 	} | ||||
| 	if (!type.isNull()) | ||||
| @@ -362,6 +434,10 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 	} | ||||
| 	if (!overwriteMinecraftArguments.isNull()) | ||||
| 	{ | ||||
| 		if(isVanilla()) | ||||
| 		{ | ||||
| 			version->vanillaMinecraftArguments = overwriteMinecraftArguments; | ||||
| 		} | ||||
| 		version->minecraftArguments = overwriteMinecraftArguments; | ||||
| 	} | ||||
| 	if (!addMinecraftArguments.isNull()) | ||||
| @@ -384,13 +460,17 @@ void VersionFile::applyTo(VersionFinal *version) | ||||
| 	{ | ||||
| 		version->tweakers.removeAll(tweaker); | ||||
| 	} | ||||
| 	version->jarMods.append(jarMods); | ||||
| 	if (shouldOverwriteLibs) | ||||
| 	{ | ||||
| 		version->libraries.clear(); | ||||
| 		QList<OneSixLibraryPtr> libs; | ||||
| 		for (auto lib : overwriteLibs) | ||||
| 		{ | ||||
| 			version->libraries.append(createLibrary(lib)); | ||||
| 			libs.append(createLibrary(lib)); | ||||
| 		} | ||||
| 		if(isVanilla()) | ||||
| 			version->vanillaLibraries = libs; | ||||
| 		version->libraries = libs; | ||||
| 	} | ||||
| 	for (auto lib : addLibs) | ||||
| 	{ | ||||
|   | ||||
| @@ -81,6 +81,18 @@ struct RawLibrary | ||||
| 	static RawLibraryPtr fromJson(const QJsonObject &libObj, const QString &filename); | ||||
| }; | ||||
|  | ||||
| struct Jarmod; | ||||
| typedef std::shared_ptr<Jarmod> JarmodPtr; | ||||
| struct Jarmod | ||||
| { | ||||
| 	QString name; | ||||
| 	QString baseurl; | ||||
| 	QString hint; | ||||
| 	QString absoluteUrl; | ||||
| 	 | ||||
| 	static JarmodPtr fromJson(const QJsonObject &libObj, const QString &filename); | ||||
| }; | ||||
|  | ||||
| struct VersionFile; | ||||
| typedef std::shared_ptr<VersionFile> VersionFilePtr; | ||||
| struct VersionFile | ||||
| @@ -92,7 +104,8 @@ public: /* methods */ | ||||
| 	static OneSixLibraryPtr createLibrary(RawLibraryPtr lib); | ||||
| 	int findLibrary(QList<OneSixLibraryPtr> haystack, const QString &needle); | ||||
| 	void applyTo(VersionFinal *version); | ||||
|  | ||||
| 	bool isVanilla(); | ||||
| 	bool hasJarMods(); | ||||
| public: /* data */ | ||||
| 	int order = 0; | ||||
| 	QString name; | ||||
| @@ -124,4 +137,8 @@ public: /* data */ | ||||
| 	QList<RawLibraryPtr> overwriteLibs; | ||||
| 	QList<RawLibraryPtr> addLibs; | ||||
| 	QList<QString> removeLibs; | ||||
|  | ||||
| 	QSet<QString> traits; | ||||
|  | ||||
| 	QList<JarmodPtr> jarMods; | ||||
| }; | ||||
|   | ||||
| @@ -21,16 +21,7 @@ | ||||
|  | ||||
| #include "OneSixVersionBuilder.h" | ||||
| #include "OneSixInstance.h" | ||||
|  | ||||
| template <typename A, typename B> QMap<A, B> invert(const QMap<B, A> &in) | ||||
| { | ||||
| 	QMap<A, B> out; | ||||
| 	for (auto it = in.begin(); it != in.end(); ++it) | ||||
| 	{ | ||||
| 		out.insert(it.value(), it.key()); | ||||
| 	} | ||||
| 	return out; | ||||
| } | ||||
| #include <pathutils.h> | ||||
|  | ||||
| VersionFinal::VersionFinal(OneSixInstance *instance, QObject *parent) | ||||
| 	: QAbstractListModel(parent), m_instance(instance) | ||||
| @@ -38,11 +29,10 @@ VersionFinal::VersionFinal(OneSixInstance *instance, QObject *parent) | ||||
| 	clear(); | ||||
| } | ||||
|  | ||||
| void VersionFinal::reload(const bool onlyVanilla, const QStringList &external) | ||||
| void VersionFinal::reload(const QStringList &external) | ||||
| { | ||||
| 	//FIXME: source of epic failure. | ||||
| 	beginResetModel(); | ||||
| 	OneSixVersionBuilder::build(this, m_instance, onlyVanilla, external); | ||||
| 	OneSixVersionBuilder::build(this, m_instance, external); | ||||
| 	reapply(true); | ||||
| 	endResetModel(); | ||||
| } | ||||
| @@ -60,6 +50,8 @@ void VersionFinal::clear() | ||||
| 	mainClass.clear(); | ||||
| 	libraries.clear(); | ||||
| 	tweakers.clear(); | ||||
| 	jarMods.clear(); | ||||
| 	traits.clear(); | ||||
| } | ||||
|  | ||||
| bool VersionFinal::canRemove(const int index) const | ||||
| @@ -119,6 +111,11 @@ VersionFilePtr VersionFinal::versionFile(const QString &id) | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
| bool VersionFinal::hasJarMods() | ||||
| { | ||||
| 	return !jarMods.isEmpty(); | ||||
| } | ||||
|  | ||||
| bool VersionFinal::hasFtbPack() | ||||
| { | ||||
| 	return versionFile("org.multimc.ftb.pack.json") != nullptr; | ||||
| @@ -129,6 +126,36 @@ bool VersionFinal::removeFtbPack() | ||||
| 	return remove("org.multimc.ftb.pack.json"); | ||||
| } | ||||
|  | ||||
| bool VersionFinal::isVanilla() | ||||
| { | ||||
| 	QDir patches(PathCombine(m_instance->instanceRoot(), "patches/")); | ||||
| 	return versionFiles.size() > 1 || QFile::exists(PathCombine(m_instance->instanceRoot(), "custom.json")); | ||||
| } | ||||
|  | ||||
| bool VersionFinal::revertToVanilla() | ||||
| { | ||||
| 	beginResetModel(); | ||||
| 	auto it = versionFiles.begin(); | ||||
| 	while (it != versionFiles.end()) | ||||
| 	{ | ||||
| 		if ((*it)->fileId != "org.multimc.version.json") | ||||
| 		{ | ||||
| 			QFile::remove((*it)->filename); | ||||
| 			it = versionFiles.erase(it); | ||||
| 		} | ||||
| 		else | ||||
| 			it++; | ||||
| 	} | ||||
| 	reapply(true); | ||||
| 	endResetModel(); | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| bool VersionFinal::usesLegacyCustomJson() | ||||
| { | ||||
| 	return QFile::exists(PathCombine(m_instance->instanceRoot(), "custom.json")); | ||||
| } | ||||
|  | ||||
| QList<std::shared_ptr<OneSixLibrary> > VersionFinal::getActiveNormalLibs() | ||||
| { | ||||
| 	QList<std::shared_ptr<OneSixLibrary> > output; | ||||
| @@ -229,15 +256,6 @@ int VersionFinal::columnCount(const QModelIndex &parent) const | ||||
| 	return 2; | ||||
| } | ||||
|  | ||||
| bool VersionFinal::isCustom() | ||||
| { | ||||
| 	return QDir(m_instance->instanceRoot()).exists("custom.json"); | ||||
| } | ||||
| bool VersionFinal::revertToBase() | ||||
| { | ||||
| 	return QDir(m_instance->instanceRoot()).remove("custom.json"); | ||||
| } | ||||
|  | ||||
| QMap<QString, int> VersionFinal::getExistingOrder() const | ||||
| { | ||||
|  | ||||
| @@ -356,8 +374,10 @@ void VersionFinal::finalize() | ||||
| 	{ | ||||
| 		assets = "legacy"; | ||||
| 	} | ||||
| 	if (minecraftArguments.isEmpty()) | ||||
| 	auto finalizeArguments = [&]( QString & minecraftArguments, const QString & processArguments ) -> void | ||||
| 	{ | ||||
| 		if (!minecraftArguments.isEmpty()) | ||||
| 			return; | ||||
| 		QString toCompare = processArguments.toLower(); | ||||
| 		if (toCompare == "legacy") | ||||
| 		{ | ||||
| @@ -370,8 +390,11 @@ void VersionFinal::finalize() | ||||
| 		else if (toCompare == "username_session_version") | ||||
| 		{ | ||||
| 			minecraftArguments = "--username ${auth_player_name} " | ||||
| 								 "--session ${auth_session} " | ||||
| 								 "--version ${profile_name}"; | ||||
| 								"--session ${auth_session} " | ||||
| 								"--version ${profile_name}"; | ||||
| 		} | ||||
| 	} | ||||
| 	}; | ||||
| 	finalizeArguments(vanillaMinecraftArguments, vanillaProcessArguments); | ||||
| 	finalizeArguments(minecraftArguments, processArguments); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -38,22 +38,29 @@ public: | ||||
| 	virtual int columnCount(const QModelIndex &parent) const; | ||||
| 	virtual Qt::ItemFlags flags(const QModelIndex &index) const; | ||||
|  | ||||
| 	void reload(const bool onlyVanilla = false, const QStringList &external = QStringList()); | ||||
| 	void reload(const QStringList &external = QStringList()); | ||||
| 	void clear(); | ||||
|  | ||||
| 	bool canRemove(const int index) const; | ||||
|  | ||||
| 	QString versionFileId(const int index) const; | ||||
|  | ||||
| 	// does this instance have an all overriding custom.json | ||||
| 	bool isCustom(); | ||||
| 	// remove custom.json | ||||
| 	bool revertToBase(); | ||||
| 	// does this instance have an FTB pack patch file? | ||||
| 	// is this version unmodded vanilla minecraft? | ||||
| 	bool isVanilla(); | ||||
| 	// remove any customizations on top of vanilla | ||||
| 	bool revertToVanilla(); | ||||
| 	 | ||||
| 	// does this version have an FTB pack patch file? | ||||
| 	bool hasFtbPack(); | ||||
| 	// remove FTB pack | ||||
| 	bool removeFtbPack(); | ||||
| 	 | ||||
| 	// does this version have any jar mods? | ||||
| 	bool hasJarMods(); | ||||
| 	 | ||||
| 	// does this version still use a legacy custom.json file? | ||||
| 	bool usesLegacyCustomJson(); | ||||
| 	 | ||||
|  | ||||
| 	enum MoveDirection { MoveUp, MoveDown }; | ||||
| 	void move(const int index, const MoveDirection direction); | ||||
| @@ -91,6 +98,8 @@ public: | ||||
| 	 * ex: "username_session_version" | ||||
| 	 */ | ||||
| 	QString processArguments; | ||||
| 	/// Same as above, but only for vanilla | ||||
| 	QString vanillaProcessArguments; | ||||
| 	/** | ||||
| 	 * arguments that should be used for launching minecraft | ||||
| 	 * | ||||
| @@ -98,6 +107,8 @@ public: | ||||
| 	 *      --version ${version_name} --gameDir ${game_directory} --assetsDir ${game_assets}" | ||||
| 	 */ | ||||
| 	QString minecraftArguments; | ||||
| 	/// Same as above, but only for vanilla | ||||
| 	QString vanillaMinecraftArguments; | ||||
| 	/** | ||||
| 	 * the minimum launcher version required by this version ... current is 4 (at point of | ||||
| 	 * writing) | ||||
| @@ -114,6 +125,15 @@ public: | ||||
|  | ||||
| 	/// the list of libs - both active and inactive, native and java | ||||
| 	QList<std::shared_ptr<OneSixLibrary>> libraries; | ||||
| 	 | ||||
| 	/// same, but only vanilla. | ||||
| 	QList<std::shared_ptr<OneSixLibrary>> vanillaLibraries; | ||||
|  | ||||
| 	/// traits, collected from all the version files (version files can only add) | ||||
| 	QSet<QString> traits; | ||||
|  | ||||
| 	/// A list of jar mods. version files can add those. | ||||
| 	QList<JarmodPtr> jarMods; | ||||
|  | ||||
| 	/* | ||||
| 	FIXME: add support for those rules here? Looks like a pile of quick hacks to me though. | ||||
|   | ||||
							
								
								
									
										62
									
								
								logic/forge/ForgeData.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								logic/forge/ForgeData.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| #include "ForgeData.h" | ||||
|  | ||||
| extern ForgeData g_forgeData = ForgeData(); | ||||
|  | ||||
| ForgeData::ForgeData() | ||||
| { | ||||
| 	// 1.3.* | ||||
| 	auto libs13 = | ||||
| 		QList<FMLlib>{{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false}, | ||||
| 					  {"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false}, | ||||
| 					  {"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.3.2"] = libs13; | ||||
|  | ||||
| 	// 1.4.* | ||||
| 	auto libs14 = QList<FMLlib>{ | ||||
| 		{"argo-2.25.jar", "bb672829fde76cb163004752b86b0484bd0a7f4b", false}, | ||||
| 		{"guava-12.0.1.jar", "b8e78b9af7bf45900e14c6f958486b6ca682195f", false}, | ||||
| 		{"asm-all-4.0.jar", "98308890597acb64047f7e896638e0d98753ae82", false}, | ||||
| 		{"bcprov-jdk15on-147.jar", "b6f5d9926b0afbde9f4dbe3db88c5247be7794bb", false}}; | ||||
|  | ||||
| 	fmlLibsMapping["1.4"] = libs14; | ||||
| 	fmlLibsMapping["1.4.1"] = libs14; | ||||
| 	fmlLibsMapping["1.4.2"] = libs14; | ||||
| 	fmlLibsMapping["1.4.3"] = libs14; | ||||
| 	fmlLibsMapping["1.4.4"] = libs14; | ||||
| 	fmlLibsMapping["1.4.5"] = libs14; | ||||
| 	fmlLibsMapping["1.4.6"] = libs14; | ||||
| 	fmlLibsMapping["1.4.7"] = libs14; | ||||
|  | ||||
| 	// 1.5 | ||||
| 	fmlLibsMapping["1.5"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.zip", "5f7c142d53776f16304c0bbe10542014abad6af8", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
|  | ||||
| 	// 1.5.1 | ||||
| 	fmlLibsMapping["1.5.1"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.1.zip", "22e221a0d89516c1f721d6cab056a7e37471d0a6", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
|  | ||||
| 	// 1.5.2 | ||||
| 	fmlLibsMapping["1.5.2"] = QList<FMLlib>{ | ||||
| 		{"argo-small-3.2.jar", "58912ea2858d168c50781f956fa5b59f0f7c6b51", false}, | ||||
| 		{"guava-14.0-rc3.jar", "931ae21fa8014c3ce686aaa621eae565fefb1a6a", false}, | ||||
| 		{"asm-all-4.1.jar", "054986e962b88d8660ae4566475658469595ef58", false}, | ||||
| 		{"bcprov-jdk15on-148.jar", "960dea7c9181ba0b17e8bab0c06a43f0a5f04e65", true}, | ||||
| 		{"deobfuscation_data_1.5.2.zip", "446e55cd986582c70fcf12cb27bc00114c5adfd9", false}, | ||||
| 		{"scala-library.jar", "458d046151ad179c85429ed7420ffb1eaf6ddf85", true}}; | ||||
| 	 | ||||
| 	// don't use installers for those. | ||||
| 	forgeInstallerBlacklist = QSet<QString>({ | ||||
| 		"1.5.2" | ||||
| 	}); | ||||
| } | ||||
							
								
								
									
										21
									
								
								logic/forge/ForgeData.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								logic/forge/ForgeData.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| #pragma once | ||||
| #include <QMap> | ||||
| #include <QString> | ||||
| #include <QSet> | ||||
|  | ||||
| struct FMLlib | ||||
| { | ||||
| 	QString filename; | ||||
| 	QString checksum; | ||||
| 	bool ours; | ||||
| }; | ||||
|  | ||||
| struct ForgeData | ||||
| { | ||||
| 	ForgeData(); | ||||
| 	// mapping between minecraft versions and FML libraries required | ||||
| 	QMap<QString, QList<FMLlib>> fmlLibsMapping; | ||||
| 	// set of minecraft versions for which using forge installers is blacklisted | ||||
| 	QSet<QString> forgeInstallerBlacklist; | ||||
| }; | ||||
| extern ForgeData g_forgeData; | ||||
| @@ -14,9 +14,15 @@ | ||||
|  */ | ||||
| 
 | ||||
| #include "ForgeInstaller.h" | ||||
| #include "VersionFinal.h" | ||||
| #include "OneSixLibrary.h" | ||||
| #include "net/HttpMetaCache.h" | ||||
| #include "logic/VersionFinal.h" | ||||
| #include "logic/OneSixLibrary.h" | ||||
| #include "logic/net/HttpMetaCache.h" | ||||
| #include "logic/tasks/Task.h" | ||||
| #include "logic/OneSixInstance.h" | ||||
| #include "logic/forge/ForgeVersionList.h" | ||||
| #include "ForgeData.h" | ||||
| #include "gui/dialogs/ProgressDialog.h" | ||||
| 
 | ||||
| #include <quazip.h> | ||||
| #include <quazipfile.h> | ||||
| #include <pathutils.h> | ||||
| @@ -24,18 +30,12 @@ | ||||
| #include <QRegularExpression> | ||||
| #include <QRegularExpressionMatch> | ||||
| #include "MultiMC.h" | ||||
| #include "tasks/Task.h" | ||||
| #include "OneSixInstance.h" | ||||
| #include "lists/ForgeVersionList.h" | ||||
| #include "gui/dialogs/ProgressDialog.h" | ||||
| 
 | ||||
| #include <QJsonDocument> | ||||
| #include <QJsonArray> | ||||
| #include <QSaveFile> | ||||
| #include <QCryptographicHash> | ||||
| 
 | ||||
| ForgeInstaller::ForgeInstaller() | ||||
| 	: BaseInstaller() | ||||
| ForgeInstaller::ForgeInstaller() : BaseInstaller() | ||||
| { | ||||
| } | ||||
| void ForgeInstaller::prepare(const QString &filename, const QString &universalUrl) | ||||
| @@ -115,8 +115,8 @@ void ForgeInstaller::prepare(const QString &filename, const QString &universalUr | ||||
| 	} | ||||
| 	file.close(); | ||||
| 
 | ||||
| 	m_forge_version = newVersion; | ||||
| 	realVersionId = m_forge_version->id = installObj.value("minecraft").toString(); | ||||
| 	m_forge_json = newVersion; | ||||
| 	realVersionId = m_forge_json->id = installObj.value("minecraft").toString(); | ||||
| } | ||||
| bool ForgeInstaller::add(OneSixInstance *to) | ||||
| { | ||||
| @@ -128,7 +128,7 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 	QJsonObject obj; | ||||
| 	obj.insert("order", 5); | ||||
| 
 | ||||
| 	if (!m_forge_version) | ||||
| 	if (!m_forge_json) | ||||
| 		return false; | ||||
| 	int sliding_insert_window = 0; | ||||
| 	{ | ||||
| @@ -136,7 +136,7 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 
 | ||||
| 		// 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) | ||||
| 		for (auto lib : m_forge_json->libraries) | ||||
| 		{ | ||||
| 			QString libName = lib->name(); | ||||
| 			// WARNING: This could actually break.
 | ||||
| @@ -157,7 +157,7 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 			bool found = false; | ||||
| 			bool equals = false; | ||||
| 			// find an entry that matches this one
 | ||||
| 			for (auto tolib : to->getVanillaVersion()->libraries) | ||||
| 			for (auto tolib : to->getFullVersion()->vanillaLibraries) | ||||
| 			{ | ||||
| 				if (tolib->name() != libName) | ||||
| 					continue; | ||||
| @@ -187,8 +187,8 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 			librariesPlus.prepend(libObj); | ||||
| 		} | ||||
| 		obj.insert("+libraries", librariesPlus); | ||||
| 		obj.insert("mainClass", m_forge_version->mainClass); | ||||
| 		QString args = m_forge_version->minecraftArguments; | ||||
| 		obj.insert("mainClass", m_forge_json->mainClass); | ||||
| 		QString args = m_forge_json->minecraftArguments; | ||||
| 		QStringList tweakers; | ||||
| 		{ | ||||
| 			QRegularExpression expression("--tweakClass ([a-zA-Z0-9\\.]*)"); | ||||
| @@ -200,7 +200,7 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 				match = expression.match(args); | ||||
| 			} | ||||
| 		} | ||||
| 		if (!args.isEmpty() && args != to->getVanillaVersion()->minecraftArguments) | ||||
| 		if (!args.isEmpty() && args != to->getFullVersion()->vanillaMinecraftArguments) | ||||
| 		{ | ||||
| 			obj.insert("minecraftArguments", args); | ||||
| 		} | ||||
| @@ -208,10 +208,10 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 		{ | ||||
| 			obj.insert("+tweakers", QJsonArray::fromStringList(tweakers)); | ||||
| 		} | ||||
| 		if (!m_forge_version->processArguments.isEmpty() && | ||||
| 			m_forge_version->processArguments != to->getVanillaVersion()->processArguments) | ||||
| 		if (!m_forge_json->processArguments.isEmpty() && | ||||
| 			m_forge_json->processArguments != to->getFullVersion()->vanillaProcessArguments) | ||||
| 		{ | ||||
| 			obj.insert("processArguments", m_forge_version->processArguments); | ||||
| 			obj.insert("processArguments", m_forge_json->processArguments); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| @@ -233,11 +233,54 @@ bool ForgeInstaller::add(OneSixInstance *to) | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| bool ForgeInstaller::addLegacy(OneSixInstance *to) | ||||
| { | ||||
| 	if (!BaseInstaller::add(to)) | ||||
| 	{ | ||||
| 		return false; | ||||
| 	} | ||||
| 
 | ||||
| 	QJsonObject obj; | ||||
| 	obj.insert("order", 5); | ||||
| 	{ | ||||
| 		QJsonArray jarmodsPlus; | ||||
| 		{ | ||||
| 			QJsonObject libObj; | ||||
| 			libObj.insert("name", m_forge_version->universal_filename); | ||||
| 			jarmodsPlus.append(libObj); | ||||
| 		} | ||||
| 		obj.insert("+jarMods", jarmodsPlus); | ||||
| 	} | ||||
| 
 | ||||
| 	obj.insert("name", QString("Forge")); | ||||
| 	obj.insert("fileId", id()); | ||||
| 	obj.insert("version", m_forge_version->jobbuildver); | ||||
| 	obj.insert("mcVersion", to->intendedVersionId()); | ||||
| 	if (g_forgeData.fmlLibsMapping.contains(m_forge_version->mcver)) | ||||
| 	{ | ||||
| 		QJsonArray traitsPlus; | ||||
| 		traitsPlus.append(QString("legacyFML")); | ||||
| 		obj.insert("+traits", traitsPlus); | ||||
| 	} | ||||
| 
 | ||||
| 	QFile file(filename(to->instanceRoot())); | ||||
| 	if (!file.open(QFile::WriteOnly)) | ||||
| 	{ | ||||
| 		QLOG_ERROR() << "Error opening" << file.fileName() | ||||
| 					 << "for reading:" << file.errorString(); | ||||
| 		return false; | ||||
| 	} | ||||
| 	file.write(QJsonDocument(obj).toJson()); | ||||
| 	file.close(); | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| class ForgeInstallTask : public Task | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	ForgeInstallTask(ForgeInstaller *installer, OneSixInstance *instance, BaseVersionPtr version, QObject *parent = 0) | ||||
| 	ForgeInstallTask(ForgeInstaller *installer, OneSixInstance *instance, | ||||
| 					 BaseVersionPtr version, QObject *parent = 0) | ||||
| 		: Task(parent), m_installer(installer), m_instance(instance), m_version(version) | ||||
| 	{ | ||||
| 	} | ||||
| @@ -245,57 +288,60 @@ public: | ||||
| protected: | ||||
| 	void executeTask() override | ||||
| 	{ | ||||
| 		setStatus(tr("Installing forge...")); | ||||
| 		ForgeVersionPtr forgeVersion = std::dynamic_pointer_cast<ForgeVersion>(m_version); | ||||
| 		if (!forgeVersion) | ||||
| 		{ | ||||
| 			setStatus(tr("Installing forge...")); | ||||
| 			ForgeVersionPtr forgeVersion = | ||||
| 				std::dynamic_pointer_cast<ForgeVersion>(m_version); | ||||
| 			if (!forgeVersion) | ||||
| 			emitFailed(tr("Unknown error occured")); | ||||
| 			return; | ||||
| 		} | ||||
| 		prepare(forgeVersion); | ||||
| 	} | ||||
| 	void prepare(ForgeVersionPtr forgeVersion) | ||||
| 	{ | ||||
| 		auto entry = | ||||
| 			MMC->metacache()->resolveEntry("minecraftforge", forgeVersion->filename()); | ||||
| 		auto installFunction = [this, entry, forgeVersion]() | ||||
| 		{ | ||||
| 			if (!install(entry, forgeVersion)) | ||||
| 			{ | ||||
| 				emitFailed(tr("Unknown error occured")); | ||||
| 				return; | ||||
| 			} | ||||
| 			auto entry = MMC->metacache()->resolveEntry("minecraftforge", forgeVersion->filename); | ||||
| 			if (entry->stale) | ||||
| 			{ | ||||
| 				NetJob *fjob = new NetJob("Forge download"); | ||||
| 				fjob->addNetAction(CacheDownload::make(forgeVersion->installer_url, entry)); | ||||
| 				connect(fjob, &NetJob::progress, [this](qint64 current, qint64 total){setProgress(100 * current / qMax((qint64)1, total));}); | ||||
| 				connect(fjob, &NetJob::status, [this](const QString &msg){setStatus(msg);}); | ||||
| 				connect(fjob, &NetJob::failed, [this](){emitFailed(tr("Failure to download forge"));}); | ||||
| 				connect(fjob, &NetJob::succeeded, [this, entry, forgeVersion]() | ||||
| 				{ | ||||
| 					if (!install(entry, forgeVersion)) | ||||
| 					{ | ||||
| 						QLOG_ERROR() << "Failure installing forge"; | ||||
| 						emitFailed(tr("Failure to install forge")); | ||||
| 					} | ||||
| 					else | ||||
| 					{ | ||||
| 						reload(); | ||||
| 					} | ||||
| 				}); | ||||
| 				fjob->start(); | ||||
| 				QLOG_ERROR() << "Failure installing forge"; | ||||
| 				emitFailed(tr("Failure to install forge")); | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				if (!install(entry, forgeVersion)) | ||||
| 				{ | ||||
| 					QLOG_ERROR() << "Failure installing forge"; | ||||
| 					emitFailed(tr("Failure to install forge")); | ||||
| 				} | ||||
| 				else | ||||
| 				{ | ||||
| 					reload(); | ||||
| 				} | ||||
| 				reload(); | ||||
| 			} | ||||
| 		}; | ||||
| 		 | ||||
| 		if (entry->stale) | ||||
| 		{ | ||||
| 			NetJob *fjob = new NetJob("Forge download"); | ||||
| 			fjob->addNetAction(CacheDownload::make(forgeVersion->url(), entry)); | ||||
| 			connect(fjob, &NetJob::progress, [this](qint64 current, qint64 total) | ||||
| 			{ setProgress(100 * current / qMax((qint64)1, total)); }); | ||||
| 			connect(fjob, &NetJob::status, [this](const QString & msg) | ||||
| 			{ setStatus(msg); }); | ||||
| 			connect(fjob, &NetJob::failed, [this]() | ||||
| 			{ emitFailed(tr("Failure to download forge")); }); | ||||
| 			connect(fjob, &NetJob::succeeded, installFunction); | ||||
| 			fjob->start(); | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			installFunction(); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	bool install(const std::shared_ptr<MetaEntry> &entry, const ForgeVersionPtr &forgeVersion) | ||||
| 	{ | ||||
| 		QString forgePath = entry->getFullPath(); | ||||
| 		m_installer->prepare(forgePath, forgeVersion->universal_url); | ||||
| 		return m_installer->add(m_instance); | ||||
| 		if (forgeVersion->usesInstaller()) | ||||
| 		{ | ||||
| 			QString forgePath = entry->getFullPath(); | ||||
| 			m_installer->prepare(forgePath, forgeVersion->universal_url); | ||||
| 			return m_installer->add(m_instance); | ||||
| 		} | ||||
| 		else | ||||
| 			return m_installer->addLegacy(m_instance); | ||||
| 	} | ||||
| 	void reload() | ||||
| 	{ | ||||
| @@ -320,8 +366,14 @@ private: | ||||
| 	BaseVersionPtr m_version; | ||||
| }; | ||||
| 
 | ||||
| ProgressProvider *ForgeInstaller::createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) | ||||
| ProgressProvider *ForgeInstaller::createInstallTask(OneSixInstance *instance, | ||||
| 													BaseVersionPtr version, QObject *parent) | ||||
| { | ||||
| 	if (!version) | ||||
| 	{ | ||||
| 		return nullptr; | ||||
| 	} | ||||
| 	m_forge_version = std::dynamic_pointer_cast<ForgeVersion>(version); | ||||
| 	return new ForgeInstallTask(this, instance, version, parent); | ||||
| } | ||||
| 
 | ||||
| @@ -15,28 +15,34 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "BaseInstaller.h" | ||||
| #include "logic/BaseInstaller.h" | ||||
| 
 | ||||
| #include <QString> | ||||
| #include <memory> | ||||
| 
 | ||||
| class VersionFinal; | ||||
| class ForgeInstallTask; | ||||
| class ForgeVersion; | ||||
| 
 | ||||
| class ForgeInstaller : public BaseInstaller | ||||
| { | ||||
| 	friend class ForgeInstallTask; | ||||
| public: | ||||
| 	ForgeInstaller(); | ||||
| 	virtual ~ForgeInstaller(){}; | ||||
| 	virtual ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override; | ||||
| 
 | ||||
| protected: | ||||
| 	virtual QString id() const override { return "net.minecraftforge"; } | ||||
| 	void prepare(const QString &filename, const QString &universalUrl); | ||||
| 	bool add(OneSixInstance *to) override; | ||||
| 
 | ||||
| 	QString id() const override { return "net.minecraftforge"; } | ||||
| 
 | ||||
| 	ProgressProvider *createInstallTask(OneSixInstance *instance, BaseVersionPtr version, QObject *parent) override; | ||||
| 	bool addLegacy(OneSixInstance *to); | ||||
| 
 | ||||
| private: | ||||
| 	// the version, read from the installer
 | ||||
| 	std::shared_ptr<VersionFinal> m_forge_version; | ||||
| 	// the parsed version json, read from the installer
 | ||||
| 	std::shared_ptr<VersionFinal> m_forge_json; | ||||
| 	// the actual forge version
 | ||||
| 	std::shared_ptr<ForgeVersion> m_forge_version; | ||||
| 	QString internalPath; | ||||
| 	QString finalPath; | ||||
| 	QString realVersionId; | ||||
| @@ -15,10 +15,10 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "NetAction.h" | ||||
| #include "HttpMetaCache.h" | ||||
| #include "ForgeXzDownload.h" | ||||
| #include "NetJob.h" | ||||
| #include "logic/net/NetAction.h" | ||||
| #include "logic/net/HttpMetaCache.h" | ||||
| #include "logic/net/NetJob.h" | ||||
| #include "logic/forge/ForgeXzDownload.h" | ||||
| #include <QFile> | ||||
| #include <QTemporaryFile> | ||||
| typedef std::shared_ptr<class ForgeMirrors> ForgeMirrorsPtr; | ||||
							
								
								
									
										55
									
								
								logic/forge/ForgeVersion.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								logic/forge/ForgeVersion.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,55 @@ | ||||
| #include "ForgeVersion.h" | ||||
| #include "ForgeData.h" | ||||
| #include <QObject> | ||||
|  | ||||
| QString ForgeVersion::name() | ||||
| { | ||||
| 	return "Forge " + jobbuildver; | ||||
| } | ||||
|  | ||||
| QString ForgeVersion::descriptor() | ||||
| { | ||||
| 	return universal_filename; | ||||
| } | ||||
|  | ||||
| QString ForgeVersion::typeString() const | ||||
| { | ||||
| 	if (is_recommended) | ||||
| 		return QObject::tr("Recommended"); | ||||
| 	return QString(); | ||||
| } | ||||
|  | ||||
| bool ForgeVersion::operator<(BaseVersion &a) | ||||
| { | ||||
| 	ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a); | ||||
| 	if (!pa) | ||||
| 		return true; | ||||
| 	return m_buildnr < pa->m_buildnr; | ||||
| } | ||||
|  | ||||
| bool ForgeVersion::operator>(BaseVersion &a) | ||||
| { | ||||
| 	ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a); | ||||
| 	if (!pa) | ||||
| 		return false; | ||||
| 	return m_buildnr > pa->m_buildnr; | ||||
| } | ||||
|  | ||||
| bool ForgeVersion::usesInstaller() | ||||
| { | ||||
| 	if(installer_url.isEmpty()) | ||||
| 		return false; | ||||
| 	if(g_forgeData.forgeInstallerBlacklist.contains(mcver)) | ||||
| 		return false; | ||||
| 	return true; | ||||
| } | ||||
|  | ||||
| QString ForgeVersion::filename() | ||||
| { | ||||
| 	return usesInstaller() ? installer_filename : universal_filename; | ||||
| } | ||||
|  | ||||
| QString ForgeVersion::url() | ||||
| { | ||||
| 	return usesInstaller() ? installer_url : universal_url; | ||||
| } | ||||
							
								
								
									
										31
									
								
								logic/forge/ForgeVersion.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								logic/forge/ForgeVersion.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| #pragma once | ||||
| #include <QString> | ||||
| #include <memory> | ||||
| #include "logic/BaseVersion.h" | ||||
|  | ||||
| struct ForgeVersion; | ||||
| typedef std::shared_ptr<ForgeVersion> ForgeVersionPtr; | ||||
|  | ||||
| struct ForgeVersion : public BaseVersion | ||||
| { | ||||
| 	virtual QString descriptor() override; | ||||
| 	virtual QString name() override; | ||||
| 	virtual QString typeString() const override; | ||||
| 	virtual bool operator<(BaseVersion &a) override; | ||||
| 	virtual bool operator>(BaseVersion &a) override; | ||||
|  | ||||
| 	QString filename(); | ||||
| 	QString url(); | ||||
| 	 | ||||
| 	bool usesInstaller(); | ||||
|  | ||||
| 	int m_buildnr = 0; | ||||
| 	QString universal_url; | ||||
| 	QString changelog_url; | ||||
| 	QString installer_url; | ||||
| 	QString jobbuildver; | ||||
| 	QString mcver; | ||||
| 	QString universal_filename; | ||||
| 	QString installer_filename; | ||||
| 	bool is_recommended = false; | ||||
| }; | ||||
| @@ -13,9 +13,10 @@ | ||||
|  * limitations under the License. | ||||
|  */ | ||||
| 
 | ||||
| #include "ForgeVersionList.h" | ||||
| #include <logic/net/NetJob.h> | ||||
| #include <logic/net/URLConstants.h> | ||||
| #include "logic/forge/ForgeVersionList.h" | ||||
| #include "logic/forge/ForgeVersion.h" | ||||
| #include "logic/net/NetJob.h" | ||||
| #include "logic/net/URLConstants.h" | ||||
| #include "MultiMC.h" | ||||
| 
 | ||||
| #include <QtNetwork> | ||||
| @@ -236,7 +237,7 @@ bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out) | ||||
| 		if (!build_nr) | ||||
| 			continue; | ||||
| 		QJsonArray files = obj.value("files").toArray(); | ||||
| 		QString url, jobbuildver, mcver, buildtype, filename; | ||||
| 		QString url, jobbuildver, mcver, buildtype, universal_filename; | ||||
| 		QString changelog_url, installer_url; | ||||
| 		QString installer_filename; | ||||
| 		bool valid = false; | ||||
| @@ -254,7 +255,7 @@ bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out) | ||||
| 				url = file.value("url").toString(); | ||||
| 				jobbuildver = file.value("jobbuildver").toString(); | ||||
| 				int lastSlash = url.lastIndexOf('/'); | ||||
| 				filename = url.mid(lastSlash + 1); | ||||
| 				universal_filename = url.mid(lastSlash + 1); | ||||
| 				valid = true; | ||||
| 			} | ||||
| 			else if (buildtype == "changelog") | ||||
| @@ -282,14 +283,8 @@ bool ForgeListLoadTask::parseForgeList(QList<BaseVersionPtr> &out) | ||||
| 			fVersion->installer_url = installer_url; | ||||
| 			fVersion->jobbuildver = jobbuildver; | ||||
| 			fVersion->mcver = mcver; | ||||
| 			if (installer_filename.isEmpty()) | ||||
| 			{ | ||||
| 				fVersion->filename = filename; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				fVersion->filename = installer_filename; | ||||
| 			} | ||||
| 			fVersion->installer_filename = installer_filename; | ||||
| 			fVersion->universal_filename = universal_filename; | ||||
| 			fVersion->m_buildnr = build_nr; | ||||
| 			out.append(fVersion); | ||||
| 		} | ||||
| @@ -342,7 +337,7 @@ bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out) | ||||
| 		fVersion->m_buildnr = number.value("build").toDouble(); | ||||
| 		fVersion->jobbuildver = number.value("version").toString(); | ||||
| 		fVersion->mcver = number.value("mcversion").toString(); | ||||
| 		fVersion->filename = ""; | ||||
| 		fVersion->universal_filename = ""; | ||||
| 		QString filename, installer_filename; | ||||
| 		QJsonArray files = number.value("files").toArray(); | ||||
| 		for (auto fIt = files.begin(); fIt != files.end(); ++fIt) | ||||
| @@ -380,7 +375,8 @@ bool ForgeListLoadTask::parseForgeGradleList(QList<BaseVersionPtr> &out) | ||||
| 		{ | ||||
| 			continue; | ||||
| 		} | ||||
| 		fVersion->filename = fVersion->installer_url.isEmpty() ? filename : installer_filename; | ||||
| 		fVersion->universal_filename = filename; | ||||
| 		fVersion->installer_filename = installer_filename; | ||||
| 		out.append(fVersion); | ||||
| 	} | ||||
| 
 | ||||
| @@ -18,57 +18,12 @@ | ||||
| #include <QObject> | ||||
| #include <QAbstractListModel> | ||||
| #include <QUrl> | ||||
| 
 | ||||
| #include <QNetworkReply> | ||||
| #include "BaseVersionList.h" | ||||
| 
 | ||||
| #include "logic/lists/BaseVersionList.h" | ||||
| #include "logic/tasks/Task.h" | ||||
| #include "logic/net/NetJob.h" | ||||
| 
 | ||||
| class ForgeVersion; | ||||
| typedef std::shared_ptr<ForgeVersion> ForgeVersionPtr; | ||||
| 
 | ||||
| struct ForgeVersion : public BaseVersion | ||||
| { | ||||
| 	virtual QString descriptor() override | ||||
| 	{ | ||||
| 		return filename; | ||||
| 	} | ||||
| 	; | ||||
| 	virtual QString name() override | ||||
| 	{ | ||||
| 		return "Forge " + jobbuildver; | ||||
| 	} | ||||
| 	; | ||||
| 	virtual QString typeString() const override | ||||
| 	{ | ||||
| 		if (installer_url.isEmpty()) | ||||
| 			return "Universal"; | ||||
| 		else | ||||
| 			return "Installer"; | ||||
| 	} | ||||
| 
 | ||||
| 	virtual bool operator<(BaseVersion &a) override | ||||
| 	{ | ||||
| 		ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a); | ||||
| 		if(!pa) | ||||
| 			return true; | ||||
| 		return m_buildnr < pa->m_buildnr; | ||||
| 	} | ||||
| 	virtual bool operator>(BaseVersion &a) override | ||||
| 	{ | ||||
| 		ForgeVersion *pa = dynamic_cast<ForgeVersion *>(&a); | ||||
| 		if(!pa) | ||||
| 			return false; | ||||
| 		return m_buildnr > pa->m_buildnr; | ||||
| 	} | ||||
| 	int m_buildnr = 0; | ||||
| 	QString universal_url; | ||||
| 	QString changelog_url; | ||||
| 	QString installer_url; | ||||
| 	QString jobbuildver; | ||||
| 	QString mcver; | ||||
| 	QString filename; | ||||
| }; | ||||
| #include "logic/forge/ForgeVersion.h" | ||||
| 
 | ||||
| class ForgeVersionList : public BaseVersionList | ||||
| { | ||||
| @@ -15,8 +15,8 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "NetAction.h" | ||||
| #include "HttpMetaCache.h" | ||||
| #include "logic/net/NetAction.h" | ||||
| #include "logic/net/HttpMetaCache.h" | ||||
| #include <QFile> | ||||
| #include <QTemporaryFile> | ||||
| #include "ForgeMirror.h" | ||||
| @@ -15,7 +15,7 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "Mod.h" | ||||
| #include "logic/Mod.h" | ||||
| 
 | ||||
| class MinecraftForge : public Mod | ||||
| { | ||||
| @@ -212,6 +212,7 @@ void MCVListLoadTask::list_downloaded() | ||||
| 	{ | ||||
| 		bool is_snapshot = false; | ||||
| 		bool is_latest = false; | ||||
| 		bool legacyLaunch = false; | ||||
|  | ||||
| 		// Load the version info. | ||||
| 		if (!versions[i].isObject()) | ||||
| @@ -236,32 +237,28 @@ void MCVListLoadTask::list_downloaded() | ||||
| 			// FIXME: log this somewhere | ||||
| 			continue; | ||||
| 		} | ||||
| 		// Parse the type. | ||||
| 		MinecraftVersion::VersionType versionType; | ||||
| 		// OneSix or Legacy. use filter to determine type | ||||
| 		if (versionTypeStr == "release") | ||||
| 		{ | ||||
| 			versionType = legacyWhitelist.contains(versionID) ? MinecraftVersion::Legacy | ||||
| 															  : MinecraftVersion::OneSix; | ||||
| 			legacyLaunch = legacyWhitelist.contains(versionID); | ||||
| 			is_latest = (versionID == latestReleaseID); | ||||
| 			is_snapshot = false; | ||||
| 		} | ||||
| 		else if (versionTypeStr == "snapshot") // It's a snapshot... yay | ||||
| 		{ | ||||
| 			versionType = legacyWhitelist.contains(versionID) ? MinecraftVersion::Legacy | ||||
| 															  : MinecraftVersion::OneSix; | ||||
| 			legacyLaunch = legacyWhitelist.contains(versionID); | ||||
| 			is_latest = (versionID == latestSnapshotID); | ||||
| 			is_snapshot = true; | ||||
| 		} | ||||
| 		else if (versionTypeStr == "old_alpha") | ||||
| 		{ | ||||
| 			versionType = MinecraftVersion::Nostalgia; | ||||
| 			legacyLaunch = false; | ||||
| 			is_latest = false; | ||||
| 			is_snapshot = false; | ||||
| 		} | ||||
| 		else if (versionTypeStr == "old_beta") | ||||
| 		{ | ||||
| 			versionType = MinecraftVersion::Legacy; | ||||
| 			legacyLaunch = true; | ||||
| 			is_latest = false; | ||||
| 			is_snapshot = false; | ||||
| 		} | ||||
| @@ -280,7 +277,8 @@ void MCVListLoadTask::list_downloaded() | ||||
| 		mcVersion->download_url = dlUrl; | ||||
| 		mcVersion->is_latest = is_latest; | ||||
| 		mcVersion->is_snapshot = is_snapshot; | ||||
| 		mcVersion->type = versionType; | ||||
| 		if(legacyLaunch) | ||||
| 			mcVersion->features.insert("legacy"); | ||||
| 		tempList.append(mcVersion); | ||||
| 	} | ||||
| 	m_list->updateListData(tempList); | ||||
|   | ||||
| @@ -20,11 +20,11 @@ | ||||
| 
 | ||||
| #include "logger/QsLog.h" | ||||
| 
 | ||||
| #include "VersionFinal.h" | ||||
| #include "OneSixLibrary.h" | ||||
| #include "OneSixInstance.h" | ||||
| #include "logic/VersionFinal.h" | ||||
| #include "logic/OneSixLibrary.h" | ||||
| #include "logic/OneSixInstance.h" | ||||
| #include "MultiMC.h" | ||||
| #include "lists/LiteLoaderVersionList.h" | ||||
| #include "logic/liteloader/LiteLoaderVersionList.h" | ||||
| 
 | ||||
| LiteLoaderInstaller::LiteLoaderInstaller() : BaseInstaller() | ||||
| { | ||||
| @@ -15,12 +15,11 @@ | ||||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include "BaseInstaller.h" | ||||
| 
 | ||||
| #include <QString> | ||||
| #include <QMap> | ||||
| 
 | ||||
| #include "logic/lists/LiteLoaderVersionList.h" | ||||
| #include "logic/BaseInstaller.h" | ||||
| #include "logic/liteloader/LiteLoaderVersionList.h" | ||||
| 
 | ||||
| class LiteLoaderInstaller : public BaseInstaller | ||||
| { | ||||
| @@ -19,10 +19,10 @@ | ||||
| 
 | ||||
| #include <QString> | ||||
| #include <QStringList> | ||||
| #include "BaseVersionList.h" | ||||
| #include "logic/lists/BaseVersionList.h" | ||||
| #include "logic/tasks/Task.h" | ||||
| #include "logic/BaseVersion.h" | ||||
| #include <logic/net/NetJob.h> | ||||
| #include "logic/net/NetJob.h" | ||||
| 
 | ||||
| class LLListLoadTask; | ||||
| class QNetworkReply; | ||||
| @@ -21,7 +21,7 @@ | ||||
| #include "MD5EtagDownload.h" | ||||
| #include "CacheDownload.h" | ||||
| #include "HttpMetaCache.h" | ||||
| #include "ForgeXzDownload.h" | ||||
| //#include "logic/forge/ForgeXzDownload.h" | ||||
| #include "logic/tasks/ProgressProvider.h" | ||||
|  | ||||
| class NetJob; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user