From 14123c6d1653b79b6c58e7766dc97e5d06bf1fc9 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 20 Sep 2014 23:03:13 +0200 Subject: [PATCH] QtBiomeVisualiser: Added list of vanilla worlds. --- Tools/QtBiomeVisualiser/MainWindow.cpp | 134 +++++++++++++++++++++++-- Tools/QtBiomeVisualiser/MainWindow.h | 20 ++++ 2 files changed, 146 insertions(+), 8 deletions(-) diff --git a/Tools/QtBiomeVisualiser/MainWindow.cpp b/Tools/QtBiomeVisualiser/MainWindow.cpp index b6db806f9..c56cf8bc2 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.cpp +++ b/Tools/QtBiomeVisualiser/MainWindow.cpp @@ -5,9 +5,13 @@ #include #include #include +#include +#include #include "inifile/iniFile.h" #include "ChunkSource.h" #include "Generating/BioGen.h" +#include "StringCompression.h" +#include "WorldStorage/FastNBT.h" @@ -16,6 +20,8 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) { + initMinecraftPath(); + m_BiomeView = new BiomeView(this); setCentralWidget(m_BiomeView); @@ -66,8 +72,41 @@ void MainWindow::open() +void MainWindow::openVanillaWorld() +{ + QAction * action = qobject_cast(sender()); + if (action == nullptr) + { + return; + } + m_BiomeView->setChunkSource(std::shared_ptr(new AnvilSource(action->data().toString()))); + m_BiomeView->redraw(); +} + + + + + +void MainWindow::initMinecraftPath() +{ + #ifdef Q_OS_MAC + m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/Library/Application Support/minecraft"); + #elif defined Q_OS_WIN32 + QSettings ini(QSettings::IniFormat, QSettings::UserScope, ".minecraft", "minecraft1"); + m_MinecraftPath = QFileInfo(ini.fileName()).absolutePath(); + #else + m_MinecraftPath = QDir::homePath() + QDir::toNativeSeparators("/.minecraft"); + #endif +} + + + + + void MainWindow::createActions() { + createWorldActions(); + m_actGen = new QAction(tr("&Generate..."), this); m_actGen->setShortcut(tr("Ctrl+N")); m_actGen->setStatusTip(tr("Open a generator INI file and display the generated biomes")); @@ -93,15 +132,94 @@ void MainWindow::createActions() -void MainWindow::createMenus() +void MainWindow::createWorldActions() { - QMenu * mFile = menuBar()->addMenu(tr("&World")); - mFile->addAction(m_actGen); - mFile->addAction(m_actOpen); - mFile->addSeparator(); - mFile->addAction(m_actReload); - mFile->addSeparator(); - mFile->addAction(m_actExit); + QDir mc(m_MinecraftPath); + if (!mc.cd("saves")) + { + return; + } + + QDirIterator it(mc); + int key = 1; + while (it.hasNext()) + { + it.next(); + if (!it.fileInfo().isDir()) + { + continue; + } + QString name = getWorldName(it.filePath().toStdString()); + if (name.isEmpty()) + { + continue; + } + QAction * w = new QAction(this); + w->setText(name); + w->setData(it.filePath() + "/region"); + if (key < 10) + { + w->setShortcut("Ctrl+" + QString::number(key)); + key++; + } + connect(w, SIGNAL(triggered()), this, SLOT(openVanillaWorld())); + m_WorldActions.append(w); + } +} + + + + + +void MainWindow::createMenus() +{ + QMenu * file = menuBar()->addMenu(tr("&Map")); + file->addAction(m_actGen); + file->addSeparator(); + QMenu * worlds = file->addMenu(tr("Open existing")); + worlds->addActions(m_WorldActions); + if (m_WorldActions.empty()) + { + worlds->setEnabled(false); + } + file->addAction(m_actOpen); + file->addSeparator(); + file->addAction(m_actReload); + file->addSeparator(); + file->addAction(m_actExit); +} + + + + + +QString MainWindow::getWorldName(const AString & a_Path) +{ + AString levelData = cFile::ReadWholeFile(a_Path + "/level.dat"); + if (levelData.empty()) + { + // No such file / no data + return QString(); + } + + AString uncompressed; + if (UncompressStringGZIP(levelData.data(), levelData.size(), uncompressed) != Z_OK) + { + return QString(); + } + cParsedNBT nbt(uncompressed.data(), uncompressed.size()); + if (!nbt.IsValid()) + { + return QString(); + } + AString name = nbt.GetName(1); + OutputDebugStringA(name.c_str()); + int levelNameTag = nbt.FindTagByPath(nbt.GetRoot(), "Data\\LevelName"); + if ((levelNameTag <= 0) || (nbt.GetType(levelNameTag) != TAG_String)) + { + return QString(); + } + return QString::fromStdString(nbt.GetString(levelNameTag)); } diff --git a/Tools/QtBiomeVisualiser/MainWindow.h b/Tools/QtBiomeVisualiser/MainWindow.h index b37bf4120..997d7a5d2 100644 --- a/Tools/QtBiomeVisualiser/MainWindow.h +++ b/Tools/QtBiomeVisualiser/MainWindow.h @@ -1,5 +1,6 @@ #pragma once +#include #include #include "BiomeView.h" @@ -25,6 +26,9 @@ private slots: /** Opens an existing world and displays the loaded biomes. */ void open(); + /** Opens a vanilla world that is specified by the calling action. */ + void openVanillaWorld(); + protected: // Actions: QAction * m_actGen; @@ -32,12 +36,28 @@ protected: QAction * m_actReload; QAction * m_actExit; + /** List of actions that open the specific vanilla world. */ + QList m_WorldActions; + + /** Path to the vanilla folder. */ + QString m_MinecraftPath; + + + /** Initializes the m_MinecraftPath based on the proper MC path */ + void initMinecraftPath(); /** Creates the actions that the UI supports. */ void createActions(); + /** Creates the actions that open a specific vanilla world. Iterates over the minecraft saves folder. */ + void createWorldActions(); + /** Creates the menu bar and connects its events. */ void createMenus(); + + /** Returns the name of the vanilla world in the specified path. + Reads the level.dat file for the name. Returns an empty string on failure. */ + QString getWorldName(const AString & a_Path); };