2525import com .github .steveice10 .opennbt .tag .builtin .StringTag ;
2626import com .github .steveice10 .opennbt .tag .builtin .Tag ;
2727import com .google .common .base .Preconditions ;
28+ import com .viaversion .viaversion .api .connection .UserConnection ;
2829import com .viaversion .viaversion .api .minecraft .GameProfile ;
2930import com .viaversion .viaversion .api .minecraft .HolderSet ;
3031import com .viaversion .viaversion .api .minecraft .SoundEvent ;
6061import com .viaversion .viaversion .protocols .protocol1_20_5to1_20_3 .data .PotionEffects1_20_5 ;
6162import com .viaversion .viaversion .protocols .protocol1_20_5to1_20_3 .data .Potions1_20_5 ;
6263import com .viaversion .viaversion .protocols .protocol1_20_5to1_20_3 .data .TrimMaterials1_20_3 ;
64+ import com .viaversion .viaversion .protocols .protocol1_20_5to1_20_3 .storage .BannerPatternStorage ;
6365import com .viaversion .viaversion .util .ComponentUtil ;
6466import com .viaversion .viaversion .util .UUIDUtil ;
6567import it .unimi .dsi .fastutil .ints .Int2IntMap ;
@@ -215,8 +217,8 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
215217 }
216218 });
217219 register (StructuredDataKey .BASE_COLOR , (data , tag ) -> tag .putInt ("Base" , data ));
218- register (StructuredDataKey .CHARGED_PROJECTILES , (data , tag ) -> convertItemList (data , tag , "ChargedProjectiles" ));
219- register (StructuredDataKey .BUNDLE_CONTENTS , (data , tag ) -> convertItemList (data , tag , "Items" ));
220+ register (StructuredDataKey .CHARGED_PROJECTILES , (connection , data , tag ) -> convertItemList (connection , data , tag , "ChargedProjectiles" ));
221+ register (StructuredDataKey .BUNDLE_CONTENTS , (connection , data , tag ) -> convertItemList (connection , data , tag , "Items" ));
220222 register (StructuredDataKey .LODESTONE_TRACKER , (data , tag ) -> {
221223 final CompoundTag positionTag = new CompoundTag ();
222224 tag .put ("LodestonePos" , positionTag );
@@ -304,10 +306,10 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
304306 beeTag .putInt ("MinOccupationTicks" , bee .minTicksInHive ());
305307 bees .add (beeTag );
306308 }
307- getBlockEntityTag (tag ).put ("Bees" , bees );
309+ getBlockEntityTag (tag , "beehive" ).put ("Bees" , bees );
308310 });
309311 register (StructuredDataKey .LOCK , (data , tag ) -> getBlockEntityTag (tag ).put ("Lock" , data ));
310- register (StructuredDataKey .NOTE_BLOCK_SOUND , (data , tag ) -> getBlockEntityTag (tag ).putString ("note_block_sound" , data ));
312+ register (StructuredDataKey .NOTE_BLOCK_SOUND , (data , tag ) -> getBlockEntityTag (tag , "player_head" ).putString ("note_block_sound" , data ));
311313 register (StructuredDataKey .POT_DECORATIONS , (data , tag ) -> {
312314 IntArrayTag originalSherds = null ;
313315
@@ -327,7 +329,7 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
327329 if (originalSherds != null ) {
328330 getBackupTag (tag ).put ("pot_decorations" , originalSherds );
329331 }
330- getBlockEntityTag (tag ).put ("sherds" , sherds );
332+ getBlockEntityTag (tag , "decorated_pot" ).put ("sherds" , sherds );
331333 });
332334 register (StructuredDataKey .CREATIVE_SLOT_LOCK , (data , tag ) -> tag .put ("CustomCreativeLock" , new CompoundTag ()));
333335 register (StructuredDataKey .DEBUG_STICK_STATE , (data , tag ) -> tag .put ("DebugProperty" , data ));
@@ -342,7 +344,13 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
342344 });
343345 register (StructuredDataKey .BLOCK_ENTITY_DATA , (data , tag ) -> {
344346 // Handling of previously block entity tags is done using the getBlockEntityTag method
345- tag .put ("BlockEntityTag" , data );
347+ // Merge with already added tag if needed
348+ final CompoundTag blockEntityTag = tag .getCompoundTag ("BlockEntityTag" );
349+ if (blockEntityTag != null ) {
350+ blockEntityTag .putAll (data );
351+ } else {
352+ tag .put ("BlockEntityTag" , data );
353+ }
346354 });
347355 register (StructuredDataKey .CONTAINER_LOOT , (data , tag ) -> {
348356 final Tag lootTable = data .get ("loot_table" );
@@ -421,7 +429,8 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
421429 }
422430 tag .put ("effects" , effectsTag );
423431 });
424- register (StructuredDataKey .BANNER_PATTERNS , (data , tag ) -> {
432+ register (StructuredDataKey .BANNER_PATTERNS , (connection , data , tag ) -> {
433+ final BannerPatternStorage patternStorage = connection .get (BannerPatternStorage .class );
425434 if (backupInconvertibleData ) {
426435 // Backup whole data if one of the entries is inconvertible
427436 // Since we don't want to break the order of the entries
@@ -430,7 +439,8 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
430439 return true ;
431440 }
432441
433- final String identifier = BannerPatterns1_20_5 .idToKey (layer .pattern ().id ());
442+ final int id = layer .pattern ().id ();
443+ final String identifier = patternStorage != null ? patternStorage .pattern (id ) : BannerPatterns1_20_5 .idToKey (id );
434444 return identifier == null || identifier .equals ("flow" ) || identifier .equals ("guster" );
435445 })) {
436446 final ListTag <CompoundTag > originalPatterns = new ListTag <>(CompoundTag .class );
@@ -459,7 +469,8 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
459469 continue ;
460470 }
461471
462- final String key = BannerPatterns1_20_5 .idToKey (layer .pattern ().id ());
472+ final int id = layer .pattern ().id ();
473+ final String key = patternStorage != null ? patternStorage .pattern (id ) : BannerPatterns1_20_5 .idToKey (id );
463474 if (key == null ) {
464475 continue ;
465476 }
@@ -474,9 +485,9 @@ public StructuredDataConverter(final boolean backupInconvertibleData) {
474485 patternTag .putInt ("Color" , layer .dyeColor ());
475486 patternsTag .add (patternTag );
476487 }
477- tag .put ("Patterns" , patternsTag );
488+ getBlockEntityTag ( tag , "banner" ) .put ("Patterns" , patternsTag );
478489 });
479- register (StructuredDataKey .CONTAINER , (data , tag ) -> convertItemList (data , tag , "Items" ));
490+ register (StructuredDataKey .CONTAINER , (connection , data , tag ) -> convertItemList (connection , data , tag , "Items" ));
480491 register (StructuredDataKey .CAN_PLACE_ON , (data , tag ) -> convertBlockPredicates (tag , data , "CanPlaceOn" , HIDE_CAN_PLACE_ON ));
481492 register (StructuredDataKey .CAN_BREAK , (data , tag ) -> convertBlockPredicates (tag , data , "CanDestroy" , HIDE_CAN_DESTROY ));
482493 register (StructuredDataKey .MAP_POST_PROCESSING , (data , tag ) -> {
@@ -654,6 +665,15 @@ private static CompoundTag getBlockEntityTag(final CompoundTag tag) {
654665 return getOrCreate (tag , "BlockEntityTag" );
655666 }
656667
668+ private CompoundTag getBlockEntityTag (final CompoundTag tag , final String blockEntity ) {
669+ final CompoundTag blockEntityTag = getOrCreate (tag , "BlockEntityTag" );
670+ if (!blockEntityTag .contains ("id" )) {
671+ // Add in the assumed (and required) block entity id
672+ blockEntityTag .putString ("id" , blockEntity );
673+ }
674+ return blockEntityTag ;
675+ }
676+
657677 private static CompoundTag getDisplayTag (final CompoundTag tag ) {
658678 return getOrCreate (tag , "display" );
659679 }
@@ -768,7 +788,7 @@ private CompoundTag convertPotionEffectData(final PotionEffectData data) {
768788 return effectDataTag ;
769789 }
770790
771- private void convertItemList (final Item [] items , final CompoundTag tag , final String key ) {
791+ private void convertItemList (final UserConnection connection , final Item [] items , final CompoundTag tag , final String key ) {
772792 final ListTag <CompoundTag > itemsTag = new ListTag <>(CompoundTag .class );
773793 for (final Item item : items ) {
774794 final CompoundTag savedItem = new CompoundTag ();
@@ -782,7 +802,7 @@ private void convertItemList(final Item[] items, final CompoundTag tag, final St
782802
783803 final CompoundTag itemTag = new CompoundTag ();
784804 for (final StructuredData <?> data : item .structuredData ().data ().values ()) {
785- writeToTag (data , itemTag );
805+ writeToTag (connection , data , itemTag );
786806 }
787807 savedItem .put ("tag" , itemTag );
788808 } else {
@@ -827,24 +847,35 @@ private void putHideFlag(final CompoundTag tag, final int value) {
827847 tag .putInt ("HideFlags" , tag .getInt ("HideFlags" ) | value );
828848 }
829849
830- public <T > void writeToTag (final StructuredData <T > data , final CompoundTag tag ) {
850+ public <T > void writeToTag (final UserConnection connection , final StructuredData <T > data , final CompoundTag tag ) {
831851 if (data .isEmpty ()) {
832852 return ;
833853 }
834854
835855 //noinspection unchecked
836856 final DataConverter <T > converter = (DataConverter <T >) rewriters .get (data .key ());
837857 Preconditions .checkNotNull (converter , "No converter for %s found" , data .key ());
838- converter .convert (data .value (), tag );
858+ converter .convert (connection , data .value (), tag );
839859 }
840860
841861 private <T > void register (final StructuredDataKey <T > key , final DataConverter <T > converter ) {
842862 rewriters .put (key , converter );
843863 }
844864
865+ private <T > void register (final StructuredDataKey <T > key , final SimpleDataConverter <T > converter ) {
866+ final DataConverter <T > c = (connection , data , tag ) -> converter .convert (data , tag );
867+ rewriters .put (key , c );
868+ }
869+
845870 @ FunctionalInterface
846- interface DataConverter <T > {
871+ interface SimpleDataConverter <T > {
847872
848873 void convert (T data , CompoundTag tag );
849874 }
875+
876+ @ FunctionalInterface
877+ interface DataConverter <T > {
878+
879+ void convert (UserConnection connection , T data , CompoundTag tag );
880+ }
850881}
0 commit comments