summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2014-05-13 23:57:34 +0200
committerPetr Mrázek <peterix@gmail.com>2014-06-09 01:38:31 +0200
commit55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d (patch)
tree5957085e7e33d0b8f85859f421c1571b0ae6f978
parentf3900f2966e8c211fee51ece156da054df2d47c7 (diff)
downloadMultiMC-55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d.tar
MultiMC-55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d.tar.gz
MultiMC-55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d.tar.lz
MultiMC-55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d.tar.xz
MultiMC-55a0d110b654a93ef1bb9ee50a6f02ecaec7f88d.zip
Lock down the version cache. Just enough to make it annoying to corrupt the files.
-rw-r--r--gui/dialogs/InstanceEditDialog.cpp55
-rw-r--r--gui/dialogs/InstanceEditDialog.h1
-rw-r--r--logic/OneSixInstance.cpp21
-rw-r--r--logic/minecraft/MinecraftVersion.cpp4
-rw-r--r--logic/minecraft/MinecraftVersionList.cpp42
-rw-r--r--logic/minecraft/MinecraftVersionList.h2
-rw-r--r--logic/minecraft/VersionBuilder.cpp19
-rw-r--r--logic/minecraft/VersionBuilder.h1
8 files changed, 99 insertions, 46 deletions
diff --git a/gui/dialogs/InstanceEditDialog.cpp b/gui/dialogs/InstanceEditDialog.cpp
index 5bd923e3..48657c71 100644
--- a/gui/dialogs/InstanceEditDialog.cpp
+++ b/gui/dialogs/InstanceEditDialog.cpp
@@ -50,6 +50,7 @@
#include "CustomMessageBox.h"
#include <QDesktopServices>
#include <QMessageBox>
+#include <QListView>
#include <QString>
#include <QUrl>
@@ -171,6 +172,26 @@ void InstanceEditDialog::on_removeLibraryBtn_clicked()
}
}
+void InstanceEditDialog::on_jarmodBtn_clicked()
+{
+ QFileDialog w;
+ w.setFileMode(QFileDialog::AnyFile);
+ // w.setOption(QFileDialog::DontUseNativeDialog, true);
+ QListView *l = w.findChild<QListView *>("listView");
+ if (l)
+ {
+ l->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ }
+ QTreeView *t = w.findChild<QTreeView *>();
+ if (t)
+ {
+ t->setSelectionMode(QAbstractItemView::ExtendedSelection);
+ }
+ int result = w.exec();
+ auto list = w.selectedFiles();
+ QLOG_INFO() << list.join(" ");
+}
+
void InstanceEditDialog::on_resetLibraryOrderBtn_clicked()
{
try
@@ -192,8 +213,10 @@ void InstanceEditDialog::on_moveLibraryUpBtn_clicked()
try
{
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
- const int newRow = 0;m_version->move(row, VersionFinal::MoveUp);
- //ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect);
+ const int newRow = 0;
+ m_version->move(row, VersionFinal::MoveUp);
+ // ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow),
+ // QItemSelectionModel::ClearAndSelect);
}
catch (MMCError &e)
{
@@ -210,8 +233,10 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked()
try
{
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
- const int newRow = 0;m_version->move(row, VersionFinal::MoveDown);
- //ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect);
+ const int newRow = 0;
+ m_version->move(row, VersionFinal::MoveDown);
+ // ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow),
+ // QItemSelectionModel::ClearAndSelect);
}
catch (MMCError &e)
{
@@ -221,7 +246,8 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked()
void InstanceEditDialog::on_changeMCVersionBtn_clicked()
{
- VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"), this);
+ VersionSelectDialog vselect(m_inst->versionList().get(), tr("Change Minecraft version"),
+ this);
if (!vselect.exec() || !vselect.selectedVersion())
return;
@@ -266,8 +292,9 @@ void InstanceEditDialog::on_forgeBtn_clicked()
// FIXME: use actual model, not reloading. Move logic to model.
if (m_version->hasFtbPack())
{
- if (QMessageBox::question(this, tr("Revert?"),
- tr("This action will remove the FTB pack version patch. Continue?")) !=
+ if (QMessageBox::question(
+ this, tr("Revert?"),
+ tr("This action will remove the FTB pack version patch. Continue?")) !=
QMessageBox::Yes)
{
return;
@@ -293,7 +320,8 @@ void InstanceEditDialog::on_forgeBtn_clicked()
if (vselect.exec() && vselect.selectedVersion())
{
ProgressDialog dialog(this);
- dialog.exec(ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
+ dialog.exec(
+ ForgeInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
}
}
@@ -301,8 +329,9 @@ void InstanceEditDialog::on_liteloaderBtn_clicked()
{
if (m_version->hasFtbPack())
{
- if (QMessageBox::question(this, tr("Revert?"),
- tr("This action will remove the FTB pack version patch. Continue?")) !=
+ if (QMessageBox::question(
+ this, tr("Revert?"),
+ tr("This action will remove the FTB pack version patch. Continue?")) !=
QMessageBox::Yes)
{
return;
@@ -329,7 +358,8 @@ void InstanceEditDialog::on_liteloaderBtn_clicked()
if (vselect.exec() && vselect.selectedVersion())
{
ProgressDialog dialog(this);
- dialog.exec(LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
+ dialog.exec(
+ LiteLoaderInstaller().createInstallTask(m_inst, vselect.selectedVersion(), this));
}
}
@@ -497,8 +527,7 @@ void InstanceEditDialog::loaderCurrent(QModelIndex current, QModelIndex previous
ui->frame->updateWithMod(m);
}
-void InstanceEditDialog::versionCurrent(const QModelIndex &current,
- const QModelIndex &previous)
+void InstanceEditDialog::versionCurrent(const QModelIndex &current, const QModelIndex &previous)
{
if (!current.isValid())
{
diff --git a/gui/dialogs/InstanceEditDialog.h b/gui/dialogs/InstanceEditDialog.h
index d601074a..e99899be 100644
--- a/gui/dialogs/InstanceEditDialog.h
+++ b/gui/dialogs/InstanceEditDialog.h
@@ -44,6 +44,7 @@ slots:
void on_resetLibraryOrderBtn_clicked();
void on_moveLibraryUpBtn_clicked();
void on_moveLibraryDownBtn_clicked();
+ void on_jarmodBtn_clicked();
// loader mod tab
void on_addModBtn_clicked();
diff --git a/logic/OneSixInstance.cpp b/logic/OneSixInstance.cpp
index 574dfc69..fc53bd39 100644
--- a/logic/OneSixInstance.cpp
+++ b/logic/OneSixInstance.cpp
@@ -24,6 +24,7 @@
#include "logic/OneSixInstance_p.h"
#include "logic/OneSixUpdate.h"
#include "logic/minecraft/VersionFinal.h"
+#include "minecraft/VersionBuildError.h"
#include "logic/assets/AssetsUtils.h"
#include "icons/IconList.h"
@@ -42,21 +43,13 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings,
void OneSixInstance::init()
{
- // FIXME: why is this decided here? what does this even mean?
- if (QDir(instanceRoot()).exists("version.json"))
+ try
{
- try
- {
- reloadVersion();
- }
- catch (MMCError &e)
- {
- // QLOG_ERROR() << "Caught exception on instance init: " << e.cause();
- }
+ reloadVersion();
}
- else
+ catch (MMCError &e)
{
- clearVersion();
+ QLOG_ERROR() << "Caught exception on instance init: " << e.cause();
}
}
@@ -389,6 +382,10 @@ void OneSixInstance::reloadVersion()
d->m_flags.remove(VersionBrokenFlag);
emit versionReloaded();
}
+ catch (VersionIncomplete & error)
+ {
+
+ }
catch (MMCError &error)
{
d->version->clear();
diff --git a/logic/minecraft/MinecraftVersion.cpp b/logic/minecraft/MinecraftVersion.cpp
index b66b9768..21cdbacc 100644
--- a/logic/minecraft/MinecraftVersion.cpp
+++ b/logic/minecraft/MinecraftVersion.cpp
@@ -56,9 +56,9 @@ bool MinecraftVersion::isMinecraftVersion()
// 2. if discrepancies are found, fall out and fail (impossible to apply incomplete version).
void MinecraftVersion::applyFileTo(VersionFinal *version)
{
- QFileInfo versionFile(QString("versions/%1/%1.json").arg(m_descriptor));
+ QFileInfo versionFile(QString("versions/%1/%1.dat").arg(m_descriptor));
- auto versionObj = VersionBuilder::parseJsonFile(versionFile, false, false);
+ auto versionObj = VersionBuilder::parseBinaryJsonFile(versionFile);
versionObj->applyTo(version);
}
diff --git a/logic/minecraft/MinecraftVersionList.cpp b/logic/minecraft/MinecraftVersionList.cpp
index 8c30e38d..b561606b 100644
--- a/logic/minecraft/MinecraftVersionList.cpp
+++ b/logic/minecraft/MinecraftVersionList.cpp
@@ -29,6 +29,8 @@
#include <logic/VersionFilterData.h>
#include <pathutils.h>
+static const char * localVersionCache = "versions/versions.dat";
+
class ListLoadError : public MMCError
{
public:
@@ -78,7 +80,7 @@ void MinecraftVersionList::sortInternal()
void MinecraftVersionList::loadCachedList()
{
- QFile localIndex("versions/versions.json");
+ QFile localIndex(localVersionCache);
if (!localIndex.exists())
{
return;
@@ -92,13 +94,18 @@ void MinecraftVersionList::loadCachedList()
auto data = localIndex.readAll();
try
{
- loadMojangList(data, Local);
+ localIndex.close();
+ QJsonDocument jsonDoc = QJsonDocument::fromBinaryData(data);
+ if (jsonDoc.isNull())
+ {
+ throw ListLoadError(tr("Error reading the version list."));
+ }
+ loadMojangList(jsonDoc, Local);
}
catch (MMCError &e)
{
// the cache has gone bad for some reason... flush it.
QLOG_ERROR() << "The minecraft version cache is corrupted. Flushing cache.";
- localIndex.close();
localIndex.remove();
return;
}
@@ -172,18 +179,10 @@ void MinecraftVersionList::loadBuiltinList()
}
}
-void MinecraftVersionList::loadMojangList(QByteArray data, VersionSource source)
+void MinecraftVersionList::loadMojangList(QJsonDocument jsonDoc, VersionSource source)
{
QLOG_INFO() << "Loading" << ((source == Remote) ? "remote" : "local") << "version list.";
- QJsonParseError jsonError;
- QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
- if (jsonError.error != QJsonParseError::NoError)
- {
- throw ListLoadError(
- tr("Error parsing version list JSON: %1").arg(jsonError.errorString()));
- }
-
if (!jsonDoc.isObject())
{
throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object"));
@@ -391,7 +390,14 @@ void MCVListLoadTask::list_downloaded()
vlistReply->deleteLater();
try
{
- m_list->loadMojangList(data, Remote);
+ QJsonParseError jsonError;
+ QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &jsonError);
+ if (jsonError.error != QJsonParseError::NoError)
+ {
+ throw ListLoadError(
+ tr("Error parsing version list JSON: %1").arg(jsonError.errorString()));
+ }
+ m_list->loadMojangList(jsonDoc, Remote);
}
catch (MMCError &e)
{
@@ -474,9 +480,9 @@ void MCVListVersionUpdateTask::json_downloaded()
// now dump the file to disk
auto doc = file->toJson(false);
- auto newdata = doc.toJson();
+ auto newdata = doc.toBinaryData();
QLOG_INFO() << newdata;
- QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".json";
+ QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".dat";
ensureFilePathExists(targetPath);
QSaveFile vfile1(targetPath);
if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
@@ -511,9 +517,9 @@ std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version)
void MinecraftVersionList::saveCachedList()
{
// FIXME: throw.
- if (!ensureFilePathExists("versions/versions.json"))
+ if (!ensureFilePathExists(localVersionCache))
return;
- QSaveFile tfile("versions/versions.json");
+ QSaveFile tfile(localVersionCache);
if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
return;
QJsonObject toplevel;
@@ -554,7 +560,7 @@ void MinecraftVersionList::saveCachedList()
}
QJsonDocument doc(toplevel);
- QByteArray jsonData = doc.toJson();
+ QByteArray jsonData = doc.toBinaryData();
qint64 result = tfile.write(jsonData);
if (result == -1)
return;
diff --git a/logic/minecraft/MinecraftVersionList.h b/logic/minecraft/MinecraftVersionList.h
index bbbd71e1..4753ce05 100644
--- a/logic/minecraft/MinecraftVersionList.h
+++ b/logic/minecraft/MinecraftVersionList.h
@@ -34,7 +34,7 @@ class MinecraftVersionList : public BaseVersionList
private:
void sortInternal();
void loadBuiltinList();
- void loadMojangList(QByteArray data, VersionSource source);
+ void loadMojangList(QJsonDocument jsonDoc, VersionSource source);
void loadCachedList();
void saveCachedList();
void finalizeUpdate(QString version);
diff --git a/logic/minecraft/VersionBuilder.cpp b/logic/minecraft/VersionBuilder.cpp
index d19c2877..cff70821 100644
--- a/logic/minecraft/VersionBuilder.cpp
+++ b/logic/minecraft/VersionBuilder.cpp
@@ -237,6 +237,25 @@ VersionFilePtr VersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const bo
// info.").arg(file.fileName());
}
+VersionFilePtr VersionBuilder::parseBinaryJsonFile(const QFileInfo &fileInfo)
+{
+ QFile file(fileInfo.absoluteFilePath());
+ if (!file.open(QFile::ReadOnly))
+ {
+ throw JSONValidationError(QObject::tr("Unable to open the version file %1: %2.")
+ .arg(fileInfo.fileName(), file.errorString()));
+ }
+ QJsonDocument doc = QJsonDocument::fromBinaryData(file.readAll());
+ file.close();
+ if (doc.isNull())
+ {
+ file.remove();
+ throw JSONValidationError(
+ QObject::tr("Unable to process the version file %1.").arg(fileInfo.fileName()));
+ }
+ return VersionFile::fromJson(doc, file.fileName(), false, false);
+}
+
QMap<QString, int> VersionBuilder::readOverrideOrders(OneSixInstance *instance)
{
QMap<QString, int> out;
diff --git a/logic/minecraft/VersionBuilder.h b/logic/minecraft/VersionBuilder.h
index fc06e614..6097840b 100644
--- a/logic/minecraft/VersionBuilder.h
+++ b/logic/minecraft/VersionBuilder.h
@@ -31,6 +31,7 @@ public:
static void build(VersionFinal *version, OneSixInstance *instance, const QStringList &external);
static void readJsonAndApplyToVersion(VersionFinal *version, const QJsonObject &obj);
static VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB = false);
+ static VersionFilePtr parseBinaryJsonFile(const QFileInfo &fileInfo);
static QMap<QString, int> readOverrideOrders(OneSixInstance *instance);
static bool writeOverrideOrders(const QMap<QString, int> &order, OneSixInstance *instance);