summaryrefslogtreecommitdiffstats
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
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
-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
-rw-r--r--application/CMakeLists.txt3
-rw-r--r--application/InstancePageProvider.h2
-rw-r--r--application/pages/instance/GameOptionsPage.cpp40
-rw-r--r--application/pages/instance/GameOptionsPage.h63
-rw-r--r--application/pages/instance/GameOptionsPage.ui88
10 files changed, 389 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;
+};
diff --git a/application/CMakeLists.txt b/application/CMakeLists.txt
index 30ef7268..26852df0 100644
--- a/application/CMakeLists.txt
+++ b/application/CMakeLists.txt
@@ -84,6 +84,8 @@ SET(MULTIMC_SOURCES
pages/BasePageProvider.h
# GUI - instance pages
+ pages/instance/GameOptionsPage.cpp
+ pages/instance/GameOptionsPage.h
pages/instance/VersionPage.cpp
pages/instance/VersionPage.h
pages/instance/TexturePackPage.h
@@ -229,6 +231,7 @@ SET(MULTIMC_SOURCES
######## UIs ########
SET(MULTIMC_UIS
# Instance pages
+ pages/instance/GameOptionsPage.ui
pages/instance/VersionPage.ui
pages/instance/ModFolderPage.ui
pages/instance/LogPage.ui
diff --git a/application/InstancePageProvider.h b/application/InstancePageProvider.h
index e72ba797..db57941e 100644
--- a/application/InstancePageProvider.h
+++ b/application/InstancePageProvider.h
@@ -16,6 +16,7 @@
#include "pages/instance/LegacyUpgradePage.h"
#include "pages/instance/WorldListPage.h"
#include "pages/instance/ServersPage.h"
+#include "pages/instance/GameOptionsPage.h"
#include "Env.h"
@@ -46,6 +47,7 @@ public:
values.append(new NotesPage(onesix.get()));
values.append(new WorldListPage(onesix.get(), onesix->worldList(), "worlds", "worlds", tr("Worlds"), "Worlds"));
values.append(new ServersPage(onesix.get()));
+ values.append(new GameOptionsPage(onesix.get()));
values.append(new ScreenshotsPage(FS::PathCombine(onesix->gameRoot(), "screenshots")));
values.append(new InstanceSettingsPage(onesix.get()));
}
diff --git a/application/pages/instance/GameOptionsPage.cpp b/application/pages/instance/GameOptionsPage.cpp
new file mode 100644
index 00000000..5555fc79
--- /dev/null
+++ b/application/pages/instance/GameOptionsPage.cpp
@@ -0,0 +1,40 @@
+#include "GameOptionsPage.h"
+#include "ui_GameOptionsPage.h"
+#include "minecraft/MinecraftInstance.h"
+#include "minecraft/gameoptions/GameOptions.h"
+
+GameOptionsPage::GameOptionsPage(MinecraftInstance * inst, QWidget* parent)
+ : QWidget(parent), ui(new Ui::GameOptionsPage)
+{
+ ui->setupUi(this);
+ ui->tabWidget->tabBar()->hide();
+ m_model = inst->gameOptionsModel();
+ ui->optionsView->setModel(m_model.get());
+ auto head = ui->optionsView->header();
+ if(head->count())
+ {
+ head->setSectionResizeMode(0, QHeaderView::ResizeToContents);
+ for(int i = 1; i < head->count(); i++)
+ {
+ head->setSectionResizeMode(i, QHeaderView::Stretch);
+ }
+ }
+}
+
+GameOptionsPage::~GameOptionsPage()
+{
+ // m_model->save();
+}
+
+void GameOptionsPage::openedImpl()
+{
+ // m_model->observe();
+}
+
+void GameOptionsPage::closedImpl()
+{
+ // m_model->unobserve();
+}
+
+#include "GameOptionsPage.moc"
+
diff --git a/application/pages/instance/GameOptionsPage.h b/application/pages/instance/GameOptionsPage.h
new file mode 100644
index 00000000..ae47747f
--- /dev/null
+++ b/application/pages/instance/GameOptionsPage.h
@@ -0,0 +1,63 @@
+/* Copyright 2013-2019 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 <QWidget>
+#include <QString>
+
+#include "pages/BasePage.h"
+#include <MultiMC.h>
+
+namespace Ui
+{
+class GameOptionsPage;
+}
+
+class GameOptions;
+class MinecraftInstance;
+
+class GameOptionsPage : public QWidget, public BasePage
+{
+ Q_OBJECT
+
+public:
+ explicit GameOptionsPage(MinecraftInstance *inst, QWidget *parent = 0);
+ virtual ~GameOptionsPage();
+
+ void openedImpl() override;
+ void closedImpl() override;
+
+ virtual QString displayName() const override
+ {
+ return tr("Game Options");
+ }
+ virtual QIcon icon() const override
+ {
+ return MMC->getThemedIcon("settings");
+ }
+ virtual QString id() const override
+ {
+ return "gameoptions";
+ }
+ virtual QString helpPage() const override
+ {
+ return "Game-Options-management";
+ }
+
+private: // data
+ Ui::GameOptionsPage *ui = nullptr;
+ std::shared_ptr<GameOptions> m_model;
+};
diff --git a/application/pages/instance/GameOptionsPage.ui b/application/pages/instance/GameOptionsPage.ui
new file mode 100644
index 00000000..f0a5ce0e
--- /dev/null
+++ b/application/pages/instance/GameOptionsPage.ui
@@ -0,0 +1,88 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>GameOptionsPage</class>
+ <widget class="QWidget" name="GameOptionsPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>706</width>
+ <height>575</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item row="0" column="0">
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <attribute name="title">
+ <string notr="true">Tab 1</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout_2">
+ <item row="0" column="0" colspan="2">
+ <widget class="QTreeView" name="optionsView">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="acceptDrops">
+ <bool>true</bool>
+ </property>
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::SingleSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ <property name="iconSize">
+ <size>
+ <width>64</width>
+ <height>64</height>
+ </size>
+ </property>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
+ </property>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>optionsView</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>