aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetr Mrázek <peterix@gmail.com>2015-09-06 23:35:58 +0200
committerPetr Mrázek <peterix@gmail.com>2015-09-06 23:35:58 +0200
commit38693e1d6ca7f05d9488348ddf298488d1cc0995 (patch)
treed99551fc3ebbef931d10ee45cb34f2ee791cc1fe
parent40b233448c7a3977d45831b8aa6cf31019c03940 (diff)
downloadPrismLauncher-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar.gz
PrismLauncher-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar.bz2
PrismLauncher-38693e1d6ca7f05d9488348ddf298488d1cc0995.zip
GH-1047 parse world files and integrate MCEdit with world page
-rw-r--r--CMakeLists.txt5
-rw-r--r--application/pages/WorldListPage.cpp104
-rw-r--r--application/pages/WorldListPage.h6
-rw-r--r--application/pages/WorldListPage.ui209
-rw-r--r--depends/libnbtplusplus/CMakeLists.txt50
-rw-r--r--depends/libnbtplusplus/COPYING674
-rw-r--r--depends/libnbtplusplus/COPYING.LESSER165
-rw-r--r--depends/libnbtplusplus/PRD.md60
-rw-r--r--depends/libnbtplusplus/README.md15
-rw-r--r--depends/libnbtplusplus/include/crtp_tag.h66
-rw-r--r--depends/libnbtplusplus/include/endian_str.h113
-rw-r--r--depends/libnbtplusplus/include/io/stream_reader.h138
-rw-r--r--depends/libnbtplusplus/include/io/stream_writer.h122
-rw-r--r--depends/libnbtplusplus/include/make_unique.h37
-rw-r--r--depends/libnbtplusplus/include/nbt_tags.h29
-rw-r--r--depends/libnbtplusplus/include/nbt_visitor.h82
-rw-r--r--depends/libnbtplusplus/include/primitive_detail.h46
-rw-r--r--depends/libnbtplusplus/include/tag.h159
-rw-r--r--depends/libnbtplusplus/include/tag_array.h131
-rw-r--r--depends/libnbtplusplus/include/tag_compound.h144
-rw-r--r--depends/libnbtplusplus/include/tag_list.h224
-rw-r--r--depends/libnbtplusplus/include/tag_primitive.h102
-rw-r--r--depends/libnbtplusplus/include/tag_string.h74
-rw-r--r--depends/libnbtplusplus/include/tagfwd.h51
-rw-r--r--depends/libnbtplusplus/include/text/json_formatter.h47
-rw-r--r--depends/libnbtplusplus/include/value.h223
-rw-r--r--depends/libnbtplusplus/include/value_initializer.h67
-rw-r--r--depends/libnbtplusplus/src/endian_str.cpp284
-rw-r--r--depends/libnbtplusplus/src/io/stream_reader.cpp110
-rw-r--r--depends/libnbtplusplus/src/io/stream_writer.cpp54
-rw-r--r--depends/libnbtplusplus/src/tag.cpp105
-rw-r--r--depends/libnbtplusplus/src/tag_array.cpp110
-rw-r--r--depends/libnbtplusplus/src/tag_compound.cpp109
-rw-r--r--depends/libnbtplusplus/src/tag_list.cpp150
-rw-r--r--depends/libnbtplusplus/src/tag_string.cpp44
-rw-r--r--depends/libnbtplusplus/src/text/json_formatter.cpp195
-rw-r--r--depends/libnbtplusplus/src/value.cpp376
-rw-r--r--depends/libnbtplusplus/src/value_initializer.cpp36
-rw-r--r--depends/libnbtplusplus/test/CMakeLists.txt22
-rw-r--r--depends/libnbtplusplus/test/endian_str_test.h175
-rw-r--r--depends/libnbtplusplus/test/format_test.cpp81
-rw-r--r--depends/libnbtplusplus/test/nbttest.h476
-rw-r--r--depends/libnbtplusplus/test/read_test.h216
-rw-r--r--depends/libnbtplusplus/test/testfiles/bigtest.nbtbin0 -> 561 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/bigtest_uncomprbin0 -> 1601 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/errortest_eof1bin0 -> 43 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/errortest_eof2bin0 -> 94 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/errortest_neg_lengthbin0 -> 47 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/errortest_noendbin0 -> 48 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/level.dat.2bin0 -> 175521 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/littletest_uncomprbin0 -> 1601 bytes
-rw-r--r--depends/libnbtplusplus/test/testfiles/toplevel_stringbin0 -> 165 bytes
-rw-r--r--depends/libnbtplusplus/test/write_test.h248
-rw-r--r--logic/CMakeLists.txt2
-rw-r--r--logic/minecraft/World.cpp126
-rw-r--r--logic/minecraft/World.h24
-rw-r--r--logic/minecraft/WorldList.cpp34
-rw-r--r--logic/minecraft/WorldList.h144
58 files changed, 6091 insertions, 173 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 411c4b16..2655379b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,6 +118,11 @@ include_directories(${PACK200_INCLUDE_DIR})
add_subdirectory(depends/rainbow)
include_directories(${RAINBOW_INCLUDE_DIR})
+# Add color thingy
+add_subdirectory(depends/libnbtplusplus)
+include_directories(${LIBNBTPP_INCLUDE_DIR})
+include_directories(${LIBNBTPP_BIN_INCLUDE_DIR})
+
######## MultiMC Libs ########
# Add the util library.
diff --git a/application/pages/WorldListPage.cpp b/application/pages/WorldListPage.cpp
index de31f519..8b95b2b0 100644
--- a/application/pages/WorldListPage.cpp
+++ b/application/pages/WorldListPage.cpp
@@ -19,7 +19,12 @@
#include "dialogs/ModEditDialogCommon.h"
#include <QEvent>
#include <QKeyEvent>
+#include <QClipboard>
#include <QMessageBox>
+#include <QTreeView>
+
+
+#include "MultiMC.h"
WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worlds, QString id,
QString iconName, QString displayName, QString helpPage,
@@ -28,8 +33,20 @@ WorldListPage::WorldListPage(BaseInstance *inst, std::shared_ptr<WorldList> worl
{
ui->setupUi(this);
ui->tabWidget->tabBar()->hide();
- ui->worldTreeView->setModel(m_worlds.get());
+ QSortFilterProxyModel * proxy = new QSortFilterProxyModel(this);
+ proxy->setSourceModel(m_worlds.get());
+ ui->worldTreeView->setSortingEnabled(true);
+ ui->worldTreeView->setModel(proxy);
ui->worldTreeView->installEventFilter(this);
+
+ auto head = ui->worldTreeView->header();
+
+ head->setSectionResizeMode(0, QHeaderView::Stretch);
+ head->setSectionResizeMode(1, QHeaderView::ResizeToContents);
+ connect(ui->worldTreeView->selectionModel(),
+ SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this,
+ SLOT(worldChanged(const QModelIndex &, const QModelIndex &)));
+ worldChanged(QModelIndex(), QModelIndex());
}
void WorldListPage::opened()
@@ -79,12 +96,12 @@ bool WorldListPage::eventFilter(QObject *obj, QEvent *ev)
return worldListFilter(keyEvent);
return QWidget::eventFilter(obj, ev);
}
+
void WorldListPage::on_rmWorldBtn_clicked()
{
- int first, last;
- auto list = ui->worldTreeView->selectionModel()->selectedRows();
+ auto proxiedIndex = getSelectedWorld();
- if (!lastfirst(list, first, last))
+ if(!proxiedIndex.isValid())
return;
auto result = QMessageBox::question(this,
@@ -98,7 +115,7 @@ void WorldListPage::on_rmWorldBtn_clicked()
return;
}
m_worlds->stopWatching();
- m_worlds->deleteWorlds(first, last);
+ m_worlds->deleteWorld(proxiedIndex.row());
m_worlds->startWatching();
}
@@ -106,3 +123,80 @@ void WorldListPage::on_viewFolderBtn_clicked()
{
openDirInDefaultProgram(m_worlds->dir().absolutePath(), true);
}
+
+QModelIndex WorldListPage::getSelectedWorld()
+{
+ auto index = ui->worldTreeView->selectionModel()->currentIndex();
+
+ auto proxy = (QSortFilterProxyModel *) ui->worldTreeView->model();
+ return proxy->mapToSource(index);
+}
+
+void WorldListPage::on_copySeedBtn_clicked()
+{
+ QModelIndex index = getSelectedWorld();
+
+ if (!index.isValid())
+ {
+ return;
+ }
+ int64_t seed = m_worlds->data(index, WorldList::SeedRole).toLongLong();
+ MMC->clipboard()->setText(QString::number(seed));
+}
+
+void WorldListPage::on_mcEditBtn_clicked()
+{
+ const QString mceditPath = MMC->settings()->get("MCEditPath").toString();
+
+ QModelIndex index = getSelectedWorld();
+
+ if (!index.isValid())
+ {
+ return;
+ }
+
+ auto fullPath = m_worlds->data(index, WorldList::FolderRole).toString();
+
+#ifdef Q_OS_OSX
+ QProcess *process = new QProcess();
+ connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), process, SLOT(deleteLater()));
+ process->setProgram(mceditPath);
+ process->setArguments(QStringList() << fullPath);
+ process->start();
+#else
+ QDir mceditDir(mceditPath);
+ QString program;
+ #ifdef Q_OS_LINUX
+ if (mceditDir.exists("mcedit.py"))
+ {
+ program = mceditDir.absoluteFilePath("mcedit.py");
+ }
+ else if (mceditDir.exists("mcedit.sh"))
+ {
+ program = mceditDir.absoluteFilePath("mcedit.sh");
+ }
+ #elif defined(Q_OS_WIN32)
+ if (mceditDir.exists("mcedit.exe"))
+ {
+ program = mceditDir.absoluteFilePath("mcedit.exe");
+ }
+ else if (mceditDir.exists("mcedit2.exe"))
+ {
+ program = mceditDir.absoluteFilePath("mcedit2.exe");
+ }
+ #endif
+ if(program.size())
+ {
+ QProcess::startDetached(program, QStringList() << fullPath, mceditPath);
+ }
+#endif
+}
+
+void WorldListPage::worldChanged(const QModelIndex &current, const QModelIndex &previous)
+{
+ QModelIndex index = getSelectedWorld();
+ bool enable = index.isValid();
+ ui->copySeedBtn->setEnabled(enable);
+ ui->mcEditBtn->setEnabled(enable);
+ ui->rmWorldBtn->setEnabled(enable);
+}
diff --git a/application/pages/WorldListPage.h b/application/pages/WorldListPage.h
index d3de5d3c..c79f1be6 100644
--- a/application/pages/WorldListPage.h
+++ b/application/pages/WorldListPage.h
@@ -67,6 +67,9 @@ protected:
BaseInstance *m_inst;
private:
+ QModelIndex getSelectedWorld();
+
+private:
Ui::WorldListPage *ui;
std::shared_ptr<WorldList> m_worlds;
QString m_iconName;
@@ -75,6 +78,9 @@ private:
QString m_helpName;
private slots:
+ void on_copySeedBtn_clicked();
+ void on_mcEditBtn_clicked();
void on_rmWorldBtn_clicked();
void on_viewFolderBtn_clicked();
+ void worldChanged(const QModelIndex &current, const QModelIndex &previous);
};
diff --git a/application/pages/WorldListPage.ui b/application/pages/WorldListPage.ui
index b8100acd..9d396fa6 100644
--- a/application/pages/WorldListPage.ui
+++ b/application/pages/WorldListPage.ui
@@ -1,94 +1,125 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>WorldListPage</class>
- <widget class="QWidget" name="WorldListPage">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>723</width>
- <height>532</height>
- </rect>
- </property>
- <property name="windowTitle">
- <string>Mods</string>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <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>
- <widget class="QTabWidget" name="tabWidget">
- <property name="currentIndex">
- <number>0</number>
- </property>
- <widget class="QWidget" name="tab">
- <attribute name="title">
- <string>Tab 1</string>
- </attribute>
- <layout class="QGridLayout" name="gridLayout">
- <item row="0" column="0">
- <widget class="QTreeView" name="worldTreeView">
- <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="dragDropMode">
- <enum>QAbstractItemView::DropOnly</enum>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <layout class="QVBoxLayout" name="verticalLayout_2">
- <item>
- <widget class="QPushButton" name="rmWorldBtn">
- <property name="text">
- <string>&amp;Remove</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="verticalSpacer">
- <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="viewFolderBtn">
- <property name="text">
- <string>&amp;View Folder</string>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </widget>
- </item>
+ <class>WorldListPage</class>
+ <widget class="QWidget" name="WorldListPage">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>723</width>
+ <height>532</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Mods</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <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>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>0</number>
+ </property>
+ <widget class="QWidget" name="tab">
+ <attribute name="title">
+ <string>Tab 1</string>
+ </attribute>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <widget class="QTreeView" name="worldTreeView">
+ <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="dragDropMode">
+ <enum>QAbstractItemView::DropOnly</enum>
+ </property>
+ <property name="sortingEnabled">
+ <bool>true</bool>
+ </property>
+ <property name="allColumnsShowFocus">
+ <bool>true</bool>
+ </property>
+ <attribute name="headerStretchLastSection">
+ <bool>false</bool>
+ </attribute>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <layout class="QVBoxLayout" name="verticalLayout_2">
+ <item>
+ <widget class="QPushButton" name="mcEditBtn">
+ <property name="text">
+ <string>MCEdit</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="copySeedBtn">
+ <property name="text">
+ <string>Copy Seed</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="rmWorldBtn">
+ <property name="text">
+ <string>&amp;Remove</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer">
+ <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="viewFolderBtn">
+ <property name="text">
+ <string>&amp;View Folder</string>
+ </property>
+ </widget>
+ </item>
</layout>
+ </item>
+ </layout>
+ </widget>
</widget>
- <resources/>
- <connections/>
+ </item>
+ </layout>
+ </widget>
+ <tabstops>
+ <tabstop>tabWidget</tabstop>
+ <tabstop>worldTreeView</tabstop>
+ <tabstop>mcEditBtn</tabstop>
+ <tabstop>copySeedBtn</tabstop>
+ <tabstop>rmWorldBtn</tabstop>
+ <tabstop>viewFolderBtn</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
</ui>
diff --git a/depends/libnbtplusplus/CMakeLists.txt b/depends/libnbtplusplus/CMakeLists.txt
new file mode 100644
index 00000000..63bd3d41
--- /dev/null
+++ b/depends/libnbtplusplus/CMakeLists.txt
@@ -0,0 +1,50 @@
+cmake_minimum_required(VERSION 3.2)
+project(libnbt++ VERSION 2.1)
+
+add_definitions(-std=c++11)
+include_directories(include)
+
+set(nbt_sources
+ src/endian_str.cpp
+ src/tag.cpp
+ src/tag_array.cpp
+ src/tag_compound.cpp
+ src/tag_list.cpp
+ src/tag_string.cpp
+ src/value.cpp
+ src/value_initializer.cpp
+
+ src/io/stream_reader.cpp
+ src/io/stream_writer.cpp
+
+ src/text/json_formatter.cpp
+
+ include/value_initializer.h
+ include/tag.h
+ include/io
+ include/io/stream_writer.h
+ include/io/stream_reader.h
+ include/crtp_tag.h
+ include/tag_string.h
+ include/value.h
+ include/tag_primitive.h
+ include/tag_list.h
+ include/tagfwd.h
+ include/make_unique.h
+ include/primitive_detail.h
+ include/endian_str.h
+ include/tag_compound.h
+ include/nbt_tags.h
+ include/nbt_visitor.h
+ include/text
+ include/text/json_formatter.h
+ include/tag_array.h
+)
+
+set(LIBNBTPP_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include" PARENT_SCOPE)
+set(LIBNBTPP_BIN_INCLUDE_DIR "${CMAKE_CURRENT_BINARY_DIR}" PARENT_SCOPE)
+
+add_library(nbt++ SHARED ${nbt_sources})
+generate_export_header(nbt++)
+
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
diff --git a/depends/libnbtplusplus/COPYING b/depends/libnbtplusplus/COPYING
new file mode 100644
index 00000000..94a9ed02
--- /dev/null
+++ b/depends/libnbtplusplus/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+ To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. You must make sure that they, too, receive
+or can get the source code. And you must show them these terms so they
+know their rights.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an