From 4b9bb2ab4894c52f60baba3273c27948ad022292 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 20 Jul 2018 23:09:33 +0200 Subject: Add Tag print functions and nbtdump tool --- src/CMakeLists.txt | 8 +++++++ src/NBT/ByteArrayTag.hpp | 18 ++++++++++++++++ src/NBT/ByteTag.hpp | 6 ++++++ src/NBT/CompoundTag.hpp | 14 ++++++++++++ src/NBT/DoubleTag.hpp | 10 +++++++++ src/NBT/EndTag.hpp | 3 +++ src/NBT/FloatTag.hpp | 10 +++++++++ src/NBT/IntArrayTag.hpp | 18 ++++++++++++++++ src/NBT/IntTag.hpp | 6 ++++++ src/NBT/ListTag.hpp | 14 ++++++++++++ src/NBT/LongTag.hpp | 6 ++++++ src/NBT/ShortTag.hpp | 6 ++++++ src/NBT/StringTag.hpp | 4 ++++ src/NBT/Tag.hpp | 7 ++++++ src/nbtdump.cpp | 55 ++++++++++++++++++++++++++++++++++++++++++++++++ 15 files changed, 185 insertions(+) create mode 100644 src/nbtdump.cpp (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f433bd4..57bd303 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -17,3 +17,11 @@ add_executable(MinedMap ) set_target_properties(MinedMap PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall") target_link_libraries(MinedMap ${ZLIB_LIBRARIES} ${PNG_LIBRARIES}) + +add_executable(nbtdump + nbtdump.cpp + GZip.cpp + NBT/Tag.cpp +) +set_target_properties(nbtdump PROPERTIES COMPILE_FLAGS "-std=c++11 -Wall") +target_link_libraries(nbtdump ${ZLIB_LIBRARIES}) diff --git a/src/NBT/ByteArrayTag.hpp b/src/NBT/ByteArrayTag.hpp index 0e56a9a..36d9fe7 100644 --- a/src/NBT/ByteArrayTag.hpp +++ b/src/NBT/ByteArrayTag.hpp @@ -51,6 +51,24 @@ public: return Type::ByteArray; } + virtual void print(std::ostream& os, const std::string &indent) const { + os << "(" << len << ") [" << std::endl; + + std::string inner = indent + " "; + + for (size_t i = 0; i < len; i++) { + uint8_t v = value[i]; + + os << inner + << (unsigned)v << " / " + << (int)(int8_t)v << " / " + << std::hex << "0x" << (unsigned)v << std::dec + << std::endl; + } + + os << indent << "]"; + } + uint32_t getLength() const { return len; } diff --git a/src/NBT/ByteTag.hpp b/src/NBT/ByteTag.hpp index 64bdaa1..dc7e212 100644 --- a/src/NBT/ByteTag.hpp +++ b/src/NBT/ByteTag.hpp @@ -47,6 +47,12 @@ public: return Type::Byte; } + virtual void print(std::ostream& os, const std::string &) const { + os << (unsigned)getValue() << " / " + << (int)(int8_t)getValue() << " / " + << std::hex << "0x" << (unsigned)getValue() << std::dec; + } + uint8_t getValue() const { return value; } diff --git a/src/NBT/CompoundTag.hpp b/src/NBT/CompoundTag.hpp index 39fa25d..6be0479 100644 --- a/src/NBT/CompoundTag.hpp +++ b/src/NBT/CompoundTag.hpp @@ -54,6 +54,20 @@ public: return Type::Compound; } + virtual void print(std::ostream& os, const std::string &indent) const { + os << "{" << std::endl; + + std::string inner = indent + " "; + + for (const auto &item : *this) { + os << inner << item.first << ": " << item.second->getType() << " "; + item.second->print(os, inner); + os << std::endl; + } + + os << indent << "}"; + } + template std::shared_ptr get(const std::string &key) const { auto it = find(key); if (it == end()) diff --git a/src/NBT/DoubleTag.hpp b/src/NBT/DoubleTag.hpp index dace193..035ff94 100644 --- a/src/NBT/DoubleTag.hpp +++ b/src/NBT/DoubleTag.hpp @@ -46,6 +46,16 @@ public: virtual Type getType() const { return Type::Double; } + + virtual void print(std::ostream& os, const std::string &) const { + union { + uint64_t i; + double d; + }; + + i = Buffer::parse64(ptr); + os << d; + } }; } diff --git a/src/NBT/EndTag.hpp b/src/NBT/EndTag.hpp index c969e98..4582f5d 100644 --- a/src/NBT/EndTag.hpp +++ b/src/NBT/EndTag.hpp @@ -42,6 +42,9 @@ public: virtual Type getType() const { return Type::End; } + + virtual void print(std::ostream&, const std::string &) const { + } }; } diff --git a/src/NBT/FloatTag.hpp b/src/NBT/FloatTag.hpp index ad9cc64..7bb8df2 100644 --- a/src/NBT/FloatTag.hpp +++ b/src/NBT/FloatTag.hpp @@ -46,6 +46,16 @@ public: virtual Type getType() const { return Type::Float; } + + virtual void print(std::ostream& os, const std::string &) const { + union { + uint32_t i; + float f; + }; + + i = Buffer::parse32(ptr); + os << f; + } }; } diff --git a/src/NBT/IntArrayTag.hpp b/src/NBT/IntArrayTag.hpp index 22f84b2..5fdd3fc 100644 --- a/src/NBT/IntArrayTag.hpp +++ b/src/NBT/IntArrayTag.hpp @@ -50,6 +50,24 @@ public: virtual Type getType() const { return Type::IntArray; } + + virtual void print(std::ostream& os, const std::string &indent) const { + os << "(" << len << ") [" << std::endl; + + std::string inner = indent + " "; + + for (size_t i = 0; i < len; i++) { + uint32_t v = Buffer::parse32(&ptr[4*i]); + + os << inner + << v << " / " + << (int32_t)v << " / " + << std::hex << "0x" << v << std::dec + << std::endl; + } + + os << indent << "]"; + } }; } diff --git a/src/NBT/IntTag.hpp b/src/NBT/IntTag.hpp index b0337c7..eacac52 100644 --- a/src/NBT/IntTag.hpp +++ b/src/NBT/IntTag.hpp @@ -47,6 +47,12 @@ public: return Type::Int; } + virtual void print(std::ostream& os, const std::string &) const { + os << getValue() << " / " + << (int32_t)getValue() << " / " + << std::hex << "0x" << getValue() << std::dec; + } + uint32_t getValue() const { return Buffer::parse32(ptr); } diff --git a/src/NBT/ListTag.hpp b/src/NBT/ListTag.hpp index 757a0aa..833c41e 100644 --- a/src/NBT/ListTag.hpp +++ b/src/NBT/ListTag.hpp @@ -65,6 +65,20 @@ public: virtual Type getSubtype() const { return type; } + + virtual void print(std::ostream& os, const std::string &indent) const { + os << getSubtype() << " [" << std::endl; + + std::string inner = indent + " "; + + for (const auto &item : *this) { + os << inner; + item->print(os, inner); + os << std::endl; + } + + os << indent << "]"; + } }; } diff --git a/src/NBT/LongTag.hpp b/src/NBT/LongTag.hpp index b07bc1a..4f6bec3 100644 --- a/src/NBT/LongTag.hpp +++ b/src/NBT/LongTag.hpp @@ -47,6 +47,12 @@ public: return Type::Long; } + virtual void print(std::ostream& os, const std::string &) const { + os << getValue() << " / " + << (int64_t)getValue() << " / " + << std::hex << "0x" << getValue() << std::dec; + } + uint64_t getValue() const { return Buffer::parse64(ptr); } diff --git a/src/NBT/ShortTag.hpp b/src/NBT/ShortTag.hpp index 7415317..c08e1fe 100644 --- a/src/NBT/ShortTag.hpp +++ b/src/NBT/ShortTag.hpp @@ -47,6 +47,12 @@ public: return Type::Short; } + virtual void print(std::ostream& os, const std::string &) const { + os << getValue() << " / " + << (int16_t)getValue() << " / " + << std::hex << "0x" << getValue() << std::dec; + } + uint16_t getValue() const { return Buffer::parse16(ptr); } diff --git a/src/NBT/StringTag.hpp b/src/NBT/StringTag.hpp index 42432f2..5f68d63 100644 --- a/src/NBT/StringTag.hpp +++ b/src/NBT/StringTag.hpp @@ -48,6 +48,10 @@ public: virtual Type getType() const { return Type::String; } + + virtual void print(std::ostream& os, const std::string &) const { + os << "\"" << std::string(reinterpret_cast(ptr), len) << "\""; + } }; } diff --git a/src/NBT/Tag.hpp b/src/NBT/Tag.hpp index a3c0c76..bb71b23 100644 --- a/src/NBT/Tag.hpp +++ b/src/NBT/Tag.hpp @@ -60,11 +60,18 @@ public: static std::pair> readNamedTag(Buffer *buffer); virtual Type getType() const = 0; + virtual void print(std::ostream& os, const std::string &indent) const = 0; virtual ~Tag() {} }; std::ostream& operator<<(std::ostream& os, Tag::Type type); +static inline std::ostream& operator<<(std::ostream& os, const Tag &tag) { + os << tag.getType() << " "; + tag.print(os, ""); + return os; +} + } } diff --git a/src/nbtdump.cpp b/src/nbtdump.cpp new file mode 100644 index 0000000..b364f41 --- /dev/null +++ b/src/nbtdump.cpp @@ -0,0 +1,55 @@ +/* + Copyright (c) 2018, Matthias Schiffer + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "Buffer.hpp" +#include "GZip.hpp" +#include "Util.hpp" +#include "NBT/Tag.hpp" + +#include +#include +#include + + +int main(int argc, char *argv[]) { + using namespace MinedMap; + + if (argc != 2) { + std::fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + std::vector buffer = readGZip(argv[1]); + + Buffer nbt(buffer.data(), buffer.size()); + std::pair> tag = NBT::Tag::readNamedTag(&nbt); + if (tag.first != "") + throw std::invalid_argument("invalid root tag"); + + std::cout << *tag.second << std::endl; + + return 0; +} -- cgit v1.2.3