summaryrefslogtreecommitdiffstats
path: root/api/logic
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2019-01-30 00:35:24 +0100
committerPetr Mrázek <peterix@gmail.com>2019-01-30 00:35:24 +0100
commit62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e (patch)
tree4a83da8a22fbb67281ea4c9a729ef750f0ce37ad /api/logic
parentc1ea42d3d9b793b52d52310f69174f1c5ab9daef (diff)
downloadMultiMC-62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e.tar
MultiMC-62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e.tar.gz
MultiMC-62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e.tar.lz
MultiMC-62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e.tar.xz
MultiMC-62c9fcdc6cd6b80540cdb8d79ce92db32cfd284e.zip
NOISSUE first step towards having game options management
Diffstat (limited to 'api/logic')
-rw-r--r--api/logic/CMakeLists.txt2
-rw-r--r--api/logic/minecraft/MinecraftInstance.cpp10
-rw-r--r--api/logic/minecraft/MinecraftInstance.h4
-rw-r--r--api/logic/minecraft/gameoptions/GameOptions.cpp144
-rw-r--r--api/logic/minecraft/gameoptions/GameOptions.h34
5 files changed, 193 insertions, 1 deletions
diff --git a/api/logic/CMakeLists.txt b/api/logic/CMakeLists.txt
index 45b01b9f..57a197be 100644
--- a/api/logic/CMakeLists.txt
+++ b/api/logic/CMakeLists.txt
@@ -211,6 +211,8 @@ set(MINECRAFT_SOURCES
minecraft/auth/flows/RefreshTask.cpp
minecraft/auth/flows/ValidateTask.h
minecraft/auth/flows/ValidateTask.cpp
+ minecraft/gameoptions/GameOptions.h
+ minecraft/gameoptions/GameOptions.cpp
minecraft/update/AssetUpdateTask.h
minecraft/update/AssetUpdateTask.cpp
minecraft/update/FMLLibrariesTask.cpp
diff --git a/api/logic/minecraft/MinecraftInstance.cpp b/api/logic/minecraft/MinecraftInstance.cpp
index fecb951a..bf4eb1bd 100644
--- a/api/logic/minecraft/MinecraftInstance.cpp
+++ b/api/logic/minecraft/MinecraftInstance.cpp
@@ -35,6 +35,7 @@
#include "AssetsUtils.h"
#include "MinecraftUpdate.h"
#include "MinecraftLoadAndCheck.h"
+#include <minecraft/gameoptions/GameOptions.h>
#define IBUS "@im=ibus"
@@ -935,6 +936,15 @@ std::shared_ptr<WorldList> MinecraftInstance::worldList() const
return m_world_list;
}
+std::shared_ptr<GameOptions> MinecraftInstance::gameOptionsModel() const
+{
+ if (!m_game_options)
+ {
+ m_game_options.reset(new GameOptions(FS::PathCombine(gameRoot(), "options.txt")));
+ }
+ return m_game_options;
+}
+
QList< Mod > MinecraftInstance::getJarMods() const
{
auto profile = m_components->getProfile();
diff --git a/api/logic/minecraft/MinecraftInstance.h b/api/logic/minecraft/MinecraftInstance.h
index 5f0fa353..091d1bf7 100644
--- a/api/logic/minecraft/MinecraftInstance.h
+++ b/api/logic/minecraft/MinecraftInstance.h
@@ -9,6 +9,7 @@
class ModsModel;
class SimpleModList;
class WorldList;
+class GameOptions;
class LaunchStep;
class ComponentList;
@@ -72,7 +73,7 @@ public:
std::shared_ptr<SimpleModList> resourcePackList() const;
std::shared_ptr<SimpleModList> texturePackList() const;
std::shared_ptr<WorldList> worldList() const;
-
+ std::shared_ptr<GameOptions> gameOptionsModel() const;
////// Launch stuff //////
shared_qobject_ptr<Task> createUpdateTask(Net::Mode mode) override;
@@ -130,6 +131,7 @@ protected: // data
mutable std::shared_ptr<SimpleModList> m_resource_pack_list;
mutable std::shared_ptr<SimpleModList> m_texture_pack_list;
mutable std::shared_ptr<WorldList> m_world_list;
+ mutable std::shared_ptr<GameOptions> m_game_options;
};
typedef std::shared_ptr<MinecraftInstance> MinecraftInstancePtr;
diff --git a/api/logic/minecraft/gameoptions/GameOptions.cpp b/api/logic/minecraft/gameoptions/GameOptions.cpp
new file mode 100644
index 00000000..5dab8b86
--- /dev/null
+++ b/api/logic/minecraft/gameoptions/GameOptions.cpp
@@ -0,0 +1,144 @@
+#include "GameOptions.h"
+#include "FileSystem.h"
+#include <QDebug>
+#include <QSaveFile>
+
+namespace {
+bool load(const QString& path, std::vector<GameOptionItem> &contents, int & version)
+{
+ contents.clear();
+ QFile file(path);
+ if (!file.open(QFile::ReadOnly))
+ {
+ qWarning() << "Failed to read options file.";
+ return false;
+ }
+ version = 0;
+ while(!file.atEnd())
+ {
+ auto line = file.readLine();
+ if(line.back() == '\n')
+ {
+ line.chop(1);
+ }
+ auto separatorIndex = line.indexOf(':');
+ if(separatorIndex == -1)
+ {
+ continue;
+ }
+ auto key = QString::fromUtf8(line.data(), separatorIndex);
+ auto value = QString::fromUtf8(line.data() + separatorIndex + 1, line.size() - 1 - separatorIndex);
+ qDebug() << "!!" << key << "!!";
+ if(key == "version")
+ {
+ version = value.toInt();
+ continue;
+ }
+ contents.emplace_back(GameOptionItem{key, value});
+ }
+ qDebug() << "Loaded" << path << "with version:" << version;
+ return true;
+}
+bool save(const QString& path, std::vector<GameOptionItem> &mapping, int version)
+{
+ QSaveFile out(path);
+ if(!out.open(QIODevice::WriteOnly))
+ {
+ return false;
+ }
+ if(version != 0)
+ {
+ QString versionLine = QString("version:%1\n").arg(version);
+ out.write(versionLine.toUtf8());
+ }
+ auto iter = mapping.begin();
+ while (iter != mapping.end())
+ {
+ out.write(iter->key.toUtf8());
+ out.write(":");
+ out.write(iter->value.toUtf8());
+ out.write("\n");
+ iter++;
+ }
+ return out.commit();
+}
+}
+
+GameOptions::GameOptions(const QString& path):
+ path(path)
+{
+ reload();
+}
+
+QVariant GameOptions::headerData(int section, Qt::Orientation orientation, int role) const
+{
+ if(role != Qt::DisplayRole)
+ {
+ return QAbstractListModel::headerData(section, orientation, role);
+ }
+ switch(section)
+ {
+ case 0:
+ return tr("Key");
+ case 1:
+ return tr("Value");
+ default:
+ return QVariant();
+ }
+}
+
+QVariant GameOptions::data(const QModelIndex& index, int role) const
+{
+ if (!index.isValid())
+ return QVariant();
+
+ int row = index.row();
+ int column = index.column();
+
+ if (row < 0 || row >= int(contents.size()))
+ return QVariant();
+
+ switch (role)
+ {
+ case Qt::DisplayRole:
+ if(column == 0)
+ {
+ return contents[row].key;
+ }
+ else
+ {
+ return contents[row].value;
+ }
+ default:
+ return QVariant();
+ }
+ return QVariant();
+}
+
+int GameOptions::rowCount(const QModelIndex&) const
+{
+ return contents.size();
+}
+
+int GameOptions::columnCount(const QModelIndex&) const
+{
+ return 2;
+}
+
+bool GameOptions::isLoaded() const
+{
+ return loaded;
+}
+
+bool GameOptions::reload()
+{
+ beginResetModel();
+ loaded = load(path, contents, version);
+ endResetModel();
+ return loaded;
+}
+
+bool GameOptions::save()
+{
+ return ::save(path, contents, version);
+}
diff --git a/api/logic/minecraft/gameoptions/GameOptions.h b/api/logic/minecraft/gameoptions/GameOptions.h
new file mode 100644
index 00000000..c6d25492
--- /dev/null
+++ b/api/logic/minecraft/gameoptions/GameOptions.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include <map>
+#include <QString>
+#include <QAbstractListModel>
+
+struct GameOptionItem
+{
+ QString key;
+ QString value;
+};
+
+class GameOptions : public QAbstractListModel
+{
+ Q_OBJECT
+public:
+ explicit GameOptions(const QString& path);
+ virtual ~GameOptions() = default;
+
+ int rowCount(const QModelIndex &parent = QModelIndex()) const override;
+ int columnCount(const QModelIndex & parent) const override;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
+ QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
+
+ bool isLoaded() const;
+ bool reload();
+ bool save();
+
+private:
+ std::vector<GameOptionItem> contents;
+ bool loaded = false;
+ QString path;
+ int version = 0;
+};