mirror of
https://github.com/quizhizhe/LiteLoaderBDS-1.16.40.git
synced 2025-06-06 12:03:39 +00:00
2160 lines
73 KiB
C++
2160 lines
73 KiB
C++
#include "APIHelp.h"
|
|
#include "NbtAPI.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include "ItemAPI.h"
|
|
#include "BlockAPI.h"
|
|
#include <MC/EndTag.hpp>
|
|
#include <MC/ByteTag.hpp>
|
|
#include <MC/ShortTag.hpp>
|
|
#include <MC/IntTag.hpp>
|
|
#include <MC/Int64Tag.hpp>
|
|
#include <MC/FloatTag.hpp>
|
|
#include <MC/DoubleTag.hpp>
|
|
#include <MC/ByteArrayTag.hpp>
|
|
#include <MC/StringTag.hpp>
|
|
#include <MC/ListTag.hpp>
|
|
#include <MC/CompoundTag.hpp>
|
|
|
|
using namespace std;
|
|
|
|
|
|
//////////////////// Class Definition ////////////////////
|
|
|
|
ClassDefine<void> NbtStaticBuilder =
|
|
defineClass("NBT")
|
|
.function("parseSNBT", &NbtStatic::parseSNBT)
|
|
.function("parseBinaryNBT", &NbtStatic::parseBinaryNBT)
|
|
.property("End", &NbtStatic::getType<Tag::Type::End>)
|
|
.property("Byte", &NbtStatic::getType<Tag::Type::Byte>)
|
|
.property("Short", &NbtStatic::getType<Tag::Type::Short>)
|
|
.property("Int", &NbtStatic::getType<Tag::Type::Int>)
|
|
.property("Long", &NbtStatic::getType<Tag::Type::Int64>)
|
|
.property("Float", &NbtStatic::getType<Tag::Type::Float>)
|
|
.property("Double", &NbtStatic::getType<Tag::Type::Double>)
|
|
.property("ByteArray", &NbtStatic::getType<Tag::Type::ByteArray>)
|
|
.property("String", &NbtStatic::getType<Tag::Type::String>)
|
|
.property("List", &NbtStatic::getType<Tag::Type::List>)
|
|
.property("Compound", &NbtStatic::getType<Tag::Type::Compound>)
|
|
|
|
// For Compatibility
|
|
.function("createTag", &NbtStatic::newTag)
|
|
.function("newTag", &NbtStatic::newTag)
|
|
.build();
|
|
|
|
ClassDefine<NbtEndClass> NbtEndClassBuilder =
|
|
defineClass<NbtEndClass>("NbtEnd")
|
|
.constructor(&NbtEndClass::constructor)
|
|
.instanceFunction("getType", &NbtEndClass::getType)
|
|
.instanceFunction("toString", &NbtEndClass::toString)
|
|
.instanceFunction("set", &NbtEndClass::set)
|
|
.instanceFunction("get", &NbtEndClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtByteClass> NbtByteClassBuilder =
|
|
defineClass<NbtByteClass>("NbtByte")
|
|
.constructor(&NbtByteClass::constructor)
|
|
.instanceFunction("getType", &NbtByteClass::getType)
|
|
.instanceFunction("toString", &NbtByteClass::toString)
|
|
.instanceFunction("set", &NbtByteClass::set)
|
|
.instanceFunction("get", &NbtByteClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtShortClass> NbtShortClassBuilder =
|
|
defineClass<NbtShortClass>("NbtShort")
|
|
.constructor(&NbtShortClass::constructor)
|
|
.instanceFunction("getType", &NbtShortClass::getType)
|
|
.instanceFunction("toString", &NbtShortClass::toString)
|
|
.instanceFunction("set", &NbtShortClass::set)
|
|
.instanceFunction("get", &NbtShortClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtIntClass> NbtIntClassBuilder =
|
|
defineClass<NbtIntClass>("NbtInt")
|
|
.constructor(&NbtIntClass::constructor)
|
|
.instanceFunction("getType", &NbtIntClass::getType)
|
|
.instanceFunction("toString", &NbtIntClass::toString)
|
|
.instanceFunction("set", &NbtIntClass::set)
|
|
.instanceFunction("get", &NbtIntClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtLongClass> NbtLongClassBuilder =
|
|
defineClass<NbtLongClass>("NbtLong")
|
|
.constructor(&NbtLongClass::constructor)
|
|
.instanceFunction("getType", &NbtLongClass::getType)
|
|
.instanceFunction("toString", &NbtLongClass::toString)
|
|
.instanceFunction("set", &NbtLongClass::set)
|
|
.instanceFunction("get", &NbtLongClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtFloatClass> NbtFloatClassBuilder =
|
|
defineClass<NbtFloatClass>("NbtFloat")
|
|
.constructor(&NbtFloatClass::constructor)
|
|
.instanceFunction("getType", &NbtFloatClass::getType)
|
|
.instanceFunction("toString", &NbtFloatClass::toString)
|
|
.instanceFunction("set", &NbtFloatClass::set)
|
|
.instanceFunction("get", &NbtFloatClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtDoubleClass> NbtDoubleClassBuilder =
|
|
defineClass<NbtDoubleClass>("NbtDouble")
|
|
.constructor(&NbtDoubleClass::constructor)
|
|
.instanceFunction("getType", &NbtDoubleClass::getType)
|
|
.instanceFunction("toString", &NbtDoubleClass::toString)
|
|
.instanceFunction("set", &NbtDoubleClass::set)
|
|
.instanceFunction("get", &NbtDoubleClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtStringClass> NbtStringClassBuilder =
|
|
defineClass<NbtStringClass>("NbtString")
|
|
.constructor(&NbtStringClass::constructor)
|
|
.instanceFunction("getType", &NbtStringClass::getType)
|
|
.instanceFunction("toString", &NbtStringClass::toString)
|
|
.instanceFunction("set", &NbtStringClass::set)
|
|
.instanceFunction("get", &NbtStringClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtByteArrayClass> NbtByteArrayClassBuilder =
|
|
defineClass<NbtByteArrayClass>("NbtByteArray")
|
|
.constructor(&NbtByteArrayClass::constructor)
|
|
.instanceFunction("getType", &NbtByteArrayClass::getType)
|
|
.instanceFunction("toString", &NbtByteArrayClass::toString)
|
|
.instanceFunction("set", &NbtByteArrayClass::set)
|
|
.instanceFunction("get", &NbtByteArrayClass::get)
|
|
.build();
|
|
|
|
ClassDefine<NbtListClass> NbtListClassBuilder =
|
|
defineClass<NbtListClass>("NbtList")
|
|
.constructor(&NbtListClass::constructor)
|
|
.instanceFunction("getType", &NbtListClass::getType)
|
|
.instanceFunction("toString", &NbtListClass::toString)
|
|
.instanceFunction("getSize", &NbtListClass::getSize)
|
|
.instanceFunction("getTypeOf", &NbtListClass::getTypeOf)
|
|
.instanceFunction("setEnd", &NbtListClass::setEnd)
|
|
.instanceFunction("setByte", &NbtListClass::setByte)
|
|
.instanceFunction("setInt", &NbtListClass::setInt)
|
|
.instanceFunction("setShort", &NbtListClass::setShort)
|
|
.instanceFunction("setLong", &NbtListClass::setLong)
|
|
.instanceFunction("setFloat", &NbtListClass::setFloat)
|
|
.instanceFunction("setDouble", &NbtListClass::setDouble)
|
|
.instanceFunction("setString", &NbtListClass::setString)
|
|
.instanceFunction("setByteArray", &NbtListClass::setByteArray)
|
|
.instanceFunction("setTag", &NbtListClass::setTag)
|
|
.instanceFunction("addTag", &NbtListClass::addTag)
|
|
.instanceFunction("removeTag", &NbtListClass::removeTag)
|
|
.instanceFunction("getData", &NbtListClass::getData)
|
|
.instanceFunction("getTag", &NbtListClass::getTag)
|
|
.instanceFunction("toArray", &NbtListClass::toArray)
|
|
.build();
|
|
|
|
ClassDefine<NbtCompoundClass> NbtCompoundClassBuilder =
|
|
defineClass<NbtCompoundClass>("NbtCompound")
|
|
.constructor(&NbtCompoundClass::constructor)
|
|
.instanceFunction("getType", &NbtCompoundClass::getType)
|
|
.instanceFunction("toString", &NbtCompoundClass::toString)
|
|
.instanceFunction("getKeys", &NbtCompoundClass::getKeys)
|
|
.instanceFunction("getTypeOf", &NbtCompoundClass::getTypeOf)
|
|
.instanceFunction("setEnd", &NbtCompoundClass::setEnd)
|
|
.instanceFunction("setByte", &NbtCompoundClass::setByte)
|
|
.instanceFunction("setInt", &NbtCompoundClass::setInt)
|
|
.instanceFunction("setShort", &NbtCompoundClass::setShort)
|
|
.instanceFunction("setLong", &NbtCompoundClass::setLong)
|
|
.instanceFunction("setFloat", &NbtCompoundClass::setFloat)
|
|
.instanceFunction("setDouble", &NbtCompoundClass::setDouble)
|
|
.instanceFunction("setString", &NbtCompoundClass::setString)
|
|
.instanceFunction("setByteArray", &NbtCompoundClass::setByteArray)
|
|
.instanceFunction("setTag", &NbtCompoundClass::setTag)
|
|
.instanceFunction("removeTag", &NbtCompoundClass::removeTag)
|
|
.instanceFunction("getData", &NbtCompoundClass::getData)
|
|
.instanceFunction("getTag", &NbtCompoundClass::getTag)
|
|
.instanceFunction("toObject", &NbtCompoundClass::toObject)
|
|
.instanceFunction("toSNBT", &NbtCompoundClass::toSNBT)
|
|
.instanceFunction("toBinaryNBT", &NbtCompoundClass::toBinaryNBT)
|
|
.instanceFunction("destroy", &NbtCompoundClass::destroy)
|
|
.build();
|
|
|
|
|
|
//////////////////// Classes NbtEnd ////////////////////
|
|
|
|
NbtEndClass::NbtEndClass(const Local<Object>& scriptObj, std::unique_ptr<EndTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtEndClass::NbtEndClass(std::unique_ptr<EndTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtEndClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtEndClass* NbtEndClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = EndTag::create();
|
|
return new NbtEndClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create EndTag!");
|
|
}
|
|
|
|
EndTag* NbtEndClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtEndClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtEndClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtEndClass::pack(EndTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<EndTag> nbt(tag);
|
|
auto* nbtObj = new NbtEndClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtEndClass(Tag::asTypedTag<EndTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtEnd!");
|
|
}
|
|
|
|
Local<Value> NbtEndClass::pack(std::unique_ptr<EndTag> tag) {
|
|
try {
|
|
return (new NbtEndClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtEnd!");
|
|
}
|
|
|
|
Local<Value> NbtEndClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::End);
|
|
}
|
|
|
|
Local<Value> NbtEndClass::get(const Arguments& args) {
|
|
try {
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtEndClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtEndClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1)
|
|
|
|
try {
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtByte ////////////////////
|
|
|
|
NbtByteClass::NbtByteClass(const Local<Object>& scriptObj, std::unique_ptr<ByteTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtByteClass::NbtByteClass(std::unique_ptr<ByteTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtByteClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtByteClass* NbtByteClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = ByteTag::create((char)args[0].toInt());
|
|
return new NbtByteClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create ByteTag!");
|
|
}
|
|
|
|
ByteTag* NbtByteClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtByteClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtByteClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtByteClass::pack(ByteTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<ByteTag> nbt(tag);
|
|
auto* nbtObj = new NbtByteClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtByteClass(Tag::asTypedTag<ByteTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtByte!");
|
|
}
|
|
|
|
Local<Value> NbtByteClass::pack(std::unique_ptr<ByteTag> tag) {
|
|
try {
|
|
return (new NbtByteClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtByte!");
|
|
}
|
|
|
|
Local<Value> NbtByteClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Byte);
|
|
}
|
|
|
|
Local<Value> NbtByteClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtByteClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtByteClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set((char)args[0].toInt()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtInt ////////////////////
|
|
|
|
NbtIntClass::NbtIntClass(const Local<Object>& scriptObj, std::unique_ptr<IntTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtIntClass::NbtIntClass(std::unique_ptr<IntTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtIntClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtIntClass* NbtIntClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = IntTag::create(args[0].toInt());
|
|
return new NbtIntClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create IntTag!");
|
|
}
|
|
|
|
IntTag* NbtIntClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtIntClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtIntClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtIntClass::pack(IntTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<IntTag> nbt(tag);
|
|
auto* nbtObj = new NbtIntClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtIntClass(Tag::asTypedTag<IntTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtInt!");
|
|
}
|
|
|
|
Local<Value> NbtIntClass::pack(std::unique_ptr<IntTag> tag) {
|
|
try {
|
|
return (new NbtIntClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtInt!");
|
|
}
|
|
|
|
Local<Value> NbtIntClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Int);
|
|
}
|
|
|
|
Local<Value> NbtIntClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtIntClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtIntClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1)
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].toInt()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtShort ////////////////////
|
|
|
|
NbtShortClass::NbtShortClass(const Local<Object>& scriptObj, std::unique_ptr<ShortTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtShortClass::NbtShortClass(std::unique_ptr<ShortTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtShortClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtShortClass* NbtShortClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = ShortTag::create(args[0].toInt());
|
|
return new NbtShortClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create ShortTag!");
|
|
}
|
|
|
|
ShortTag* NbtShortClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtShortClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtShortClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtShortClass::pack(ShortTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<ShortTag> nbt(tag);
|
|
auto* nbtObj = new NbtShortClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtShortClass(Tag::asTypedTag<ShortTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtShort!");
|
|
}
|
|
|
|
Local<Value> NbtShortClass::pack(std::unique_ptr<ShortTag> tag) {
|
|
try {
|
|
return (new NbtShortClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtShort!");
|
|
}
|
|
|
|
Local<Value> NbtShortClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Short);
|
|
}
|
|
|
|
Local<Value> NbtShortClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtShortClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtShortClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].toInt()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtLong ////////////////////
|
|
|
|
NbtLongClass::NbtLongClass(const Local<Object>& scriptObj, std::unique_ptr<Int64Tag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtLongClass::NbtLongClass(std::unique_ptr<Int64Tag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtLongClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtLongClass* NbtLongClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = Int64Tag::create(args[0].asNumber().toInt64());
|
|
return new NbtLongClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create LongTag!");
|
|
}
|
|
|
|
Int64Tag* NbtLongClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtLongClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtLongClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtLongClass::pack(Int64Tag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<Int64Tag> nbt(tag);
|
|
auto* nbtObj = new NbtLongClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtLongClass(Tag::asTypedTag<Int64Tag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtLong!");
|
|
}
|
|
|
|
Local<Value> NbtLongClass::pack(std::unique_ptr<Int64Tag> tag) {
|
|
try {
|
|
return (new NbtLongClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtLong!");
|
|
}
|
|
|
|
Local<Value> NbtLongClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Int64);
|
|
}
|
|
|
|
Local<Value> NbtLongClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtLongClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtLongClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].asNumber().toInt64()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtFloat ////////////////////
|
|
|
|
NbtFloatClass::NbtFloatClass(const Local<Object>& scriptObj, std::unique_ptr<FloatTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtFloatClass::NbtFloatClass(std::unique_ptr<FloatTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtFloatClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtFloatClass* NbtFloatClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = FloatTag::create(args[0].asNumber().toFloat());
|
|
return new NbtFloatClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create FloatTag!");
|
|
}
|
|
|
|
FloatTag* NbtFloatClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtFloatClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtFloatClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::pack(FloatTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<FloatTag> nbt(tag);
|
|
auto* nbtObj = new NbtFloatClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtFloatClass(Tag::asTypedTag<FloatTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtFloat!");
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::pack(std::unique_ptr<FloatTag> tag) {
|
|
try {
|
|
return (new NbtFloatClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtFloat!");
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Float);
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtFloatClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].asNumber().toFloat()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtDouble ////////////////////
|
|
|
|
NbtDoubleClass::NbtDoubleClass(const Local<Object>& scriptObj, std::unique_ptr<DoubleTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtDoubleClass::NbtDoubleClass(std::unique_ptr<DoubleTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtDoubleClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtDoubleClass* NbtDoubleClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = DoubleTag::create(args[0].asNumber().toDouble());
|
|
return new NbtDoubleClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create DoubleTag!");
|
|
}
|
|
|
|
DoubleTag* NbtDoubleClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtDoubleClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtDoubleClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::pack(DoubleTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<DoubleTag> nbt(tag);
|
|
auto* nbtObj = new NbtDoubleClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtDoubleClass(Tag::asTypedTag<DoubleTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtDouble!");
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::pack(std::unique_ptr<DoubleTag> tag) {
|
|
try {
|
|
return (new NbtDoubleClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtDouble!");
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Double);
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::get(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtDoubleClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].asNumber().toDouble()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtString ////////////////////
|
|
|
|
NbtStringClass::NbtStringClass(const Local<Object>& scriptObj, std::unique_ptr<StringTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtStringClass::NbtStringClass(std::unique_ptr<StringTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtStringClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtStringClass* NbtStringClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = StringTag::create(args[0].toStr());
|
|
return new NbtStringClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create StringTag!");
|
|
}
|
|
|
|
StringTag* NbtStringClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtStringClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtStringClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtStringClass::pack(StringTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<StringTag> nbt(tag);
|
|
auto* nbtObj = new NbtStringClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtStringClass(Tag::asTypedTag<StringTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtString!");
|
|
}
|
|
|
|
Local<Value> NbtStringClass::pack(std::unique_ptr<StringTag> tag) {
|
|
try {
|
|
return (new NbtStringClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtString!");
|
|
}
|
|
|
|
Local<Value> NbtStringClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::String);
|
|
}
|
|
|
|
Local<Value> NbtStringClass::get(const Arguments& args) {
|
|
try {
|
|
return String::newString(nbt->get());
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtStringClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtStringClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
return Boolean::newBoolean(nbt->set(args[0].toStr()));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtByteArray ////////////////////
|
|
|
|
NbtByteArrayClass::NbtByteArrayClass(const Local<Object>& scriptObj, std::unique_ptr<ByteArrayTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtByteArrayClass::NbtByteArrayClass(std::unique_ptr<ByteArrayTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtByteArrayClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtByteArrayClass* NbtByteArrayClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto buf = args[0].asByteBuffer();
|
|
auto tag = ByteArrayTag::create((char*)buf.getRawBytes(), buf.byteLength());
|
|
return new NbtByteArrayClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create ByteArrayTag!");
|
|
}
|
|
|
|
ByteArrayTag* NbtByteArrayClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtByteArrayClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtByteArrayClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::pack(ByteArrayTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<ByteArrayTag> nbt(tag);
|
|
auto* nbtObj = new NbtByteArrayClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtByteArrayClass(Tag::asTypedTag<ByteArrayTag>(tag->copy())))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtByteArray!");
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::pack(std::unique_ptr<ByteArrayTag> tag) {
|
|
try {
|
|
return (new NbtByteArrayClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtByteArray!");
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::ByteArray);
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::get(const Arguments& args) {
|
|
try {
|
|
auto& data = nbt->value();
|
|
return ByteBuffer::newByteBuffer(data.data.get(), data.size);
|
|
}
|
|
CATCH("Fail in NbtValueGet!")
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtByteArrayClass::set(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
Local<ByteBuffer> buf = args[0].asByteBuffer();
|
|
return Boolean::newBoolean(nbt->set(TagMemoryChunk((char*)buf.getRawBytes(), buf.byteLength())));
|
|
}
|
|
CATCH("Fail in NbtValueSet!")
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtList ////////////////////
|
|
|
|
NbtListClass::NbtListClass(const Local<Object>& scriptObj, std::unique_ptr<ListTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
NbtListClass::NbtListClass(std::unique_ptr<ListTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtListClass>{}) {
|
|
this->nbt = std::move(p);
|
|
}
|
|
|
|
////////////////// Helper //////////////////
|
|
void NbtListClassAddHelper(ListTag* tag, Local<Array>& arr) {
|
|
if (arr.size() > 0) {
|
|
Local<Value> t = arr.get(0);
|
|
if (IsInstanceOf<NbtEndClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtEndClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtByteClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtByteClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtShortClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtShortClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtIntClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtIntClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtLongClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtLongClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtFloatClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtFloatClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtDoubleClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtDoubleClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtStringClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtStringClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtByteArrayClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtByteArrayClass::extract(arr.get(i))->copy());
|
|
else if (IsInstanceOf<NbtListClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtListClass::extract(arr.get(i))->copyList());
|
|
else if (IsInstanceOf<NbtCompoundClass>(t))
|
|
for (int i = 0; i < arr.size(); ++i)
|
|
tag->add(NbtCompoundClass::extract(arr.get(i))->clone());
|
|
else if (t.isArray()) {
|
|
for (int i = 0; i < arr.size(); ++i) {
|
|
auto arrTag = ListTag::create();
|
|
auto data = arr.get(i).asArray();
|
|
NbtListClassAddHelper(arrTag.get(), data);
|
|
tag->add(std::move(arrTag));
|
|
}
|
|
} else if (t.isObject()) {
|
|
for (int i = 0; i < arr.size(); ++i) {
|
|
auto objTag = CompoundTag::create();
|
|
auto data = arr.get(i).asObject();
|
|
NbtCompoundClassAddHelper(objTag.get(), data);
|
|
tag->add(std::move(objTag));
|
|
}
|
|
} else {
|
|
throw script::Exception("Wrong Type of data to set into NBT List!");
|
|
}
|
|
}
|
|
}
|
|
|
|
NbtListClass* NbtListClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = ListTag::create();
|
|
|
|
if (args.size() >= 1 && args[0].isArray()) {
|
|
auto arr = args[0].asArray();
|
|
NbtListClassAddHelper(tag.get(), arr);
|
|
}
|
|
|
|
return new NbtListClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create ListTag!");
|
|
}
|
|
|
|
ListTag* NbtListClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtListClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtListClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtListClass::pack(ListTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<ListTag> nbt(tag);
|
|
auto* nbtObj = new NbtListClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtListClass(tag->copyList()))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtList!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::pack(std::unique_ptr<ListTag> tag) {
|
|
try {
|
|
return (new NbtListClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtList!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::List);
|
|
}
|
|
|
|
Local<Value> NbtListClass::getSize(const Arguments& args) {
|
|
try {
|
|
return Number::newNumber((int)nbt->getSize());
|
|
}
|
|
CATCH("Fail in NBT GetSize!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::getTypeOf(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
return Local<Value>();
|
|
}
|
|
|
|
return Number::newNumber(int(list[index]->getTagType()));
|
|
}
|
|
CATCH("Fail in NBT GetTypeOf!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setEnd(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::End) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asEndTag()->set();
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetEnd!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setByte(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Byte) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asByteTag()->set(args[1].toInt());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetByte!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setInt(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Int) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asIntTag()->set(args[1].toInt());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetInt!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setShort(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Short) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asShortTag()->set(args[1].toInt());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetShort!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setLong(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Int64) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asInt64Tag()->set(args[1].asNumber().toInt64());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetLong!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setFloat(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Float) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asFloatTag()->set(args[1].asNumber().toFloat());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetFloat!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setDouble(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::Double) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asDoubleTag()->set(args[1].asNumber().toDouble());
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetDouble!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setString(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::String) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
list[index]->asStringTag()->set(args[1].toStr());
|
|
}
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetString!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setByteArray(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kByteBuffer);
|
|
|
|
try {
|
|
auto list = nbt->get();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
} else if (list[0]->getTagType() != Tag::Type::ByteArray) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Set wrong type of element into NBT List!");
|
|
} else {
|
|
auto data = args[1].asByteBuffer();
|
|
list[index]->asByteArrayTag()->set(TagMemoryChunk((char*)data.getRawBytes(), data.byteLength()));
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetByteArray!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::setTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
return Local<Value>();
|
|
}
|
|
|
|
if (IsInstanceOf<NbtEndClass>(args[1])) {
|
|
list[index] = NbtEndClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtByteClass>(args[1])) {
|
|
list[index] = NbtByteClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtShortClass>(args[1])) {
|
|
list[index] = NbtShortClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtIntClass>(args[1])) {
|
|
list[index] = NbtIntClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtLongClass>(args[1])) {
|
|
list[index] = NbtLongClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtFloatClass>(args[1])) {
|
|
list[index] = NbtFloatClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtDoubleClass>(args[1])) {
|
|
list[index] = NbtDoubleClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtStringClass>(args[1])) {
|
|
list[index] = NbtStringClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtByteArrayClass>(args[1])) {
|
|
list[index] = NbtByteArrayClass::extract(args[1])->copy().release();
|
|
} else if (IsInstanceOf<NbtListClass>(args[1])) {
|
|
list[index] = NbtListClass::extract(args[1])->copyList().release();
|
|
} else if (IsInstanceOf<NbtCompoundClass>(args[1])) {
|
|
list[index] = NbtCompoundClass::extract(args[1])->clone().release();
|
|
} else {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Unknown type! Cannot set Tag into List");
|
|
return Local<Value>();
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetTag!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::addTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
|
|
try {
|
|
if (IsInstanceOf<NbtEndClass>(args[0])) {
|
|
nbt->add(NbtEndClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtByteClass>(args[0])) {
|
|
nbt->add(NbtByteClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtShortClass>(args[0])) {
|
|
nbt->add(NbtShortClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtIntClass>(args[0])) {
|
|
nbt->add(NbtIntClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtLongClass>(args[0])) {
|
|
nbt->add(NbtLongClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtFloatClass>(args[0])) {
|
|
nbt->add(NbtFloatClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtDoubleClass>(args[0])) {
|
|
nbt->add(NbtDoubleClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtStringClass>(args[0])) {
|
|
nbt->add(NbtStringClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtByteArrayClass>(args[0])) {
|
|
nbt->add(NbtByteArrayClass::extract(args[0])->copy());
|
|
} else if (IsInstanceOf<NbtListClass>(args[0])) {
|
|
nbt->add(NbtListClass::extract(args[0])->copyList());
|
|
} else if (IsInstanceOf<NbtCompoundClass>(args[0])) {
|
|
nbt->add(NbtCompoundClass::extract(args[0])->clone());
|
|
} else {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Unknown type! Cannot add Tag into List");
|
|
return Local<Value>();
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT AddTag!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::removeTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Bad Index of NBT List!");
|
|
return Local<Value>();
|
|
}
|
|
|
|
list.erase(list.begin() + index); //===== delete?
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetTag!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::getData(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
return Local<Value>();
|
|
}
|
|
|
|
return Tag2Value(list[index]);
|
|
}
|
|
CATCH("Fail in NBTgetData!")
|
|
}
|
|
|
|
Local<Value> NbtListClass::getTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto index = args[0].toInt();
|
|
|
|
if (index >= list.size() || index < 0) {
|
|
return Local<Value>();
|
|
}
|
|
|
|
Local<Value> res;
|
|
switch (list[index]->getTagType()) {
|
|
case Tag::Type::End:
|
|
res = NbtEndClass::pack(list[index]->asEndTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Byte:
|
|
res = NbtByteClass::pack(list[index]->asByteTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Short:
|
|
res = NbtShortClass::pack(list[index]->asShortTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Int:
|
|
res = NbtIntClass::pack(list[index]->asIntTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Int64:
|
|
res = NbtLongClass::pack(list[index]->asInt64Tag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Float:
|
|
res = NbtFloatClass::pack(list[index]->asFloatTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Double:
|
|
res = NbtDoubleClass::pack(list[index]->asDoubleTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::String:
|
|
res = NbtStringClass::pack(list[index]->asStringTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::ByteArray:
|
|
res = NbtByteArrayClass::pack(list[index]->asByteArrayTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::List:
|
|
res = NbtListClass::pack(list[index]->asListTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Compound:
|
|
res = NbtCompoundClass::pack(list[index]->asCompoundTag(), true); // share ptr
|
|
break;
|
|
default:
|
|
res = Local<Value>();
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
CATCH("Fail in NBT GetTag!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::toArray(const Arguments& args) {
|
|
try {
|
|
auto& list = nbt->value();
|
|
Local<Array> arr = Array::newArray();
|
|
|
|
for (auto& tag : list) {
|
|
arr.add(Tag2Value(tag, true));
|
|
}
|
|
return arr;
|
|
}
|
|
CATCH("Fail in NBTtoArray!");
|
|
}
|
|
|
|
Local<Value> NbtListClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
|
|
//////////////////// Classes NbtCompound ////////////////////
|
|
|
|
NbtCompoundClass::NbtCompoundClass(const Local<Object>& scriptObj, std::unique_ptr<CompoundTag> p)
|
|
: ScriptClass(scriptObj) {
|
|
nbt = std::move(p);
|
|
}
|
|
|
|
NbtCompoundClass::NbtCompoundClass(std::unique_ptr<CompoundTag> p)
|
|
: ScriptClass(ScriptClass::ConstructFromCpp<NbtCompoundClass>{}) {
|
|
nbt = std::move(p);
|
|
}
|
|
|
|
////////////////// Helper //////////////////
|
|
void NbtCompoundClassAddHelper(CompoundTag* tag, Local<Object>& obj) {
|
|
auto keys = obj.getKeyNames();
|
|
if (keys.size() > 0) {
|
|
for (int i = 0; i < keys.size(); ++i) {
|
|
Local<Value> t = obj.get(keys[i]);
|
|
if (IsInstanceOf<NbtEndClass>(t))
|
|
tag->put(keys[i], NbtEndClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtByteClass>(t))
|
|
tag->put(keys[i], NbtByteClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtShortClass>(t))
|
|
tag->put(keys[i], NbtShortClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtIntClass>(t))
|
|
tag->put(keys[i], NbtIntClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtLongClass>(t))
|
|
tag->put(keys[i], NbtLongClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtFloatClass>(t))
|
|
tag->put(keys[i], NbtFloatClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtDoubleClass>(t))
|
|
tag->put(keys[i], NbtDoubleClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtStringClass>(t))
|
|
tag->put(keys[i], NbtStringClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtByteArrayClass>(t))
|
|
tag->put(keys[i], NbtByteArrayClass::extract(obj.get(keys[i]))->copy());
|
|
else if (IsInstanceOf<NbtListClass>(t))
|
|
tag->put(keys[i], NbtListClass::extract(obj.get(keys[i]))->copyList());
|
|
else if (IsInstanceOf<NbtCompoundClass>(t))
|
|
tag->put(keys[i], NbtCompoundClass::extract(obj.get(keys[i]))->clone());
|
|
else if (t.isArray()) {
|
|
auto arrTag = ListTag::create();
|
|
auto data = obj.get(keys[i]).asArray();
|
|
NbtListClassAddHelper(arrTag.get(), data);
|
|
tag->put(keys[i], std::move(arrTag));
|
|
} else if (t.isObject()) {
|
|
auto objTag = CompoundTag::create();
|
|
auto data = obj.get(keys[i]).asObject();
|
|
NbtCompoundClassAddHelper(objTag.get(), data);
|
|
tag->put(keys[i], std::move(objTag));
|
|
} else {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Wrong Type of data to set into NBT Compound!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
NbtCompoundClass* NbtCompoundClass::constructor(const Arguments& args) {
|
|
try {
|
|
auto tag = CompoundTag::create();
|
|
|
|
if (args.size() >= 1 && args[0].isObject()) {
|
|
auto obj = args[0].asObject();
|
|
NbtCompoundClassAddHelper(tag.get(), obj);
|
|
}
|
|
|
|
return new NbtCompoundClass(args.thiz(), std::move(tag));
|
|
}
|
|
CATCH_C("Fail in Create ListTag!");
|
|
}
|
|
|
|
CompoundTag* NbtCompoundClass::extract(Local<Value> v) {
|
|
if (EngineScope::currentEngine()->isInstanceOf<NbtCompoundClass>(v))
|
|
return EngineScope::currentEngine()->getNativeInstance<NbtCompoundClass>(v)->nbt.get();
|
|
else
|
|
return nullptr;
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::pack(CompoundTag* tag, bool noDelete) {
|
|
try {
|
|
if (noDelete) // unique_ptr 共享指针 + noDelete
|
|
{
|
|
std::unique_ptr<CompoundTag> nbt(tag);
|
|
auto* nbtObj = new NbtCompoundClass(std::move(nbt));
|
|
nbtObj->canDelete = false;
|
|
return nbtObj->getScriptObject();
|
|
} else
|
|
return (new NbtCompoundClass(tag->clone()))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtCompound!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::pack(std::unique_ptr<CompoundTag> tag) {
|
|
try {
|
|
return (new NbtCompoundClass(std::move(tag)))->getScriptObject();
|
|
}
|
|
CATCH("Fail in construct NbtCompound!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::getType(const Arguments& args) {
|
|
return Number::newNumber((int)Tag::Type::Compound);
|
|
}
|
|
|
|
|
|
Local<Value> NbtCompoundClass::getKeys(const Arguments& args) {
|
|
try {
|
|
Local<Array> arr = Array::newArray();
|
|
auto& list = nbt->value();
|
|
for (auto& [k, v] : list) {
|
|
arr.add(String::newString(k));
|
|
}
|
|
|
|
return arr;
|
|
}
|
|
CATCH("Fail in NBT GetKeys!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::getTypeOf(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto key = args[0].toStr();
|
|
|
|
return Number::newNumber(int(list.at(key).getTagType()));
|
|
} catch (const out_of_range& e) {
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in NBT GetTypeOf!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setEnd(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
nbt->putByte(key, (char)0);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetEnd!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setByte(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = char(args[1].toInt());
|
|
nbt->putByte(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetByte!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setInt(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = int(args[1].toInt());
|
|
nbt->putInt(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetInt!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setShort(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = short(args[1].toInt());
|
|
nbt->putShort(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetShort!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setLong(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = args[1].asNumber().toInt64();
|
|
nbt->putInt64(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetLong!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setFloat(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = args[1].asNumber().toFloat();
|
|
nbt->putFloat(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetFloat!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setDouble(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto key = args[0].toStr();
|
|
auto data = args[1].asNumber().toDouble();
|
|
|
|
list.at(key).asDoubleTag()->value() = data;
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetDouble!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setString(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kString);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = args[1].toStr();
|
|
nbt->putString(key, data);
|
|
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetString!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setByteArray(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
CHECK_ARG_TYPE(args[1], ValueKind::kByteBuffer);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
auto data = args[1].asByteBuffer();
|
|
|
|
nbt->putByteArray(key, (char*)data.getRawBytes(), data.byteLength());
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetString!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::setTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 2);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
|
|
if (IsInstanceOf<NbtEndClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtEndClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtByteClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtByteClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtShortClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtShortClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtIntClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtIntClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtLongClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtLongClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtFloatClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtFloatClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtDoubleClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtDoubleClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtStringClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtStringClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtByteArrayClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtByteArrayClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtListClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtListClass::extract(args[1])->copy()));
|
|
} else if (IsInstanceOf<NbtCompoundClass>(args[1])) {
|
|
nbt->put(key, std::move(NbtCompoundClass::extract(args[1])->copy()));
|
|
} else {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Unknown type! Cannot set Tag into Compound");
|
|
return Local<Value>();
|
|
}
|
|
return this->getScriptObject();
|
|
}
|
|
CATCH("Fail in NBT SetTag!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::removeTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto key = args[0].toStr();
|
|
|
|
list.erase(key);
|
|
return this->getScriptObject();
|
|
} catch (const out_of_range& e) {
|
|
LOG_ERROR_WITH_SCRIPT_INFO("Key no found in NBT Compound!");
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in NBT RemoveTag!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::getData(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto& list = nbt->value();
|
|
auto key = args[0].toStr();
|
|
|
|
return Tag2Value(list.at(key).asTag());
|
|
} catch (const out_of_range& e) {
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in NBT GetData!")
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::getTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto key = args[0].toStr();
|
|
|
|
Local<Value> res;
|
|
switch (nbt->value().at(key).getTagType()) {
|
|
case Tag::Type::End:
|
|
res = NbtEndClass::pack(nbt->value().at(key).asEndTag(), true); // share ptr
|
|
break;
|
|
case Tag::Type::Byte:
|
|
res = NbtByteClass::pack((ByteTag*)nbt->getByteTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Short:
|
|
res = NbtShortClass::pack((ShortTag*)nbt->getShortTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Int:
|
|
res = NbtIntClass::pack((IntTag*)nbt->getIntTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Int64:
|
|
res = NbtLongClass::pack((Int64Tag*)nbt->getInt64Tag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Float:
|
|
res = NbtFloatClass::pack((FloatTag*)nbt->getFloatTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Double:
|
|
res = NbtDoubleClass::pack((DoubleTag*)nbt->getDoubleTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::String:
|
|
res = NbtStringClass::pack((StringTag*)nbt->getStringTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::ByteArray:
|
|
res = NbtByteArrayClass::pack((ByteArrayTag*)nbt->getByteArrayTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::List:
|
|
res = NbtListClass::pack((ListTag*)nbt->getListTag(key), true); // share ptr
|
|
break;
|
|
case Tag::Type::Compound:
|
|
res = NbtCompoundClass::pack((CompoundTag*)nbt->getCompoundTag(key), true); // share ptr
|
|
break;
|
|
default:
|
|
res = Local<Value>();
|
|
break;
|
|
}
|
|
return res;
|
|
} catch (const out_of_range& e) {
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in NBT GetTag!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::toObject(const Arguments& args) {
|
|
try {
|
|
auto& comp = nbt->value();
|
|
Local<Object> obj = Object::newObject();
|
|
|
|
for (auto& [k, v] : comp) {
|
|
obj.set(k, Tag2Value(v.asTag(), true));
|
|
}
|
|
return obj;
|
|
}
|
|
CATCH("Fail in NBT ToObject!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::toSNBT(const Arguments& args) {
|
|
try {
|
|
int indent = args.size() >= 1 ? args[0].toInt() : -1;
|
|
if (indent == -1)
|
|
return String::newString(nbt->toSNBT(0, SnbtFormat::Minimize));
|
|
else
|
|
return String::newString(nbt->toSNBT(indent, SnbtFormat::PartialNewLine));
|
|
}
|
|
CATCH("Fail in toSNBT!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::toBinaryNBT(const Arguments& args) {
|
|
try {
|
|
auto res = nbt->toBinaryNBT();
|
|
return ByteBuffer::newByteBuffer(res.data(), res.size());
|
|
}
|
|
CATCH("Fail in toBinaryNBT!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::toString(const Arguments& args) {
|
|
if (args.size() >= 1)
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
return String::newString(nbt->toJson(args.size() >= 1 ? args[0].toInt() : -1));
|
|
}
|
|
CATCH("Fail in NBTtoJson!");
|
|
}
|
|
|
|
Local<Value> NbtCompoundClass::destroy(const Arguments& args) {
|
|
return Boolean::newBoolean(true);
|
|
}
|
|
|
|
//////////////////// APIs ////////////////////
|
|
|
|
Local<Value> NbtStatic::newTag(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kNumber);
|
|
|
|
try {
|
|
auto type = args[0].toInt();
|
|
|
|
Local<Value> res;
|
|
switch (type) {
|
|
case Tag::Type::End: {
|
|
auto tag = EndTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set();
|
|
}
|
|
res = NbtEndClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Byte: {
|
|
auto tag = ByteTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].toInt());
|
|
}
|
|
res = NbtByteClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Short: {
|
|
auto tag = ShortTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].toInt());
|
|
}
|
|
res = NbtShortClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Int: {
|
|
auto tag = IntTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].toInt());
|
|
}
|
|
res = NbtIntClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Int64: {
|
|
auto tag = Int64Tag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].asNumber().toInt64());
|
|
}
|
|
res = NbtLongClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Float: {
|
|
auto tag = FloatTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].asNumber().toFloat());
|
|
}
|
|
res = NbtFloatClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Double: {
|
|
auto tag = DoubleTag::create();
|
|
if (args.size() >= 2 && args[1].isNumber()) {
|
|
tag->set(args[1].asNumber().toDouble());
|
|
}
|
|
res = NbtDoubleClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::String: {
|
|
auto tag = StringTag::create();
|
|
if (args.size() >= 2 && args[1].isString()) {
|
|
tag->set(args[1].toStr());
|
|
}
|
|
res = NbtStringClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::ByteArray: {
|
|
auto tag = ByteArrayTag::create();
|
|
if (args.size() >= 2 && args[1].isByteBuffer()) {
|
|
Local<ByteBuffer> buf = args[1].asByteBuffer();
|
|
tag->set(TagMemoryChunk((char*)buf.getRawBytes(), buf.byteLength()));
|
|
}
|
|
res = NbtByteArrayClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::List: {
|
|
auto tag = ListTag::create();
|
|
if (args.size() >= 2 && args[1].isArray()) {
|
|
Local<Array> arr = args[1].asArray();
|
|
NbtListClassAddHelper(tag.get(), arr);
|
|
}
|
|
res = NbtListClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
case Tag::Type::Compound: {
|
|
auto tag = CompoundTag::create();
|
|
if (args.size() >= 2 && args[1].isObject()) {
|
|
Local<Object> obj = args[1].asObject();
|
|
NbtCompoundClassAddHelper(tag.get(), obj);
|
|
}
|
|
res = NbtCompoundClass::pack(std::move(tag));
|
|
break;
|
|
}
|
|
default:
|
|
res = Local<Value>();
|
|
break;
|
|
}
|
|
return res;
|
|
}
|
|
CATCH("Fail in NBT CreateTag!");
|
|
}
|
|
|
|
Local<Value> NbtStatic::parseSNBT(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kString);
|
|
|
|
try {
|
|
auto tag = CompoundTag::fromSNBT(args[0].toStr());
|
|
if (tag)
|
|
return NbtCompoundClass::pack(std::move(tag));
|
|
else
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in parseSNBT!");
|
|
}
|
|
|
|
Local<Value> NbtStatic::parseBinaryNBT(const Arguments& args) {
|
|
CHECK_ARGS_COUNT(args, 1);
|
|
CHECK_ARG_TYPE(args[0], ValueKind::kByteBuffer);
|
|
|
|
try {
|
|
auto data = args[0].asByteBuffer();
|
|
auto tag = CompoundTag::fromBinaryNBT(data.getRawBytes(), data.byteLength());
|
|
if (tag)
|
|
return NbtCompoundClass::pack(std::move(tag));
|
|
else
|
|
return Local<Value>();
|
|
}
|
|
CATCH("Fail in parseBinaryNBT!");
|
|
}
|
|
|
|
|
|
//////////////////// Helper ////////////////////
|
|
|
|
bool IsNbtClass(Local<Value> value) {
|
|
return IsInstanceOf<NbtEndClass>(value) || IsInstanceOf<NbtByteClass>(value) || IsInstanceOf<NbtShortClass>(value) || IsInstanceOf<NbtIntClass>(value) || IsInstanceOf<NbtLongClass>(value) || IsInstanceOf<NbtFloatClass>(value) || IsInstanceOf<NbtDoubleClass>(value) || IsInstanceOf<NbtStringClass>(value) || IsInstanceOf<NbtByteArrayClass>(value) || IsInstanceOf<NbtListClass>(value) || IsInstanceOf<NbtCompoundClass>(value);
|
|
}
|
|
|
|
|
|
//////////////////// Tag To Value ////////////////////
|
|
|
|
Local<Value> Tag2Value_CompoundHelper(CompoundTag* nbt, bool autoExpansion = false);
|
|
|
|
Local<Value> Tag2Value_ListHelper(ListTag* nbt, bool autoExpansion = false) {
|
|
Local<Array> res = Array::newArray();
|
|
|
|
auto& list = nbt->asListTag()->value();
|
|
for (auto& tag : list) {
|
|
switch (tag->getTagType()) {
|
|
case Tag::Type::End:
|
|
res.add(Local<Value>());
|
|
break;
|
|
case Tag::Type::Byte:
|
|
res.add(Number::newNumber(tag->asByteTag()->value()));
|
|
break;
|
|
case Tag::Type::Short:
|
|
res.add(Number::newNumber(tag->asShortTag()->value()));
|
|
break;
|
|
case Tag::Type::Int:
|
|
res.add(Number::newNumber(tag->asIntTag()->value()));
|
|
break;
|
|
case Tag::Type::Int64:
|
|
res.add(Number::newNumber(tag->asInt64Tag()->value()));
|
|
break;
|
|
case Tag::Type::Float:
|
|
res.add(Number::newNumber(tag->asFloatTag()->value()));
|
|
break;
|
|
case Tag::Type::Double:
|
|
res.add(Number::newNumber(tag->asDoubleTag()->value()));
|
|
break;
|
|
case Tag::Type::String:
|
|
res.add(String::newString(tag->asStringTag()->value()));
|
|
break;
|
|
case Tag::Type::ByteArray: {
|
|
auto& data = tag->asByteArrayTag()->value();
|
|
res.add(ByteBuffer::newByteBuffer(data.data.get(), data.size));
|
|
break;
|
|
}
|
|
case Tag::Type::List:
|
|
if (!autoExpansion)
|
|
res.add(NbtListClass::pack(tag->asListTag()));
|
|
else
|
|
res.add(Tag2Value_ListHelper(tag->asListTag(), autoExpansion));
|
|
break;
|
|
case Tag::Type::Compound:
|
|
if (!autoExpansion)
|
|
res.add(NbtCompoundClass::pack(tag->asCompoundTag()));
|
|
else
|
|
res.add(Tag2Value_CompoundHelper(tag->asCompoundTag(), autoExpansion));
|
|
default:
|
|
res.add(Local<Value>());
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Local<Value> Tag2Value_CompoundHelper(CompoundTag* nbt, bool autoExpansion) {
|
|
Local<Object> res = Object::newObject();
|
|
|
|
auto& list = nbt->asCompoundTag()->value();
|
|
for (auto& [key, tag] : list) {
|
|
switch (tag.getTagType()) {
|
|
case Tag::Type::End:
|
|
res.set(key, Local<Value>());
|
|
break;
|
|
case Tag::Type::Byte:
|
|
res.set(key, Number::newNumber(tag.asByteTag()->get()));
|
|
break;
|
|
case Tag::Type::Short:
|
|
res.set(key, Number::newNumber(tag.asShortTag()->get()));
|
|
break;
|
|
case Tag::Type::Int:
|
|
res.set(key, Number::newNumber(tag.asIntTag()->get()));
|
|
break;
|
|
case Tag::Type::Int64:
|
|
res.set(key, Number::newNumber(tag.asInt64Tag()->get()));
|
|
break;
|
|
case Tag::Type::Float:
|
|
res.set(key, Number::newNumber(tag.asFloatTag()->get()));
|
|
break;
|
|
case Tag::Type::Double:
|
|
res.set(key, Number::newNumber(tag.asDoubleTag()->get()));
|
|
break;
|
|
case Tag::Type::String:
|
|
res.set(key, String::newString(tag.asStringTag()->get()));
|
|
break;
|
|
case Tag::Type::ByteArray: {
|
|
auto& data = tag.asByteArrayTag()->value();
|
|
res.set(key, ByteBuffer::newByteBuffer(data.data.get(), data.size));
|
|
break;
|
|
}
|
|
case Tag::Type::List:
|
|
if (!autoExpansion)
|
|
res.set(key, NbtListClass::pack(tag.asListTag()));
|
|
else
|
|
res.set(key, Tag2Value_ListHelper(tag.asListTag(), autoExpansion));
|
|
break;
|
|
case Tag::Type::Compound:
|
|
if (!autoExpansion)
|
|
res.set(key, NbtCompoundClass::pack(tag.asCompoundTag()));
|
|
else
|
|
res.set(key, Tag2Value_CompoundHelper(tag.asCompoundTag(), autoExpansion));
|
|
default:
|
|
res.set(key, Local<Value>());
|
|
break;
|
|
}
|
|
}
|
|
return res;
|
|
}
|
|
|
|
Local<Value> Tag2Value(Tag* nbt, bool autoExpansion) {
|
|
Local<Value> value;
|
|
|
|
switch (nbt->getTagType()) {
|
|
case Tag::Type::End:
|
|
value = Number::newNumber(0);
|
|
break;
|
|
case Tag::Type::Byte:
|
|
value = Number::newNumber(nbt->asByteTag()->get());
|
|
break;
|
|
case Tag::Type::Short:
|
|
value = Number::newNumber(nbt->asShortTag()->get());
|
|
break;
|
|
case Tag::Type::Int:
|
|
value = Number::newNumber(nbt->asIntTag()->get());
|
|
break;
|
|
case Tag::Type::Int64:
|
|
value = Number::newNumber(nbt->asInt64Tag()->get());
|
|
break;
|
|
case Tag::Type::Float:
|
|
value = Number::newNumber(nbt->asFloatTag()->get());
|
|
break;
|
|
case Tag::Type::Double:
|
|
value = Number::newNumber(nbt->asDoubleTag()->get());
|
|
break;
|
|
case Tag::Type::String:
|
|
value = String::newString(nbt->asStringTag()->get());
|
|
break;
|
|
case Tag::Type::ByteArray: {
|
|
auto& data = nbt->asByteArrayTag()->value();
|
|
value = ByteBuffer::newByteBuffer(data.data.get(), data.size);
|
|
break;
|
|
}
|
|
case Tag::Type::List:
|
|
if (!autoExpansion)
|
|
value = NbtListClass::pack(nbt->asListTag());
|
|
else
|
|
value = Tag2Value_ListHelper(nbt->asListTag(), autoExpansion);
|
|
break;
|
|
case Tag::Type::Compound:
|
|
if (!autoExpansion)
|
|
value = NbtCompoundClass::pack(nbt->asCompoundTag());
|
|
else
|
|
value = Tag2Value_CompoundHelper(nbt->asCompoundTag(), autoExpansion);
|
|
break;
|
|
default:
|
|
value = Local<Value>();
|
|
break;
|
|
}
|
|
return value;
|
|
} |