Lock down the version cache. Just enough to make it annoying to corrupt the files.
This commit is contained in:
parent
f3900f2966
commit
55a0d110b6
@ -50,6 +50,7 @@
|
|||||||
#include "CustomMessageBox.h"
|
#include "CustomMessageBox.h"
|
||||||
#include <QDesktopServices>
|
#include <QDesktopServices>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
|
#include <QListView>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QUrl>
|
#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()
|
void InstanceEditDialog::on_resetLibraryOrderBtn_clicked()
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@ -192,8 +213,10 @@ void InstanceEditDialog::on_moveLibraryUpBtn_clicked()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
|
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
|
||||||
const int newRow = 0;m_version->move(row, VersionFinal::MoveUp);
|
const int newRow = 0;
|
||||||
//ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect);
|
m_version->move(row, VersionFinal::MoveUp);
|
||||||
|
// ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow),
|
||||||
|
// QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
catch (MMCError &e)
|
catch (MMCError &e)
|
||||||
{
|
{
|
||||||
@ -210,8 +233,10 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked()
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
|
const int row = ui->libraryTreeView->selectionModel()->selectedRows().first().row();
|
||||||
const int newRow = 0;m_version->move(row, VersionFinal::MoveDown);
|
const int newRow = 0;
|
||||||
//ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow), QItemSelectionModel::ClearAndSelect);
|
m_version->move(row, VersionFinal::MoveDown);
|
||||||
|
// ui->libraryTreeView->selectionModel()->setCurrentIndex(m_version->index(newRow),
|
||||||
|
// QItemSelectionModel::ClearAndSelect);
|
||||||
}
|
}
|
||||||
catch (MMCError &e)
|
catch (MMCError &e)
|
||||||
{
|
{
|
||||||
@ -221,7 +246,8 @@ void InstanceEditDialog::on_moveLibraryDownBtn_clicked()
|
|||||||
|
|
||||||
void InstanceEditDialog::on_changeMCVersionBtn_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())
|
if (!vselect.exec() || !vselect.selectedVersion())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -266,8 +292,9 @@ void InstanceEditDialog::on_forgeBtn_clicked()
|
|||||||
// FIXME: use actual model, not reloading. Move logic to model.
|
// FIXME: use actual model, not reloading. Move logic to model.
|
||||||
if (m_version->hasFtbPack())
|
if (m_version->hasFtbPack())
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, tr("Revert?"),
|
if (QMessageBox::question(
|
||||||
tr("This action will remove the FTB pack version patch. Continue?")) !=
|
this, tr("Revert?"),
|
||||||
|
tr("This action will remove the FTB pack version patch. Continue?")) !=
|
||||||
QMessageBox::Yes)
|
QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -293,7 +320,8 @@ void InstanceEditDialog::on_forgeBtn_clicked()
|
|||||||
if (vselect.exec() && vselect.selectedVersion())
|
if (vselect.exec() && vselect.selectedVersion())
|
||||||
{
|
{
|
||||||
ProgressDialog dialog(this);
|
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 (m_version->hasFtbPack())
|
||||||
{
|
{
|
||||||
if (QMessageBox::question(this, tr("Revert?"),
|
if (QMessageBox::question(
|
||||||
tr("This action will remove the FTB pack version patch. Continue?")) !=
|
this, tr("Revert?"),
|
||||||
|
tr("This action will remove the FTB pack version patch. Continue?")) !=
|
||||||
QMessageBox::Yes)
|
QMessageBox::Yes)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -329,7 +358,8 @@ void InstanceEditDialog::on_liteloaderBtn_clicked()
|
|||||||
if (vselect.exec() && vselect.selectedVersion())
|
if (vselect.exec() && vselect.selectedVersion())
|
||||||
{
|
{
|
||||||
ProgressDialog dialog(this);
|
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);
|
ui->frame->updateWithMod(m);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InstanceEditDialog::versionCurrent(const QModelIndex ¤t,
|
void InstanceEditDialog::versionCurrent(const QModelIndex ¤t, const QModelIndex &previous)
|
||||||
const QModelIndex &previous)
|
|
||||||
{
|
{
|
||||||
if (!current.isValid())
|
if (!current.isValid())
|
||||||
{
|
{
|
||||||
|
@ -44,6 +44,7 @@ slots:
|
|||||||
void on_resetLibraryOrderBtn_clicked();
|
void on_resetLibraryOrderBtn_clicked();
|
||||||
void on_moveLibraryUpBtn_clicked();
|
void on_moveLibraryUpBtn_clicked();
|
||||||
void on_moveLibraryDownBtn_clicked();
|
void on_moveLibraryDownBtn_clicked();
|
||||||
|
void on_jarmodBtn_clicked();
|
||||||
|
|
||||||
// loader mod tab
|
// loader mod tab
|
||||||
void on_addModBtn_clicked();
|
void on_addModBtn_clicked();
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "logic/OneSixInstance_p.h"
|
#include "logic/OneSixInstance_p.h"
|
||||||
#include "logic/OneSixUpdate.h"
|
#include "logic/OneSixUpdate.h"
|
||||||
#include "logic/minecraft/VersionFinal.h"
|
#include "logic/minecraft/VersionFinal.h"
|
||||||
|
#include "minecraft/VersionBuildError.h"
|
||||||
|
|
||||||
#include "logic/assets/AssetsUtils.h"
|
#include "logic/assets/AssetsUtils.h"
|
||||||
#include "icons/IconList.h"
|
#include "icons/IconList.h"
|
||||||
@ -42,21 +43,13 @@ OneSixInstance::OneSixInstance(const QString &rootDir, SettingsObject *settings,
|
|||||||
|
|
||||||
void OneSixInstance::init()
|
void OneSixInstance::init()
|
||||||
{
|
{
|
||||||
// FIXME: why is this decided here? what does this even mean?
|
try
|
||||||
if (QDir(instanceRoot()).exists("version.json"))
|
|
||||||
{
|
{
|
||||||
try
|
reloadVersion();
|
||||||
{
|
|
||||||
reloadVersion();
|
|
||||||
}
|
|
||||||
catch (MMCError &e)
|
|
||||||
{
|
|
||||||
// QLOG_ERROR() << "Caught exception on instance init: " << e.cause();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
catch (MMCError &e)
|
||||||
{
|
{
|
||||||
clearVersion();
|
QLOG_ERROR() << "Caught exception on instance init: " << e.cause();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,6 +381,10 @@ void OneSixInstance::reloadVersion()
|
|||||||
d->version->reload(externalPatches());
|
d->version->reload(externalPatches());
|
||||||
d->m_flags.remove(VersionBrokenFlag);
|
d->m_flags.remove(VersionBrokenFlag);
|
||||||
emit versionReloaded();
|
emit versionReloaded();
|
||||||
|
}
|
||||||
|
catch (VersionIncomplete & error)
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (MMCError &error)
|
catch (MMCError &error)
|
||||||
{
|
{
|
||||||
|
@ -56,9 +56,9 @@ bool MinecraftVersion::isMinecraftVersion()
|
|||||||
// 2. if discrepancies are found, fall out and fail (impossible to apply incomplete version).
|
// 2. if discrepancies are found, fall out and fail (impossible to apply incomplete version).
|
||||||
void MinecraftVersion::applyFileTo(VersionFinal *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);
|
versionObj->applyTo(version);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,8 @@
|
|||||||
#include <logic/VersionFilterData.h>
|
#include <logic/VersionFilterData.h>
|
||||||
#include <pathutils.h>
|
#include <pathutils.h>
|
||||||
|
|
||||||
|
static const char * localVersionCache = "versions/versions.dat";
|
||||||
|
|
||||||
class ListLoadError : public MMCError
|
class ListLoadError : public MMCError
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -78,7 +80,7 @@ void MinecraftVersionList::sortInternal()
|
|||||||
|
|
||||||
void MinecraftVersionList::loadCachedList()
|
void MinecraftVersionList::loadCachedList()
|
||||||
{
|
{
|
||||||
QFile localIndex("versions/versions.json");
|
QFile localIndex(localVersionCache);
|
||||||
if (!localIndex.exists())
|
if (!localIndex.exists())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
@ -92,13 +94,18 @@ void MinecraftVersionList::loadCachedList()
|
|||||||
auto data = localIndex.readAll();
|
auto data = localIndex.readAll();
|
||||||
try
|
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)
|
catch (MMCError &e)
|
||||||
{
|
{
|
||||||
// the cache has gone bad for some reason... flush it.
|
// the cache has gone bad for some reason... flush it.
|
||||||
QLOG_ERROR() << "The minecraft version cache is corrupted. Flushing cache.";
|
QLOG_ERROR() << "The minecraft version cache is corrupted. Flushing cache.";
|
||||||
localIndex.close();
|
|
||||||
localIndex.remove();
|
localIndex.remove();
|
||||||
return;
|
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.";
|
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())
|
if (!jsonDoc.isObject())
|
||||||
{
|
{
|
||||||
throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object"));
|
throw ListLoadError(tr("Error parsing version list JSON: jsonDoc is not an object"));
|
||||||
@ -391,7 +390,14 @@ void MCVListLoadTask::list_downloaded()
|
|||||||
vlistReply->deleteLater();
|
vlistReply->deleteLater();
|
||||||
try
|
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)
|
catch (MMCError &e)
|
||||||
{
|
{
|
||||||
@ -474,9 +480,9 @@ void MCVListVersionUpdateTask::json_downloaded()
|
|||||||
|
|
||||||
// now dump the file to disk
|
// now dump the file to disk
|
||||||
auto doc = file->toJson(false);
|
auto doc = file->toJson(false);
|
||||||
auto newdata = doc.toJson();
|
auto newdata = doc.toBinaryData();
|
||||||
QLOG_INFO() << newdata;
|
QLOG_INFO() << newdata;
|
||||||
QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".json";
|
QString targetPath = "versions/" + versionToUpdate + "/" + versionToUpdate + ".dat";
|
||||||
ensureFilePathExists(targetPath);
|
ensureFilePathExists(targetPath);
|
||||||
QSaveFile vfile1(targetPath);
|
QSaveFile vfile1(targetPath);
|
||||||
if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
|
if (!vfile1.open(QIODevice::Truncate | QIODevice::WriteOnly))
|
||||||
@ -511,9 +517,9 @@ std::shared_ptr<Task> MinecraftVersionList::createUpdateTask(QString version)
|
|||||||
void MinecraftVersionList::saveCachedList()
|
void MinecraftVersionList::saveCachedList()
|
||||||
{
|
{
|
||||||
// FIXME: throw.
|
// FIXME: throw.
|
||||||
if (!ensureFilePathExists("versions/versions.json"))
|
if (!ensureFilePathExists(localVersionCache))
|
||||||
return;
|
return;
|
||||||
QSaveFile tfile("versions/versions.json");
|
QSaveFile tfile(localVersionCache);
|
||||||
if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
if (!tfile.open(QIODevice::WriteOnly | QIODevice::Truncate))
|
||||||
return;
|
return;
|
||||||
QJsonObject toplevel;
|
QJsonObject toplevel;
|
||||||
@ -554,7 +560,7 @@ void MinecraftVersionList::saveCachedList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
QJsonDocument doc(toplevel);
|
QJsonDocument doc(toplevel);
|
||||||
QByteArray jsonData = doc.toJson();
|
QByteArray jsonData = doc.toBinaryData();
|
||||||
qint64 result = tfile.write(jsonData);
|
qint64 result = tfile.write(jsonData);
|
||||||
if (result == -1)
|
if (result == -1)
|
||||||
return;
|
return;
|
||||||
|
@ -34,7 +34,7 @@ class MinecraftVersionList : public BaseVersionList
|
|||||||
private:
|
private:
|
||||||
void sortInternal();
|
void sortInternal();
|
||||||
void loadBuiltinList();
|
void loadBuiltinList();
|
||||||
void loadMojangList(QByteArray data, VersionSource source);
|
void loadMojangList(QJsonDocument jsonDoc, VersionSource source);
|
||||||
void loadCachedList();
|
void loadCachedList();
|
||||||
void saveCachedList();
|
void saveCachedList();
|
||||||
void finalizeUpdate(QString version);
|
void finalizeUpdate(QString version);
|
||||||
|
@ -237,6 +237,25 @@ VersionFilePtr VersionBuilder::parseJsonFile(const QFileInfo &fileInfo, const bo
|
|||||||
// info.").arg(file.fileName());
|
// 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> VersionBuilder::readOverrideOrders(OneSixInstance *instance)
|
||||||
{
|
{
|
||||||
QMap<QString, int> out;
|
QMap<QString, int> out;
|
||||||
|
@ -31,6 +31,7 @@ public:
|
|||||||
static void build(VersionFinal *version, OneSixInstance *instance, const QStringList &external);
|
static void build(VersionFinal *version, OneSixInstance *instance, const QStringList &external);
|
||||||
static void readJsonAndApplyToVersion(VersionFinal *version, const QJsonObject &obj);
|
static void readJsonAndApplyToVersion(VersionFinal *version, const QJsonObject &obj);
|
||||||
static VersionFilePtr parseJsonFile(const QFileInfo &fileInfo, const bool requireOrder, bool isFTB = false);
|
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 QMap<QString, int> readOverrideOrders(OneSixInstance *instance);
|
||||||
static bool writeOverrideOrders(const QMap<QString, int> &order, OneSixInstance *instance);
|
static bool writeOverrideOrders(const QMap<QString, int> &order, OneSixInstance *instance);
|
||||||
|
Loading…
Reference in New Issue
Block a user