mirror of
https://github.com/neocturne/MinedMap.git
synced 2025-03-05 17:44:52 +01:00
NBT: rework type system
This commit is contained in:
parent
315bb38444
commit
f1f783877f
17 changed files with 162 additions and 228 deletions
|
@ -40,12 +40,16 @@ private:
|
||||||
const uint8_t *value;
|
const uint8_t *value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<ByteArrayTag> Type;
|
||||||
|
|
||||||
|
|
||||||
ByteArrayTag(Buffer *buffer) {
|
ByteArrayTag(Buffer *buffer) {
|
||||||
len = buffer->get32();
|
len = buffer->get32();
|
||||||
value = buffer->get(len);
|
value = buffer->get(len);
|
||||||
}
|
}
|
||||||
virtual Type getType() const {
|
|
||||||
return Type::ByteArray;
|
virtual const TagType & getType() const {
|
||||||
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||||
|
|
|
@ -37,12 +37,15 @@ private:
|
||||||
uint8_t value;
|
uint8_t value;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<ByteTag> Type;
|
||||||
|
|
||||||
|
|
||||||
ByteTag(Buffer *buffer) {
|
ByteTag(Buffer *buffer) {
|
||||||
value = buffer->get8();
|
value = buffer->get8();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Byte;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "EndTag.hpp"
|
||||||
#include "Tag.hpp"
|
#include "Tag.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
@ -37,18 +38,21 @@ namespace NBT {
|
||||||
|
|
||||||
class CompoundTag : public Tag, public std::unordered_map<std::string, std::shared_ptr<const Tag>> {
|
class CompoundTag : public Tag, public std::unordered_map<std::string, std::shared_ptr<const Tag>> {
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<CompoundTag> Type;
|
||||||
|
|
||||||
|
|
||||||
CompoundTag(Buffer *buffer) {
|
CompoundTag(Buffer *buffer) {
|
||||||
while (true) {
|
while (true) {
|
||||||
std::pair<std::string, std::shared_ptr<const Tag>> v = Tag::readNamedTag(buffer);
|
std::pair<std::string, std::shared_ptr<const Tag>> v = Tag::readNamedTag(buffer);
|
||||||
if (v.second->getType() == Type::End)
|
if (v.second->getType() == EndTag::Type)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
insert(std::move(v));
|
insert(std::move(v));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Compound;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||||
|
|
|
@ -37,12 +37,15 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<DoubleTag> Type;
|
||||||
|
|
||||||
|
|
||||||
DoubleTag(Buffer *buffer) {
|
DoubleTag(Buffer *buffer) {
|
||||||
ptr = buffer->get(8);
|
ptr = buffer->get(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Double;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -34,10 +34,13 @@ namespace NBT {
|
||||||
|
|
||||||
class EndTag : public Tag {
|
class EndTag : public Tag {
|
||||||
public:
|
public:
|
||||||
EndTag() {}
|
static const MakeType<EndTag> Type;
|
||||||
|
|
||||||
virtual Type getType() const {
|
|
||||||
return Type::End;
|
EndTag(Buffer *) {}
|
||||||
|
|
||||||
|
virtual const TagType & getType() const {
|
||||||
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream&, const std::string &) const {
|
virtual void print(std::ostream&, const std::string &) const {
|
||||||
|
|
|
@ -36,12 +36,15 @@ class FloatTag : public Tag {
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<FloatTag> Type;
|
||||||
|
|
||||||
|
|
||||||
FloatTag(Buffer *buffer) {
|
FloatTag(Buffer *buffer) {
|
||||||
ptr = buffer->get(4);
|
ptr = buffer->get(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Float;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -40,13 +40,16 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<IntArrayTag> Type;
|
||||||
|
|
||||||
|
|
||||||
IntArrayTag(Buffer *buffer) {
|
IntArrayTag(Buffer *buffer) {
|
||||||
len = buffer->get32();
|
len = buffer->get32();
|
||||||
ptr = buffer->get(4*len);
|
ptr = buffer->get(4*len);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::IntArray;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||||
|
|
|
@ -37,12 +37,15 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<IntTag> Type;
|
||||||
|
|
||||||
|
|
||||||
IntTag(Buffer *buffer) {
|
IntTag(Buffer *buffer) {
|
||||||
ptr = buffer->get(4);
|
ptr = buffer->get(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Int;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -34,34 +34,29 @@
|
||||||
namespace MinedMap {
|
namespace MinedMap {
|
||||||
namespace NBT {
|
namespace NBT {
|
||||||
|
|
||||||
|
class ListTag : public Tag, public std::vector<std::shared_ptr<const Tag>> {
|
||||||
class ListTagBase : public Tag {
|
|
||||||
public:
|
|
||||||
virtual Type getType() const {
|
|
||||||
return Type::List;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual Type getSubtype() const = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
class ListTag : public ListTagBase, public std::vector<std::shared_ptr<const T>> {
|
|
||||||
private:
|
private:
|
||||||
Type type;
|
const TagType *subtype;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ListTag(Type type0, Buffer *buffer) : type(type0) {
|
static const MakeType<ListTag> Type;
|
||||||
|
|
||||||
|
|
||||||
|
ListTag(Buffer *buffer) {
|
||||||
|
subtype = &getTypeById(buffer->get8());
|
||||||
|
|
||||||
uint32_t len = buffer->get32();
|
uint32_t len = buffer->get32();
|
||||||
|
|
||||||
this->resize(len);
|
|
||||||
|
|
||||||
for (uint32_t i = 0; i < len; i++)
|
for (uint32_t i = 0; i < len; i++)
|
||||||
(*this)[i] = std::static_pointer_cast<const T>(Tag::readTag(type, buffer));
|
push_back(subtype->read(buffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getSubtype() const {
|
virtual const TagType & getType() const {
|
||||||
return type;
|
return Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual const TagType & getSubtype() const {
|
||||||
|
return *subtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||||
|
|
|
@ -40,13 +40,16 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<LongArrayTag> Type;
|
||||||
|
|
||||||
|
|
||||||
LongArrayTag(Buffer *buffer) {
|
LongArrayTag(Buffer *buffer) {
|
||||||
len = buffer->get32();
|
len = buffer->get32();
|
||||||
ptr = buffer->get(8*len);
|
ptr = buffer->get(8*len);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::LongArray;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const {
|
virtual void print(std::ostream& os, const std::string &indent) const {
|
||||||
|
|
|
@ -37,12 +37,15 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<LongTag> Type;
|
||||||
|
|
||||||
|
|
||||||
LongTag(Buffer *buffer) {
|
LongTag(Buffer *buffer) {
|
||||||
ptr = buffer->get(8);
|
ptr = buffer->get(8);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Long;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -37,12 +37,15 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<ShortTag> Type;
|
||||||
|
|
||||||
|
|
||||||
ShortTag(Buffer *buffer) {
|
ShortTag(Buffer *buffer) {
|
||||||
ptr = buffer->get(2);
|
ptr = buffer->get(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::Short;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
|
@ -38,13 +38,16 @@ private:
|
||||||
const uint8_t *ptr;
|
const uint8_t *ptr;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
static const MakeType<StringTag> Type;
|
||||||
|
|
||||||
|
|
||||||
StringTag(Buffer *buffer) {
|
StringTag(Buffer *buffer) {
|
||||||
len = buffer->get16();
|
len = buffer->get16();
|
||||||
ptr = buffer->get(len);
|
ptr = buffer->get(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Type getType() const {
|
virtual const TagType & getType() const {
|
||||||
return Type::String;
|
return Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void print(std::ostream& os, const std::string &) const {
|
virtual void print(std::ostream& os, const std::string &) const {
|
||||||
|
|
190
src/NBT/Tag.cpp
190
src/NBT/Tag.cpp
|
@ -41,176 +41,50 @@
|
||||||
#include "LongArrayTag.hpp"
|
#include "LongArrayTag.hpp"
|
||||||
|
|
||||||
|
|
||||||
#include <stdexcept>
|
|
||||||
|
|
||||||
|
|
||||||
namespace MinedMap {
|
namespace MinedMap {
|
||||||
namespace NBT {
|
namespace NBT {
|
||||||
|
|
||||||
std::shared_ptr<const Tag> Tag::readTag(Type type, Buffer *buffer) {
|
const Tag::MakeType<EndTag> EndTag::Type("End");
|
||||||
switch (type) {
|
const Tag::MakeType<ByteTag> ByteTag::Type("Byte");
|
||||||
case Type::End:
|
const Tag::MakeType<ShortTag> ShortTag::Type("Short");
|
||||||
return std::make_shared<EndTag>();
|
const Tag::MakeType<IntTag> IntTag::Type("Int");
|
||||||
|
const Tag::MakeType<LongTag> LongTag::Type("Long");
|
||||||
|
const Tag::MakeType<FloatTag> FloatTag::Type("Float");
|
||||||
|
const Tag::MakeType<DoubleTag> DoubleTag::Type("Double");
|
||||||
|
const Tag::MakeType<ByteArrayTag> ByteArrayTag::Type("ByteArray");
|
||||||
|
const Tag::MakeType<StringTag> StringTag::Type("String");
|
||||||
|
const Tag::MakeType<ListTag> ListTag::Type("List");
|
||||||
|
const Tag::MakeType<CompoundTag> CompoundTag::Type("Compound");
|
||||||
|
const Tag::MakeType<IntArrayTag> IntArrayTag::Type("IntArray");
|
||||||
|
const Tag::MakeType<LongArrayTag> LongArrayTag::Type("LongArray");
|
||||||
|
|
||||||
case Type::Byte:
|
|
||||||
return std::make_shared<ByteTag>(buffer);
|
|
||||||
|
|
||||||
case Type::Short:
|
const std::vector<const TagType *> Tag::types = {
|
||||||
return std::make_shared<ShortTag>(buffer);
|
&EndTag::Type,
|
||||||
|
&ByteTag::Type,
|
||||||
|
&ShortTag::Type,
|
||||||
|
&IntTag::Type,
|
||||||
|
&LongTag::Type,
|
||||||
|
&FloatTag::Type,
|
||||||
|
&DoubleTag::Type,
|
||||||
|
&ByteArrayTag::Type,
|
||||||
|
&StringTag::Type,
|
||||||
|
&ListTag::Type,
|
||||||
|
&CompoundTag::Type,
|
||||||
|
&IntArrayTag::Type,
|
||||||
|
&LongArrayTag::Type,
|
||||||
|
};
|
||||||
|
|
||||||
case Type::Int:
|
|
||||||
return std::make_shared<IntTag>(buffer);
|
|
||||||
|
|
||||||
case Type::Long:
|
|
||||||
return std::make_shared<LongTag>(buffer);
|
|
||||||
|
|
||||||
case Type::Float:
|
|
||||||
return std::make_shared<FloatTag>(buffer);
|
|
||||||
|
|
||||||
case Type::Double:
|
|
||||||
return std::make_shared<DoubleTag>(buffer);
|
|
||||||
|
|
||||||
case Type::ByteArray:
|
|
||||||
return std::make_shared<ByteArrayTag>(buffer);
|
|
||||||
|
|
||||||
case Type::String:
|
|
||||||
return std::make_shared<StringTag>(buffer);
|
|
||||||
|
|
||||||
case Type::List:
|
|
||||||
return readList(buffer);
|
|
||||||
|
|
||||||
case Type::Compound:
|
|
||||||
return std::make_shared<CompoundTag>(buffer);
|
|
||||||
|
|
||||||
case Type::IntArray:
|
|
||||||
return std::make_shared<IntArrayTag>(buffer);
|
|
||||||
|
|
||||||
case Type::LongArray:
|
|
||||||
return std::make_shared<LongArrayTag>(buffer);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Tag::readTag: unknown tag type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<const Tag> Tag::readList(Buffer *buffer) {
|
|
||||||
Type type = static_cast<Type>(buffer->get8());
|
|
||||||
|
|
||||||
switch (type) {
|
|
||||||
case Type::End:
|
|
||||||
return std::make_shared<ListTag<EndTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Byte:
|
|
||||||
return std::make_shared<ListTag<ByteTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Short:
|
|
||||||
return std::make_shared<ListTag<ShortTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Int:
|
|
||||||
return std::make_shared<ListTag<IntTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Long:
|
|
||||||
return std::make_shared<ListTag<LongTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Float:
|
|
||||||
return std::make_shared<ListTag<FloatTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Double:
|
|
||||||
return std::make_shared<ListTag<DoubleTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::ByteArray:
|
|
||||||
return std::make_shared<ListTag<ByteArrayTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::String:
|
|
||||||
return std::make_shared<ListTag<StringTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::List:
|
|
||||||
return std::make_shared<ListTag<ListTagBase>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::Compound:
|
|
||||||
return std::make_shared<ListTag<CompoundTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::IntArray:
|
|
||||||
return std::make_shared<ListTag<IntArrayTag>>(type, buffer);
|
|
||||||
|
|
||||||
case Type::LongArray:
|
|
||||||
return std::make_shared<ListTag<LongArrayTag>>(type, buffer);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw std::runtime_error("Tag::readList: unknown tag type");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<std::string, std::shared_ptr<const Tag>> Tag::readNamedTag(Buffer *buffer) {
|
std::pair<std::string, std::shared_ptr<const Tag>> Tag::readNamedTag(Buffer *buffer) {
|
||||||
Type type = static_cast<Type>(buffer->get8());
|
const TagType &type = getTypeById(buffer->get8());
|
||||||
if (type == Type::End)
|
if (type == EndTag::Type)
|
||||||
return std::make_pair("", std::shared_ptr<EndTag>(new EndTag()));
|
return std::make_pair("", std::make_shared<EndTag>(buffer));
|
||||||
|
|
||||||
uint16_t len = buffer->get16();
|
uint16_t len = buffer->get16();
|
||||||
std::string name(reinterpret_cast<const char*>(buffer->get(len)), len);
|
std::string name(reinterpret_cast<const char*>(buffer->get(len)), len);
|
||||||
|
|
||||||
return std::make_pair(name, readTag(type, buffer));
|
return std::make_pair(name, type.read(buffer));
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, Tag::Type type) {
|
|
||||||
switch (type) {
|
|
||||||
case Tag::Type::End:
|
|
||||||
os << "End";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Byte:
|
|
||||||
os << "Byte";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Short:
|
|
||||||
os << "Short";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Int:
|
|
||||||
os << "Int";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Long:
|
|
||||||
os << "Long";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Float:
|
|
||||||
os << "Float";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Double:
|
|
||||||
os << "Double";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::ByteArray:
|
|
||||||
os << "ByteArray";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::String:
|
|
||||||
os << "String";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::List:
|
|
||||||
os << "List";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::Compound:
|
|
||||||
os << "Compound";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::IntArray:
|
|
||||||
os << "IntArray";
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Tag::Type::LongArray:
|
|
||||||
os << "LongArray";
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
os.setstate(std::ios_base::failbit);
|
|
||||||
}
|
|
||||||
|
|
||||||
return os;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "../Buffer.hpp"
|
#include "../Buffer.hpp"
|
||||||
|
|
||||||
|
@ -36,37 +37,61 @@
|
||||||
namespace MinedMap {
|
namespace MinedMap {
|
||||||
namespace NBT {
|
namespace NBT {
|
||||||
|
|
||||||
|
class Tag;
|
||||||
|
|
||||||
|
class TagType {
|
||||||
|
public:
|
||||||
|
TagType() = default;
|
||||||
|
TagType(const TagType&) = delete;
|
||||||
|
TagType & operator=(const TagType&) = delete;
|
||||||
|
|
||||||
|
virtual const char * getName() const = 0;
|
||||||
|
virtual std::shared_ptr<const Tag> read(Buffer *buffer) const = 0;
|
||||||
|
|
||||||
|
bool operator==(const TagType &type) const {
|
||||||
|
return this == &type;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class Tag {
|
class Tag {
|
||||||
private:
|
private:
|
||||||
static std::shared_ptr<const Tag> readList(Buffer *buffer);
|
static const std::vector<const TagType *> types;
|
||||||
|
|
||||||
public:
|
protected:
|
||||||
enum class Type {
|
template<typename T>
|
||||||
End = 0,
|
class MakeType : public TagType {
|
||||||
Byte = 1,
|
private:
|
||||||
Short = 2,
|
const char *name;
|
||||||
Int = 3,
|
|
||||||
Long = 4,
|
public:
|
||||||
Float = 5,
|
MakeType(const char *name0) : name(name0) {}
|
||||||
Double = 6,
|
|
||||||
ByteArray = 7,
|
virtual const char * getName() const {
|
||||||
String = 8,
|
return name;
|
||||||
List = 9,
|
}
|
||||||
Compound = 10,
|
|
||||||
IntArray = 11,
|
virtual std::shared_ptr<const Tag> read(Buffer *buffer) const {
|
||||||
LongArray = 12,
|
return std::make_shared<T>(buffer);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static std::shared_ptr<const Tag> readTag(Type type, Buffer *buffer);
|
|
||||||
|
static const TagType & getTypeById(uint8_t id) {
|
||||||
|
return *types.at(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
static std::pair<std::string, std::shared_ptr<const Tag>> readNamedTag(Buffer *buffer);
|
static std::pair<std::string, std::shared_ptr<const Tag>> readNamedTag(Buffer *buffer);
|
||||||
|
|
||||||
virtual Type getType() const = 0;
|
virtual const TagType & getType() const = 0;
|
||||||
virtual void print(std::ostream& os, const std::string &indent) const = 0;
|
virtual void print(std::ostream& os, const std::string &indent) const = 0;
|
||||||
|
|
||||||
virtual ~Tag() {}
|
virtual ~Tag() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& os, Tag::Type type);
|
static inline std::ostream& operator<<(std::ostream& os, const TagType &type) {
|
||||||
|
return os << type.getName();
|
||||||
|
}
|
||||||
|
|
||||||
static inline std::ostream& operator<<(std::ostream& os, const Tag &tag) {
|
static inline std::ostream& operator<<(std::ostream& os, const Tag &tag) {
|
||||||
os << tag.getType() << " ";
|
os << tag.getType() << " ";
|
||||||
|
|
|
@ -44,8 +44,9 @@ Chunk::Chunk(const ChunkData *data) {
|
||||||
std::shared_ptr<const NBT::ByteTag> lightPopulatedTag = level->get<NBT::ByteTag>("LightPopulated");
|
std::shared_ptr<const NBT::ByteTag> lightPopulatedTag = level->get<NBT::ByteTag>("LightPopulated");
|
||||||
bool lightPopulated = lightPopulatedTag && lightPopulatedTag->getValue();
|
bool lightPopulated = lightPopulatedTag && lightPopulatedTag->getValue();
|
||||||
|
|
||||||
sections = assertValue(level->get<NBT::ListTag<NBT::CompoundTag>>("Sections"));
|
sections = assertValue(level->get<NBT::ListTag>("Sections"));
|
||||||
maxY = (assertValue(sections->back()->get<NBT::ByteTag>("Y"))->getValue() + 1) * SIZE;
|
const NBT::CompoundTag *lastSection = assertValue(dynamic_cast<const NBT::CompoundTag *>(sections->back().get()));
|
||||||
|
maxY = (assertValue(lastSection->get<NBT::ByteTag>("Y"))->getValue() + 1) * SIZE;
|
||||||
|
|
||||||
|
|
||||||
std::shared_ptr<const NBT::ByteArrayTag> biomeTag = assertValue(level->get<NBT::ByteArrayTag>("Biomes"));
|
std::shared_ptr<const NBT::ByteArrayTag> biomeTag = assertValue(level->get<NBT::ByteArrayTag>("Biomes"));
|
||||||
|
@ -65,7 +66,8 @@ Chunk::Chunk(const ChunkData *data) {
|
||||||
std::memset(blockBlockLight.get(), 0, maxY * SIZE * SIZE / 2);
|
std::memset(blockBlockLight.get(), 0, maxY * SIZE * SIZE / 2);
|
||||||
|
|
||||||
|
|
||||||
for (auto §ion : *sections) {
|
for (auto §ionTag : *sections) {
|
||||||
|
const NBT::CompoundTag *section = assertValue(dynamic_cast<const NBT::CompoundTag *>(sectionTag.get()));
|
||||||
std::shared_ptr<const NBT::ByteArrayTag> blocks = assertValue(section->get<NBT::ByteArrayTag>("Blocks"));
|
std::shared_ptr<const NBT::ByteArrayTag> blocks = assertValue(section->get<NBT::ByteArrayTag>("Blocks"));
|
||||||
std::shared_ptr<const NBT::ByteArrayTag> data = assertValue(section->get<NBT::ByteArrayTag>("Data"));
|
std::shared_ptr<const NBT::ByteArrayTag> data = assertValue(section->get<NBT::ByteArrayTag>("Data"));
|
||||||
size_t Y = assertValue(section->get<NBT::ByteTag>("Y"))->getValue();
|
size_t Y = assertValue(section->get<NBT::ByteTag>("Y"))->getValue();
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<const NBT::CompoundTag> level;
|
std::shared_ptr<const NBT::CompoundTag> level;
|
||||||
std::shared_ptr<const NBT::ListTag<NBT::CompoundTag>> sections;
|
std::shared_ptr<const NBT::ListTag> sections;
|
||||||
|
|
||||||
|
|
||||||
unsigned maxY;
|
unsigned maxY;
|
||||||
|
@ -107,7 +107,7 @@ public:
|
||||||
return *level;
|
return *level;
|
||||||
}
|
}
|
||||||
|
|
||||||
const NBT::ListTag<NBT::CompoundTag> & getSections() const {
|
const NBT::ListTag & getSections() const {
|
||||||
return *sections;
|
return *sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue