11#include " api/NbtAPI.h"
22
33#include " api/APIHelp.h"
4- #include " api/BlockAPI.h"
5- #include " api/ItemAPI.h"
64#include " legacyapi/Base64.h"
75#include " mc/nbt/ByteArrayTag.h"
86#include " mc/nbt/ByteTag.h"
@@ -345,6 +343,7 @@ NbtByteClass* NbtByteClass::constructor(const Arguments& args) {
345343 CATCH_C (" Fail in Create ByteTag!" );
346344}
347345
346+ // Because the class must own the Tag, so we return Tag's raw pointer
348347ByteTag* NbtByteClass::extract (Local<Value> v) {
349348 if (EngineScope::currentEngine ()->isInstanceOf <NbtByteClass>(v))
350349 return EngineScope::currentEngine ()->getNativeInstance <NbtByteClass>(v)->nbt .get ();
@@ -353,7 +352,7 @@ ByteTag* NbtByteClass::extract(Local<Value> v) {
353352
354353Local<Value> NbtByteClass::pack (ByteTag* tag, bool noDelete) {
355354 try {
356- if (noDelete) // unique_ptr 共享指针 + noDelete
355+ if (noDelete) // unique_ptr shared pointer + noDelete
357356 {
358357 NbtByteClass* nbtObj = new NbtByteClass (std::unique_ptr<ByteTag>(tag));
359358 nbtObj->canDelete = false ;
@@ -423,7 +422,7 @@ IntTag* NbtIntClass::extract(Local<Value> v) {
423422
424423Local<Value> NbtIntClass::pack (IntTag* tag, bool noDelete) {
425424 try {
426- if (noDelete) // unique_ptr 共享指针 + noDelete
425+ if (noDelete) // unique_ptr shared pointer + noDelete
427426 {
428427 NbtIntClass* nbtObj = new NbtIntClass (std::unique_ptr<IntTag>(tag));
429428 nbtObj->canDelete = false ;
@@ -494,7 +493,7 @@ ShortTag* NbtShortClass::extract(Local<Value> v) {
494493
495494Local<Value> NbtShortClass::pack (ShortTag* tag, bool noDelete) {
496495 try {
497- if (noDelete) // unique_ptr 共享指针 + noDelete
496+ if (noDelete) // unique_ptr shared pointer + noDelete
498497 {
499498 NbtShortClass* nbtObj = new NbtShortClass (std::unique_ptr<ShortTag>(tag));
500499 nbtObj->canDelete = false ;
@@ -564,7 +563,7 @@ Int64Tag* NbtLongClass::extract(Local<Value> v) {
564563
565564Local<Value> NbtLongClass::pack (Int64Tag* tag, bool noDelete) {
566565 try {
567- if (noDelete) // unique_ptr 共享指针 + noDelete
566+ if (noDelete) // unique_ptr shared pointer + noDelete
568567 {
569568 NbtLongClass* nbtObj = new NbtLongClass (std::unique_ptr<Int64Tag>(tag));
570569 nbtObj->canDelete = false ;
@@ -635,7 +634,7 @@ FloatTag* NbtFloatClass::extract(Local<Value> v) {
635634
636635Local<Value> NbtFloatClass::pack (FloatTag* tag, bool noDelete) {
637636 try {
638- if (noDelete) // unique_ptr 共享指针 + noDelete
637+ if (noDelete) // unique_ptr shared pointer + noDelete
639638 {
640639 NbtFloatClass* nbtObj = new NbtFloatClass (std::unique_ptr<FloatTag>(tag));
641640 nbtObj->canDelete = false ;
@@ -706,7 +705,7 @@ DoubleTag* NbtDoubleClass::extract(Local<Value> v) {
706705
707706Local<Value> NbtDoubleClass::pack (DoubleTag* tag, bool noDelete) {
708707 try {
709- if (noDelete) // unique_ptr 共享指针 + noDelete
708+ if (noDelete) // unique_ptr shared pointer + noDelete
710709 {
711710 NbtDoubleClass* nbtObj = new NbtDoubleClass (std::unique_ptr<DoubleTag>(tag));
712711 nbtObj->canDelete = false ;
@@ -777,7 +776,7 @@ StringTag* NbtStringClass::extract(Local<Value> v) {
777776
778777Local<Value> NbtStringClass::pack (StringTag* tag, bool noDelete) {
779778 try {
780- if (noDelete) // unique_ptr 共享指针 + noDelete
779+ if (noDelete) // unique_ptr shared pointer + noDelete
781780 {
782781 NbtStringClass* nbtObj = new NbtStringClass (std::unique_ptr<StringTag>(tag));
783782 nbtObj->canDelete = false ;
@@ -855,7 +854,7 @@ ByteArrayTag* NbtByteArrayClass::extract(Local<Value> v) {
855854
856855Local<Value> NbtByteArrayClass::pack (ByteArrayTag* tag, bool noDelete) {
857856 try {
858- if (noDelete) // unique_ptr 共享指针 + noDelete
857+ if (noDelete) // unique_ptr shared pointer + noDelete
859858 {
860859 NbtByteArrayClass* nbtObj = new NbtByteArrayClass (std::unique_ptr<ByteArrayTag>(tag));
861860 nbtObj->canDelete = false ;
@@ -920,28 +919,29 @@ NbtListClass::NbtListClass(std::unique_ptr<ListTag> p) : ScriptClass(ScriptClass
920919
921920// //////////////// Helper //////////////////
922921void NbtListClassAddHelper (ListTag* tag, Local<Array>& arr) {
923- if (arr.size () > 0 ) {
922+ if (arr.size ()
923+ > 0 ) { // ListTag::add deletes the Tag which is provided as argument, so make a copy of Tag before using it.
924924 Local<Value> t = arr.get (0 );
925925 if (IsInstanceOf<NbtByteClass>(t))
926- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtByteClass::extract (arr.get (i)));
926+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtByteClass::extract (arr.get (i))-> copy () );
927927 else if (IsInstanceOf<NbtShortClass>(t))
928- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtShortClass::extract (arr.get (i)));
928+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtShortClass::extract (arr.get (i))-> copy () );
929929 else if (IsInstanceOf<NbtIntClass>(t))
930- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtIntClass::extract (arr.get (i)));
930+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtIntClass::extract (arr.get (i))-> copy () );
931931 else if (IsInstanceOf<NbtLongClass>(t))
932- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtLongClass::extract (arr.get (i)));
932+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtLongClass::extract (arr.get (i))-> copy () );
933933 else if (IsInstanceOf<NbtFloatClass>(t))
934- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtFloatClass::extract (arr.get (i)));
934+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtFloatClass::extract (arr.get (i))-> copy () );
935935 else if (IsInstanceOf<NbtDoubleClass>(t))
936- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtDoubleClass::extract (arr.get (i)));
936+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtDoubleClass::extract (arr.get (i))-> copy () );
937937 else if (IsInstanceOf<NbtStringClass>(t))
938- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtStringClass::extract (arr.get (i)));
938+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtStringClass::extract (arr.get (i))-> copy () );
939939 else if (IsInstanceOf<NbtByteArrayClass>(t))
940- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtByteArrayClass::extract (arr.get (i)));
940+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtByteArrayClass::extract (arr.get (i))-> copy () );
941941 else if (IsInstanceOf<NbtListClass>(t))
942- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtListClass::extract (arr.get (i)));
942+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtListClass::extract (arr.get (i))-> copyList () );
943943 else if (IsInstanceOf<NbtCompoundClass>(t))
944- for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtCompoundClass::extract (arr.get (i)));
944+ for (int i = 0 ; i < arr.size (); ++i) tag->add (*NbtCompoundClass::extract (arr.get (i))-> clone () );
945945 else if (t.isArray ()) {
946946 for (int i = 0 ; i < arr.size (); ++i) {
947947 auto arrTag = ListTag ();
@@ -984,7 +984,7 @@ ListTag* NbtListClass::extract(Local<Value> v) {
984984
985985Local<Value> NbtListClass::pack (ListTag* tag, bool noDelete) {
986986 try {
987- if (noDelete) // unique_ptr 共享指针 + noDelete
987+ if (noDelete) // unique_ptr shared pointer + noDelete
988988 {
989989 NbtListClass* nbtObj = new NbtListClass (std::unique_ptr<ListTag>(tag));
990990 nbtObj->canDelete = false ;
@@ -1232,26 +1232,27 @@ Local<Value> NbtListClass::setTag(const Arguments& args) {
12321232 return Local<Value>();
12331233 }
12341234
1235- if (IsInstanceOf<NbtByteClass>(args[1 ])) {
1236- list[index] = std::unique_ptr<ByteTag>(NbtByteClass::extract (args[1 ]));
1235+ if (IsInstanceOf<NbtByteClass>(args[1 ]
1236+ )) { // Tag is stored as unique_ptr in TagClass, but TagClass must own the Tag, so I have to copy the Tag
1237+ list[index] = NbtByteClass::extract (args[1 ])->copy ();
12371238 } else if (IsInstanceOf<NbtShortClass>(args[1 ])) {
1238- list[index] = std::unique_ptr<ShortTag>( NbtShortClass::extract (args[1 ]));
1239+ list[index] = NbtShortClass::extract (args[1 ])-> copy ( );
12391240 } else if (IsInstanceOf<NbtIntClass>(args[1 ])) {
1240- list[index] = std::unique_ptr<IntTag>( NbtIntClass::extract (args[1 ]));
1241+ list[index] = NbtIntClass::extract (args[1 ])-> copy ( );
12411242 } else if (IsInstanceOf<NbtLongClass>(args[1 ])) {
1242- list[index] = std::unique_ptr<Int64Tag>( NbtLongClass::extract (args[1 ]));
1243+ list[index] = NbtLongClass::extract (args[1 ])-> copy ( );
12431244 } else if (IsInstanceOf<NbtFloatClass>(args[1 ])) {
1244- list[index] = std::unique_ptr<FloatTag>( NbtFloatClass::extract (args[1 ]));
1245+ list[index] = NbtFloatClass::extract (args[1 ])-> copy ( );
12451246 } else if (IsInstanceOf<NbtDoubleClass>(args[1 ])) {
1246- list[index] = std::unique_ptr<DoubleTag>( NbtDoubleClass::extract (args[1 ]));
1247+ list[index] = NbtDoubleClass::extract (args[1 ])-> copy ( );
12471248 } else if (IsInstanceOf<NbtStringClass>(args[1 ])) {
1248- list[index] = std::unique_ptr<StringTag>( NbtStringClass::extract (args[1 ]));
1249+ list[index] = NbtStringClass::extract (args[1 ])-> copy ( );
12491250 } else if (IsInstanceOf<NbtByteArrayClass>(args[1 ])) {
1250- list[index] = std::unique_ptr<ByteArrayTag>( NbtByteArrayClass::extract (args[1 ]));
1251+ list[index] = NbtByteArrayClass::extract (args[1 ])-> copy ( );
12511252 } else if (IsInstanceOf<NbtListClass>(args[1 ])) {
1252- list[index] = std::unique_ptr<ListTag>( NbtListClass::extract (args[1 ]));
1253+ list[index] = NbtListClass::extract (args[1 ])-> copyList ( );
12531254 } else if (IsInstanceOf<NbtCompoundClass>(args[1 ])) {
1254- list[index] = std::unique_ptr<CompoundTag>( NbtCompoundClass::extract (args[1 ]));
1255+ list[index] = NbtCompoundClass::extract (args[1 ])-> clone ( );
12551256 } else {
12561257 LOG_ERROR_WITH_SCRIPT_INFO (" Unknown type! Cannot set Tag into List" );
12571258 return Local<Value>();
@@ -1264,27 +1265,27 @@ Local<Value> NbtListClass::setTag(const Arguments& args) {
12641265Local<Value> NbtListClass::addTag (const Arguments& args) {
12651266 CHECK_ARGS_COUNT (args, 1 );
12661267
1267- try {
1268+ try { // ListTag::add deletes the Tag which is provided as argument, so make a copy of Tag before using it.
12681269 if (IsInstanceOf<NbtByteClass>(args[0 ])) {
1269- nbt->add (*NbtByteClass::extract (args[0 ]));
1270+ nbt->add (*NbtByteClass::extract (args[0 ])-> copy () );
12701271 } else if (IsInstanceOf<NbtShortClass>(args[0 ])) {
1271- nbt->add (*NbtShortClass::extract (args[0 ]));
1272+ nbt->add (*NbtShortClass::extract (args[0 ])-> copy () );
12721273 } else if (IsInstanceOf<NbtIntClass>(args[0 ])) {
1273- nbt->add (*NbtIntClass::extract (args[0 ]));
1274+ nbt->add (*NbtIntClass::extract (args[0 ])-> copy () );
12741275 } else if (IsInstanceOf<NbtLongClass>(args[0 ])) {
1275- nbt->add (*NbtLongClass::extract (args[0 ]));
1276+ nbt->add (*NbtLongClass::extract (args[0 ])-> copy () );
12761277 } else if (IsInstanceOf<NbtFloatClass>(args[0 ])) {
1277- nbt->add (*NbtFloatClass::extract (args[0 ]));
1278+ nbt->add (*NbtFloatClass::extract (args[0 ])-> copy () );
12781279 } else if (IsInstanceOf<NbtDoubleClass>(args[0 ])) {
1279- nbt->add (*NbtDoubleClass::extract (args[0 ]));
1280+ nbt->add (*NbtDoubleClass::extract (args[0 ])-> copy () );
12801281 } else if (IsInstanceOf<NbtStringClass>(args[0 ])) {
1281- nbt->add (*NbtStringClass::extract (args[0 ]));
1282+ nbt->add (*NbtStringClass::extract (args[0 ])-> copy () );
12821283 } else if (IsInstanceOf<NbtByteArrayClass>(args[0 ])) {
1283- nbt->add (*NbtByteArrayClass::extract (args[0 ]));
1284+ nbt->add (*NbtByteArrayClass::extract (args[0 ])-> copy () );
12841285 } else if (IsInstanceOf<NbtListClass>(args[0 ])) {
1285- nbt->add (*NbtListClass::extract (args[0 ]));
1286+ nbt->add (*NbtListClass::extract (args[0 ])-> copyList () );
12861287 } else if (IsInstanceOf<NbtCompoundClass>(args[0 ])) {
1287- nbt->add (*NbtCompoundClass::extract (args[0 ]));
1288+ nbt->add (*NbtCompoundClass::extract (args[0 ])-> clone () );
12881289 } else {
12891290 LOG_ERROR_WITH_SCRIPT_INFO (" Unknown type! Cannot add Tag into List" );
12901291 return Local<Value>();
@@ -1433,17 +1434,27 @@ void NbtCompoundClassAddHelper(CompoundTag* tag, Local<Object>& obj) {
14331434 if (keys.size () > 0 ) {
14341435 for (int i = 0 ; i < keys.size (); ++i) {
14351436 Local<Value> t = obj.get (keys[i]);
1436- if (IsInstanceOf<NbtByteClass>(t)) tag->at (keys[i]) = *NbtByteClass::extract (obj.get (keys[i]));
1437- else if (IsInstanceOf<NbtShortClass>(t)) tag->at (keys[i]) = *NbtShortClass::extract (obj.get (keys[i]));
1438- else if (IsInstanceOf<NbtIntClass>(t)) tag->at (keys[i]) = *NbtIntClass::extract (obj.get (keys[i]));
1439- else if (IsInstanceOf<NbtLongClass>(t)) tag->at (keys[i]) = *NbtLongClass::extract (obj.get (keys[i]));
1440- else if (IsInstanceOf<NbtFloatClass>(t)) tag->at (keys[i]) = *NbtFloatClass::extract (obj.get (keys[i]));
1441- else if (IsInstanceOf<NbtDoubleClass>(t)) tag->at (keys[i]) = *NbtDoubleClass::extract (obj.get (keys[i]));
1442- else if (IsInstanceOf<NbtStringClass>(t)) tag->at (keys[i]) = *NbtStringClass::extract (obj.get (keys[i]));
1437+ if (IsInstanceOf<NbtByteClass>(t
1438+ )) // Assignment refers to the rvalue, so the Tag is copied before assignment
1439+ tag->at (keys[i]) = NbtByteClass::extract (obj.get (keys[i]))->copy ()->as <ByteTag>();
1440+ else if (IsInstanceOf<NbtShortClass>(t))
1441+ tag->at (keys[i]) = NbtShortClass::extract (obj.get (keys[i]))->copy ()->as <ShortTag>();
1442+ else if (IsInstanceOf<NbtIntClass>(t))
1443+ tag->at (keys[i]) = NbtIntClass::extract (obj.get (keys[i]))->copy ()->as <IntTag>();
1444+ else if (IsInstanceOf<NbtLongClass>(t))
1445+ tag->at (keys[i]) = NbtLongClass::extract (obj.get (keys[i]))->copy ()->as <Int64Tag>();
1446+ else if (IsInstanceOf<NbtFloatClass>(t))
1447+ tag->at (keys[i]) = NbtFloatClass::extract (obj.get (keys[i]))->copy ()->as <FloatTag>();
1448+ else if (IsInstanceOf<NbtDoubleClass>(t))
1449+ tag->at (keys[i]) = NbtDoubleClass::extract (obj.get (keys[i]))->copy ()->as <DoubleTag>();
1450+ else if (IsInstanceOf<NbtStringClass>(t))
1451+ tag->at (keys[i]) = NbtStringClass::extract (obj.get (keys[i]))->copy ()->as <StringTag>();
14431452 else if (IsInstanceOf<NbtByteArrayClass>(t))
14441453 tag->at (keys[i]) = *NbtByteArrayClass::extract (obj.get (keys[i]));
1445- else if (IsInstanceOf<NbtListClass>(t)) tag->at (keys[i]) = *NbtListClass::extract (obj.get (keys[i]));
1446- else if (IsInstanceOf<NbtCompoundClass>(t)) tag->at (keys[i]) = *NbtCompoundClass::extract (obj.get (keys[i]));
1454+ else if (IsInstanceOf<NbtListClass>(t))
1455+ tag->at (keys[i]) = *NbtListClass::extract (obj.get (keys[i]))->copyList ();
1456+ else if (IsInstanceOf<NbtCompoundClass>(t))
1457+ tag->at (keys[i]) = *NbtCompoundClass::extract (obj.get (keys[i]))->clone ();
14471458 else if (t.isArray ()) {
14481459 auto arrTag = ListTag ();
14491460 auto data = obj.get (keys[i]).asArray ();
@@ -1475,15 +1486,15 @@ NbtCompoundClass* NbtCompoundClass::constructor(const Arguments& args) {
14751486 CATCH_C (" Fail in Create CompoundTag!" );
14761487}
14771488
1478- std::unique_ptr< CompoundTag> NbtCompoundClass::extract (Local<Value> v) {
1489+ CompoundTag* NbtCompoundClass::extract (Local<Value> v) {
14791490 if (EngineScope::currentEngine ()->isInstanceOf <NbtCompoundClass>(v))
1480- return std::move (EngineScope::currentEngine ()->getNativeInstance <NbtCompoundClass>(v)->nbt );
1491+ return std::move (EngineScope::currentEngine ()->getNativeInstance <NbtCompoundClass>(v)->nbt . get () );
14811492 else return nullptr ;
14821493}
14831494
14841495Local<Value> NbtCompoundClass::pack (CompoundTag* tag, bool noDelete) {
14851496 try {
1486- if (noDelete) // unique_ptr 共享指针 + noDelete
1497+ if (noDelete) // unique_ptr shared pointer + noDelete
14871498 {
14881499 NbtCompoundClass* nbtObj = new NbtCompoundClass (std::unique_ptr<CompoundTag>(tag));
14891500 nbtObj->canDelete = false ;
@@ -1674,26 +1685,27 @@ Local<Value> NbtCompoundClass::setTag(const Arguments& args) {
16741685 try {
16751686 auto key = args[0 ].toStr ();
16761687
1677- if (IsInstanceOf<NbtByteClass>(args[1 ])) {
1678- nbt->at (key) = *NbtByteClass::extract (args[1 ]);
1688+ if (IsInstanceOf<NbtByteClass>(args[1 ]
1689+ )) { // Assignment refers to the rvalue, so the Tag is copied before assignment
1690+ nbt->at (key) = NbtByteClass::extract (args[1 ])->copy ()->as <ByteTag>();
16791691 } else if (IsInstanceOf<NbtShortClass>(args[1 ])) {
1680- nbt->at (key) = * NbtShortClass::extract (args[1 ]);
1692+ nbt->at (key) = NbtShortClass::extract (args[1 ])-> copy ()-> as <ShortTag>( );
16811693 } else if (IsInstanceOf<NbtIntClass>(args[1 ])) {
1682- nbt->at (key) = * NbtIntClass::extract (args[1 ]);
1694+ nbt->at (key) = NbtIntClass::extract (args[1 ])-> copy ()-> as <IntTag>( );
16831695 } else if (IsInstanceOf<NbtLongClass>(args[1 ])) {
1684- nbt->at (key) = * NbtLongClass::extract (args[1 ]);
1696+ nbt->at (key) = NbtLongClass::extract (args[1 ])-> copy ()-> as <Int64Tag>( );
16851697 } else if (IsInstanceOf<NbtFloatClass>(args[1 ])) {
1686- nbt->at (key) = * NbtFloatClass::extract (args[1 ]);
1698+ nbt->at (key) = NbtFloatClass::extract (args[1 ])-> copy ()-> as <FloatTag>( );
16871699 } else if (IsInstanceOf<NbtDoubleClass>(args[1 ])) {
1688- nbt->at (key) = * NbtDoubleClass::extract (args[1 ]);
1700+ nbt->at (key) = NbtDoubleClass::extract (args[1 ])-> copy ()-> as <DoubleTag>( );
16891701 } else if (IsInstanceOf<NbtStringClass>(args[1 ])) {
1690- nbt->at (key) = * NbtStringClass::extract (args[1 ]);
1702+ nbt->at (key) = NbtStringClass::extract (args[1 ])-> copy ()-> as <StringTag>( );
16911703 } else if (IsInstanceOf<NbtByteArrayClass>(args[1 ])) {
1692- nbt->at (key) = * NbtByteArrayClass::extract (args[1 ]);
1704+ nbt->at (key) = NbtByteArrayClass::extract (args[1 ])-> copy ()-> as <ByteArrayTag>( );
16931705 } else if (IsInstanceOf<NbtListClass>(args[1 ])) {
1694- nbt->at (key) = *NbtListClass::extract (args[1 ]);
1706+ nbt->at (key) = *NbtListClass::extract (args[1 ])-> copyList () ;
16951707 } else if (IsInstanceOf<NbtCompoundClass>(args[1 ])) {
1696- nbt->at (key) = *NbtCompoundClass::extract (args[1 ]);
1708+ nbt->at (key) = *NbtCompoundClass::extract (args[1 ])-> clone () ;
16971709 } else {
16981710 LOG_ERROR_WITH_SCRIPT_INFO (" Unknown type! Cannot set Tag into Compound" );
16991711 return Local<Value>();
0 commit comments