diff options
author | Petr Mrázek <peterix@gmail.com> | 2015-09-06 23:35:58 +0200 |
---|---|---|
committer | Petr Mrázek <peterix@gmail.com> | 2015-09-06 23:35:58 +0200 |
commit | 38693e1d6ca7f05d9488348ddf298488d1cc0995 (patch) | |
tree | d99551fc3ebbef931d10ee45cb34f2ee791cc1fe /logic/minecraft/World.cpp | |
parent | 40b233448c7a3977d45831b8aa6cf31019c03940 (diff) | |
download | MultiMC-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar MultiMC-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar.gz MultiMC-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar.lz MultiMC-38693e1d6ca7f05d9488348ddf298488d1cc0995.tar.xz MultiMC-38693e1d6ca7f05d9488348ddf298488d1cc0995.zip |
GH-1047 parse world files and integrate MCEdit with world page
Diffstat (limited to 'logic/minecraft/World.cpp')
-rw-r--r-- | logic/minecraft/World.cpp | 126 |
1 files changed, 121 insertions, 5 deletions
diff --git a/logic/minecraft/World.cpp b/logic/minecraft/World.cpp index 3443fb45..4ef7845f 100644 --- a/logic/minecraft/World.cpp +++ b/logic/minecraft/World.cpp @@ -15,9 +15,16 @@ #include <QDir> #include <QString> +#include <QDebug> #include "World.h" #include <pathutils.h> +#include "GZip.h" +#include <sstream> +#include <io/stream_reader.h> +#include <tag_string.h> +#include <tag_primitive.h> + World::World(const QFileInfo &file) { repath(file); @@ -26,8 +33,117 @@ World::World(const QFileInfo &file) void World::repath(const QFileInfo &file) { m_file = file; - m_name = file.fileName(); - is_valid = file.isDir() && QDir(file.filePath()).exists("level.dat"); + m_folderName = file.fileName(); + QDir worldDir(file.filePath()); + is_valid = file.isDir() && worldDir.exists("level.dat"); + if(!is_valid) + { + return; + } + + auto fullFilePath = worldDir.absoluteFilePath("level.dat"); + QFile f(fullFilePath); + is_valid = f.open(QIODevice::ReadOnly); + if(!is_valid) + { + return; + } + + QByteArray output; + is_valid = GZip::inflate(f.readAll(), output); + if(!is_valid) + { + return; + } + f.close(); + + auto read_string = [](nbt::value& parent, const char * name, const QString & fallback = QString()) -> QString + { + try + { + auto &namedValue = parent.at(name); + if(namedValue.get_type() != nbt::tag_type::String) + { + return fallback; + } + auto & tag_str = namedValue.as<nbt::tag_string>(); + return QString::fromStdString(tag_str.get()); + } + catch(std::out_of_range e) + { + // fallback for old world formats + return fallback; + } + }; + + auto read_long = [](nbt::value& parent, const char * name, const int64_t & fallback = 0) -> int64_t + { + try + { + auto &namedValue = parent.at(name); + if(namedValue.get_type() != nbt::tag_type::Long) + { + return fallback; + } + auto & tag_str = namedValue.as<nbt::tag_long>(); + return tag_str.get(); + } + catch(std::out_of_range e) + { + // fallback for old world formats + return fallback; + } + }; + + try + { + std::istringstream foo(std::string(output.constData(), output.size())); + auto pair = nbt::io::read_compound(foo); + is_valid = pair.first == ""; + + if(!is_valid) + { + return; + } + std::ostringstream ostr; + is_valid = pair.second != nullptr; + if(!is_valid) + { + qDebug() << "FAIL~!!!"; + return; + } + + auto &val = pair.second->at("Data"); + is_valid = val.get_type() == nbt::tag_type::Compound; + if(!is_valid) + return; + + m_actualName = read_string(val, "LevelName", m_folderName); + + + int64_t temp = read_long(val, "LastPlayed", 0); + if(temp == 0) + { + QFileInfo finfo(fullFilePath); + m_lastPlayed = finfo.lastModified(); + } + else + { + m_lastPlayed = QDateTime::fromMSecsSinceEpoch(temp); + } + + m_randomSeed = read_long(val, "RandomSeed", 0); + + qDebug() << "World Name:" << m_actualName; + qDebug() << "Last Played:" << m_lastPlayed.toString(); + qDebug() << "Seed:" << m_randomSeed; + } + catch (nbt::io::input_error e) + { + qWarning() << "Unable to load" << m_folderName << ":" << e.what(); + is_valid = false; + return; + } } bool World::replace(World &with) @@ -37,7 +153,7 @@ bool World::replace(World &with) bool success = copyPath(with.m_file.filePath(), m_file.path()); if (success) { - m_name = with.m_name; + m_folderName = with.m_folderName; m_file.refresh(); } return success; @@ -64,9 +180,9 @@ bool World::destroy() bool World::operator==(const World &other) const { - return is_valid == other.is_valid && name() == other.name(); + return is_valid == other.is_valid && folderName() == other.folderName(); } bool World::strongCompare(const World &other) const { - return is_valid == other.is_valid && name() == other.name(); + return is_valid == other.is_valid && folderName() == other.folderName(); } |