From a24f9b204c95ab536b4e9d25cb77a1e52147cb0a Mon Sep 17 00:00:00 2001 From: Bjarne Koll Date: Wed, 28 May 2025 13:23:32 +0200 Subject: [PATCH] 1.21.6 dev Co-authored-by: Bjarne Koll Co-authored-by: Jake Potrebic Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com> Co-authored-by: Lulu13022002 <41980282+Lulu13022002@users.noreply.github.com> Co-authored-by: Noah van der Aa Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> Co-authored-by: Spottedleaf --- .github/workflows/build.yml | 3 + .github/workflows/test_results.yml | 3 +- README.md | 4 +- build-data/paper.at | 41 +- gradle.properties | 5 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../paper/entity/ai/VanillaGoal.java | 103 +- .../paper/registry/keys/AttributeKeys.java | 23 +- .../registry/keys/BannerPatternKeys.java | 2 +- .../paper/registry/keys/BiomeKeys.java | 2 +- .../paper/registry/keys/BlockTypeKeys.java | 9 +- .../paper/registry/keys/CatVariantKeys.java | 2 +- .../registry/keys/ChickenVariantKeys.java | 2 +- .../paper/registry/keys/CowVariantKeys.java | 2 +- .../paper/registry/keys/DamageTypeKeys.java | 2 +- .../registry/keys/DataComponentTypeKeys.java | 2 +- .../paper/registry/keys/EnchantmentKeys.java | 2 +- .../paper/registry/keys/FluidKeys.java | 2 +- .../paper/registry/keys/FrogVariantKeys.java | 2 +- .../paper/registry/keys/GameEventKeys.java | 2 +- .../paper/registry/keys/InstrumentKeys.java | 2 +- .../paper/registry/keys/ItemTypeKeys.java | 881 +- .../paper/registry/keys/JukeboxSongKeys.java | 9 +- .../registry/keys/MapDecorationTypeKeys.java | 2 +- .../paper/registry/keys/MenuTypeKeys.java | 2 +- .../paper/registry/keys/MobEffectKeys.java | 2 +- .../registry/keys/PaintingVariantKeys.java | 2 +- .../paper/registry/keys/PigVariantKeys.java | 2 +- .../paper/registry/keys/SoundEventKeys.java | 233 +- .../paper/registry/keys/StructureKeys.java | 2 +- .../registry/keys/StructureTypeKeys.java | 2 +- .../paper/registry/keys/TrimMaterialKeys.java | 2 +- .../paper/registry/keys/TrimPatternKeys.java | 2 +- .../registry/keys/VillagerProfessionKeys.java | 2 +- .../paper/registry/keys/VillagerTypeKeys.java | 2 +- .../registry/keys/WolfSoundVariantKeys.java | 2 +- .../paper/registry/keys/WolfVariantKeys.java | 2 +- .../keys/tags/BannerPatternTagKeys.java | 2 +- .../registry/keys/tags/BiomeTagKeys.java | 2 +- .../registry/keys/tags/BlockTypeTagKeys.java | 37 +- .../registry/keys/tags/DamageTypeTagKeys.java | 2 +- .../keys/tags/EnchantmentTagKeys.java | 2 +- .../registry/keys/tags/EntityTypeTagKeys.java | 16 +- .../registry/keys/tags/FluidTagKeys.java | 2 +- .../registry/keys/tags/GameEventTagKeys.java | 2 +- .../registry/keys/tags/InstrumentTagKeys.java | 2 +- .../registry/keys/tags/ItemTypeTagKeys.java | 23 +- .../keys/tags/PaintingVariantTagKeys.java | 2 +- .../registry/keys/tags/StructureTagKeys.java | 2 +- .../com/destroystokyo/paper/MaterialTags.java | 2 +- .../paper/entity/ai/GoalKey.java | 29 +- .../brigadier/CommandRegistrationFlag.java | 3 +- .../datacomponent/DataComponentHolder.java | 13 +- .../datacomponent/DataComponentTypes.java | 3 +- .../datacomponent/DataComponentView.java | 13 +- .../datacomponent/item/BlocksAttacks.java | 11 +- .../datacomponent/item/CustomModelData.java | 2 +- .../paper/datacomponent/item/Equippable.java | 34 + .../item/ItemAdventurePredicate.java | 1 - .../item/ItemAttributeModifiers.java | 54 +- .../item/ItemComponentTypesBridge.java | 2 +- .../attribute/AttributeModifierDisplay.java | 85 + .../AttributeModifierDisplayBridge.java | 24 + .../blocksattacks/BlocksAttacksBridge.java | 4 +- .../item/blocksattacks/DamageReduction.java | 6 +- .../item/consumable/ItemUseAnimation.java | 5 +- .../plugin/configuration/package-info.java | 5 +- .../lifecycle/event/LifecycleEvent.java | 1 - .../event/LifecycleEventManager.java | 3 - .../lifecycle/event/LifecycleEventOwner.java | 3 - .../event/handler/LifecycleEventHandler.java | 4 - .../LifecycleEventHandlerConfiguration.java | 3 - ...torLifecycleEventHandlerConfiguration.java | 3 - ...zedLifecycleEventHandlerConfiguration.java | 3 - .../handler/configuration/package-info.java | 6 + .../lifecycle/event/handler/package-info.java | 6 + .../plugin/lifecycle/event/package-info.java | 6 + .../lifecycle/event/registrar/Registrar.java | 1 - .../event/registrar/RegistrarEvent.java | 3 - .../registrar/ReloadableRegistrarEvent.java | 4 - .../event/registrar/package-info.java | 6 + .../event/types/LifecycleEventType.java | 5 - .../types/LifecycleEventTypeProvider.java | 2 - .../event/types/LifecycleEvents.java | 3 - .../event/types/TagEventTypeProvider.java | 3 - .../lifecycle/event/types/package-info.java | 6 + .../papermc/paper/registry/TypedKeyImpl.java | 3 + .../data/EnchantmentRegistryEntry.java | 11 +- .../data/InlinedRegistryBuilderProvider.java | 1 - .../data/JukeboxSongRegistryEntry.java | 134 + .../data/SoundEventRegistryEntry.java | 63 + .../registry/event/RegistryComposeEvent.java | 38 + .../registry/event/RegistryEntryAddEvent.java | 3 - .../paper/registry/event/RegistryEvent.java | 3 - .../registry/event/RegistryEventProvider.java | 24 +- .../event/RegistryEventProviderImpl.java | 7 +- .../event/RegistryEventTypeProvider.java | 2 +- .../paper/registry/event/RegistryEvents.java | 11 +- .../registry/event/RegistryFreezeEvent.java | 29 +- .../registry/event/WritableRegistry.java | 3 - .../paper/registry/event/package-info.java | 9 + .../type/RegistryEntryAddConfiguration.java | 4 +- .../event/type/RegistryEntryAddEventType.java | 3 - .../registry/event/type/package-info.java | 9 + .../paper/registry/holder/RegistryHolder.java | 50 + .../paper/registry/holder/package-info.java | 9 + paper-api/src/main/java/org/bukkit/Art.java | 13 +- .../main/java/org/bukkit/EntityEffect.java | 7 +- .../src/main/java/org/bukkit/FeatureFlag.java | 2 +- paper-api/src/main/java/org/bukkit/Fluid.java | 2 +- .../src/main/java/org/bukkit/GameEvent.java | 2 +- .../src/main/java/org/bukkit/GameRule.java | 5 + .../src/main/java/org/bukkit/JukeboxSong.java | 4 +- .../src/main/java/org/bukkit/Location.java | 20 +- .../src/main/java/org/bukkit/Material.java | 42 +- .../main/java/org/bukkit/MusicInstrument.java | 2 +- paper-api/src/main/java/org/bukkit/Sound.java | 68 +- .../main/java/org/bukkit/SoundCategory.java | 37 +- .../src/main/java/org/bukkit/Statistic.java | 5 +- paper-api/src/main/java/org/bukkit/Tag.java | 27 +- .../src/main/java/org/bukkit/Vibration.java | 5 +- paper-api/src/main/java/org/bukkit/World.java | 32 +- .../java/org/bukkit/attribute/Attribute.java | 12 + .../src/main/java/org/bukkit/block/Biome.java | 2 +- .../main/java/org/bukkit/block/BlockType.java | 5 +- .../org/bukkit/block/banner/PatternType.java | 2 +- .../bukkit/block/data/type/DriedGhast.java | 32 + .../java/org/bukkit/damage/DamageType.java | 2 +- .../java/org/bukkit/entity/Armadillo.java | 3 + .../src/main/java/org/bukkit/entity/Boat.java | 2 +- .../src/main/java/org/bukkit/entity/Cat.java | 2 +- .../main/java/org/bukkit/entity/Chicken.java | 2 +- .../src/main/java/org/bukkit/entity/Cow.java | 2 +- .../java/org/bukkit/entity/EnderSignal.java | 2 +- .../main/java/org/bukkit/entity/Entity.java | 2 +- .../java/org/bukkit/entity/EntityType.java | 5 +- .../main/java/org/bukkit/entity/Flying.java | 2 + .../src/main/java/org/bukkit/entity/Fox.java | 2 +- .../src/main/java/org/bukkit/entity/Frog.java | 2 +- .../java/org/bukkit/entity/HappyGhast.java | 7 + .../main/java/org/bukkit/entity/Panda.java | 2 +- .../src/main/java/org/bukkit/entity/Pig.java | 2 +- .../src/main/java/org/bukkit/entity/Pose.java | 3 +- .../main/java/org/bukkit/entity/Salmon.java | 2 +- .../main/java/org/bukkit/entity/Sniffer.java | 2 +- .../java/org/bukkit/entity/TropicalFish.java | 2 +- .../main/java/org/bukkit/entity/Villager.java | 4 +- .../src/main/java/org/bukkit/entity/Wolf.java | 2 +- .../org/bukkit/entity/memory/MemoryKey.java | 2 +- .../bukkit/event/block/SpongeAbsorbEvent.java | 6 +- .../bukkit/generator/structure/Structure.java | 2 +- .../generator/structure/StructureType.java | 2 +- .../org/bukkit/inventory/EquipmentSlot.java | 2 +- .../java/org/bukkit/inventory/ItemRarity.java | 2 +- .../java/org/bukkit/inventory/ItemType.java | 118 +- .../org/bukkit/inventory/PlayerInventory.java | 7 +- .../inventory/meta/trim/TrimMaterial.java | 2 +- .../inventory/meta/trim/TrimPattern.java | 2 +- .../inventory/recipe/CookingBookCategory.java | 2 +- .../recipe/CraftingBookCategory.java | 2 +- .../main/java/org/bukkit/map/MapCursor.java | 2 +- .../main/java/org/bukkit/map/MapPalette.java | 2 +- .../main/java/org/bukkit/material/Cake.java | 2 +- .../persistence/PersistentDataContainer.java | 4 +- .../java/org/bukkit/potion/PotionType.java | 2 +- .../org/bukkit/scoreboard/DisplaySlot.java | 2 +- .../java/org/bukkit/tag/DamageTypeTags.java | 2 +- .../main/java/io/papermc/generator/Main.java | 11 +- .../java/io/papermc/generator/Rewriters.java | 19 +- .../generator/registry/RegistryEntries.java | 32 +- .../generator/registry/RegistryEntry.java | 25 +- .../PaperPatternSourceSetRewriter.java | 4 +- .../generator/rewriter/types/Types.java | 2 + .../types/registry/EnumRegistryRewriter.java | 2 +- .../registry/PaperRegistriesRewriter.java | 14 +- .../registry/RegistryEventsRewriter.java | 3 +- .../types/registry/RegistryFieldRewriter.java | 2 +- .../types/registry/RegistryTagRewriter.java | 2 +- .../rewriter/types/registry/TagRewriter.java | 2 +- .../types/simple/EntityTypeRewriter.java | 3 +- .../types/simple/MaterialRewriter.java | 5 +- .../types/simple/StatisticRewriter.java | 4 +- .../trial/DataComponentTypesRewriter.java | 261 - .../types/simple/trial/PoseRewriter.java | 93 + .../utils/ScanOldGeneratedSourceCode.java | 4 +- .../holder/DataPropertyWriterBase.java | 22 +- .../generator/types/goal/MobGoalNames.java | 452 +- .../types/registry/GeneratedKeyType.java | 2 +- .../types/registry/GeneratedTagKeyType.java | 2 +- .../papermc/generator/utils/Annotations.java | 2 +- .../papermc/generator/utils/Formatting.java | 43 +- .../generator/BlockStatePropertyTest.java | 2 +- .../generator/MobGoalConverterTest.java | 2 +- paper-server/build.gradle.kts | 12 +- ...-Manager-and-add-advanced-packet-sup.patch | 57 +- .../0003-Entity-Activation-Range-2.0.patch | 114 +- .../patches/features/0004-Anti-Xray.patch | 72 +- ...ocity-compression-and-cipher-natives.patch | 6 +- ...ptimize-Collision-to-not-load-chunks.patch | 6 +- ...oalSelector-Goal.Flag-Set-operations.patch | 14 +- ...e-Oversized-block-entities-in-chunks.patch | 2 +- ...e-getChunkAt-calls-for-loaded-chunks.patch | 2 +- .../0015-Rewrite-dataconverter-system.patch | 32538 ++++++++++++++++ ... 0016-Moonrise-optimisation-patches.patch} | 501 +- ...r-desync-when-new-players-are-added.patch} | 16 +- ...-Eigencraft-redstone-implementation.patch} | 0 ...ate-Current-redstone-implementation.patch} | 10 +- ...ove-exact-choice-recipe-ingredients.patch} | 4 +- ...021-Entity-load-save-limit-per-chunk.patch | 81 - ...data-to-disk-if-it-serializes-witho.patch} | 0 ...022-Entity-load-save-limit-per-chunk.patch | 80 + ...ulate-regionfile-header-if-it-is-co.patch} | 8 +- ...Incremental-chunk-and-player-saving.patch} | 20 +- ...=> 0025-Optimise-general-POI-access.patch} | 2 +- ...0026-Optional-per-player-mob-spawns.patch} | 8 +- ...g-PreCreatureSpawnEvent-with-per-pl.patch} | 8 +- ...pers.patch => 0028-Optimize-Hoppers.patch} | 18 +- ...nfiles-on-save-configuration-option.patch} | 2 +- ...n-checking-in-player-move-packet-ha.patch} | 68 +- .../features/0031-DataConverter-Fixes.patch | 24 + .../moonrise/paper/PaperHooks.java.patch | 13 +- .../util/BaseChunkSystemHooks.java.patch | 4 +- .../brigadier/tree/CommandNode.java.patch | 21 +- .../io/papermc/paper/FeatureHooks.java.patch | 2 +- .../commands/CommandSourceStack.java.patch | 31 +- .../minecraft/commands/Commands.java.patch | 86 +- .../commands/PermissionSource.java.patch | 24 + .../arguments/EntityArgument.java.patch | 5 +- .../selector/EntitySelector.java.patch | 2 +- .../selector/EntitySelectorParser.java.patch | 2 +- .../minecraft/core/HolderLookup.java.patch | 40 + .../minecraft/core/MappedRegistry.java.patch | 11 +- .../core/RegistrySetBuilder.java.patch | 30 + .../ShearsDispenseItemBehavior.java.patch | 20 +- .../registries/BuiltInRegistries.java.patch | 26 +- .../framework/GameTestMainUtil.java.patch | 2 +- .../framework/StructureUtils.java.patch | 2 +- .../net/minecraft/nbt/CompoundTag.java.patch | 2 +- .../minecraft/network/Connection.java.patch | 14 +- .../network/FriendlyByteBuf.java.patch | 6 +- .../network/chat/Component.java.patch | 2 +- .../network/codec/ByteBufCodecs.java.patch | 2 +- ...ClientboundLevelChunkPacketData.java.patch | 2 +- ...lientboundLoginDisconnectPacket.java.patch | 45 +- .../resources/RegistryDataLoader.java.patch | 40 +- .../resources/RegistryOps.java.patch | 24 + .../net/minecraft/server/Main.java.patch | 30 +- .../server/MinecraftServer.java.patch | 98 +- .../server/PlayerAdvancements.java.patch | 12 +- .../ReloadableServerRegistries.java.patch | 6 +- .../server/ServerScoreboard.java.patch | 70 +- .../commands/BanPlayerCommands.java.patch | 2 +- .../server/commands/DeOpCommands.java.patch | 2 +- .../server/commands/EffectCommands.java.patch | 6 +- .../commands/GameModeCommand.java.patch | 30 +- .../server/commands/GiveCommand.java.patch | 22 +- .../server/commands/KickCommand.java.patch | 2 +- .../server/commands/LocateCommand.java.patch | 2 +- .../server/commands/ReloadCommand.java.patch | 2 +- .../server/commands/RideCommand.java.patch | 4 +- .../commands/WorldBorderCommand.java.patch | 12 +- .../dedicated/DedicatedServer.java.patch | 2 +- .../DedicatedServerProperties.java.patch | 8 +- .../server/level/ServerChunkCache.java.patch | 10 +- .../server/level/ServerEntity.java.patch | 17 +- .../server/level/ServerLevel.java.patch | 116 +- .../server/level/ServerPlayer.java.patch | 222 +- .../level/ServerPlayerGameMode.java.patch | 6 +- .../ServerCommonPacketListenerImpl.java.patch | 21 +- ...ConfigurationPacketListenerImpl.java.patch | 9 +- .../ServerGamePacketListenerImpl.java.patch | 368 +- ...rverHandshakePacketListenerImpl.java.patch | 12 +- .../server/packs/PathPackResources.java.patch | 2 +- .../server/players/PlayerList.java.patch | 548 +- .../stats/ServerRecipeBook.java.patch | 6 +- .../stats/ServerStatsCounter.java.patch | 4 +- .../util/PlaceholderLookupProvider.java.patch | 16 + .../util/datafix/DataFixers.java.patch | 2 +- .../fixes/RaidRenamesDataFix.java.patch | 10 - .../world/RandomizableContainer.java.patch | 24 +- .../world/entity/AgeableMob.java.patch | 37 +- .../world/entity/AreaEffectCloud.java.patch | 23 +- .../world/entity/ConversionType.java.patch | 4 +- .../minecraft/world/entity/Entity.java.patch | 625 +- .../world/entity/EntitySelector.java.patch | 11 +- .../world/entity/EntityType.java.patch | 36 +- .../world/entity/ExperienceOrb.java.patch | 140 +- .../world/entity/Interaction.java.patch | 2 +- .../world/entity/Leashable.java.patch | 43 +- .../world/entity/LightningBolt.java.patch | 16 +- .../world/entity/LivingEntity.java.patch | 205 +- .../net/minecraft/world/entity/Mob.java.patch | 80 +- .../world/entity/NeutralMob.java.patch | 8 +- .../entity/OminousItemSpawner.java.patch | 6 +- .../world/entity/TamableAnimal.java.patch | 29 +- .../attributes/AttributeInstance.java.patch | 2 +- .../ai/attributes/AttributeMap.java.patch | 2 +- .../ai/attributes/Attributes.java.patch | 4 +- .../ai/behavior/BabyFollowAdult.java.patch | 39 +- .../world/entity/ai/goal/TemptGoal.java.patch | 22 +- .../GroundPathNavigation.java.patch | 2 +- .../world/entity/ambient/Bat.java.patch | 8 +- .../world/entity/animal/Animal.java.patch | 24 +- .../world/entity/animal/Bee.java.patch | 56 +- .../world/entity/animal/Cat.java.patch | 10 +- .../world/entity/animal/Chicken.java.patch | 2 +- .../world/entity/animal/Dolphin.java.patch | 12 +- .../world/entity/animal/Fox.java.patch | 32 +- .../world/entity/animal/HappyGhast.java.patch | 25 + .../world/entity/animal/IronGolem.java.patch | 4 +- .../entity/animal/MushroomCow.java.patch | 4 +- .../world/entity/animal/Ocelot.java.patch | 4 +- .../world/entity/animal/Panda.java.patch | 12 +- .../world/entity/animal/Parrot.java.patch | 8 +- .../world/entity/animal/Pig.java.patch | 2 +- .../world/entity/animal/Pufferfish.java.patch | 6 +- .../world/entity/animal/Rabbit.java.patch | 4 +- .../animal/ShoulderRidingEntity.java.patch | 18 +- .../world/entity/animal/SnowGolem.java.patch | 8 +- .../world/entity/animal/Turtle.java.patch | 14 +- .../entity/animal/allay/Allay.java.patch | 24 +- .../animal/armadillo/Armadillo.java.patch | 8 +- .../entity/animal/axolotl/Axolotl.java.patch | 6 +- .../entity/animal/camel/Camel.java.patch | 10 +- .../world/entity/animal/frog/Frog.java.patch | 2 +- .../entity/animal/frog/Tadpole.java.patch | 28 +- .../world/entity/animal/goat/Goat.java.patch | 6 +- .../horse/AbstractChestedHorse.java.patch | 2 +- .../animal/horse/AbstractHorse.java.patch | 51 +- .../entity/animal/horse/Llama.java.patch | 6 +- .../animal/horse/SkeletonHorse.java.patch | 2 +- .../animal/horse/TraderLlama.java.patch | 4 +- .../entity/animal/sheep/Sheep.java.patch | 6 +- .../entity/animal/sniffer/Sniffer.java.patch | 4 +- .../world/entity/animal/wolf/Wolf.java.patch | 34 +- .../boss/enderdragon/EndCrystal.java.patch | 22 +- .../boss/enderdragon/EnderDragon.java.patch | 54 +- .../DragonSittingFlamingPhase.java.patch | 2 +- .../entity/boss/wither/WitherBoss.java.patch | 16 +- .../entity/decoration/ArmorStand.java.patch | 136 +- .../decoration/BlockAttachedEntity.java.patch | 14 +- .../entity/decoration/ItemFrame.java.patch | 18 +- .../LeashFenceKnotEntity.java.patch | 72 +- .../entity/decoration/Painting.java.patch | 2 +- .../entity/item/FallingBlockEntity.java.patch | 36 +- .../world/entity/item/ItemEntity.java.patch | 44 +- .../world/entity/item/PrimedTnt.java.patch | 18 +- .../monster/AbstractSkeleton.java.patch | 12 +- .../world/entity/monster/Bogged.java.patch | 4 +- .../world/entity/monster/Creeper.java.patch | 20 +- .../world/entity/monster/Drowned.java.patch | 2 +- .../world/entity/monster/EnderMan.java.patch | 18 +- .../world/entity/monster/Endermite.java.patch | 2 +- .../world/entity/monster/Evoker.java.patch | 2 +- .../world/entity/monster/Ghast.java.patch | 4 +- .../world/entity/monster/Phantom.java.patch | 30 +- .../world/entity/monster/Pillager.java.patch | 2 +- .../world/entity/monster/Ravager.java.patch | 4 +- .../world/entity/monster/Shulker.java.patch | 6 +- .../world/entity/monster/Skeleton.java.patch | 2 +- .../world/entity/monster/Slime.java.patch | 46 +- .../monster/SpellcasterIllager.java.patch | 2 +- .../world/entity/monster/Vex.java.patch | 10 +- .../entity/monster/Vindicator.java.patch | 2 +- .../world/entity/monster/Zombie.java.patch | 38 +- .../entity/monster/ZombieVillager.java.patch | 20 +- .../entity/monster/ZombifiedPiglin.java.patch | 8 +- .../monster/creaking/Creaking.java.patch | 6 +- .../entity/monster/hoglin/Hoglin.java.patch | 2 +- .../monster/piglin/AbstractPiglin.java.patch | 2 +- .../entity/monster/piglin/Piglin.java.patch | 32 +- .../entity/monster/warden/Warden.java.patch | 4 +- .../world/entity/npc/Villager.java.patch | 24 +- .../entity/npc/WanderingTrader.java.patch | 10 +- .../npc/WanderingTraderSpawner.java.patch | 2 +- .../world/entity/player/Inventory.java.patch | 20 +- .../world/entity/player/Player.java.patch | 94 +- .../projectile/AbstractArrow.java.patch | 28 +- .../AbstractHurtingProjectile.java.patch | 4 +- .../AbstractThrownPotion.java.patch | 14 +- .../entity/projectile/EvokerFangs.java.patch | 4 +- .../entity/projectile/EyeOfEnder.java.patch | 18 +- .../FireworkRocketEntity.java.patch | 30 +- .../entity/projectile/FishingHook.java.patch | 34 +- .../projectile/LargeFireball.java.patch | 14 +- .../entity/projectile/Projectile.java.patch | 58 +- .../projectile/ShulkerBullet.java.patch | 22 +- .../projectile/SpectralArrow.java.patch | 2 +- .../projectile/ThrownEnderpearl.java.patch | 18 +- .../ThrownExperienceBottle.java.patch | 28 +- .../ThrownLingeringPotion.java.patch | 8 +- .../projectile/ThrownSplashPotion.java.patch | 33 +- .../projectile/ThrownTrident.java.patch | 8 +- .../entity/projectile/WitherSkull.java.patch | 6 +- .../world/entity/raid/Raider.java.patch | 8 +- .../entity/vehicle/AbstractBoat.java.patch | 12 +- .../vehicle/AbstractChestBoat.java.patch | 8 +- .../vehicle/AbstractMinecart.java.patch | 39 +- .../AbstractMinecartContainer.java.patch | 6 +- .../entity/vehicle/ContainerEntity.java.patch | 22 +- .../vehicle/MinecartCommandBlock.java.patch | 4 +- .../entity/vehicle/MinecartTNT.java.patch | 8 +- .../minecraft/world/food/FoodData.java.patch | 8 +- .../world/inventory/AnvilMenu.java.patch | 28 +- .../world/inventory/GrindstoneMenu.java.patch | 2 +- .../world/item/EnderEyeItem.java.patch | 8 +- .../world/item/FireworkRocketItem.java.patch | 66 +- .../minecraft/world/item/ItemStack.java.patch | 18 +- .../minecraft/world/item/LeadItem.java.patch | 20 +- .../item/component/Consumable.java.patch | 2 +- .../item/component/CustomData.java.patch | 2 +- .../component/ResolvableProfile.java.patch | 25 +- .../item/crafting/RecipeManager.java.patch | 12 +- .../world/level/BaseCommandBlock.java.patch | 10 +- .../world/level/BaseSpawner.java.patch | 173 +- .../world/level/GameRules.java.patch | 62 +- .../minecraft/world/level/Level.java.patch | 11 +- .../world/level/ServerExplosion.java.patch | 2 +- .../world/level/TicketStorage.java.patch | 14 +- .../block/AbstractCauldronBlock.java.patch | 2 +- .../world/level/block/Block.java.patch | 2 +- .../world/level/block/CactusBlock.java.patch | 10 +- .../level/block/EndPortalBlock.java.patch | 12 +- .../level/block/LavaCauldronBlock.java.patch | 13 +- .../block/LayeredCauldronBlock.java.patch | 32 +- .../level/block/NetherPortalBlock.java.patch | 12 +- .../level/block/SculkSpreader.java.patch | 14 +- .../world/level/block/SignBlock.java.patch | 20 +- .../world/level/block/SpongeBlock.java.patch | 31 +- .../AbstractFurnaceBlockEntity.java.patch | 24 +- .../block/entity/BannerBlockEntity.java.patch | 32 +- .../block/entity/BarrelBlockEntity.java.patch | 2 +- .../BaseContainerBlockEntity.java.patch | 8 +- .../block/entity/BeaconBlockEntity.java.patch | 42 +- .../entity/BeehiveBlockEntity.java.patch | 52 +- .../level/block/entity/BlockEntity.java.patch | 56 +- .../entity/BrushableBlockEntity.java.patch | 10 +- ...alibratedSculkSensorBlockEntity.java.patch | 4 +- .../entity/CampfireBlockEntity.java.patch | 26 +- .../entity/ConduitBlockEntity.java.patch | 38 +- .../entity/DecoratedPotBlockEntity.java.patch | 16 +- .../block/entity/JigsawBlockEntity.java.patch | 2 +- .../entity/JukeboxBlockEntity.java.patch | 6 +- .../entity/LecternBlockEntity.java.patch | 12 +- ...andomizableContainerBlockEntity.java.patch | 4 +- .../entity/SculkSensorBlockEntity.java.patch | 29 +- .../SculkShriekerBlockEntity.java.patch | 4 +- .../block/entity/SignBlockEntity.java.patch | 71 +- .../block/entity/SkullBlockEntity.java.patch | 8 +- .../block/entity/TestBlockEntity.java.patch | 12 +- .../entity/TestInstanceBlockEntity.java.patch | 14 +- .../TheEndGatewayBlockEntity.java.patch | 2 +- .../trialspawner/TrialSpawner.java.patch | 68 +- ...patch => TrialSpawnerStateData.java.patch} | 8 +- .../entity/vault/VaultBlockEntity.java.patch | 8 +- .../piston/PistonMovingBlockEntity.java.patch | 4 +- .../world/level/chunk/ChunkAccess.java.patch | 16 +- .../world/level/chunk/LevelChunk.java.patch | 26 +- .../level/chunk/PalettedContainer.java.patch | 14 +- .../world/level/chunk/ProtoChunk.java.patch | 2 +- .../chunk/status/ChunkStatusTasks.java.patch | 12 +- .../chunk/storage/ChunkStorage.java.patch | 2 +- .../storage/SerializableChunkData.java.patch | 24 +- .../PersistentEntitySectionManager.java.patch | 2 +- .../structure/StructurePiece.java.patch | 13 +- .../StructureTemplate.java.patch | 114 +- .../world/level/portal/PortalShape.java.patch | 2 +- .../portal/TeleportTransition.java.patch | 13 +- .../storage/PlayerDataStorage.java.patch | 34 +- .../level/storage/TagValueInput.java.patch | 18 + .../level/storage/TagValueOutput.java.patch | 26 + .../storage/loot/LootDataType.java.patch | 6 +- .../level/storage/loot/LootTable.java.patch | 6 +- .../LootPoolSingletonContainer.java.patch | 4 +- .../0015-Rewrite-dataconverter-system.patch | 9 +- .../block/impl/CraftAmethystCluster.java | 2 +- .../craftbukkit/block/impl/CraftAnvil.java | 2 +- .../block/impl/CraftAttachedStem.java | 2 +- .../block/impl/CraftBambooStalk.java | 2 +- .../craftbukkit/block/impl/CraftBanner.java | 2 +- .../craftbukkit/block/impl/CraftBarrel.java | 2 +- .../craftbukkit/block/impl/CraftBarrier.java | 2 +- .../block/impl/CraftBaseCoralFan.java | 2 +- .../block/impl/CraftBaseCoralPlant.java | 2 +- .../block/impl/CraftBaseCoralWallFan.java | 2 +- .../craftbukkit/block/impl/CraftBed.java | 2 +- .../craftbukkit/block/impl/CraftBeehive.java | 2 +- .../craftbukkit/block/impl/CraftBeetroot.java | 2 +- .../craftbukkit/block/impl/CraftBell.java | 2 +- .../block/impl/CraftBigDripleaf.java | 2 +- .../block/impl/CraftBigDripleafStem.java | 2 +- .../block/impl/CraftBlastFurnace.java | 2 +- .../block/impl/CraftBrewingStand.java | 2 +- .../block/impl/CraftBrushable.java | 2 +- .../block/impl/CraftBubbleColumn.java | 2 +- .../craftbukkit/block/impl/CraftButton.java | 2 +- .../craftbukkit/block/impl/CraftCactus.java | 2 +- .../craftbukkit/block/impl/CraftCake.java | 2 +- .../impl/CraftCalibratedSculkSensor.java | 2 +- .../craftbukkit/block/impl/CraftCampfire.java | 2 +- .../craftbukkit/block/impl/CraftCandle.java | 2 +- .../block/impl/CraftCandleCake.java | 2 +- .../craftbukkit/block/impl/CraftCarrot.java | 2 +- .../block/impl/CraftCarvedPumpkin.java | 2 +- .../block/impl/CraftCaveVines.java | 2 +- .../block/impl/CraftCaveVinesPlant.java | 2 +- .../block/impl/CraftCeilingHangingSign.java | 2 +- .../craftbukkit/block/impl/CraftChain.java | 2 +- .../craftbukkit/block/impl/CraftChest.java | 2 +- .../block/impl/CraftChiseledBookShelf.java | 2 +- .../block/impl/CraftChorusFlower.java | 2 +- .../block/impl/CraftChorusPlant.java | 2 +- .../craftbukkit/block/impl/CraftCocoa.java | 2 +- .../block/impl/CraftCommandBlock.java | 2 +- .../block/impl/CraftComparator.java | 2 +- .../block/impl/CraftComposter.java | 2 +- .../craftbukkit/block/impl/CraftConduit.java | 2 +- .../block/impl/CraftCopperBulb.java | 2 +- .../craftbukkit/block/impl/CraftCoralFan.java | 2 +- .../block/impl/CraftCoralPlant.java | 2 +- .../block/impl/CraftCoralWallFan.java | 2 +- .../craftbukkit/block/impl/CraftCrafter.java | 2 +- .../block/impl/CraftCreakingHeart.java | 2 +- .../craftbukkit/block/impl/CraftCrop.java | 2 +- .../block/impl/CraftDaylightDetector.java | 2 +- .../block/impl/CraftDecoratedPot.java | 2 +- .../block/impl/CraftDetectorRail.java | 2 +- .../block/impl/CraftDispenser.java | 2 +- .../craftbukkit/block/impl/CraftDoor.java | 2 +- .../block/impl/CraftDoublePlant.java | 2 +- .../block/impl/CraftDriedGhast.java | 69 + .../craftbukkit/block/impl/CraftDropper.java | 2 +- .../block/impl/CraftEndPortalFrame.java | 2 +- .../craftbukkit/block/impl/CraftEndRod.java | 2 +- .../block/impl/CraftEnderChest.java | 2 +- .../craftbukkit/block/impl/CraftFarm.java | 2 +- .../craftbukkit/block/impl/CraftFence.java | 2 +- .../block/impl/CraftFenceGate.java | 2 +- .../craftbukkit/block/impl/CraftFire.java | 2 +- .../block/impl/CraftFlowerBed.java | 2 +- .../block/impl/CraftFrostedIce.java | 2 +- .../craftbukkit/block/impl/CraftFurnace.java | 2 +- .../block/impl/CraftGlazedTerracotta.java | 2 +- .../block/impl/CraftGlowLichen.java | 8 +- .../craftbukkit/block/impl/CraftGrass.java | 2 +- .../block/impl/CraftGrindstone.java | 2 +- .../block/impl/CraftHangingMoss.java | 2 +- .../block/impl/CraftHangingRoots.java | 2 +- .../craftbukkit/block/impl/CraftHay.java | 2 +- .../block/impl/CraftHeavyCore.java | 2 +- .../craftbukkit/block/impl/CraftHopper.java | 2 +- .../block/impl/CraftHugeMushroom.java | 8 +- .../impl/CraftInfestedRotatedPillar.java | 2 +- .../craftbukkit/block/impl/CraftIronBars.java | 2 +- .../craftbukkit/block/impl/CraftJigsaw.java | 2 +- .../craftbukkit/block/impl/CraftJukebox.java | 2 +- .../craftbukkit/block/impl/CraftKelp.java | 2 +- .../craftbukkit/block/impl/CraftLadder.java | 2 +- .../craftbukkit/block/impl/CraftLantern.java | 2 +- .../block/impl/CraftLayeredCauldron.java | 2 +- .../block/impl/CraftLeafLitter.java | 2 +- .../craftbukkit/block/impl/CraftLectern.java | 2 +- .../craftbukkit/block/impl/CraftLever.java | 2 +- .../craftbukkit/block/impl/CraftLight.java | 2 +- .../block/impl/CraftLightningRod.java | 2 +- .../craftbukkit/block/impl/CraftLiquid.java | 2 +- .../craftbukkit/block/impl/CraftLoom.java | 2 +- .../block/impl/CraftMangroveLeaves.java | 2 +- .../block/impl/CraftMangrovePropagule.java | 2 +- .../block/impl/CraftMangroveRoots.java | 2 +- .../block/impl/CraftMossyCarpet.java | 2 +- .../block/impl/CraftMovingPiston.java | 2 +- .../block/impl/CraftMultiface.java | 8 +- .../craftbukkit/block/impl/CraftMycelium.java | 2 +- .../block/impl/CraftNetherPortal.java | 2 +- .../block/impl/CraftNetherWart.java | 2 +- .../block/impl/CraftNoteBlock.java | 2 +- .../craftbukkit/block/impl/CraftObserver.java | 2 +- .../block/impl/CraftPiglinWallSkull.java | 2 +- .../block/impl/CraftPistonBase.java | 2 +- .../block/impl/CraftPistonHead.java | 2 +- .../block/impl/CraftPitcherCrop.java | 2 +- .../block/impl/CraftPlayerHead.java | 2 +- .../block/impl/CraftPlayerWallHead.java | 2 +- .../block/impl/CraftPointedDripstone.java | 2 +- .../craftbukkit/block/impl/CraftPotato.java | 2 +- .../block/impl/CraftPoweredRail.java | 2 +- .../block/impl/CraftPressurePlate.java | 2 +- .../craftbukkit/block/impl/CraftRail.java | 2 +- .../block/impl/CraftRedStoneOre.java | 2 +- .../block/impl/CraftRedStoneWire.java | 2 +- .../block/impl/CraftRedstoneLamp.java | 2 +- .../block/impl/CraftRedstoneTorch.java | 2 +- .../block/impl/CraftRedstoneWallTorch.java | 2 +- .../craftbukkit/block/impl/CraftRepeater.java | 2 +- .../block/impl/CraftRespawnAnchor.java | 2 +- .../block/impl/CraftRotatedPillar.java | 2 +- .../craftbukkit/block/impl/CraftSapling.java | 2 +- .../block/impl/CraftScaffolding.java | 2 +- .../block/impl/CraftSculkCatalyst.java | 2 +- .../block/impl/CraftSculkSensor.java | 2 +- .../block/impl/CraftSculkShrieker.java | 2 +- .../block/impl/CraftSculkVein.java | 8 +- .../block/impl/CraftSeaPickle.java | 2 +- .../block/impl/CraftShulkerBox.java | 2 +- .../craftbukkit/block/impl/CraftSkull.java | 2 +- .../craftbukkit/block/impl/CraftSlab.java | 2 +- .../block/impl/CraftSmallDripleaf.java | 2 +- .../craftbukkit/block/impl/CraftSmoker.java | 2 +- .../block/impl/CraftSnifferEgg.java | 2 +- .../block/impl/CraftSnowLayer.java | 2 +- .../block/impl/CraftSnowyDirt.java | 2 +- .../block/impl/CraftStainedGlassPane.java | 2 +- .../craftbukkit/block/impl/CraftStair.java | 2 +- .../block/impl/CraftStandingSign.java | 2 +- .../craftbukkit/block/impl/CraftStem.java | 2 +- .../block/impl/CraftStonecutter.java | 2 +- .../block/impl/CraftStructureBlock.java | 2 +- .../block/impl/CraftSugarCane.java | 2 +- .../block/impl/CraftSweetBerryBush.java | 2 +- .../block/impl/CraftTallFlower.java | 2 +- .../block/impl/CraftTallSeagrass.java | 2 +- .../craftbukkit/block/impl/CraftTarget.java | 2 +- .../block/impl/CraftTestBlock.java | 2 +- .../block/impl/CraftTintedParticleLeaves.java | 2 +- .../craftbukkit/block/impl/CraftTnt.java | 2 +- .../block/impl/CraftTorchflowerCrop.java | 2 +- .../craftbukkit/block/impl/CraftTrapDoor.java | 2 +- .../block/impl/CraftTrappedChest.java | 2 +- .../block/impl/CraftTrialSpawner.java | 2 +- .../craftbukkit/block/impl/CraftTripWire.java | 6 +- .../block/impl/CraftTripWireHook.java | 2 +- .../block/impl/CraftTurtleEgg.java | 2 +- .../block/impl/CraftTwistingVines.java | 2 +- .../impl/CraftUntintedParticleLeaves.java | 2 +- .../craftbukkit/block/impl/CraftVault.java | 2 +- .../craftbukkit/block/impl/CraftVine.java | 2 +- .../craftbukkit/block/impl/CraftWall.java | 2 +- .../block/impl/CraftWallBanner.java | 2 +- .../block/impl/CraftWallHangingSign.java | 2 +- .../craftbukkit/block/impl/CraftWallSign.java | 2 +- .../block/impl/CraftWallSkull.java | 2 +- .../block/impl/CraftWallTorch.java | 2 +- .../impl/CraftWaterloggedTransparent.java | 2 +- .../block/impl/CraftWeatheringCopperBulb.java | 2 +- .../block/impl/CraftWeatheringCopperDoor.java | 2 +- .../impl/CraftWeatheringCopperGrate.java | 2 +- .../block/impl/CraftWeatheringCopperSlab.java | 2 +- .../impl/CraftWeatheringCopperStair.java | 2 +- .../impl/CraftWeatheringCopperTrapDoor.java | 2 +- .../block/impl/CraftWeepingVines.java | 2 +- .../impl/CraftWeightedPressurePlate.java | 2 +- .../block/impl/CraftWitherSkull.java | 2 +- .../block/impl/CraftWitherWallSkull.java | 2 +- .../paper/entity/PaperPathfinder.java | 14 +- .../paper/entity/ai/MobGoalHelper.java | 453 +- .../paper/entity/ai/PaperGoal.java | 20 +- .../loottable/PaperLootableInventoryData.java | 65 +- .../io/papermc/paper/ServerBuildInfoImpl.java | 4 +- .../command/brigadier/APICommandMeta.java | 6 +- .../command/brigadier/PaperCommands.java | 2 +- .../command/subcommands/MobcapsCommand.java | 2 +- .../datacomponent/DataComponentAdapters.java | 1 - .../item/ItemComponentTypesBridgesImpl.java | 12 +- .../item/PaperBlocksAttacks.java | 25 +- .../datacomponent/item/PaperConsumable.java | 8 +- .../item/PaperDeathProtection.java | 8 +- .../datacomponent/item/PaperEquippable.java | 37 +- .../item/PaperItemAdventurePredicate.java | 5 +- .../item/PaperItemArmorTrim.java | 1 + .../item/PaperItemAttributeModifiers.java | 17 +- .../item/PaperItemContainerContents.java | 2 +- .../datacomponent/item/PaperItemTool.java | 6 +- .../item/PaperPotionContents.java | 2 +- .../item/PaperResolvableProfile.java | 4 +- .../datacomponent/item/PaperUseCooldown.java | 1 - .../AttributeModifierDisplayBridgeImpl.java | 25 + .../PaperAttributeModifierDisplay.java | 24 + .../item/attribute/PaperDefaultDisplay.java | 13 + .../item/attribute/PaperHiddenDisplay.java | 13 + .../attribute/PaperOverrideTextDisplay.java | 20 + .../item/attribute/package-info.java | 7 + .../BlocksAttacksBridgeImpl.java | 2 - .../blocksattacks/PaperDamageReduction.java | 13 +- .../PaperItemDamageFunction.java | 9 +- .../consumable/ConsumableTypesBridgeImpl.java | 6 +- .../consumable/PaperApplyStatusEffects.java | 2 +- .../PaperClearAllStatusEffects.java | 4 +- ...ffects.java => PaperConsumableEffect.java} | 13 +- .../consumable/PaperConsumableEffectImpl.java | 7 - .../item/consumable/PaperPlaySound.java | 2 +- .../consumable/PaperRemoveStatusEffects.java | 3 +- .../consumable/PaperTeleportRandomly.java | 4 +- .../entity/activation/ActivationType.java | 5 +- .../manager/PaperPluginInstanceManager.java | 1 - .../paper/registry/PaperRegistries.java | 10 +- .../paper/registry/PaperRegistryAccess.java | 14 +- .../registry/PaperRegistryBuilderFactory.java | 21 +- .../PaperRegistryListenerManager.java | 25 +- .../paper/registry/WritableCraftRegistry.java | 2 +- .../InlinedRegistryBuilderProviderImpl.java | 30 - .../data/PaperJukeboxSongRegistryEntry.java | 121 + .../data/PaperSoundEventRegistryEntry.java | 69 + .../paper/registry/data/util/Checks.java | 7 + .../paper/registry/data/util/Conversions.java | 52 +- .../registry/entry/RegistryEntryBuilder.java | 2 +- .../registry/entry/RegistryEntryMeta.java | 6 +- ...mpl.java => RegistryComposeEventImpl.java} | 2 +- .../event/RegistryEventTypeProviderImpl.java | 4 +- .../holder/InlinedRegistryHolderImpl.java | 8 + .../registry/holder/PaperRegistryHolders.java | 26 + .../holder/ReferenceRegistryHolderImpl.java | 8 + .../flag/PaperFeatureFlagProviderImpl.java | 2 +- .../craftbukkit/CraftOfflinePlayer.java | 6 +- .../craftbukkit/CraftRegionAccessor.java | 1 - .../org/bukkit/craftbukkit/CraftRegistry.java | 12 +- .../bukkit/craftbukkit/CraftStatistic.java | 5 +- .../org/bukkit/craftbukkit/CraftWorld.java | 28 +- .../java/org/bukkit/craftbukkit/Main.java | 71 +- .../craftbukkit/block/CapturedBlockState.java | 5 +- .../bukkit/craftbukkit/block/CraftBiome.java | 7 +- .../block/CraftBlockEntityState.java | 58 +- .../craftbukkit/block/CraftBlockStates.java | 2 +- .../craftbukkit/block/CraftConduit.java | 26 +- .../block/CraftCreatureSpawner.java | 18 +- .../craftbukkit/block/CraftFurnace.java | 4 +- .../craftbukkit/block/CraftTrialSpawner.java | 34 +- .../block/CraftTrialSpawnerConfiguration.java | 41 +- .../block/data/CraftBlockData.java | 3 +- .../entity/AbstractProjectile.java | 5 +- .../entity/CraftAbstractHorse.java | 6 +- .../craftbukkit/entity/CraftAnimals.java | 6 +- .../entity/CraftAreaEffectCloud.java | 9 +- .../craftbukkit/entity/CraftArmadillo.java | 20 +- .../craftbukkit/entity/CraftArmorStand.java | 24 +- .../craftbukkit/entity/CraftEnderSignal.java | 5 +- .../craftbukkit/entity/CraftEntity.java | 63 +- .../entity/CraftEntityFactory.java | 12 +- .../entity/CraftEntitySnapshot.java | 42 +- .../craftbukkit/entity/CraftEntityTypes.java | 2 + .../craftbukkit/entity/CraftFlying.java | 17 - .../bukkit/craftbukkit/entity/CraftGhast.java | 2 +- .../craftbukkit/entity/CraftHappyGhast.java | 10 + .../craftbukkit/entity/CraftHumanEntity.java | 32 +- .../bukkit/craftbukkit/entity/CraftItem.java | 8 +- .../entity/CraftMinecartMobSpawner.java | 12 +- .../craftbukkit/entity/CraftPhantom.java | 3 +- .../craftbukkit/entity/CraftPlayer.java | 33 +- .../craftbukkit/entity/CraftTNTPrimed.java | 3 +- .../bukkit/craftbukkit/entity/CraftVex.java | 5 +- .../craftbukkit/event/CraftEventFactory.java | 53 +- .../generator/CraftLimitedRegion.java | 17 +- .../CraftInventoryAbstractHorse.java | 25 +- .../inventory/CraftInventoryPlayer.java | 30 +- .../inventory/CraftItemFactory.java | 3 +- .../craftbukkit/inventory/CraftItemMetas.java | 4 +- .../inventory/CraftMetaBlockState.java | 26 +- .../inventory/CraftMetaBookSigned.java | 1 - .../craftbukkit/inventory/CraftMetaItem.java | 18 +- .../inventory/CraftMetaPotion.java | 4 +- .../components/CraftEquippableComponent.java | 26 +- .../craftbukkit/potion/CraftPotionUtil.java | 4 +- .../spawner/PaperSharedSpawnerLogic.java | 36 +- .../craftbukkit/structure/CraftStructure.java | 24 +- .../bukkit/craftbukkit/util/ApiVersion.java | 2 +- .../util/BlockStateListPopulator.java | 141 +- .../craftbukkit/util/CapturedBlock.java | 10 + .../craftbukkit/util/CraftChatMessage.java | 17 +- .../craftbukkit/util/CraftMagicNumbers.java | 94 +- .../util/TransformerGeneratorAccess.java | 14 +- .../util/permissions/CommandPermissions.java | 19 +- ...m.attribute.AttributeModifierDisplayBridge | 1 + .../minecraft/datapacks/paper/pack.mcmeta | 2 +- .../StepBasedCollectorRunBeforeTest.java | 38 + .../paper/registry/RegistryBuilderTest.java | 3 +- .../test/java/org/bukkit/ParticleTest.java | 2 +- .../craftbukkit/inventory/ItemMetaTest.java | 7 +- .../inventory/YamlSerializationTest.java | 2 +- .../bukkit/craftbukkit/legacy/LegacyTest.java | 4 + .../craftbukkit/util/ApiVersionTest.java | 4 +- .../registry/RegistryConversionTest.java | 15 +- .../provider/RegistryArgumentProvider.java | 33 - .../org/bukkit/support/test/RegistryTest.java | 19 - settings.gradle.kts | 2 +- test-plugin/build.gradle.kts | 5 +- .../testplugin/brigtests/Registration.java | 1 - .../example/ExampleAdminCommand.java | 7 +- .../example/IceCreamTypeArgument.java | 12 +- 788 files changed, 41006 insertions(+), 6324 deletions(-) create mode 100644 paper-api/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplay.java create mode 100644 paper-api/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplayBridge.java create mode 100644 paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/data/JukeboxSongRegistryEntry.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/data/SoundEventRegistryEntry.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/holder/RegistryHolder.java create mode 100644 paper-api/src/main/java/io/papermc/paper/registry/holder/package-info.java create mode 100644 paper-api/src/main/java/org/bukkit/block/data/type/DriedGhast.java create mode 100644 paper-api/src/main/java/org/bukkit/entity/HappyGhast.java delete mode 100644 paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/DataComponentTypesRewriter.java create mode 100644 paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/PoseRewriter.java create mode 100644 paper-server/patches/features/0015-Rewrite-dataconverter-system.patch rename paper-server/patches/features/{0015-Moonrise-optimisation-patches.patch => 0016-Moonrise-optimisation-patches.patch} (98%) rename paper-server/patches/features/{0016-Fix-entity-tracker-desync-when-new-players-are-added.patch => 0017-Fix-entity-tracker-desync-when-new-players-are-added.patch} (87%) rename paper-server/patches/features/{0017-Eigencraft-redstone-implementation.patch => 0018-Eigencraft-redstone-implementation.patch} (100%) rename paper-server/patches/features/{0018-Add-Alternate-Current-redstone-implementation.patch => 0019-Add-Alternate-Current-redstone-implementation.patch} (99%) rename paper-server/patches/features/{0019-Improve-exact-choice-recipe-ingredients.patch => 0020-Improve-exact-choice-recipe-ingredients.patch} (99%) delete mode 100644 paper-server/patches/features/0021-Entity-load-save-limit-per-chunk.patch rename paper-server/patches/features/{0020-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch => 0021-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch} (100%) create mode 100644 paper-server/patches/features/0022-Entity-load-save-limit-per-chunk.patch rename paper-server/patches/features/{0022-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch => 0023-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch} (99%) rename paper-server/patches/features/{0023-Incremental-chunk-and-player-saving.patch => 0024-Incremental-chunk-and-player-saving.patch} (89%) rename paper-server/patches/features/{0024-Optimise-general-POI-access.patch => 0025-Optimise-general-POI-access.patch} (99%) rename paper-server/patches/features/{0025-Optional-per-player-mob-spawns.patch => 0026-Optional-per-player-mob-spawns.patch} (97%) rename paper-server/patches/features/{0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch => 0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch} (93%) rename paper-server/patches/features/{0027-Optimize-Hoppers.patch => 0028-Optimize-Hoppers.patch} (97%) rename paper-server/patches/features/{0028-Flush-regionfiles-on-save-configuration-option.patch => 0029-Flush-regionfiles-on-save-configuration-option.patch} (94%) rename paper-server/patches/features/{0029-Optimise-collision-checking-in-player-move-packet-ha.patch => 0030-Optimise-collision-checking-in-player-move-packet-ha.patch} (71%) create mode 100644 paper-server/patches/features/0031-DataConverter-Fixes.patch create mode 100644 paper-server/patches/sources/net/minecraft/commands/PermissionSource.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/core/HolderLookup.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/core/RegistrySetBuilder.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/resources/RegistryOps.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/util/PlaceholderLookupProvider.java.patch delete mode 100644 paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/entity/animal/HappyGhast.java.patch rename paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/{TrialSpawnerData.java.patch => TrialSpawnerStateData.java.patch} (76%) create mode 100644 paper-server/patches/sources/net/minecraft/world/level/storage/TagValueInput.java.patch create mode 100644 paper-server/patches/sources/net/minecraft/world/level/storage/TagValueOutput.java.patch create mode 100644 paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDriedGhast.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplayBridgeImpl.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperAttributeModifierDisplay.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperDefaultDisplay.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperHiddenDisplay.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperOverrideTextDisplay.java create mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/package-info.java rename paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/{PaperConsumableEffects.java => PaperConsumableEffect.java} (69%) delete mode 100644 paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffectImpl.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/data/PaperJukeboxSongRegistryEntry.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/data/PaperSoundEventRegistryEntry.java rename paper-server/src/main/java/io/papermc/paper/registry/event/{RegistryFreezeEventImpl.java => RegistryComposeEventImpl.java} (94%) create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/holder/InlinedRegistryHolderImpl.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/holder/PaperRegistryHolders.java create mode 100644 paper-server/src/main/java/io/papermc/paper/registry/holder/ReferenceRegistryHolderImpl.java delete mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHappyGhast.java create mode 100644 paper-server/src/main/java/org/bukkit/craftbukkit/util/CapturedBlock.java create mode 100644 paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplayBridge create mode 100644 paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java delete mode 100644 paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java delete mode 100644 paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 58ad0bec4e..93f97705f6 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,6 +49,9 @@ jobs: - name: Setup Gradle uses: gradle/actions/setup-gradle@v4 + with: + # Allow cache writes on main and dev branches + cache-read-only: ${{ github.ref != 'refs/heads/main' && !startsWith(github.ref, 'refs/heads/dev/') }} - name: Configure Build uses: actions/github-script@v7 diff --git a/.github/workflows/test_results.yml b/.github/workflows/test_results.yml index 3fea18361c..e98306f4da 100644 --- a/.github/workflows/test_results.yml +++ b/.github/workflows/test_results.yml @@ -22,7 +22,8 @@ jobs: with: run_id: ${{ github.event.workflow_run.id }} path: test_artifacts - name: Test Results + name: "Test Results|Event File" + name_is_regexp: true - name: Publish Test Results uses: EnricoMi/publish-unit-test-result-action@v2 with: diff --git a/README.md b/README.md index d06d31464a..c3450456aa 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ How To (Plugin Developers) io.papermc.paper paper-api - 1.21.5-R0.1-SNAPSHOT + 1.21.6-R0.1-SNAPSHOT provided ``` @@ -53,7 +53,7 @@ repositories { } dependencies { - compileOnly("io.papermc.paper:paper-api:1.21.5-R0.1-SNAPSHOT") + compileOnly("io.papermc.paper:paper-api:1.21.6-R0.1-SNAPSHOT") } java { diff --git a/build-data/paper.at b/build-data/paper.at index 52c3bc70fa..1692a54925 100644 --- a/build-data/paper.at +++ b/build-data/paper.at @@ -140,12 +140,11 @@ public net.minecraft.world.effect.MobEffect attributeModifiers public net.minecraft.world.effect.MobEffect$AttributeTemplate public net.minecraft.world.effect.MobEffectInstance hiddenEffect public net.minecraft.world.entity.AreaEffectCloud durationOnUse -public net.minecraft.world.entity.AreaEffectCloud ownerUUID +public net.minecraft.world.entity.AreaEffectCloud owner public net.minecraft.world.entity.AreaEffectCloud potionContents public net.minecraft.world.entity.AreaEffectCloud radiusOnUse public net.minecraft.world.entity.AreaEffectCloud radiusPerTick public net.minecraft.world.entity.AreaEffectCloud reapplicationDelay -public net.minecraft.world.entity.AreaEffectCloud updateColor()V public net.minecraft.world.entity.AreaEffectCloud waitTime public net.minecraft.world.entity.Display DATA_POS_ROT_INTERPOLATION_DURATION_ID public net.minecraft.world.entity.Display createTransformation(Lnet/minecraft/network/syncher/SynchedEntityData;)Lcom/mojang/math/Transformation; @@ -330,14 +329,8 @@ public net.minecraft.world.entity.animal.wolf.Wolf setSoundVariant(Lnet/minecraf public net.minecraft.world.entity.animal.wolf.Wolf setVariant(Lnet/minecraft/core/Holder;)V public net.minecraft.world.entity.boss.enderdragon.EnderDragon subEntities public net.minecraft.world.entity.boss.wither.WitherBoss bossEvent -public net.minecraft.world.entity.decoration.ArmorStand bodyPose public net.minecraft.world.entity.decoration.ArmorStand disabledSlots -public net.minecraft.world.entity.decoration.ArmorStand headPose public net.minecraft.world.entity.decoration.ArmorStand isDisabled(Lnet/minecraft/world/entity/EquipmentSlot;)Z -public net.minecraft.world.entity.decoration.ArmorStand leftArmPose -public net.minecraft.world.entity.decoration.ArmorStand leftLegPose -public net.minecraft.world.entity.decoration.ArmorStand rightArmPose -public net.minecraft.world.entity.decoration.ArmorStand rightLegPose public net.minecraft.world.entity.decoration.ArmorStand setMarker(Z)V public net.minecraft.world.entity.decoration.ArmorStand setSmall(Z)V public net.minecraft.world.entity.decoration.HangingEntity setDirection(Lnet/minecraft/core/Direction;)V @@ -364,8 +357,6 @@ public net.minecraft.world.entity.monster.Creeper explodeCreeper()V public net.minecraft.world.entity.monster.Creeper explosionRadius public net.minecraft.world.entity.monster.Creeper maxSwell public net.minecraft.world.entity.monster.Creeper swell -public net.minecraft.world.entity.monster.Drowned groundNavigation -public net.minecraft.world.entity.monster.Drowned waterNavigation public net.minecraft.world.entity.monster.EnderMan teleport()Z public net.minecraft.world.entity.monster.EnderMan teleportTowards(Lnet/minecraft/world/entity/Entity;)Z public net.minecraft.world.entity.monster.Endermite life @@ -392,6 +383,7 @@ public net.minecraft.world.entity.monster.SpellcasterIllager$IllagerSpell public net.minecraft.world.entity.monster.Strider steering public net.minecraft.world.entity.monster.Vex hasLimitedLife public net.minecraft.world.entity.monster.Vex limitedLifeTicks +public net.minecraft.world.entity.monster.Vex owner public net.minecraft.world.entity.monster.Vindicator DOOR_BREAKING_PREDICATE public net.minecraft.world.entity.monster.Vindicator isJohnny public net.minecraft.world.entity.monster.Witch usingTime @@ -450,9 +442,7 @@ public net.minecraft.world.entity.projectile.Arrow updateColor()V public net.minecraft.world.entity.projectile.EvokerFangs warmupDelayTicks public net.minecraft.world.entity.projectile.EyeOfEnder life public net.minecraft.world.entity.projectile.EyeOfEnder surviveAfterDeath -public net.minecraft.world.entity.projectile.EyeOfEnder tx -public net.minecraft.world.entity.projectile.EyeOfEnder ty -public net.minecraft.world.entity.projectile.EyeOfEnder tz +public net.minecraft.world.entity.projectile.EyeOfEnder target public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ATTACHED_TO_TARGET public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_ID_FIREWORKS_ITEM public net.minecraft.world.entity.projectile.FireworkRocketEntity DATA_SHOT_AT_ANGLE @@ -472,10 +462,9 @@ public net.minecraft.world.entity.projectile.FishingHook timeUntilHooked public net.minecraft.world.entity.projectile.FishingHook timeUntilLured public net.minecraft.world.entity.projectile.FishingHook$FishHookState public net.minecraft.world.entity.projectile.LargeFireball explosionPower -public net.minecraft.world.entity.projectile.Projectile cachedOwner public net.minecraft.world.entity.projectile.Projectile hasBeenShot public net.minecraft.world.entity.projectile.Projectile leftOwner -public net.minecraft.world.entity.projectile.Projectile ownerUUID +public net.minecraft.world.entity.projectile.Projectile owner public net.minecraft.world.entity.projectile.ShulkerBullet currentMoveDirection public net.minecraft.world.entity.projectile.ShulkerBullet flightSteps public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaX @@ -616,7 +605,7 @@ public net.minecraft.world.level.block.entity.BedBlockEntity color public net.minecraft.world.level.block.entity.BeehiveBlockEntity savedFlowerPos public net.minecraft.world.level.block.entity.BellBlockEntity resonating public net.minecraft.world.level.block.entity.BellBlockEntity resonationTicks -public net.minecraft.world.level.block.entity.BlockEntity saveId(Lnet/minecraft/nbt/CompoundTag;)V +public net.minecraft.world.level.block.entity.BlockEntity saveId(Lnet/minecraft/world/level/storage/ValueOutput;)V public net.minecraft.world.level.block.entity.BlockEntityType validBlocks public net.minecraft.world.level.block.entity.BrewingStandBlockEntity brewTime public net.minecraft.world.level.block.entity.BrewingStandBlockEntity fuel @@ -628,10 +617,11 @@ public net.minecraft.world.level.block.entity.CampfireBlockEntity cookingTime public net.minecraft.world.level.block.entity.ChestBlockEntity openersCounter public net.minecraft.world.level.block.entity.ChestBlockEntity playSound(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/sounds/SoundEvent;)V public net.minecraft.world.level.block.entity.ChiseledBookShelfBlockEntity lastInteractedSlot +public net.minecraft.world.level.block.entity.ConduitBlockEntity MIN_KILL_SIZE public net.minecraft.world.level.block.entity.ConduitBlockEntity destroyTarget -public net.minecraft.world.level.block.entity.ConduitBlockEntity destroyTargetUUID public net.minecraft.world.level.block.entity.ConduitBlockEntity effectBlocks public net.minecraft.world.level.block.entity.ConduitBlockEntity getDestroyRangeAABB(Lnet/minecraft/core/BlockPos;)Lnet/minecraft/world/phys/AABB; +public net.minecraft.world.level.block.entity.ConduitBlockEntity updateDestroyTarget(Lnet/minecraft/world/entity/EntityReference;Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/core/BlockPos;Z)Lnet/minecraft/world/entity/EntityReference; public net.minecraft.world.level.block.entity.CrafterBlockEntity craftingTicksRemaining public net.minecraft.world.level.block.entity.DecoratedPotBlockEntity decorations public net.minecraft.world.level.block.entity.EnderChestBlockEntity openersCounter @@ -665,13 +655,14 @@ public net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity age public net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity exactTeleport public net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity exitPortal public net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity trialSpawner +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner config public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner isOminous public net.minecraft.world.level.block.entity.trialspawner.TrialSpawner stateAccessor -public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData cooldownEndsAt -public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData currentMobs -public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData detectedPlayers -public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextMobSpawnsAt -public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData nextSpawnData +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData cooldownEndsAt +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData currentMobs +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData detectedPlayers +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData nextMobSpawnsAt +public net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData nextSpawnData public net.minecraft.world.level.block.entity.vault.VaultBlockEntity serverData public net.minecraft.world.level.block.entity.vault.VaultServerData getRewardedPlayers()Ljava/util/Set; public net.minecraft.world.level.block.entity.vault.VaultServerData pauseStateUpdatingUntil(J)V @@ -690,7 +681,7 @@ public net.minecraft.world.level.chunk.LevelChunk level public net.minecraft.world.level.chunk.LevelChunk loaded public net.minecraft.world.level.chunk.LevelChunkSection states public net.minecraft.world.level.chunk.PalettedContainer registry -public net.minecraft.world.level.chunk.status.ChunkStatusTasks postLoadProtoChunk(Lnet/minecraft/server/level/ServerLevel;Ljava/util/List;)V +public net.minecraft.world.level.chunk.status.ChunkStatusTasks postLoadProtoChunk(Lnet/minecraft/server/level/ServerLevel;Lnet/minecraft/world/level/storage/ValueInput$ValueInputList;)V public net.minecraft.world.level.chunk.storage.EntityStorage entityDeserializerQueue public net.minecraft.world.level.chunk.storage.EntityStorage level public net.minecraft.world.level.chunk.storage.RegionFileStorage regionCache @@ -777,10 +768,6 @@ public-f net.minecraft.world.level.LevelSettings hardcore public-f net.minecraft.world.level.LevelSettings levelName public-f net.minecraft.world.level.block.ChestBlock MENU_PROVIDER_COMBINER public-f net.minecraft.world.level.block.entity.BannerBlockEntity baseColor -public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner normalConfig -public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner ominousConfig -public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner requiredPlayerRange -public-f net.minecraft.world.level.block.entity.trialspawner.TrialSpawner targetCooldownLength public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData centerX public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData centerZ public-f net.minecraft.world.level.saveddata.maps.MapItemSavedData dimension diff --git a/gradle.properties b/gradle.properties index 01662126e4..a8aed3f434 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,10 +1,9 @@ group=io.papermc.paper -version=1.21.5-R0.1-SNAPSHOT -mcVersion=1.21.5 +version=1.21.6-R0.1-SNAPSHOT +mcVersion=1.21.6-rc1 # Set to true while updating Minecraft version updatingMinecraft=true -updateTaskListIssue=https://github.com/PaperMC/Paper/issues/11736 org.gradle.configuration-cache=true org.gradle.caching=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index ca025c83a7..002b867c48 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java b/paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java index 12207256ae..f9de178553 100644 --- a/paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java +++ b/paper-api/src/generated/java/com/destroystokyo/paper/entity/ai/VanillaGoal.java @@ -21,6 +21,7 @@ import org.bukkit.entity.Fish; import org.bukkit.entity.Fox; import org.bukkit.entity.Ghast; import org.bukkit.entity.Guardian; +import org.bukkit.entity.HappyGhast; import org.bukkit.entity.Illager; import org.bukkit.entity.Illusioner; import org.bukkit.entity.IronGolem; @@ -67,17 +68,17 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public interface VanillaGoal extends Goal { - GoalKey RANDOM_STAND = create("random_stand", AbstractHorse.class); + GoalKey HORSE_RANDOM_STAND = create("horse_random_stand", AbstractHorse.class); - GoalKey RUN_AROUND_LIKE_CRAZY = create("run_around_like_crazy", AbstractHorse.class); + GoalKey HORSE_RUN_AROUND_LIKE_CRAZY = create("horse_run_around_like_crazy", AbstractHorse.class); - GoalKey ABSTRACT_SKELETON_MELEE = create("abstract_skeleton_melee", AbstractSkeleton.class); + GoalKey SKELETON_MELEE = create("skeleton_melee", AbstractSkeleton.class); - GoalKey LOOK_AT_TRADING_PLAYER = create("look_at_trading_player", AbstractVillager.class); + GoalKey VILLAGER_LOOK_AT_TRADING_PLAYER = create("villager_look_at_trading_player", AbstractVillager.class); - GoalKey TRADE_WITH_PLAYER = create("trade_with_player", AbstractVillager.class); + GoalKey VILLAGER_TRADE_WITH_PLAYER = create("villager_trade_with_player", AbstractVillager.class); GoalKey BREED = create("breed", Animals.class); @@ -101,12 +102,12 @@ public interface VanillaGoal extends Goal { GoalKey BEE_POLLINATE = create("bee_pollinate", Bee.class); + GoalKey BEE_VALIDATE_FLOWER = create("bee_validate_flower", Bee.class); + + GoalKey BEE_VALIDATE_HIVE = create("bee_validate_hive", Bee.class); + GoalKey BEE_WANDER = create("bee_wander", Bee.class); - GoalKey VALIDATE_FLOWER = create("validate_flower", Bee.class); - - GoalKey VALIDATE_HIVE = create("validate_hive", Bee.class); - GoalKey BLAZE_ATTACK = create("blaze_attack", Blaze.class); GoalKey CAT_AVOID_ENTITY = create("cat_avoid_entity", Cat.class); @@ -165,16 +166,16 @@ public interface VanillaGoal extends Goal { GoalKey WATER_AVOIDING_RANDOM_STROLL = create("water_avoiding_random_stroll", Creature.class); - GoalKey SWELL = create("swell", Creeper.class); + GoalKey CREEPER_SWELL = create("creeper_swell", Creeper.class); GoalKey DOLPHIN_JUMP = create("dolphin_jump", Dolphin.class); + GoalKey DOLPHIN_PLAY_WITH_ITEMS = create("dolphin_play_with_items", Dolphin.class); + GoalKey DOLPHIN_SWIM_TO_TREASURE = create("dolphin_swim_to_treasure", Dolphin.class); GoalKey DOLPHIN_SWIM_WITH_PLAYER = create("dolphin_swim_with_player", Dolphin.class); - GoalKey PLAY_WITH_ITEMS = create("play_with_items", Dolphin.class); - GoalKey DROWNED_ATTACK = create("drowned_attack", Drowned.class); GoalKey DROWNED_GO_TO_BEACH = create("drowned_go_to_beach", Drowned.class); @@ -199,14 +200,14 @@ public interface VanillaGoal extends Goal { GoalKey FISH_SWIM = create("fish_swim", Fish.class); - GoalKey DEFEND_TRUSTED = create("defend_trusted", Fox.class); - - GoalKey FACEPLANT = create("faceplant", Fox.class); - GoalKey FOX_BREED = create("fox_breed", Fox.class); + GoalKey FOX_DEFEND_TRUSTED = create("fox_defend_trusted", Fox.class); + GoalKey FOX_EAT_BERRIES = create("fox_eat_berries", Fox.class); + GoalKey FOX_FACEPLANT = create("fox_faceplant", Fox.class); + GoalKey FOX_FLOAT = create("fox_float", Fox.class); GoalKey FOX_FOLLOW_PARENT = create("fox_follow_parent", Fox.class); @@ -217,29 +218,27 @@ public interface VanillaGoal extends Goal { GoalKey FOX_PANIC = create("fox_panic", Fox.class); + GoalKey FOX_PERCH_AND_SEARCH = create("fox_perch_and_search", Fox.class); + GoalKey FOX_POUNCE = create("fox_pounce", Fox.class); GoalKey FOX_SEARCH_FOR_ITEMS = create("fox_search_for_items", Fox.class); + GoalKey FOX_SEEK_SHELTER = create("fox_seek_shelter", Fox.class); + + GoalKey FOX_SLEEP = create("fox_sleep", Fox.class); + + GoalKey FOX_STALK_PREY = create("fox_stalk_prey", Fox.class); + GoalKey FOX_STROLL_THROUGH_VILLAGE = create("fox_stroll_through_village", Fox.class); - GoalKey PERCH_AND_SEARCH = create("perch_and_search", Fox.class); - - GoalKey SEEK_SHELTER = create("seek_shelter", Fox.class); - - GoalKey SLEEP = create("sleep", Fox.class); - - GoalKey STALK_PREY = create("stalk_prey", Fox.class); - - GoalKey GHAST_LOOK = create("ghast_look", Ghast.class); - GoalKey GHAST_SHOOT_FIREBALL = create("ghast_shoot_fireball", Ghast.class); - GoalKey RANDOM_FLOAT_AROUND = create("random_float_around", Ghast.class); - GoalKey GUARDIAN_ATTACK = create("guardian_attack", Guardian.class); - GoalKey HOLD_GROUND_ATTACK = create("hold_ground_attack", Illager.class); + GoalKey HAPPY_GHAST_FLOAT = create("happy_ghast_float", HappyGhast.class); + + GoalKey ILLAGER_HOLD_GROUND_ATTACK = create("illager_hold_ground_attack", Illager.class); GoalKey RAIDER_OPEN_DOOR = create("raider_open_door", Illager.class); @@ -247,9 +246,9 @@ public interface VanillaGoal extends Goal { GoalKey ILLUSIONER_MIRROR_SPELL = create("illusioner_mirror_spell", Illusioner.class); - GoalKey DEFEND_VILLAGE = create("defend_village", IronGolem.class); + GoalKey IRON_GOLEM_DEFEND_VILLAGE = create("iron_golem_defend_village", IronGolem.class); - GoalKey OFFER_FLOWER = create("offer_flower", IronGolem.class); + GoalKey IRON_GOLEM_OFFER_FLOWER = create("iron_golem_offer_flower", IronGolem.class); GoalKey LLAMA_ATTACK_WOLF = create("llama_attack_wolf", Llama.class); @@ -269,6 +268,8 @@ public interface VanillaGoal extends Goal { GoalKey FOLLOW_MOB = create("follow_mob", Mob.class); + GoalKey GHAST_LOOK = create("ghast_look", Mob.class); + GoalKey INTERACT = create("interact", Mob.class); GoalKey LEAP_AT = create("leap_at", Mob.class); @@ -281,10 +282,14 @@ public interface VanillaGoal extends Goal { GoalKey OPEN_DOOR = create("open_door", Mob.class); + GoalKey RANDOM_FLOAT_AROUND = create("random_float_around", Mob.class); + GoalKey RANDOM_LOOK_AROUND = create("random_look_around", Mob.class); GoalKey RESET_UNIVERSAL_ANGER = create("reset_universal_anger", Mob.class); + GoalKey TEMPT_FOR_NON_PATHFINDERS = create("tempt_for_non_pathfinders", Mob.class); + GoalKey USE_ITEM = create("use_item", Mob.class); GoalKey VINDICATOR_BREAK_DOOR = create("vindicator_break_door", Mob.class); @@ -317,7 +322,7 @@ public interface VanillaGoal extends Goal { GoalKey PANDA_SNEEZE = create("panda_sneeze", Panda.class); - GoalKey LAND_ON_OWNERS_SHOULDER = create("land_on_owners_shoulder", Parrot.class); + GoalKey PARROT_LAND_ON_OWNERS_SHOULDER = create("parrot_land_on_owners_shoulder", Parrot.class); GoalKey PHANTOM_ATTACK_PLAYER = create("phantom_attack_player", Phantom.class); @@ -339,27 +344,27 @@ public interface VanillaGoal extends Goal { GoalKey RABBIT_PANIC = create("rabbit_panic", Rabbit.class); - GoalKey RAID_GARDEN = create("raid_garden", Rabbit.class); - - GoalKey LONG_DISTANCE_PATROL = create("long_distance_patrol", Raider.class); - - GoalKey NEAREST_ATTACKABLE_WITCH = create("nearest_attackable_witch", Raider.class); - - GoalKey NEAREST_HEALABLE_RAIDER = create("nearest_healable_raider", Raider.class); - - GoalKey OBTAIN_RAID_LEADER_BANNER = create("obtain_raid_leader_banner", Raider.class); - - GoalKey PATHFIND_TO_RAID = create("pathfind_to_raid", Raider.class); + GoalKey RABBIT_RAID_GARDEN = create("rabbit_raid_garden", Rabbit.class); GoalKey RAIDER_CELEBRATION = create("raider_celebration", Raider.class); + GoalKey RAIDER_LONG_DISTANCE_PATROL = create("raider_long_distance_patrol", Raider.class); + GoalKey RAIDER_MOVE_THROUGH_VILLAGE = create("raider_move_through_village", Raider.class); + GoalKey RAIDER_NEAREST_ATTACKABLE_WITCH = create("raider_nearest_attackable_witch", Raider.class); + + GoalKey RAIDER_NEAREST_HEALABLE_RAIDER = create("raider_nearest_healable_raider", Raider.class); + + GoalKey RAIDER_OBTAIN_RAID_LEADER_BANNER = create("raider_obtain_raid_leader_banner", Raider.class); + + GoalKey RAIDER_PATHFIND_TO_RAID = create("raider_pathfind_to_raid", Raider.class); + GoalKey DROWNED_TRIDENT_ATTACK = create("drowned_trident_attack", RangedEntity.class); GoalKey RANGED_ATTACK = create("ranged_attack", RangedEntity.class); - GoalKey FOLLOW_FLOCK_LEADER = create("follow_flock_leader", SchoolableFish.class); + GoalKey SCHOOLABLE_FISH_FOLLOW_FLOCK_LEADER = create("schoolable_fish_follow_flock_leader", SchoolableFish.class); GoalKey SHULKER_ATTACK = create("shulker_attack", Shulker.class); @@ -373,7 +378,7 @@ public interface VanillaGoal extends Goal { GoalKey SILVERFISH_WAKE_UP_FRIENDS = create("silverfish_wake_up_friends", Silverfish.class); - GoalKey SKELETON_TRAP = create("skeleton_trap", SkeletonHorse.class); + GoalKey SKELETON_HORSE_SKELETON_TRAP = create("skeleton_horse_skeleton_trap", SkeletonHorse.class); GoalKey SLIME_ATTACK = create("slime_attack", Slime.class); @@ -429,14 +434,14 @@ public interface VanillaGoal extends Goal { GoalKey VINDICATOR_JOHNNY_ATTACK = create("vindicator_johnny_attack", Vindicator.class); - GoalKey WANDER_TO_POSITION = create("wander_to_position", WanderingTrader.class); + GoalKey WANDERING_TRADER_WANDER_TO_POSITION = create("wandering_trader_wander_to_position", WanderingTrader.class); GoalKey WITHER_DO_NOTHING = create("wither_do_nothing", Wither.class); - GoalKey BEG = create("beg", Wolf.class); - GoalKey WOLF_AVOID_ENTITY = create("wolf_avoid_entity", Wolf.class); + GoalKey WOLF_BEG = create("wolf_beg", Wolf.class); + GoalKey ZOMBIE_ATTACK = create("zombie_attack", Zombie.class); GoalKey ZOMBIE_ATTACK_TURTLE_EGG = create("zombie_attack_turtle_egg", Zombie.class); diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java index 07e690dd93..67f9a55bd4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/AttributeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class AttributeKeys { /** * {@code minecraft:armor} @@ -81,6 +81,13 @@ public final class AttributeKeys { */ public static final TypedKey BURNING_TIME = create(key("burning_time")); + /** + * {@code minecraft:camera_distance} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey CAMERA_DISTANCE = create(key("camera_distance")); + /** * {@code minecraft:entity_interaction_range} * @@ -249,6 +256,20 @@ public final class AttributeKeys { */ public static final TypedKey WATER_MOVEMENT_EFFICIENCY = create(key("water_movement_efficiency")); + /** + * {@code minecraft:waypoint_receive_range} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey WAYPOINT_RECEIVE_RANGE = create(key("waypoint_receive_range")); + + /** + * {@code minecraft:waypoint_transmit_range} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey WAYPOINT_TRANSMIT_RANGE = create(key("waypoint_transmit_range")); + private AttributeKeys() { } diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java index a06d5f5f54..fc9b772fb4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BannerPatternKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class BannerPatternKeys { /** * {@code minecraft:base} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java index 1cdf88b0d0..02a344df98 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BiomeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class BiomeKeys { /** * {@code minecraft:badlands} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java index df46efb8f3..a8c84f7a5d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/BlockTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class BlockTypeKeys { /** * {@code minecraft:acacia_button} @@ -2475,6 +2475,13 @@ public final class BlockTypeKeys { */ public static final TypedKey DRAGON_WALL_HEAD = create(key("dragon_wall_head")); + /** + * {@code minecraft:dried_ghast} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRIED_GHAST = create(key("dried_ghast")); + /** * {@code minecraft:dried_kelp_block} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java index 4e82c1a5da..59406e2c95 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CatVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class CatVariantKeys { /** * {@code minecraft:all_black} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ChickenVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ChickenVariantKeys.java index 580b3dd8fe..61168fcbf2 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ChickenVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ChickenVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class ChickenVariantKeys { /** * {@code minecraft:cold} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CowVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CowVariantKeys.java index 2dddd4dc86..c13e13e7eb 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/CowVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/CowVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class CowVariantKeys { /** * {@code minecraft:cold} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java index 0a04639771..390c95d986 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DamageTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class DamageTypeKeys { /** * {@code minecraft:arrow} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DataComponentTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DataComponentTypeKeys.java index 768e6b30e5..4188565617 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/DataComponentTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/DataComponentTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class DataComponentTypeKeys { /** * {@code minecraft:attribute_modifiers} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java index 7ee0bc9af8..ab5027919d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/EnchantmentKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class EnchantmentKeys { /** * {@code minecraft:aqua_affinity} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java index a8ae49dddd..0a7b755b2e 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FluidKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class FluidKeys { /** * {@code minecraft:empty} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java index b3025b4077..09b23048cd 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/FrogVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class FrogVariantKeys { /** * {@code minecraft:cold} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java index c4116b607e..8e6ff8500e 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/GameEventKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class GameEventKeys { /** * {@code minecraft:block_activate} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java index d5c9c9448c..2650965e1a 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/InstrumentKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class InstrumentKeys { /** * {@code minecraft:admire_goat_horn} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java index eb25a7ee06..00e3e6acc1 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/ItemTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class ItemTypeKeys { /** * {@code minecraft:acacia_boat} @@ -746,6 +746,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BLACK_GLAZED_TERRACOTTA = create(key("black_glazed_terracotta")); + /** + * {@code minecraft:black_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLACK_HARNESS = create(key("black_harness")); + /** * {@code minecraft:black_shulker_box} * @@ -914,6 +921,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BLUE_GLAZED_TERRACOTTA = create(key("blue_glazed_terracotta")); + /** + * {@code minecraft:blue_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLUE_HARNESS = create(key("blue_harness")); + /** * {@code minecraft:blue_ice} * @@ -1194,6 +1208,13 @@ public final class ItemTypeKeys { */ public static final TypedKey BROWN_GLAZED_TERRACOTTA = create(key("brown_glazed_terracotta")); + /** + * {@code minecraft:brown_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BROWN_HARNESS = create(key("brown_harness")); + /** * {@code minecraft:brown_mushroom} * @@ -2356,6 +2377,13 @@ public final class ItemTypeKeys { */ public static final TypedKey CYAN_GLAZED_TERRACOTTA = create(key("cyan_glazed_terracotta")); + /** + * {@code minecraft:cyan_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey CYAN_HARNESS = create(key("cyan_harness")); + /** * {@code minecraft:cyan_shulker_box} * @@ -2944,6 +2972,20 @@ public final class ItemTypeKeys { */ public static final TypedKey DIRT_PATH = create(key("dirt_path")); + /** + * {@code minecraft:disc_fragment_5} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DISC_FRAGMENT_5 = create(key("disc_fragment_5")); + + /** + * {@code minecraft:dispenser} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DISPENSER = create(key("dispenser")); + /** * {@code minecraft:dolphin_spawn_egg} * @@ -2965,6 +3007,13 @@ public final class ItemTypeKeys { */ public static final TypedKey DRAGON_BREATH = create(key("dragon_breath")); + /** + * {@code minecraft:dragon_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DRAGON_EGG = create(key("dragon_egg")); + /** * {@code minecraft:dragon_head} * @@ -2973,382 +3022,11 @@ public final class ItemTypeKeys { public static final TypedKey DRAGON_HEAD = create(key("dragon_head")); /** - * {@code minecraft:drowned_spawn_egg} + * {@code minecraft:dried_ghast} * * @apiNote This field is version-dependant and may be removed in future Minecraft versions */ - public static final TypedKey DROWNED_SPAWN_EGG = create(key("drowned_spawn_egg")); - - /** - * {@code minecraft:elder_guardian_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ELDER_GUARDIAN_SPAWN_EGG = create(key("elder_guardian_spawn_egg")); - - /** - * {@code minecraft:enchanted_book} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENCHANTED_BOOK = create(key("enchanted_book")); - - /** - * {@code minecraft:end_crystal} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey END_CRYSTAL = create(key("end_crystal")); - - /** - * {@code minecraft:ender_dragon_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENDER_DRAGON_SPAWN_EGG = create(key("ender_dragon_spawn_egg")); - - /** - * {@code minecraft:ender_eye} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENDER_EYE = create(key("ender_eye")); - - /** - * {@code minecraft:enderman_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENDERMAN_SPAWN_EGG = create(key("enderman_spawn_egg")); - - /** - * {@code minecraft:endermite_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENDERMITE_SPAWN_EGG = create(key("endermite_spawn_egg")); - - /** - * {@code minecraft:evoker_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EVOKER_SPAWN_EGG = create(key("evoker_spawn_egg")); - - /** - * {@code minecraft:experience_bottle} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey EXPERIENCE_BOTTLE = create(key("experience_bottle")); - - /** - * {@code minecraft:fermented_spider_eye} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FERMENTED_SPIDER_EYE = create(key("fermented_spider_eye")); - - /** - * {@code minecraft:fire_charge} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FIRE_CHARGE = create(key("fire_charge")); - - /** - * {@code minecraft:firework_rocket} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FIREWORK_ROCKET = create(key("firework_rocket")); - - /** - * {@code minecraft:firework_star} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FIREWORK_STAR = create(key("firework_star")); - - /** - * {@code minecraft:flow_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOW_BANNER_PATTERN = create(key("flow_banner_pattern")); - - /** - * {@code minecraft:flower_banner_pattern} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOWER_BANNER_PATTERN = create(key("flower_banner_pattern")); - - /** - * {@code minecraft:flower_pot} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FLOWER_POT = create(key("flower_pot")); - - /** - * {@code minecraft:fox_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FOX_SPAWN_EGG = create(key("fox_spawn_egg")); - - /** - * {@code minecraft:frog_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey FROG_SPAWN_EGG = create(key("frog_spawn_egg")); - - /** - * {@code minecraft:ghast_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GHAST_SPAWN_EGG = create(key("ghast_spawn_egg")); - - /** - * {@code minecraft:glass_bottle} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLASS_BOTTLE = create(key("glass_bottle")); - - /** - * {@code minecraft:glistering_melon_slice} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLISTERING_MELON_SLICE = create(key("glistering_melon_slice")); - - /** - * {@code minecraft:glow_item_frame} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLOW_ITEM_FRAME = create(key("glow_item_frame")); - - /** - * {@code minecraft:glow_squid_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GLOW_SQUID_SPAWN_EGG = create(key("glow_squid_spawn_egg")); - - /** - * {@code minecraft:goat_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GOAT_SPAWN_EGG = create(key("goat_spawn_egg")); - - /** - * {@code minecraft:gold_nugget} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GOLD_NUGGET = create(key("gold_nugget")); - - /** - * {@code minecraft:golden_carrot} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GOLDEN_CARROT = create(key("golden_carrot")); - - /** - * {@code minecraft:golden_horse_armor} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GOLDEN_HORSE_ARMOR = create(key("golden_horse_armor")); - - /** - * {@code minecraft:gray_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GRAY_BANNER = create(key("gray_banner")); - - /** - * {@code minecraft:green_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GREEN_BANNER = create(key("green_banner")); - - /** - * {@code minecraft:guardian_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey GUARDIAN_SPAWN_EGG = create(key("guardian_spawn_egg")); - - /** - * {@code minecraft:hoglin_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HOGLIN_SPAWN_EGG = create(key("hoglin_spawn_egg")); - - /** - * {@code minecraft:horse_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HORSE_SPAWN_EGG = create(key("horse_spawn_egg")); - - /** - * {@code minecraft:husk_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey HUSK_SPAWN_EGG = create(key("husk_spawn_egg")); - - /** - * {@code minecraft:iron_golem_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey IRON_GOLEM_SPAWN_EGG = create(key("iron_golem_spawn_egg")); - - /** - * {@code minecraft:iron_horse_armor} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey IRON_HORSE_ARMOR = create(key("iron_horse_armor")); - - /** - * {@code minecraft:item_frame} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ITEM_FRAME = create(key("item_frame")); - - /** - * {@code minecraft:lead} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LEAD = create(key("lead")); - - /** - * {@code minecraft:leather_horse_armor} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LEATHER_HORSE_ARMOR = create(key("leather_horse_armor")); - - /** - * {@code minecraft:light_blue_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LIGHT_BLUE_BANNER = create(key("light_blue_banner")); - - /** - * {@code minecraft:light_gray_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LIGHT_GRAY_BANNER = create(key("light_gray_banner")); - - /** - * {@code minecraft:lime_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LIME_BANNER = create(key("lime_banner")); - - /** - * {@code minecraft:llama_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey LLAMA_SPAWN_EGG = create(key("llama_spawn_egg")); - - /** - * {@code minecraft:mace} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MACE = create(key("mace")); - - /** - * {@code minecraft:magenta_banner} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MAGENTA_BANNER = create(key("magenta_banner")); - - /** - * {@code minecraft:magma_cream} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MAGMA_CREAM = create(key("magma_cream")); - - /** - * {@code minecraft:magma_cube_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MAGMA_CUBE_SPAWN_EGG = create(key("magma_cube_spawn_egg")); - - /** - * {@code minecraft:map} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MAP = create(key("map")); - - /** - * {@code minecraft:mooshroom_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MOOSHROOM_SPAWN_EGG = create(key("mooshroom_spawn_egg")); - - /** - * {@code minecraft:mule_spawn_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MULE_SPAWN_EGG = create(key("mule_spawn_egg")); - - /** - * {@code minecraft:music_disc_5} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey MUSIC_DISC_5 = create(key("music_disc_5")); - - /** - * {@code minecraft:disc_fragment_5} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey DISC_FRAGMENT_5 = create(key("disc_fragment_5")); - - /** - * {@code minecraft:dispenser} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey DISPENSER = create(key("dispenser")); - - /** - * {@code minecraft:dragon_egg} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey DRAGON_EGG = create(key("dragon_egg")); + public static final TypedKey DRIED_GHAST = create(key("dried_ghast")); /** * {@code minecraft:dried_kelp} @@ -3378,6 +3056,13 @@ public final class ItemTypeKeys { */ public static final TypedKey DROPPER = create(key("dropper")); + /** + * {@code minecraft:drowned_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey DROWNED_SPAWN_EGG = create(key("drowned_spawn_egg")); + /** * {@code minecraft:dune_armor_trim_smithing_template} * @@ -3399,6 +3084,13 @@ public final class ItemTypeKeys { */ public static final TypedKey EGG = create(key("egg")); + /** + * {@code minecraft:elder_guardian_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ELDER_GUARDIAN_SPAWN_EGG = create(key("elder_guardian_spawn_egg")); + /** * {@code minecraft:elytra} * @@ -3427,6 +3119,13 @@ public final class ItemTypeKeys { */ public static final TypedKey EMERALD_ORE = create(key("emerald_ore")); + /** + * {@code minecraft:enchanted_book} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENCHANTED_BOOK = create(key("enchanted_book")); + /** * {@code minecraft:enchanted_golden_apple} * @@ -3441,6 +3140,13 @@ public final class ItemTypeKeys { */ public static final TypedKey ENCHANTING_TABLE = create(key("enchanting_table")); + /** + * {@code minecraft:end_crystal} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey END_CRYSTAL = create(key("end_crystal")); + /** * {@code minecraft:end_portal_frame} * @@ -3497,6 +3203,20 @@ public final class ItemTypeKeys { */ public static final TypedKey ENDER_CHEST = create(key("ender_chest")); + /** + * {@code minecraft:ender_dragon_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENDER_DRAGON_SPAWN_EGG = create(key("ender_dragon_spawn_egg")); + + /** + * {@code minecraft:ender_eye} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENDER_EYE = create(key("ender_eye")); + /** * {@code minecraft:ender_pearl} * @@ -3504,6 +3224,34 @@ public final class ItemTypeKeys { */ public static final TypedKey ENDER_PEARL = create(key("ender_pearl")); + /** + * {@code minecraft:enderman_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENDERMAN_SPAWN_EGG = create(key("enderman_spawn_egg")); + + /** + * {@code minecraft:endermite_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENDERMITE_SPAWN_EGG = create(key("endermite_spawn_egg")); + + /** + * {@code minecraft:evoker_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EVOKER_SPAWN_EGG = create(key("evoker_spawn_egg")); + + /** + * {@code minecraft:experience_bottle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey EXPERIENCE_BOTTLE = create(key("experience_bottle")); + /** * {@code minecraft:explorer_pottery_sherd} * @@ -3595,6 +3343,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FEATHER = create(key("feather")); + /** + * {@code minecraft:fermented_spider_eye} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FERMENTED_SPIDER_EYE = create(key("fermented_spider_eye")); + /** * {@code minecraft:fern} * @@ -3616,6 +3371,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FILLED_MAP = create(key("filled_map")); + /** + * {@code minecraft:fire_charge} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FIRE_CHARGE = create(key("fire_charge")); + /** * {@code minecraft:fire_coral} * @@ -3644,6 +3406,20 @@ public final class ItemTypeKeys { */ public static final TypedKey FIREFLY_BUSH = create(key("firefly_bush")); + /** + * {@code minecraft:firework_rocket} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FIREWORK_ROCKET = create(key("firework_rocket")); + + /** + * {@code minecraft:firework_star} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FIREWORK_STAR = create(key("firework_star")); + /** * {@code minecraft:fishing_rod} * @@ -3679,6 +3455,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FLOW_ARMOR_TRIM_SMITHING_TEMPLATE = create(key("flow_armor_trim_smithing_template")); + /** + * {@code minecraft:flow_banner_pattern} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FLOW_BANNER_PATTERN = create(key("flow_banner_pattern")); + /** * {@code minecraft:flow_pottery_sherd} * @@ -3686,6 +3469,20 @@ public final class ItemTypeKeys { */ public static final TypedKey FLOW_POTTERY_SHERD = create(key("flow_pottery_sherd")); + /** + * {@code minecraft:flower_banner_pattern} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FLOWER_BANNER_PATTERN = create(key("flower_banner_pattern")); + + /** + * {@code minecraft:flower_pot} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FLOWER_POT = create(key("flower_pot")); + /** * {@code minecraft:flowering_azalea} * @@ -3700,6 +3497,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FLOWERING_AZALEA_LEAVES = create(key("flowering_azalea_leaves")); + /** + * {@code minecraft:fox_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FOX_SPAWN_EGG = create(key("fox_spawn_egg")); + /** * {@code minecraft:friend_pottery_sherd} * @@ -3707,6 +3511,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FRIEND_POTTERY_SHERD = create(key("friend_pottery_sherd")); + /** + * {@code minecraft:frog_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey FROG_SPAWN_EGG = create(key("frog_spawn_egg")); + /** * {@code minecraft:frogspawn} * @@ -3728,6 +3539,13 @@ public final class ItemTypeKeys { */ public static final TypedKey FURNACE_MINECART = create(key("furnace_minecart")); + /** + * {@code minecraft:ghast_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GHAST_SPAWN_EGG = create(key("ghast_spawn_egg")); + /** * {@code minecraft:ghast_tear} * @@ -3749,6 +3567,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GLASS = create(key("glass")); + /** + * {@code minecraft:glass_bottle} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GLASS_BOTTLE = create(key("glass_bottle")); + /** * {@code minecraft:glass_pane} * @@ -3756,6 +3581,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GLASS_PANE = create(key("glass_pane")); + /** + * {@code minecraft:glistering_melon_slice} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GLISTERING_MELON_SLICE = create(key("glistering_melon_slice")); + /** * {@code minecraft:globe_banner_pattern} * @@ -3777,6 +3609,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GLOW_INK_SAC = create(key("glow_ink_sac")); + /** + * {@code minecraft:glow_item_frame} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GLOW_ITEM_FRAME = create(key("glow_item_frame")); + /** * {@code minecraft:glow_lichen} * @@ -3784,6 +3623,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GLOW_LICHEN = create(key("glow_lichen")); + /** + * {@code minecraft:glow_squid_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GLOW_SQUID_SPAWN_EGG = create(key("glow_squid_spawn_egg")); + /** * {@code minecraft:glowstone} * @@ -3805,6 +3651,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GOAT_HORN = create(key("goat_horn")); + /** + * {@code minecraft:goat_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GOAT_SPAWN_EGG = create(key("goat_spawn_egg")); + /** * {@code minecraft:gold_block} * @@ -3819,6 +3672,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GOLD_INGOT = create(key("gold_ingot")); + /** + * {@code minecraft:gold_nugget} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GOLD_NUGGET = create(key("gold_nugget")); + /** * {@code minecraft:gold_ore} * @@ -3847,6 +3707,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GOLDEN_BOOTS = create(key("golden_boots")); + /** + * {@code minecraft:golden_carrot} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GOLDEN_CARROT = create(key("golden_carrot")); + /** * {@code minecraft:golden_chestplate} * @@ -3868,6 +3735,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GOLDEN_HOE = create(key("golden_hoe")); + /** + * {@code minecraft:golden_horse_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GOLDEN_HORSE_ARMOR = create(key("golden_horse_armor")); + /** * {@code minecraft:golden_leggings} * @@ -3938,6 +3812,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GRAVEL = create(key("gravel")); + /** + * {@code minecraft:gray_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GRAY_BANNER = create(key("gray_banner")); + /** * {@code minecraft:gray_bed} * @@ -3994,6 +3875,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GRAY_GLAZED_TERRACOTTA = create(key("gray_glazed_terracotta")); + /** + * {@code minecraft:gray_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GRAY_HARNESS = create(key("gray_harness")); + /** * {@code minecraft:gray_shulker_box} * @@ -4029,6 +3917,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GRAY_WOOL = create(key("gray_wool")); + /** + * {@code minecraft:green_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GREEN_BANNER = create(key("green_banner")); + /** * {@code minecraft:green_bed} * @@ -4085,6 +3980,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GREEN_GLAZED_TERRACOTTA = create(key("green_glazed_terracotta")); + /** + * {@code minecraft:green_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GREEN_HARNESS = create(key("green_harness")); + /** * {@code minecraft:green_shulker_box} * @@ -4127,6 +4029,13 @@ public final class ItemTypeKeys { */ public static final TypedKey GRINDSTONE = create(key("grindstone")); + /** + * {@code minecraft:guardian_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey GUARDIAN_SPAWN_EGG = create(key("guardian_spawn_egg")); + /** * {@code minecraft:gunpowder} * @@ -4155,6 +4064,13 @@ public final class ItemTypeKeys { */ public static final TypedKey HANGING_ROOTS = create(key("hanging_roots")); + /** + * {@code minecraft:happy_ghast_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey HAPPY_GHAST_SPAWN_EGG = create(key("happy_ghast_spawn_egg")); + /** * {@code minecraft:hay_block} * @@ -4197,6 +4113,13 @@ public final class ItemTypeKeys { */ public static final TypedKey HEAVY_WEIGHTED_PRESSURE_PLATE = create(key("heavy_weighted_pressure_plate")); + /** + * {@code minecraft:hoglin_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey HOGLIN_SPAWN_EGG = create(key("hoglin_spawn_egg")); + /** * {@code minecraft:honey_block} * @@ -4260,6 +4183,13 @@ public final class ItemTypeKeys { */ public static final TypedKey HORN_CORAL_FAN = create(key("horn_coral_fan")); + /** + * {@code minecraft:horse_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey HORSE_SPAWN_EGG = create(key("horse_spawn_egg")); + /** * {@code minecraft:host_armor_trim_smithing_template} * @@ -4274,6 +4204,13 @@ public final class ItemTypeKeys { */ public static final TypedKey HOWL_POTTERY_SHERD = create(key("howl_pottery_sherd")); + /** + * {@code minecraft:husk_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey HUSK_SPAWN_EGG = create(key("husk_spawn_egg")); + /** * {@code minecraft:ice} * @@ -4379,6 +4316,13 @@ public final class ItemTypeKeys { */ public static final TypedKey IRON_DOOR = create(key("iron_door")); + /** + * {@code minecraft:iron_golem_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey IRON_GOLEM_SPAWN_EGG = create(key("iron_golem_spawn_egg")); + /** * {@code minecraft:iron_helmet} * @@ -4393,6 +4337,13 @@ public final class ItemTypeKeys { */ public static final TypedKey IRON_HOE = create(key("iron_hoe")); + /** + * {@code minecraft:iron_horse_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey IRON_HORSE_ARMOR = create(key("iron_horse_armor")); + /** * {@code minecraft:iron_ingot} * @@ -4449,6 +4400,13 @@ public final class ItemTypeKeys { */ public static final TypedKey IRON_TRAPDOOR = create(key("iron_trapdoor")); + /** + * {@code minecraft:item_frame} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_FRAME = create(key("item_frame")); + /** * {@code minecraft:jack_o_lantern} * @@ -4659,6 +4617,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LAVA_BUCKET = create(key("lava_bucket")); + /** + * {@code minecraft:lead} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LEAD = create(key("lead")); + /** * {@code minecraft:leaf_litter} * @@ -4694,6 +4659,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LEATHER_HELMET = create(key("leather_helmet")); + /** + * {@code minecraft:leather_horse_armor} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LEATHER_HORSE_ARMOR = create(key("leather_horse_armor")); + /** * {@code minecraft:leather_leggings} * @@ -4722,6 +4694,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LIGHT = create(key("light")); + /** + * {@code minecraft:light_blue_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_BLUE_BANNER = create(key("light_blue_banner")); + /** * {@code minecraft:light_blue_bed} * @@ -4778,6 +4757,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LIGHT_BLUE_GLAZED_TERRACOTTA = create(key("light_blue_glazed_terracotta")); + /** + * {@code minecraft:light_blue_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_BLUE_HARNESS = create(key("light_blue_harness")); + /** * {@code minecraft:light_blue_shulker_box} * @@ -4813,6 +4799,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LIGHT_BLUE_WOOL = create(key("light_blue_wool")); + /** + * {@code minecraft:light_gray_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_GRAY_BANNER = create(key("light_gray_banner")); + /** * {@code minecraft:light_gray_bed} * @@ -4869,6 +4862,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LIGHT_GRAY_GLAZED_TERRACOTTA = create(key("light_gray_glazed_terracotta")); + /** + * {@code minecraft:light_gray_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIGHT_GRAY_HARNESS = create(key("light_gray_harness")); + /** * {@code minecraft:light_gray_shulker_box} * @@ -4939,6 +4939,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LILY_PAD = create(key("lily_pad")); + /** + * {@code minecraft:lime_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIME_BANNER = create(key("lime_banner")); + /** * {@code minecraft:lime_bed} * @@ -4995,6 +5002,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LIME_GLAZED_TERRACOTTA = create(key("lime_glazed_terracotta")); + /** + * {@code minecraft:lime_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LIME_HARNESS = create(key("lime_harness")); + /** * {@code minecraft:lime_shulker_box} * @@ -5037,6 +5051,13 @@ public final class ItemTypeKeys { */ public static final TypedKey LINGERING_POTION = create(key("lingering_potion")); + /** + * {@code minecraft:llama_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey LLAMA_SPAWN_EGG = create(key("llama_spawn_egg")); + /** * {@code minecraft:lodestone} * @@ -5051,6 +5072,20 @@ public final class ItemTypeKeys { */ public static final TypedKey LOOM = create(key("loom")); + /** + * {@code minecraft:mace} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MACE = create(key("mace")); + + /** + * {@code minecraft:magenta_banner} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGENTA_BANNER = create(key("magenta_banner")); + /** * {@code minecraft:magenta_bed} * @@ -5107,6 +5142,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MAGENTA_GLAZED_TERRACOTTA = create(key("magenta_glazed_terracotta")); + /** + * {@code minecraft:magenta_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGENTA_HARNESS = create(key("magenta_harness")); + /** * {@code minecraft:magenta_shulker_box} * @@ -5149,6 +5191,20 @@ public final class ItemTypeKeys { */ public static final TypedKey MAGMA_BLOCK = create(key("magma_block")); + /** + * {@code minecraft:magma_cream} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGMA_CREAM = create(key("magma_cream")); + + /** + * {@code minecraft:magma_cube_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAGMA_CUBE_SPAWN_EGG = create(key("magma_cube_spawn_egg")); + /** * {@code minecraft:mangrove_boat} * @@ -5275,6 +5331,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MANGROVE_WOOD = create(key("mangrove_wood")); + /** + * {@code minecraft:map} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MAP = create(key("map")); + /** * {@code minecraft:medium_amethyst_bud} * @@ -5331,6 +5394,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MOJANG_BANNER_PATTERN = create(key("mojang_banner_pattern")); + /** + * {@code minecraft:mooshroom_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MOOSHROOM_SPAWN_EGG = create(key("mooshroom_spawn_egg")); + /** * {@code minecraft:moss_block} * @@ -5450,6 +5520,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MUDDY_MANGROVE_ROOTS = create(key("muddy_mangrove_roots")); + /** + * {@code minecraft:mule_spawn_egg} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MULE_SPAWN_EGG = create(key("mule_spawn_egg")); + /** * {@code minecraft:mushroom_stem} * @@ -5464,6 +5541,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MUSHROOM_STEW = create(key("mushroom_stew")); + /** + * {@code minecraft:music_disc_5} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MUSIC_DISC_5 = create(key("music_disc_5")); + /** * {@code minecraft:music_disc_11} * @@ -5576,6 +5660,13 @@ public final class ItemTypeKeys { */ public static final TypedKey MUSIC_DISC_STRAD = create(key("music_disc_strad")); + /** + * {@code minecraft:music_disc_tears} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MUSIC_DISC_TEARS = create(key("music_disc_tears")); + /** * {@code minecraft:music_disc_wait} * @@ -6038,6 +6129,13 @@ public final class ItemTypeKeys { */ public static final TypedKey ORANGE_GLAZED_TERRACOTTA = create(key("orange_glazed_terracotta")); + /** + * {@code minecraft:orange_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ORANGE_HARNESS = create(key("orange_harness")); + /** * {@code minecraft:orange_shulker_box} * @@ -6472,6 +6570,13 @@ public final class ItemTypeKeys { */ public static final TypedKey PINK_GLAZED_TERRACOTTA = create(key("pink_glazed_terracotta")); + /** + * {@code minecraft:pink_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey PINK_HARNESS = create(key("pink_harness")); + /** * {@code minecraft:pink_petals} * @@ -7004,6 +7109,13 @@ public final class ItemTypeKeys { */ public static final TypedKey PURPLE_GLAZED_TERRACOTTA = create(key("purple_glazed_terracotta")); + /** + * {@code minecraft:purple_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey PURPLE_HARNESS = create(key("purple_harness")); + /** * {@code minecraft:purple_shulker_box} * @@ -7277,6 +7389,13 @@ public final class ItemTypeKeys { */ public static final TypedKey RED_GLAZED_TERRACOTTA = create(key("red_glazed_terracotta")); + /** + * {@code minecraft:red_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey RED_HARNESS = create(key("red_harness")); + /** * {@code minecraft:red_mushroom} * @@ -9496,6 +9615,13 @@ public final class ItemTypeKeys { */ public static final TypedKey WHITE_GLAZED_TERRACOTTA = create(key("white_glazed_terracotta")); + /** + * {@code minecraft:white_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey WHITE_HARNESS = create(key("white_harness")); + /** * {@code minecraft:white_shulker_box} * @@ -9720,6 +9846,13 @@ public final class ItemTypeKeys { */ public static final TypedKey YELLOW_GLAZED_TERRACOTTA = create(key("yellow_glazed_terracotta")); + /** + * {@code minecraft:yellow_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey YELLOW_HARNESS = create(key("yellow_harness")); + /** * {@code minecraft:yellow_shulker_box} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java index 75ec654732..bc6563ef3d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/JukeboxSongKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class JukeboxSongKeys { /** * {@code minecraft:11} @@ -144,6 +144,13 @@ public final class JukeboxSongKeys { */ public static final TypedKey STRAD = create(key("strad")); + /** + * {@code minecraft:tears} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey TEARS = create(key("tears")); + /** * {@code minecraft:wait} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java index 4c01a72cb6..fbeab9c679 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MapDecorationTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class MapDecorationTypeKeys { /** * {@code minecraft:banner_black} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java index 4f0f994944..ae92cd963f 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MenuTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class MenuTypeKeys { /** * {@code minecraft:anvil} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java index c3d211d275..9e27edd259 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/MobEffectKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class MobEffectKeys { /** * {@code minecraft:absorption} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java index c7d6e1e53a..f6335a0066 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PaintingVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class PaintingVariantKeys { /** * {@code minecraft:alban} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PigVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PigVariantKeys.java index ea29ff7991..bbe070a1f4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/PigVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/PigVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class PigVariantKeys { /** * {@code minecraft:cold} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java index 6493f649a1..c633990cfa 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/SoundEventKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class SoundEventKeys { /** * {@code minecraft:ambient.basalt_deltas.additions} @@ -1929,6 +1929,62 @@ public final class SoundEventKeys { */ public static final TypedKey BLOCK_DISPENSER_LAUNCH = create(key("block.dispenser.launch")); + /** + * {@code minecraft:block.dried_ghast.ambient} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_AMBIENT = create(key("block.dried_ghast.ambient")); + + /** + * {@code minecraft:block.dried_ghast.ambient_water} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_AMBIENT_WATER = create(key("block.dried_ghast.ambient_water")); + + /** + * {@code minecraft:block.dried_ghast.break} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_BREAK = create(key("block.dried_ghast.break")); + + /** + * {@code minecraft:block.dried_ghast.fall} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_FALL = create(key("block.dried_ghast.fall")); + + /** + * {@code minecraft:block.dried_ghast.place} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_PLACE = create(key("block.dried_ghast.place")); + + /** + * {@code minecraft:block.dried_ghast.place_in_water} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_PLACE_IN_WATER = create(key("block.dried_ghast.place_in_water")); + + /** + * {@code minecraft:block.dried_ghast.step} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_STEP = create(key("block.dried_ghast.step")); + + /** + * {@code minecraft:block.dried_ghast.transition} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRIED_GHAST_TRANSITION = create(key("block.dried_ghast.transition")); + /** * {@code minecraft:block.dripstone_block.break} * @@ -1964,6 +2020,13 @@ public final class SoundEventKeys { */ public static final TypedKey BLOCK_DRIPSTONE_BLOCK_STEP = create(key("block.dripstone_block.step")); + /** + * {@code minecraft:block.dry_grass.ambient} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey BLOCK_DRY_GRASS_AMBIENT = create(key("block.dry_grass.ambient")); + /** * {@code minecraft:block.enchantment_table.use} * @@ -4113,13 +4176,6 @@ public final class SoundEventKeys { */ public static final TypedKey BLOCK_SAND_STEP = create(key("block.sand.step")); - /** - * {@code minecraft:block.sand.wind} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey BLOCK_SAND_WIND = create(key("block.sand.wind")); - /** * {@code minecraft:block.scaffolding.break} * @@ -7207,6 +7263,34 @@ public final class SoundEventKeys { */ public static final TypedKey ENTITY_GHAST_WARN = create(key("entity.ghast.warn")); + /** + * {@code minecraft:entity.ghastling.ambient} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_GHASTLING_AMBIENT = create(key("entity.ghastling.ambient")); + + /** + * {@code minecraft:entity.ghastling.death} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_GHASTLING_DEATH = create(key("entity.ghastling.death")); + + /** + * {@code minecraft:entity.ghastling.hurt} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_GHASTLING_HURT = create(key("entity.ghastling.hurt")); + + /** + * {@code minecraft:entity.ghastling.spawn} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_GHASTLING_SPAWN = create(key("entity.ghastling.spawn")); + /** * {@code minecraft:entity.glow_item_frame.add_item} * @@ -7452,6 +7536,62 @@ public final class SoundEventKeys { */ public static final TypedKey ENTITY_GUARDIAN_HURT_LAND = create(key("entity.guardian.hurt_land")); + /** + * {@code minecraft:entity.happy_ghast.ambient} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_AMBIENT = create(key("entity.happy_ghast.ambient")); + + /** + * {@code minecraft:entity.happy_ghast.death} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_DEATH = create(key("entity.happy_ghast.death")); + + /** + * {@code minecraft:entity.happy_ghast.equip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_EQUIP = create(key("entity.happy_ghast.equip")); + + /** + * {@code minecraft:entity.happy_ghast.harness_goggles_down} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_HARNESS_GOGGLES_DOWN = create(key("entity.happy_ghast.harness_goggles_down")); + + /** + * {@code minecraft:entity.happy_ghast.harness_goggles_up} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_HARNESS_GOGGLES_UP = create(key("entity.happy_ghast.harness_goggles_up")); + + /** + * {@code minecraft:entity.happy_ghast.hurt} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_HURT = create(key("entity.happy_ghast.hurt")); + + /** + * {@code minecraft:entity.happy_ghast.riding} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_RIDING = create(key("entity.happy_ghast.riding")); + + /** + * {@code minecraft:entity.happy_ghast.unequip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ENTITY_HAPPY_GHAST_UNEQUIP = create(key("entity.happy_ghast.unequip")); + /** * {@code minecraft:entity.hoglin.ambient} * @@ -7816,20 +7956,6 @@ public final class SoundEventKeys { */ public static final TypedKey ENTITY_ITEM_FRAME_ROTATE_ITEM = create(key("entity.item_frame.rotate_item")); - /** - * {@code minecraft:entity.leash_knot.break} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENTITY_LEASH_KNOT_BREAK = create(key("entity.leash_knot.break")); - - /** - * {@code minecraft:entity.leash_knot.place} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENTITY_LEASH_KNOT_PLACE = create(key("entity.leash_knot.place")); - /** * {@code minecraft:entity.lightning_bolt.impact} * @@ -8880,13 +9006,6 @@ public final class SoundEventKeys { */ public static final TypedKey ENTITY_POLAR_BEAR_WARNING = create(key("entity.polar_bear.warning")); - /** - * {@code minecraft:entity.puffer_fish.ambient} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TypedKey ENTITY_PUFFER_FISH_AMBIENT = create(key("entity.puffer_fish.ambient")); - /** * {@code minecraft:entity.puffer_fish.blow_out} * @@ -11323,6 +11442,13 @@ public final class SoundEventKeys { */ public static final TypedKey ITEM_HONEYCOMB_WAX_ON = create(key("item.honeycomb.wax_on")); + /** + * {@code minecraft:item.horse_armor.unequip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_HORSE_ARMOR_UNEQUIP = create(key("item.horse_armor.unequip")); + /** * {@code minecraft:item.ink_sac.use} * @@ -11330,6 +11456,34 @@ public final class SoundEventKeys { */ public static final TypedKey ITEM_INK_SAC_USE = create(key("item.ink_sac.use")); + /** + * {@code minecraft:item.lead.break} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_LEAD_BREAK = create(key("item.lead.break")); + + /** + * {@code minecraft:item.lead.tied} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_LEAD_TIED = create(key("item.lead.tied")); + + /** + * {@code minecraft:item.lead.untied} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_LEAD_UNTIED = create(key("item.lead.untied")); + + /** + * {@code minecraft:item.llama_carpet.unequip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_LLAMA_CARPET_UNEQUIP = create(key("item.llama_carpet.unequip")); + /** * {@code minecraft:item.lodestone_compass.lock} * @@ -11372,6 +11526,20 @@ public final class SoundEventKeys { */ public static final TypedKey ITEM_OMINOUS_BOTTLE_DISPOSE = create(key("item.ominous_bottle.dispose")); + /** + * {@code minecraft:item.saddle.unequip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_SADDLE_UNEQUIP = create(key("item.saddle.unequip")); + + /** + * {@code minecraft:item.shears.snip} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey ITEM_SHEARS_SNIP = create(key("item.shears.snip")); + /** * {@code minecraft:item.shield.block} * @@ -11834,6 +12002,13 @@ public final class SoundEventKeys { */ public static final TypedKey MUSIC_DISC_STRAD = create(key("music_disc.strad")); + /** + * {@code minecraft:music_disc.tears} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TypedKey MUSIC_DISC_TEARS = create(key("music_disc.tears")); + /** * {@code minecraft:music_disc.wait} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java index fb06b1cdda..77d4c390eb 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class StructureKeys { /** * {@code minecraft:ancient_city} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java index 940d54486e..107e08b553 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/StructureTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class StructureTypeKeys { /** * {@code minecraft:buried_treasure} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java index 6bea6ac6c7..48a87522bc 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimMaterialKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class TrimMaterialKeys { /** * {@code minecraft:amethyst} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java index 94ce37d29f..c3648ce3f9 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/TrimPatternKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class TrimPatternKeys { /** * {@code minecraft:bolt} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java index 95416da96c..75ccfb1764 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerProfessionKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class VillagerProfessionKeys { /** * {@code minecraft:armorer} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java index 9c629dcda5..b0a1bc7cd5 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/VillagerTypeKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class VillagerTypeKeys { /** * {@code minecraft:desert} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfSoundVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfSoundVariantKeys.java index 4bcdeb3d09..ad2deff48c 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfSoundVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfSoundVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class WolfSoundVariantKeys { /** * {@code minecraft:angry} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java index c291debdd4..07550fe27a 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/WolfVariantKeys.java @@ -23,7 +23,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public final class WolfVariantKeys { /** * {@code minecraft:ashen} diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java index a62b2e1ef7..b6f863e246 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BannerPatternTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class BannerPatternTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java index 96d90dd15d..56bff76f1f 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BiomeTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class BiomeTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java index 0ba91ccde5..e58280becf 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/BlockTypeTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class BlockTypeTagKeys { /** @@ -580,6 +580,13 @@ public final class BlockTypeTagKeys { */ public static final TagKey GUARDED_BY_PIGLINS = create(key("guarded_by_piglins")); + /** + * {@code #minecraft:happy_ghast_avoids} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey HAPPY_GHAST_AVOIDS = create(key("happy_ghast_avoids")); + /** * {@code #minecraft:hoglin_repellents} * @@ -909,13 +916,6 @@ public final class BlockTypeTagKeys { */ public static final TagKey PLANKS = create(key("planks")); - /** - * {@code #minecraft:plays_ambient_desert_block_sounds} - * - * @apiNote This field is version-dependant and may be removed in future Minecraft versions - */ - public static final TagKey PLAYS_AMBIENT_DESERT_BLOCK_SOUNDS = create(key("plays_ambient_desert_block_sounds")); - /** * {@code #minecraft:polar_bears_spawnable_on_alternate} * @@ -1203,6 +1203,27 @@ public final class BlockTypeTagKeys { */ public static final TagKey TRAPDOORS = create(key("trapdoors")); + /** + * {@code #minecraft:triggers_ambient_desert_dry_vegetation_block_sounds} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey TRIGGERS_AMBIENT_DESERT_DRY_VEGETATION_BLOCK_SOUNDS = create(key("triggers_ambient_desert_dry_vegetation_block_sounds")); + + /** + * {@code #minecraft:triggers_ambient_desert_sand_block_sounds} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey TRIGGERS_AMBIENT_DESERT_SAND_BLOCK_SOUNDS = create(key("triggers_ambient_desert_sand_block_sounds")); + + /** + * {@code #minecraft:triggers_ambient_dried_ghast_block_sounds} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey TRIGGERS_AMBIENT_DRIED_GHAST_BLOCK_SOUNDS = create(key("triggers_ambient_dried_ghast_block_sounds")); + /** * {@code #minecraft:underwater_bonemeals} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java index cf56bc9083..ef45574a5d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/DamageTypeTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class DamageTypeTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java index 09137b46ce..4a18ce181a 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EnchantmentTagKeys.java @@ -25,7 +25,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class EnchantmentTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java index e1afd736a9..b367695b93 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/EntityTypeTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class EntityTypeTagKeys { /** @@ -83,6 +83,13 @@ public final class EntityTypeTagKeys { */ public static final TagKey CAN_BREATHE_UNDER_WATER = create(key("can_breathe_under_water")); + /** + * {@code #minecraft:can_equip_harness} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey CAN_EQUIP_HARNESS = create(key("can_equip_harness")); + /** * {@code #minecraft:can_equip_saddle} * @@ -125,6 +132,13 @@ public final class EntityTypeTagKeys { */ public static final TagKey FALL_DAMAGE_IMMUNE = create(key("fall_damage_immune")); + /** + * {@code #minecraft:followable_friendly_mobs} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey FOLLOWABLE_FRIENDLY_MOBS = create(key("followable_friendly_mobs")); + /** * {@code #minecraft:freeze_hurts_extra_types} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java index 4e2fc7c7ad..15f7e876d4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/FluidTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class FluidTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java index 3c2b29d663..b2eba6f660 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/GameEventTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class GameEventTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java index e276c3dd59..74b797eb7d 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/InstrumentTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class InstrumentTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java index 4f973490e5..e0eb352bb4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/ItemTypeTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class ItemTypeTagKeys { /** @@ -601,6 +601,27 @@ public final class ItemTypeTagKeys { */ public static final TagKey HANGING_SIGNS = create(key("hanging_signs")); + /** + * {@code #minecraft:happy_ghast_food} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey HAPPY_GHAST_FOOD = create(key("happy_ghast_food")); + + /** + * {@code #minecraft:happy_ghast_tempt_items} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey HAPPY_GHAST_TEMPT_ITEMS = create(key("happy_ghast_tempt_items")); + + /** + * {@code #minecraft:harnesses} + * + * @apiNote This field is version-dependant and may be removed in future Minecraft versions + */ + public static final TagKey HARNESSES = create(key("harnesses")); + /** * {@code #minecraft:head_armor} * diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java index 607d2dd8dc..43bf31d9be 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/PaintingVariantTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class PaintingVariantTagKeys { /** diff --git a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java index 085522c722..cccccae5e4 100644 --- a/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java +++ b/paper-api/src/generated/java/io/papermc/paper/registry/keys/tags/StructureTagKeys.java @@ -24,7 +24,7 @@ import org.jspecify.annotations.NullMarked; "SpellCheckingInspection" }) @NullMarked -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") @ApiStatus.Experimental public final class StructureTagKeys { /** diff --git a/paper-api/src/main/java/com/destroystokyo/paper/MaterialTags.java b/paper-api/src/main/java/com/destroystokyo/paper/MaterialTags.java index f9af51c187..593ba5a700 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/MaterialTags.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/MaterialTags.java @@ -317,7 +317,7 @@ public class MaterialTags { */ public static final MaterialSetTag SPAWN_EGGS = new MaterialSetTag(keyFor("spawn_eggs")) .endsWith("_SPAWN_EGG") - .ensureSize("SPAWN_EGGS", 81).lock(); + .ensureSize("SPAWN_EGGS", 82).lock(); /** * Covers all colors of stained glass. diff --git a/paper-api/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java b/paper-api/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java index 7f9272bcc1..457c938497 100644 --- a/paper-api/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java +++ b/paper-api/src/main/java/com/destroystokyo/paper/entity/ai/GoalKey.java @@ -15,45 +15,46 @@ import org.jspecify.annotations.Nullable; @NullMarked public final class GoalKey { - private final Class entityClass; - private final NamespacedKey namespacedKey; + private final Class type; + private final NamespacedKey key; - private GoalKey(Class entityClass, NamespacedKey namespacedKey) { - this.entityClass = entityClass; - this.namespacedKey = namespacedKey; + private GoalKey(Class type, NamespacedKey key) { + this.type = type; + this.key = key; } public Class getEntityClass() { - return this.entityClass; + return this.type; } public NamespacedKey getNamespacedKey() { - return this.namespacedKey; + return this.key; } @Override public boolean equals(@Nullable Object o) { if (this == o) return true; if (o == null || this.getClass() != o.getClass()) return false; + GoalKey goalKey = (GoalKey) o; - return Objects.equals(this.entityClass, goalKey.entityClass) && - Objects.equals(this.namespacedKey, goalKey.namespacedKey); + return Objects.equals(this.type, goalKey.type) && + Objects.equals(this.key, goalKey.key); } @Override public int hashCode() { - return Objects.hash(this.entityClass, this.namespacedKey); + return Objects.hash(this.type, this.key); } @Override public String toString() { return new StringJoiner(", ", GoalKey.class.getSimpleName() + "[", "]") - .add("entityClass=" + this.entityClass) - .add("namespacedKey=" + this.namespacedKey) + .add("type=" + this.type) + .add("key=" + this.key) .toString(); } - public static GoalKey of(Class entityClass, NamespacedKey namespacedKey) { - return new GoalKey<>(entityClass, namespacedKey); + public static GoalKey of(Class type, NamespacedKey key) { + return new GoalKey<>(type, key); } } diff --git a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java index 3d7429d7e5..cfcf330bc9 100644 --- a/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java +++ b/paper-api/src/main/java/io/papermc/paper/command/brigadier/CommandRegistrationFlag.java @@ -17,7 +17,8 @@ public enum CommandRegistrationFlag { @Deprecated(since = "1.21.4") FLATTEN_ALIASES, /** - * Prevents this command from being sent to the client. + * @deprecated Removed as it causes a warning to appear on the client now. */ + @Deprecated(since = "1.21.6", forRemoval = true) SERVER_ONLY } diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentHolder.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentHolder.java index 8bef6143e4..8c5ffe3b29 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentHolder.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentHolder.java @@ -3,7 +3,6 @@ package io.papermc.paper.datacomponent; import org.bukkit.Utility; import org.bukkit.persistence.PersistentDataContainer; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; import org.jspecify.annotations.NullMarked; /** @@ -23,8 +22,8 @@ public interface DataComponentHolder extends DataComponentView { * @param value type */ @Utility - @org.jetbrains.annotations.ApiStatus.Experimental - public void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued type, final @NotNull io.papermc.paper.datacomponent.DataComponentBuilder valueBuilder); + @ApiStatus.Experimental + void setData(final DataComponentType.Valued type, final DataComponentBuilder valueBuilder); /** * Sets the value of the data component type for this holder. @@ -33,16 +32,16 @@ public interface DataComponentHolder extends DataComponentView { * @param value value to set * @param value type */ - @org.jetbrains.annotations.ApiStatus.Experimental - public void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull Valued type, final @NotNull T value); + @ApiStatus.Experimental + void setData(final DataComponentType.Valued type, final T value); /** * Marks this non-valued data component type as present in this itemstack. * * @param type the data component type */ - @org.jetbrains.annotations.ApiStatus.Experimental - public void setData(final io.papermc.paper.datacomponent.DataComponentType.@NotNull NonValued type); + @ApiStatus.Experimental + void setData(final DataComponentType.NonValued type); // TODO: Do we even want to have the concept of overriding here? Not sure what is going on with entity components } diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java index abcfbc610a..9e7ff539ee 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentTypes.java @@ -364,8 +364,8 @@ public final class DataComponentTypes { public static final DataComponentType.Valued RABBIT_VARIANT = valued("rabbit/variant"); public static final DataComponentType.Valued PIG_VARIANT = valued("pig/variant"); public static final DataComponentType.Valued COW_VARIANT = valued("cow/variant"); - // TODO: This is a eitherholder? Why specifically the chicken?? Oh wait this is prolly for chicken egg cause legacy item loading public static final DataComponentType.Valued CHICKEN_VARIANT = valued("chicken/variant"); + // This is a eitherholder? Why specifically the chicken?? Oh wait this is prolly for chicken egg cause legacy item loading public static final DataComponentType.Valued FROG_VARIANT = valued("frog/variant"); public static final DataComponentType.Valued HORSE_VARIANT = valued("horse/variant"); public static final DataComponentType.Valued PAINTING_VARIANT = valued("painting/variant"); @@ -376,7 +376,6 @@ public final class DataComponentTypes { public static final DataComponentType.Valued SHEEP_COLOR = valued("sheep/color"); public static final DataComponentType.Valued SHULKER_COLOR = valued("shulker/color"); - private static DataComponentType.NonValued unvalued(final String name) { final DataComponentType dataComponentType = requireNonNull(Registry.DATA_COMPONENT_TYPE.get(NamespacedKey.minecraft(name)), name + " unvalued data component type couldn't be found, this is a bug."); if (dataComponentType instanceof DataComponentType.NonValued) { diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentView.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentView.java index f06829efcc..2eebdb41e0 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentView.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/DataComponentView.java @@ -3,9 +3,8 @@ package io.papermc.paper.datacomponent; import org.bukkit.Utility; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; /** * This represents a view of a data component holder. No @@ -23,11 +22,11 @@ public interface DataComponentView { * @param type the data component type * @param the value type * @return the value for the data component type, or {@code null} if not set or marked as removed - * @see #hasData(io.papermc.paper.datacomponent.DataComponentType) for DataComponentType.NonValued + * @see #hasData(DataComponentType) for DataComponentType.NonValued */ @Contract(pure = true) @ApiStatus.Experimental - public @Nullable T getData(final DataComponentType.@NotNull Valued type); + @Nullable T getData(final DataComponentType.Valued type); /** * Gets the value for the data component type on this holder with @@ -41,7 +40,7 @@ public interface DataComponentView { @Utility @Contract(value = "_, !null -> !null", pure = true) @ApiStatus.Experimental - public @Nullable T getDataOrDefault(final DataComponentType.@NotNull Valued type, final @Nullable T fallback); + @Nullable T getDataOrDefault(final DataComponentType.Valued type, final @Nullable T fallback); /** * Checks if the data component type is set on this holder. @@ -51,7 +50,7 @@ public interface DataComponentView { */ @Contract(pure = true) @ApiStatus.Experimental - boolean hasData(final io.papermc.paper.datacomponent.@NotNull DataComponentType type); + boolean hasData(final DataComponentType type); // Not applicable to entities // /** @@ -61,5 +60,5 @@ public interface DataComponentView { // */ // @Contract("-> new") // @ApiStatus.Experimental - // java.util.@Unmodifiable Set getDataTypes(); + // @Unmodifiable Set getDataTypes(); } diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java index d7372673ac..5cfb65dfcf 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/BlocksAttacks.java @@ -4,13 +4,13 @@ import io.papermc.paper.datacomponent.DataComponentBuilder; import io.papermc.paper.datacomponent.item.blocksattacks.DamageReduction; import io.papermc.paper.datacomponent.item.blocksattacks.ItemDamageFunction; import io.papermc.paper.registry.tag.TagKey; +import java.util.List; import net.kyori.adventure.key.Key; import org.bukkit.damage.DamageType; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; -import java.util.List; /** * Holds block attacks to the holding player like Shield. @@ -62,24 +62,21 @@ public interface BlocksAttacks { * * @return a damage type tag key, or null if there is no such tag key */ - @Nullable - TagKey bypassedBy(); + @Nullable TagKey bypassedBy(); /** * Gets the key sound to play when an attack is successfully blocked. * * @return a key of the sound */ - @Nullable - Key blockSound(); + @Nullable Key blockSound(); /** * Gets the key sound to play when the item goes on its disabled cooldown due to an attack. * * @return a key of the sound */ - @Nullable - Key disableSound(); + @Nullable Key disableSound(); /** * Builder for {@link BlocksAttacks}. diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java index 334a87c198..10e4d35461 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/CustomModelData.java @@ -1,7 +1,7 @@ package io.papermc.paper.datacomponent.item; -import java.util.List; import io.papermc.paper.datacomponent.DataComponentBuilder; +import java.util.List; import org.bukkit.Color; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; diff --git a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java index 673d33f524..570ed9d28a 100644 --- a/paper-api/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java +++ b/paper-api/src/main/java/io/papermc/paper/datacomponent/item/Equippable.java @@ -104,6 +104,22 @@ public interface Equippable extends BuildableDataComponentExtensive documentation and examples of the paper-plugin.yml - * + * entry on the paper website contains a full and extensive example of possible configurations of the paper-plugin.yml. + * @see Extensive documentation and examples of the paper-plugin.yml */ package io.papermc.paper.plugin.configuration; diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java index 0b8eafd3e7..b9d5d5f56a 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEvent.java @@ -11,7 +11,6 @@ import org.jetbrains.annotations.ApiStatus; * server initialization. * @see LifecycleEvents */ -@ApiStatus.Experimental @ApiStatus.NonExtendable public interface LifecycleEvent { } diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java index e05cdb7ab1..ca07ff90f7 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventManager.java @@ -4,7 +4,6 @@ import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; import io.papermc.paper.plugin.lifecycle.event.handler.configuration.LifecycleEventHandlerConfiguration; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Manages a plugin's lifecycle events. Can be obtained @@ -12,8 +11,6 @@ import org.jspecify.annotations.NullMarked; * * @param the owning type, {@link org.bukkit.plugin.Plugin} or {@link io.papermc.paper.plugin.bootstrap.BootstrapContext} */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface LifecycleEventManager { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java index ce5891eb11..0d64e0b640 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/LifecycleEventOwner.java @@ -2,7 +2,6 @@ package io.papermc.paper.plugin.lifecycle.event; import io.papermc.paper.plugin.configuration.PluginMeta; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Implemented by types that are considered owners @@ -11,8 +10,6 @@ import org.jspecify.annotations.NullMarked; * a {@link LifecycleEventManager} where you can register * event handlers. */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface LifecycleEventOwner { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java index 3093ef23dd..181b200c78 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/LifecycleEventHandler.java @@ -1,8 +1,6 @@ package io.papermc.paper.plugin.lifecycle.event.handler; import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; -import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * A handler for a specific event. Can be implemented @@ -10,8 +8,6 @@ import org.jspecify.annotations.NullMarked; * * @param the event */ -@ApiStatus.Experimental -@NullMarked @FunctionalInterface public interface LifecycleEventHandler { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java index 9b9f4655f2..a825303285 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/LifecycleEventHandlerConfiguration.java @@ -3,7 +3,6 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import io.papermc.paper.plugin.lifecycle.event.handler.LifecycleEventHandler; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Base type for constructing configured event handlers for @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param */ @SuppressWarnings("unused") -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface LifecycleEventHandlerConfiguration { } diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java index a2acc6e386..bff8390541 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/MonitorLifecycleEventHandlerConfiguration.java @@ -3,15 +3,12 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * Handler configuration for event types that allow "monitor" handlers. * * @param the required owner type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface MonitorLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java index 100e5d169f..54734f3ac3 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/PrioritizedLifecycleEventHandlerConfiguration.java @@ -3,7 +3,6 @@ package io.papermc.paper.plugin.lifecycle.event.handler.configuration; import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * Handler configuration that allows both "monitor" and prioritized handlers. @@ -11,8 +10,6 @@ import org.jspecify.annotations.NullMarked; * * @param the required owner type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface PrioritizedLifecycleEventHandlerConfiguration extends LifecycleEventHandlerConfiguration { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/package-info.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/package-info.java new file mode 100644 index 0000000000..2bfedd6270 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/package-info.java @@ -0,0 +1,6 @@ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.plugin.lifecycle.event.handler.configuration; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/package-info.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/package-info.java new file mode 100644 index 0000000000..15cf1464cc --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/package-info.java @@ -0,0 +1,6 @@ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.plugin.lifecycle.event.handler; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/package-info.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/package-info.java new file mode 100644 index 0000000000..2047a99c61 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/package-info.java @@ -0,0 +1,6 @@ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.plugin.lifecycle.event; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java index fd9c3605a8..aa18d352ee 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/Registrar.java @@ -6,7 +6,6 @@ import org.jetbrains.annotations.ApiStatus; * To be implemented by types that provide ways to register types * either on server start or during a reload */ -@ApiStatus.Experimental @ApiStatus.NonExtendable public interface Registrar { } diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java index 7dca6be092..0e4c1efca8 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/RegistrarEvent.java @@ -3,7 +3,6 @@ package io.papermc.paper.plugin.lifecycle.event.registrar; import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * A lifecycle event that exposes a {@link Registrar} of some kind @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param registrar type * @see ReloadableRegistrarEvent */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistrarEvent extends LifecycleEvent { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java index 9bce1c13c8..e0327db6de 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/ReloadableRegistrarEvent.java @@ -2,7 +2,6 @@ package io.papermc.paper.plugin.lifecycle.event.registrar; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * A lifecycle event that exposes a {@link Registrar} that is @@ -11,8 +10,6 @@ import org.jspecify.annotations.NullMarked; * @param the registrar type * @see RegistrarEvent */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface ReloadableRegistrarEvent extends RegistrarEvent { @@ -24,7 +21,6 @@ public interface ReloadableRegistrarEvent extends Registrar @Contract(pure = true) Cause cause(); - @ApiStatus.Experimental enum Cause { /** * The initial load of the server. diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/package-info.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/package-info.java new file mode 100644 index 0000000000..4b55c80ac3 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/package-info.java @@ -0,0 +1,6 @@ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.plugin.lifecycle.event.registrar; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java index 75d9e20f53..f3594a8579 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventType.java @@ -9,7 +9,6 @@ import io.papermc.paper.plugin.lifecycle.event.handler.configuration.MonitorLife import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * Base type for all types of lifecycle events. Differs from @@ -22,8 +21,6 @@ import org.jspecify.annotations.NullMarked; * @param the event object type * @param the configuration type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface LifecycleEventType> { @@ -55,7 +52,6 @@ public interface LifecycleEventType the required owner type * @param the event object type */ - @ApiStatus.Experimental @ApiStatus.NonExtendable interface Monitorable extends LifecycleEventType> { } @@ -67,7 +63,6 @@ public interface LifecycleEventType the required owner type * @param the event object type */ - @ApiStatus.Experimental @ApiStatus.NonExtendable interface Prioritizable extends LifecycleEventType> { } diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java index ece6b72c5a..a52ab9e094 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEventTypeProvider.java @@ -5,10 +5,8 @@ import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner; import java.util.Optional; import java.util.ServiceLoader; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; @ApiStatus.Internal -@NullMarked interface LifecycleEventTypeProvider { Optional INSTANCE = ServiceLoader.load(LifecycleEventTypeProvider.class) diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java index 8ff52773b0..4145cda393 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/LifecycleEvents.java @@ -10,15 +10,12 @@ import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEvent; import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Holds various types of lifecycle events for * use when creating event handler configurations * in {@link LifecycleEventManager}. */ -@ApiStatus.Experimental -@NullMarked public final class LifecycleEvents { /** diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/TagEventTypeProvider.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/TagEventTypeProvider.java index 843ce7848c..71104512df 100644 --- a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/TagEventTypeProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/TagEventTypeProvider.java @@ -6,7 +6,6 @@ import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.tag.PostFlattenTagRegistrar; import io.papermc.paper.tag.PreFlattenTagRegistrar; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Provides event types for tag registration. @@ -14,8 +13,6 @@ import org.jspecify.annotations.NullMarked; * @see PreFlattenTagRegistrar * @see PostFlattenTagRegistrar */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface TagEventTypeProvider { diff --git a/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/package-info.java b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/package-info.java new file mode 100644 index 0000000000..a3257da32e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/package-info.java @@ -0,0 +1,6 @@ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.plugin.lifecycle.event.types; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java b/paper-api/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java index 3e29f70075..a4063783c3 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/TypedKeyImpl.java @@ -1,16 +1,19 @@ package io.papermc.paper.registry; import net.kyori.adventure.key.Key; +import net.kyori.adventure.key.KeyPattern; import org.jspecify.annotations.NullMarked; @NullMarked record TypedKeyImpl(Key key, RegistryKey registryKey) implements TypedKey { // Wrap key methods to make this easier to use + @KeyPattern.Namespace @Override public String namespace() { return this.key.namespace(); } + @KeyPattern.Value @Override public String value() { return this.key.value(); diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java index a9d6447110..e5f851d427 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/EnchantmentRegistryEntry.java @@ -3,6 +3,7 @@ package io.papermc.paper.registry.data; import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.event.RegistryComposeEvent; import io.papermc.paper.registry.set.RegistryKeySet; import io.papermc.paper.registry.set.RegistrySet; import io.papermc.paper.registry.tag.TagKey; @@ -153,7 +154,7 @@ public interface EnchantmentRegistryEntry { /** * Configures the set of supported items this enchantment can be applied on. This * can be a {@link RegistryKeySet} created via {@link RegistrySet#keySet(io.papermc.paper.registry.RegistryKey, Iterable)} or - * a tag obtained via {@link io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey)} with + * a tag obtained via {@link RegistryComposeEvent#getOrCreateTag(TagKey)} with * tag keys found in {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys} such as * {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#ENCHANTABLE_ARMOR} and * {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#ENCHANTABLE_SWORD}. @@ -161,7 +162,7 @@ public interface EnchantmentRegistryEntry { * @param supportedItems the registry key set representing the supported items. * @return this builder instance. * @see RegistrySet#keySet(RegistryKey, TypedKey[]) - * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see RegistryComposeEvent#getOrCreateTag(TagKey) */ @Contract(value = "_ -> this", mutates = "this") Builder supportedItems(RegistryKeySet supportedItems); @@ -170,7 +171,7 @@ public interface EnchantmentRegistryEntry { * Configures a set of item types this enchantment can naturally be applied to, when enchanting in an * enchantment table.This can be a {@link RegistryKeySet} created via * {@link RegistrySet#keySet(io.papermc.paper.registry.RegistryKey, Iterable)} or a tag obtained via - * {@link io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey)} with + * {@link RegistryComposeEvent#getOrCreateTag(TagKey)} with * tag keys found in {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys} such as * {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#ENCHANTABLE_ARMOR} and * {@link io.papermc.paper.registry.keys.tags.ItemTypeTagKeys#ENCHANTABLE_SWORD}. @@ -182,7 +183,7 @@ public interface EnchantmentRegistryEntry { * @param primaryItems the registry key set representing the primary items. * @return this builder instance. * @see RegistrySet#keySet(RegistryKey, TypedKey[]) - * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see RegistryComposeEvent#getOrCreateTag(TagKey) */ @Contract(value = "_ -> this", mutates = "this") Builder primaryItems(@Nullable RegistryKeySet primaryItems); @@ -285,7 +286,7 @@ public interface EnchantmentRegistryEntry { * @param exclusiveWith a registry set of enchantments exclusive to this one. * @return this builder instance. * @see RegistrySet#keySet(RegistryKey, TypedKey[]) - * @see io.papermc.paper.registry.event.RegistryFreezeEvent#getOrCreateTag(TagKey) + * @see RegistryComposeEvent#getOrCreateTag(TagKey) */ @Contract(value = "_ -> this", mutates = "this") Builder exclusiveWith(RegistryKeySet exclusiveWith); diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProvider.java b/paper-api/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProvider.java index 554bda0341..974e3b43df 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProvider.java @@ -18,5 +18,4 @@ public interface InlinedRegistryBuilderProvider { return Holder.INSTANCE.orElseThrow(); } - Art createPaintingVariant(Consumer> value); } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/JukeboxSongRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/JukeboxSongRegistryEntry.java new file mode 100644 index 0000000000..5779281e5c --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/JukeboxSongRegistryEntry.java @@ -0,0 +1,134 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.RegistryBuilderFactory; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.holder.RegistryHolder; +import java.util.function.Consumer; +import net.kyori.adventure.text.Component; +import org.bukkit.JukeboxSong; +import org.bukkit.Sound; +import org.checkerframework.checker.index.qual.Positive; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jetbrains.annotations.Range; + +/** + * A data-centric version-specific registry entry for the {@link JukeboxSong} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface JukeboxSongRegistryEntry { + + /** + * Gets the sound event for this song. + * + * @return the sound event + */ + @Contract(pure = true) + RegistryHolder soundEvent(); + + /** + * Gets the description for this song. + * + * @return the description + */ + @Contract(pure = true) + Component description(); + + /** + * Gets the length in seconds for this song. + * + * @return the length in seconds + */ + @Contract(pure = true) + @Positive float lengthInSeconds(); + + /** + * Gets the comparator output for this song. + * + * @return the comparator output + */ + @Contract(pure = true) + @Range(from = 0, to = 15) int comparatorOutput(); + + /** + * A mutable builder for the {@link JukeboxSongRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • + * {@link #soundEvent(TypedKey)}, {@link #soundEvent(Consumer)} or {@link #soundEvent(RegistryHolder)} + *
  • + *
  • {@link #description(Component)}
  • + *
  • {@link #lengthInSeconds(float)}
  • + *
  • {@link #comparatorOutput(int)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends JukeboxSongRegistryEntry, RegistryBuilder { + + /** + * Sets the sound event for this song to a sound event present + * in the {@link io.papermc.paper.registry.RegistryKey#SOUND_EVENT} registry. + *

This will override both {@link #soundEvent(Consumer)} and {@link #soundEvent(RegistryHolder)}

+ * + * @param soundEvent the sound event + * @return this builder + * @see #soundEvent(Consumer) + */ + @Contract(value = "_ -> this", mutates = "this") + Builder soundEvent(TypedKey soundEvent); + + /** + * Sets the sound event for this song to a new sound event. + *

This will override both {@link #soundEvent(TypedKey)} and {@link #soundEvent(RegistryHolder)}

+ * + * @param soundEvent the sound event + * @return this builder + * @see #soundEvent(TypedKey) + */ + @Contract(value = "_ -> this", mutates = "this") + Builder soundEvent(Consumer> soundEvent); + + /** + * Sets the sound event for this song. + *

This will override both {@link #soundEvent(Consumer)} and {@link #soundEvent(TypedKey)}

+ * + * @param soundEvent the sound event + * @return this builder + * @see #soundEvent(TypedKey) + * @see #soundEvent(Consumer) + */ + @Contract( value = "_ -> this", mutates = "this") + Builder soundEvent(RegistryHolder soundEvent); + + /** + * Sets the description for this song. + * + * @param description the description + * @return this builder + */ + @Contract(value = "_ -> this", mutates = "this") + Builder description(Component description); + + /** + * Sets the length in seconds for this song. + * + * @param lengthInSeconds the length in seconds (positive) + * @return this builder + */ + @Contract(value = "_ -> this", mutates = "this") + Builder lengthInSeconds(@Positive float lengthInSeconds); + + /** + * Sets the comparator output for this song. + * + * @param comparatorOutput the comparator output [0-15] + * @return this builder + */ + @Contract(value = "_ -> this", mutates = "this") + Builder comparatorOutput(@Range(from = 0, to = 15) int comparatorOutput); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/data/SoundEventRegistryEntry.java b/paper-api/src/main/java/io/papermc/paper/registry/data/SoundEventRegistryEntry.java new file mode 100644 index 0000000000..ea68f71a69 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/data/SoundEventRegistryEntry.java @@ -0,0 +1,63 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.RegistryBuilder; +import net.kyori.adventure.key.Key; +import org.bukkit.Sound; +import org.jetbrains.annotations.ApiStatus; +import org.jetbrains.annotations.Contract; +import org.jspecify.annotations.Nullable; + +/** + * A data-centric version-specific registry entry for the {@link Sound} type. + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface SoundEventRegistryEntry { + + /** + * Gets the resource pack location for this sound event. + * + * @return the location + */ + @Contract(pure = true) + Key location(); + + /** + * Gets the fixed range for this sound event, if present. + * + * @return the fixed range, or {@code null} if not present + */ + @Contract(pure = true) + @Nullable Float fixedRange(); + + /** + * A mutable builder for the {@link SoundEventRegistryEntry} plugins may change in applicable registry events. + *

+ * The following values are required for each builder: + *

    + *
  • {@link #location(Key)}
  • + *
+ */ + @ApiStatus.Experimental + @ApiStatus.NonExtendable + interface Builder extends SoundEventRegistryEntry, RegistryBuilder { + + /** + * Sets the resource pack location for this sound event. + * + * @param location the location + * @return this builder + */ + @Contract(value = "_ -> this", mutates = "this") + Builder location(Key location); + + /** + * Sets the fixed range for this sound event. + * + * @param fixedRange the fixed range + * @return this builder + */ + @Contract(value = "_ -> this", mutates = "this") + Builder fixedRange(@Nullable Float fixedRange); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java new file mode 100644 index 0000000000..465d0fc404 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryComposeEvent.java @@ -0,0 +1,38 @@ +package io.papermc.paper.registry.event; + +import io.papermc.paper.registry.RegistryBuilder; +import io.papermc.paper.registry.tag.Tag; +import io.papermc.paper.registry.tag.TagKey; +import org.bukkit.Keyed; +import org.jetbrains.annotations.ApiStatus; + +/** + * Event object for {@link RegistryEventProvider#compose()}. This + * event is fired after a registry is loaded with its normal values. + * It provides a way for plugins to add new objects to the registry. + * + * @param registry entry type + * @param registry entry builder type + */ +@ApiStatus.Experimental +@ApiStatus.NonExtendable +public interface RegistryComposeEvent> extends RegistryEvent { + + /** + * Get the writable registry. + * + * @return a writable registry + */ + WritableRegistry registry(); + + /** + * Gets or creates a tag for the given tag key. This tag + * is then required to be filled either from the built-in or + * custom datapack. + * + * @param tagKey the tag key + * @return the tag + * @param the tag value type + */ + Tag getOrCreateTag(TagKey tagKey); // TODO remove Keyed +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java index 56468b311e..dd9af46618 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEntryAddEvent.java @@ -6,7 +6,6 @@ import io.papermc.paper.registry.tag.Tag; import io.papermc.paper.registry.tag.TagKey; import org.bukkit.Keyed; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Event object for {@link RegistryEventProvider#entryAdd()}. This @@ -16,8 +15,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEntryAddEvent> extends RegistryEvent { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java index 3a8643c06d..420e031bf5 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvent.java @@ -3,15 +3,12 @@ package io.papermc.paper.registry.event; import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent; import io.papermc.paper.registry.RegistryKey; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Base type for all registry events. * * @param registry entry type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEvent extends LifecycleEvent { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java index 8518e93829..907a10fb33 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProvider.java @@ -7,7 +7,6 @@ import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Provider for registry events for a specific registry. @@ -15,14 +14,12 @@ import org.jspecify.annotations.NullMarked; * Supported events are: *
    *
  • {@link RegistryEntryAddEvent} (via {@link #entryAdd()})
  • - *
  • {@link RegistryFreezeEvent} (via {@link #freeze()})
  • + *
  • {@link RegistryComposeEvent} (via {@link #compose()})
  • *
* * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEventProvider> { @@ -45,8 +42,25 @@ public interface RegistryEventProvider> { * to register a handler for {@link RegistryFreezeEvent}. * * @return the registry freeze event type + * @deprecated use {@link #compose()} instead. */ - LifecycleEventType.Prioritizable> freeze(); + @SuppressWarnings({"unchecked", "rawtypes"}) + @ApiStatus.ScheduledForRemoval(inVersion = "1.21.7 or 1.22, whichever comes first") + @Deprecated(since = "1.21.6", forRemoval = true) + default LifecycleEventType.Prioritizable> freeze() { + return (LifecycleEventType.Prioritizable>) (LifecycleEventType.Prioritizable) this.compose(); + } + + /** + * Gets the event type for {@link RegistryComposeEvent} which is fired after + * a registry is loaded of expected elements. It allows for the registration of new objects. + *

+ * Can be used in {@link io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager#registerEventHandler(LifecycleEventType, LifecycleEventHandler)} + * to register a handler for {@link RegistryComposeEvent}. + * + * @return the registry freeze event type + */ + LifecycleEventType.Prioritizable> compose(); /** * Gets the registry key associated with this event type provider. diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java index 8d9afd4907..16eb6bc8a4 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventProviderImpl.java @@ -6,10 +6,8 @@ import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; @ApiStatus.Internal -@NullMarked record RegistryEventProviderImpl>(RegistryKey registryKey) implements RegistryEventProvider { static > RegistryEventProvider create(final RegistryKey registryKey) { @@ -22,8 +20,7 @@ record RegistryEventProviderImpl>(RegistryKey } @Override - public LifecycleEventType.Prioritizable> freeze() { - return RegistryEventTypeProvider.provider().registryFreeze(this); + public LifecycleEventType.Prioritizable> compose() { + return RegistryEventTypeProvider.provider().registryCompose(this); } - } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProvider.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProvider.java index d807bd2f42..38f10d2472 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProvider.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProvider.java @@ -20,5 +20,5 @@ interface RegistryEventTypeProvider { > RegistryEntryAddEventType registryEntryAdd(RegistryEventProvider type); - > LifecycleEventType.Prioritizable> registryFreeze(RegistryEventProvider type); + > LifecycleEventType.Prioritizable> registryCompose(RegistryEventProvider type); } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java index 0cf04f0e2b..e9f639f209 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryEvents.java @@ -9,11 +9,13 @@ import io.papermc.paper.registry.data.DamageTypeRegistryEntry; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; import io.papermc.paper.registry.data.FrogVariantRegistryEntry; import io.papermc.paper.registry.data.GameEventRegistryEntry; +import io.papermc.paper.registry.data.JukeboxSongRegistryEntry; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; import io.papermc.paper.registry.data.PigVariantRegistryEntry; import io.papermc.paper.registry.data.WolfVariantRegistryEntry; import org.bukkit.Art; import org.bukkit.GameEvent; +import org.bukkit.JukeboxSong; import org.bukkit.block.banner.PatternType; import org.bukkit.damage.DamageType; import org.bukkit.enchantments.Enchantment; @@ -23,25 +25,22 @@ import org.bukkit.entity.Cow; import org.bukkit.entity.Frog; import org.bukkit.entity.Pig; import org.bukkit.entity.Wolf; -import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; import static io.papermc.paper.registry.event.RegistryEventProviderImpl.create; /** - * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryFreezeEvent} + * Holds providers for {@link RegistryEntryAddEvent} and {@link RegistryComposeEvent} * handlers for each applicable registry. */ -@ApiStatus.Experimental -@NullMarked public final class RegistryEvents { // Start generate - RegistryEvents - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final RegistryEventProvider GAME_EVENT = create(RegistryKey.GAME_EVENT); public static final RegistryEventProvider DAMAGE_TYPE = create(RegistryKey.DAMAGE_TYPE); public static final RegistryEventProvider WOLF_VARIANT = create(RegistryKey.WOLF_VARIANT); public static final RegistryEventProvider ENCHANTMENT = create(RegistryKey.ENCHANTMENT); + public static final RegistryEventProvider JUKEBOX_SONG = create(RegistryKey.JUKEBOX_SONG); public static final RegistryEventProvider BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN); public static final RegistryEventProvider PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT); public static final RegistryEventProvider CAT_VARIANT = create(RegistryKey.CAT_VARIANT); diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java index 59e8ca6c5b..fdb0717f7a 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEvent.java @@ -1,11 +1,7 @@ package io.papermc.paper.registry.event; import io.papermc.paper.registry.RegistryBuilder; -import io.papermc.paper.registry.tag.Tag; -import io.papermc.paper.registry.tag.TagKey; -import org.bukkit.Keyed; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Event object for {@link RegistryEventProvider#freeze()}. This @@ -14,27 +10,10 @@ import org.jspecify.annotations.NullMarked; * * @param registry entry type * @param registry entry builder type + * @deprecated renamed to {@link RegistryComposeEvent} */ -@ApiStatus.Experimental -@NullMarked +@ApiStatus.ScheduledForRemoval(inVersion = "1.21.7 or 1.22, whichever comes first") +@Deprecated(since = "1.21.6", forRemoval = true) @ApiStatus.NonExtendable -public interface RegistryFreezeEvent> extends RegistryEvent { - - /** - * Get the writable registry. - * - * @return a writable registry - */ - WritableRegistry registry(); - - /** - * Gets or creates a tag for the given tag key. This tag - * is then required to be filled either from the built-in or - * custom datapack. - * - * @param tagKey the tag key - * @return the tag - * @param the tag value type - */ - Tag getOrCreateTag(TagKey tagKey); +public interface RegistryFreezeEvent> extends RegistryComposeEvent { } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java index fed7ad660f..9f32ef1d8e 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/WritableRegistry.java @@ -5,7 +5,6 @@ import io.papermc.paper.registry.RegistryBuilderFactory; import io.papermc.paper.registry.TypedKey; import java.util.function.Consumer; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * A registry which supports registering new objects. @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface WritableRegistry> { diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java b/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java new file mode 100644 index 0000000000..9a6ff1553e --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/package-info.java @@ -0,0 +1,9 @@ +/** + * This package contains events related to the Paper registry system. + */ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.registry.event; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java index d9bde790f7..776a6b2ff4 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddConfiguration.java @@ -4,15 +4,15 @@ import io.papermc.paper.plugin.bootstrap.BootstrapContext; import io.papermc.paper.plugin.lifecycle.event.handler.configuration.PrioritizedLifecycleEventHandlerConfiguration; import io.papermc.paper.registry.TypedKey; import java.util.function.Predicate; +import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Contract; -import org.jspecify.annotations.NullMarked; /** * Specific configuration for {@link io.papermc.paper.registry.event.RegistryEntryAddEvent}s. * * @param registry entry type */ -@NullMarked +@ApiStatus.NonExtendable public interface RegistryEntryAddConfiguration extends PrioritizedLifecycleEventHandlerConfiguration { /** diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java index 93447ef589..29d8e1d25e 100644 --- a/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/RegistryEntryAddEventType.java @@ -5,7 +5,6 @@ import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; import io.papermc.paper.registry.RegistryBuilder; import io.papermc.paper.registry.event.RegistryEntryAddEvent; import org.jetbrains.annotations.ApiStatus; -import org.jspecify.annotations.NullMarked; /** * Lifecycle event type for {@link RegistryEntryAddEvent}s. @@ -13,8 +12,6 @@ import org.jspecify.annotations.NullMarked; * @param registry entry type * @param registry entry builder type */ -@ApiStatus.Experimental -@NullMarked @ApiStatus.NonExtendable public interface RegistryEntryAddEventType> extends LifecycleEventType, RegistryEntryAddConfiguration> { } diff --git a/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java b/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java new file mode 100644 index 0000000000..cf23472df1 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/event/type/package-info.java @@ -0,0 +1,9 @@ +/** + * This package contains events related to the Paper registry system. + */ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.registry.event.type; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/io/papermc/paper/registry/holder/RegistryHolder.java b/paper-api/src/main/java/io/papermc/paper/registry/holder/RegistryHolder.java new file mode 100644 index 0000000000..06ea3436f3 --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/holder/RegistryHolder.java @@ -0,0 +1,50 @@ +package io.papermc.paper.registry.holder; + +import io.papermc.paper.registry.TypedKey; +import org.jetbrains.annotations.ApiStatus; + +/** + * During the registry loading phase, some values can be references to values to-be-loaded + * in the future, or inlined, anonymous values that already exist. This type (and subtypes) represent + * that structure. + * @param the registry's type + * @param the type of the registry entry (for inlined values) + */ +@ApiStatus.Experimental +public sealed interface RegistryHolder permits RegistryHolder.Reference, RegistryHolder.Inlined { + + /** + * A holder that references a registry value by key, but does not have the entry itself. + * This is used for entries that are only referenced by key and may not yet have any value associated with them. + * + * @param the registry's type + * @param the type of the registry entry + */ + @ApiStatus.NonExtendable + non-sealed interface Reference extends RegistryHolder { + + /** + * The key of the referenced value. + * + * @return the key of the value + */ + TypedKey key(); + } + + /** + * A holder that contains an inlined registry entry, an anonymous value (does not have a key). + * + * @param the registry's type + * @param the type of the registry entry + */ + @ApiStatus.NonExtendable + non-sealed interface Inlined extends RegistryHolder { + + /** + * The inlined entry. + * + * @return the inlined entry + */ + ENTRY entry(); + } +} diff --git a/paper-api/src/main/java/io/papermc/paper/registry/holder/package-info.java b/paper-api/src/main/java/io/papermc/paper/registry/holder/package-info.java new file mode 100644 index 0000000000..ced91104ce --- /dev/null +++ b/paper-api/src/main/java/io/papermc/paper/registry/holder/package-info.java @@ -0,0 +1,9 @@ +/** + * Registry holders. + */ +@ApiStatus.Experimental +@NullMarked +package io.papermc.paper.registry.holder; + +import org.jetbrains.annotations.ApiStatus; +import org.jspecify.annotations.NullMarked; diff --git a/paper-api/src/main/java/org/bukkit/Art.java b/paper-api/src/main/java/org/bukkit/Art.java index d6f8e471c1..a98c9f7f72 100644 --- a/paper-api/src/main/java/org/bukkit/Art.java +++ b/paper-api/src/main/java/org/bukkit/Art.java @@ -24,19 +24,8 @@ import org.jetbrains.annotations.Nullable; */ public interface Art extends OldEnum, Keyed { - /** - * Create an inlined painting variant. - * - * @param value a consumer for the builder factory - * @return the created painting variant - */ - @ApiStatus.Experimental - static @NotNull Art create(final @NotNull Consumer> value) { - return InlinedRegistryBuilderProvider.instance().createPaintingVariant(value); - } - // Start generate - Art - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Art ALBAN = getArt("alban"); Art AZTEC = getArt("aztec"); diff --git a/paper-api/src/main/java/org/bukkit/EntityEffect.java b/paper-api/src/main/java/org/bukkit/EntityEffect.java index cbf1d7a674..3a53a48472 100644 --- a/paper-api/src/main/java/org/bukkit/EntityEffect.java +++ b/paper-api/src/main/java/org/bukkit/EntityEffect.java @@ -476,7 +476,12 @@ public enum EntityEffect { * * @see org.bukkit.inventory.EquipmentSlot#SADDLE */ - BREAK_EQUIPMENT_SADDLE(68, LivingEntity.class); + BREAK_EQUIPMENT_SADDLE(68, LivingEntity.class), + /** + * Ravager roars. + */ + RAVAGER_ROARED(69, Ravager.class), + ; private final byte data; private final Set> applicableClasses; diff --git a/paper-api/src/main/java/org/bukkit/FeatureFlag.java b/paper-api/src/main/java/org/bukkit/FeatureFlag.java index fafcec1db7..4dc3ec75a5 100644 --- a/paper-api/src/main/java/org/bukkit/FeatureFlag.java +++ b/paper-api/src/main/java/org/bukkit/FeatureFlag.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.ApiStatus; public interface FeatureFlag extends Keyed { // Start generate - FeatureFlag - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 @ApiStatus.Experimental FeatureFlag MINECART_IMPROVEMENTS = create("minecart_improvements"); diff --git a/paper-api/src/main/java/org/bukkit/Fluid.java b/paper-api/src/main/java/org/bukkit/Fluid.java index ad12f82e27..283a0b7177 100644 --- a/paper-api/src/main/java/org/bukkit/Fluid.java +++ b/paper-api/src/main/java/org/bukkit/Fluid.java @@ -13,7 +13,7 @@ import org.jetbrains.annotations.NotNull; public interface Fluid extends OldEnum, Keyed { // Start generate - Fluid - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Fluid EMPTY = getFluid("empty"); Fluid FLOWING_LAVA = getFluid("flowing_lava"); diff --git a/paper-api/src/main/java/org/bukkit/GameEvent.java b/paper-api/src/main/java/org/bukkit/GameEvent.java index 2e08337e6f..bc125214f1 100644 --- a/paper-api/src/main/java/org/bukkit/GameEvent.java +++ b/paper-api/src/main/java/org/bukkit/GameEvent.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.Nullable; public abstract class GameEvent implements Keyed { // Start generate - GameEvent - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final GameEvent BLOCK_ACTIVATE = getEvent("block_activate"); public static final GameEvent BLOCK_ATTACH = getEvent("block_attach"); diff --git a/paper-api/src/main/java/org/bukkit/GameRule.java b/paper-api/src/main/java/org/bukkit/GameRule.java index d0d215a80a..ff5893a714 100644 --- a/paper-api/src/main/java/org/bukkit/GameRule.java +++ b/paper-api/src/main/java/org/bukkit/GameRule.java @@ -305,6 +305,11 @@ public final class GameRule implements net.kyori.adventure.translation.Transl */ public static final GameRule SPAWN_CHUNK_RADIUS = new GameRule<>("spawnChunkRadius", Integer.class); + /** + * Configures if the world uses the locator bar. + */ + public static final GameRule LOCATOR_BAR = new GameRule<>("locatorBar", Boolean.class); + // All GameRules instantiated above this for organizational purposes private final String name; private final Class type; diff --git a/paper-api/src/main/java/org/bukkit/JukeboxSong.java b/paper-api/src/main/java/org/bukkit/JukeboxSong.java index 5a20983a64..860152202c 100644 --- a/paper-api/src/main/java/org/bukkit/JukeboxSong.java +++ b/paper-api/src/main/java/org/bukkit/JukeboxSong.java @@ -12,7 +12,7 @@ import org.jetbrains.annotations.NotNull; public interface JukeboxSong extends Keyed, Translatable { // Start generate - JukeboxSong - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 JukeboxSong ELEVEN = get("11"); JukeboxSong THIRTEEN = get("13"); @@ -47,6 +47,8 @@ public interface JukeboxSong extends Keyed, Translatable { JukeboxSong STRAD = get("strad"); + JukeboxSong TEARS = get("tears"); + JukeboxSong WAIT = get("wait"); JukeboxSong WARD = get("ward"); diff --git a/paper-api/src/main/java/org/bukkit/Location.java b/paper-api/src/main/java/org/bukkit/Location.java index a4a5444d0a..47f667ccc8 100644 --- a/paper-api/src/main/java/org/bukkit/Location.java +++ b/paper-api/src/main/java/org/bukkit/Location.java @@ -852,6 +852,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param radius X Radius * @return the collection of entities near location. This will always be a non-null collection. */ @@ -861,6 +862,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xzRadius X/Z Radius * @param yRadius Y Radius * @return the collection of living entities near location. This will always be a non-null collection. @@ -871,6 +873,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xRadius X Radius * @param yRadius Y Radius * @param zRadius Z radius @@ -882,6 +885,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param radius Radius * @param predicate a predicate used to filter results * @return the collection of living entities near location. This will always be a non-null collection. @@ -892,6 +896,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xzRadius X/Z Radius * @param yRadius Y Radius * @param predicate a predicate used to filter results @@ -903,6 +908,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xRadius X Radius * @param yRadius Y Radius * @param zRadius Z radius @@ -915,6 +921,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param radius X/Y/Z Radius * @return the collection of players near location. This will always be a non-null collection. */ @@ -924,6 +931,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xzRadius X/Z Radius * @param yRadius Y Radius * @return the collection of players near location. This will always be a non-null collection. @@ -934,6 +942,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xRadius X Radius * @param yRadius Y Radius * @param zRadius Z Radius @@ -945,6 +954,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param radius X/Y/Z Radius * @param predicate a predicate used to filter results * @return the collection of players near location. This will always be a non-null collection. @@ -955,6 +965,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xzRadius X/Z Radius * @param yRadius Y Radius * @param predicate a predicate used to filter results @@ -966,6 +977,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets nearby players within the specified radius (bounding box) + * * @param xRadius X Radius * @param yRadius Y Radius * @param zRadius Z Radius @@ -978,6 +990,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param radius X/Y/Z radius to search within * @param the entity type @@ -989,6 +1002,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box) + * * @param clazz Type to filter by * @param xzRadius X/Z radius to search within * @param yRadius Y radius to search within @@ -1001,6 +1015,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param xRadius X Radius * @param yRadius Y Radius @@ -1014,6 +1029,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param radius X/Y/Z radius to search within * @param predicate a predicate used to filter results @@ -1026,6 +1042,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box) + * * @param clazz Type to filter by * @param xzRadius X/Z radius to search within * @param yRadius Y radius to search within @@ -1039,6 +1056,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param xRadius X Radius * @param yRadius Y Radius @@ -1047,7 +1065,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm * @param the entity type * @return the collection of entities near location. This will always be a non-null collection. */ - public @NotNull Collection getNearbyEntitiesByType(final @Nullable Class clazz, final double xRadius, final double yRadius, final double zRadius, final @Nullable Predicate predicate) { + public @NotNull Collection getNearbyEntitiesByType(final @Nullable Class clazz, final double xRadius, final double yRadius, final double zRadius, final @Nullable Predicate predicate) { final World world = this.getWorld(); if (world == null) { throw new IllegalArgumentException("Location has no world"); diff --git a/paper-api/src/main/java/org/bukkit/Material.java b/paper-api/src/main/java/org/bukkit/Material.java index 5a1b9f8183..6a559381d4 100644 --- a/paper-api/src/main/java/org/bukkit/Material.java +++ b/paper-api/src/main/java/org/bukkit/Material.java @@ -60,6 +60,7 @@ import org.bukkit.block.data.type.DaylightDetector; import org.bukkit.block.data.type.DecoratedPot; import org.bukkit.block.data.type.Dispenser; import org.bukkit.block.data.type.Door; +import org.bukkit.block.data.type.DriedGhast; import org.bukkit.block.data.type.Dripleaf; import org.bukkit.block.data.type.EndPortalFrame; import org.bukkit.block.data.type.EnderChest; @@ -144,7 +145,7 @@ import org.jetbrains.annotations.Nullable; public enum Material implements Keyed, Translatable, net.kyori.adventure.translation.Translatable { // Paper // // Start generate - Items - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 ACACIA_BOAT(-1, 1), ACACIA_CHEST_BOAT(-1, 1), AIR(-1), @@ -173,6 +174,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla BIRCH_CHEST_BOAT(-1, 1), BLACK_BUNDLE(-1, 1), BLACK_DYE(-1), + BLACK_HARNESS(-1, 1), BLADE_POTTERY_SHERD(-1), BLAZE_POWDER(-1), BLAZE_ROD(-1), @@ -180,6 +182,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla BLUE_BUNDLE(-1, 1), BLUE_DYE(-1), BLUE_EGG(-1, 16), + BLUE_HARNESS(-1, 1), BOGGED_SPAWN_EGG(-1), BOLT_ARMOR_TRIM_SMITHING_TEMPLATE(-1), BONE(-1), @@ -196,6 +199,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla BROWN_BUNDLE(-1, 1), BROWN_DYE(-1), BROWN_EGG(-1, 16), + BROWN_HARNESS(-1, 1), BRUSH(-1, 1), BUCKET(-1, 16), BUNDLE(-1, 1), @@ -242,6 +246,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla CROSSBOW(-1, 1), CYAN_BUNDLE(-1, 1), CYAN_DYE(-1), + CYAN_HARNESS(-1, 1), DANGER_POTTERY_SHERD(-1), DARK_OAK_BOAT(-1, 1), DARK_OAK_CHEST_BOAT(-1, 1), @@ -257,18 +262,10 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla DIAMOND_PICKAXE(-1, 1), DIAMOND_SHOVEL(-1, 1), DIAMOND_SWORD(-1, 1), - DRAGON_BREATH(-1), - END_CRYSTAL(-1), - FIELD_MASONED_BANNER_PATTERN(-1, 1), - FLOW_BANNER_PATTERN(-1, 1), - GLOBE_BANNER_PATTERN(-1, 1), - IRON_NUGGET(-1), - KNOWLEDGE_BOOK(-1, 1), - LINGERING_POTION(-1, 1), - MUSIC_DISC_5(-1, 1), DISC_FRAGMENT_5(-1), DOLPHIN_SPAWN_EGG(-1), DONKEY_SPAWN_EGG(-1), + DRAGON_BREATH(-1), DRIED_KELP(-1), DROWNED_SPAWN_EGG(-1), DUNE_ARMOR_TRIM_SMITHING_TEMPLATE(-1), @@ -279,6 +276,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla EMERALD(-1), ENCHANTED_BOOK(-1, 1), ENCHANTED_GOLDEN_APPLE(-1), + END_CRYSTAL(-1), ENDER_DRAGON_SPAWN_EGG(-1), ENDER_EYE(-1), ENDER_PEARL(-1, 16), @@ -290,6 +288,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla EYE_ARMOR_TRIM_SMITHING_TEMPLATE(-1), FEATHER(-1), FERMENTED_SPIDER_EYE(-1), + FIELD_MASONED_BANNER_PATTERN(-1, 1), FILLED_MAP(-1), FIRE_CHARGE(-1), FIREWORK_ROCKET(-1), @@ -298,6 +297,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla FLINT(-1), FLINT_AND_STEEL(-1, 1), FLOW_ARMOR_TRIM_SMITHING_TEMPLATE(-1), + FLOW_BANNER_PATTERN(-1, 1), FLOW_POTTERY_SHERD(-1), FLOWER_BANNER_PATTERN(-1, 1), FOX_SPAWN_EGG(-1), @@ -308,6 +308,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla GHAST_TEAR(-1), GLASS_BOTTLE(-1), GLISTERING_MELON_SLICE(-1), + GLOBE_BANNER_PATTERN(-1, 1), GLOW_BERRIES(-1), GLOW_INK_SAC(-1), GLOW_ITEM_FRAME(-1), @@ -331,12 +332,15 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla GOLDEN_SWORD(-1, 1), GRAY_BUNDLE(-1, 1), GRAY_DYE(-1), + GRAY_HARNESS(-1, 1), GREEN_BUNDLE(-1, 1), GREEN_DYE(-1), + GREEN_HARNESS(-1, 1), GUARDIAN_SPAWN_EGG(-1), GUNPOWDER(-1), GUSTER_BANNER_PATTERN(-1, 1), GUSTER_POTTERY_SHERD(-1), + HAPPY_GHAST_SPAWN_EGG(-1), HEART_OF_THE_SEA(-1), HEART_POTTERY_SHERD(-1), HEARTBREAK_POTTERY_SHERD(-1), @@ -358,12 +362,14 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla IRON_HORSE_ARMOR(-1, 1), IRON_INGOT(-1), IRON_LEGGINGS(-1, 1), + IRON_NUGGET(-1), IRON_PICKAXE(-1, 1), IRON_SHOVEL(-1, 1), IRON_SWORD(-1, 1), ITEM_FRAME(-1), JUNGLE_BOAT(-1, 1), JUNGLE_CHEST_BOAT(-1, 1), + KNOWLEDGE_BOOK(-1, 1), LAPIS_LAZULI(-1), LAVA_BUCKET(-1, 1), LEAD(-1), @@ -375,14 +381,19 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla LEATHER_LEGGINGS(-1, 1), LIGHT_BLUE_BUNDLE(-1, 1), LIGHT_BLUE_DYE(-1), + LIGHT_BLUE_HARNESS(-1, 1), LIGHT_GRAY_BUNDLE(-1, 1), LIGHT_GRAY_DYE(-1), + LIGHT_GRAY_HARNESS(-1, 1), LIME_BUNDLE(-1, 1), LIME_DYE(-1), + LIME_HARNESS(-1, 1), + LINGERING_POTION(-1, 1), LLAMA_SPAWN_EGG(-1), MACE(-1, 1), MAGENTA_BUNDLE(-1, 1), MAGENTA_DYE(-1), + MAGENTA_HARNESS(-1, 1), MAGMA_CREAM(-1), MAGMA_CUBE_SPAWN_EGG(-1), MANGROVE_BOAT(-1, 1), @@ -398,6 +409,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla MOURNER_POTTERY_SHERD(-1), MULE_SPAWN_EGG(-1), MUSHROOM_STEW(-1, 1), + MUSIC_DISC_5(-1, 1), MUSIC_DISC_11(-1, 1), MUSIC_DISC_13(-1, 1), MUSIC_DISC_BLOCKS(-1, 1), @@ -414,6 +426,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla MUSIC_DISC_RELIC(-1, 1), MUSIC_DISC_STAL(-1, 1), MUSIC_DISC_STRAD(-1, 1), + MUSIC_DISC_TEARS(-1, 1), MUSIC_DISC_WAIT(-1, 1), MUSIC_DISC_WARD(-1, 1), MUTTON(-1), @@ -440,6 +453,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla OMINOUS_TRIAL_KEY(-1), ORANGE_BUNDLE(-1, 1), ORANGE_DYE(-1), + ORANGE_HARNESS(-1, 1), PAINTING(-1), PALE_OAK_BOAT(-1, 1), PALE_OAK_CHEST_BOAT(-1, 1), @@ -455,6 +469,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla PILLAGER_SPAWN_EGG(-1), PINK_BUNDLE(-1, 1), PINK_DYE(-1), + PINK_HARNESS(-1, 1), PITCHER_POD(-1), PLENTY_POTTERY_SHERD(-1), POISONOUS_POTATO(-1), @@ -474,6 +489,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla PUMPKIN_SEEDS(-1), PURPLE_BUNDLE(-1, 1), PURPLE_DYE(-1), + PURPLE_HARNESS(-1, 1), QUARTZ(-1), RABBIT(-1), RABBIT_FOOT(-1), @@ -488,6 +504,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla RECOVERY_COMPASS(-1), RED_BUNDLE(-1, 1), RED_DYE(-1), + RED_HARNESS(-1, 1), REDSTONE(-1), RESIN_BRICK(-1), RIB_ARMOR_TRIM_SMITHING_TEMPLATE(-1), @@ -569,6 +586,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla WHEAT_SEEDS(-1), WHITE_BUNDLE(-1, 1), WHITE_DYE(-1), + WHITE_HARNESS(-1, 1), WILD_ARMOR_TRIM_SMITHING_TEMPLATE(-1), WIND_CHARGE(-1), WITCH_SPAWN_EGG(-1), @@ -585,6 +603,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla WRITTEN_BOOK(-1, 16), YELLOW_BUNDLE(-1, 1), YELLOW_DYE(-1), + YELLOW_HARNESS(-1, 1), ZOGLIN_SPAWN_EGG(-1), ZOMBIE_HORSE_SPAWN_EGG(-1), ZOMBIE_SPAWN_EGG(-1), @@ -592,7 +611,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla ZOMBIFIED_PIGLIN_SPAWN_EGG(-1), // End generate - Items // Start generate - Blocks - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 ACACIA_BUTTON(-1, Switch.class), ACACIA_DOOR(-1, Door.class), ACACIA_FENCE(-1, Fence.class), @@ -942,6 +961,7 @@ public enum Material implements Keyed, Translatable, net.kyori.adventure.transla DRAGON_EGG(-1), DRAGON_HEAD(-1, Skull.class), DRAGON_WALL_HEAD(-1, WallSkull.class), + DRIED_GHAST(-1, DriedGhast.class), DRIED_KELP_BLOCK(-1), DRIPSTONE_BLOCK(-1), DROPPER(-1, Dispenser.class), diff --git a/paper-api/src/main/java/org/bukkit/MusicInstrument.java b/paper-api/src/main/java/org/bukkit/MusicInstrument.java index 096723765a..1e975fd76b 100644 --- a/paper-api/src/main/java/org/bukkit/MusicInstrument.java +++ b/paper-api/src/main/java/org/bukkit/MusicInstrument.java @@ -13,7 +13,7 @@ import org.jspecify.annotations.Nullable; public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable { // Start generate - MusicInstrument - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final MusicInstrument ADMIRE_GOAT_HORN = getInstrument("admire_goat_horn"); public static final MusicInstrument CALL_GOAT_HORN = getInstrument("call_goat_horn"); diff --git a/paper-api/src/main/java/org/bukkit/Sound.java b/paper-api/src/main/java/org/bukkit/Sound.java index 8d5fc91fa6..6f54ee85e5 100644 --- a/paper-api/src/main/java/org/bukkit/Sound.java +++ b/paper-api/src/main/java/org/bukkit/Sound.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.NotNull; public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound.Sound.Type { // Paper - implement Sound.Type // Start generate - Sound - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Sound AMBIENT_BASALT_DELTAS_ADDITIONS = getSound("ambient.basalt_deltas.additions"); Sound AMBIENT_BASALT_DELTAS_LOOP = getSound("ambient.basalt_deltas.loop"); @@ -569,6 +569,22 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound BLOCK_DISPENSER_LAUNCH = getSound("block.dispenser.launch"); + Sound BLOCK_DRIED_GHAST_AMBIENT = getSound("block.dried_ghast.ambient"); + + Sound BLOCK_DRIED_GHAST_AMBIENT_WATER = getSound("block.dried_ghast.ambient_water"); + + Sound BLOCK_DRIED_GHAST_BREAK = getSound("block.dried_ghast.break"); + + Sound BLOCK_DRIED_GHAST_FALL = getSound("block.dried_ghast.fall"); + + Sound BLOCK_DRIED_GHAST_PLACE = getSound("block.dried_ghast.place"); + + Sound BLOCK_DRIED_GHAST_PLACE_IN_WATER = getSound("block.dried_ghast.place_in_water"); + + Sound BLOCK_DRIED_GHAST_STEP = getSound("block.dried_ghast.step"); + + Sound BLOCK_DRIED_GHAST_TRANSITION = getSound("block.dried_ghast.transition"); + Sound BLOCK_DRIPSTONE_BLOCK_BREAK = getSound("block.dripstone_block.break"); Sound BLOCK_DRIPSTONE_BLOCK_FALL = getSound("block.dripstone_block.fall"); @@ -579,6 +595,8 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound BLOCK_DRIPSTONE_BLOCK_STEP = getSound("block.dripstone_block.step"); + Sound BLOCK_DRY_GRASS_AMBIENT = getSound("block.dry_grass.ambient"); + Sound BLOCK_ENCHANTMENT_TABLE_USE = getSound("block.enchantment_table.use"); Sound BLOCK_END_GATEWAY_SPAWN = getSound("block.end_gateway.spawn"); @@ -1193,8 +1211,6 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound BLOCK_SAND_STEP = getSound("block.sand.step"); - Sound BLOCK_SAND_WIND = getSound("block.sand.wind"); - Sound BLOCK_SCAFFOLDING_BREAK = getSound("block.scaffolding.break"); Sound BLOCK_SCAFFOLDING_FALL = getSound("block.scaffolding.fall"); @@ -2077,6 +2093,14 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ENTITY_GHAST_WARN = getSound("entity.ghast.warn"); + Sound ENTITY_GHASTLING_AMBIENT = getSound("entity.ghastling.ambient"); + + Sound ENTITY_GHASTLING_DEATH = getSound("entity.ghastling.death"); + + Sound ENTITY_GHASTLING_HURT = getSound("entity.ghastling.hurt"); + + Sound ENTITY_GHASTLING_SPAWN = getSound("entity.ghastling.spawn"); + Sound ENTITY_GLOW_ITEM_FRAME_ADD_ITEM = getSound("entity.glow_item_frame.add_item"); Sound ENTITY_GLOW_ITEM_FRAME_BREAK = getSound("entity.glow_item_frame.break"); @@ -2147,6 +2171,22 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ENTITY_GUARDIAN_HURT_LAND = getSound("entity.guardian.hurt_land"); + Sound ENTITY_HAPPY_GHAST_AMBIENT = getSound("entity.happy_ghast.ambient"); + + Sound ENTITY_HAPPY_GHAST_DEATH = getSound("entity.happy_ghast.death"); + + Sound ENTITY_HAPPY_GHAST_EQUIP = getSound("entity.happy_ghast.equip"); + + Sound ENTITY_HAPPY_GHAST_HARNESS_GOGGLES_DOWN = getSound("entity.happy_ghast.harness_goggles_down"); + + Sound ENTITY_HAPPY_GHAST_HARNESS_GOGGLES_UP = getSound("entity.happy_ghast.harness_goggles_up"); + + Sound ENTITY_HAPPY_GHAST_HURT = getSound("entity.happy_ghast.hurt"); + + Sound ENTITY_HAPPY_GHAST_RIDING = getSound("entity.happy_ghast.riding"); + + Sound ENTITY_HAPPY_GHAST_UNEQUIP = getSound("entity.happy_ghast.unequip"); + Sound ENTITY_HOGLIN_AMBIENT = getSound("entity.hoglin.ambient"); Sound ENTITY_HOGLIN_ANGRY = getSound("entity.hoglin.angry"); @@ -2251,10 +2291,6 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ENTITY_ITEM_FRAME_ROTATE_ITEM = getSound("entity.item_frame.rotate_item"); - Sound ENTITY_LEASH_KNOT_BREAK = getSound("entity.leash_knot.break"); - - Sound ENTITY_LEASH_KNOT_PLACE = getSound("entity.leash_knot.place"); - Sound ENTITY_LIGHTNING_BOLT_IMPACT = getSound("entity.lightning_bolt.impact"); Sound ENTITY_LIGHTNING_BOLT_THUNDER = getSound("entity.lightning_bolt.thunder"); @@ -2555,8 +2591,6 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ENTITY_POLAR_BEAR_WARNING = getSound("entity.polar_bear.warning"); - Sound ENTITY_PUFFER_FISH_AMBIENT = getSound("entity.puffer_fish.ambient"); - Sound ENTITY_PUFFER_FISH_BLOW_OUT = getSound("entity.puffer_fish.blow_out"); Sound ENTITY_PUFFER_FISH_BLOW_UP = getSound("entity.puffer_fish.blow_up"); @@ -3253,8 +3287,18 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ITEM_HONEYCOMB_WAX_ON = getSound("item.honeycomb.wax_on"); + Sound ITEM_HORSE_ARMOR_UNEQUIP = getSound("item.horse_armor.unequip"); + Sound ITEM_INK_SAC_USE = getSound("item.ink_sac.use"); + Sound ITEM_LEAD_BREAK = getSound("item.lead.break"); + + Sound ITEM_LEAD_TIED = getSound("item.lead.tied"); + + Sound ITEM_LEAD_UNTIED = getSound("item.lead.untied"); + + Sound ITEM_LLAMA_CARPET_UNEQUIP = getSound("item.llama_carpet.unequip"); + Sound ITEM_LODESTONE_COMPASS_LOCK = getSound("item.lodestone_compass.lock"); Sound ITEM_MACE_SMASH_AIR = getSound("item.mace.smash_air"); @@ -3267,6 +3311,10 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound ITEM_OMINOUS_BOTTLE_DISPOSE = getSound("item.ominous_bottle.dispose"); + Sound ITEM_SADDLE_UNEQUIP = getSound("item.saddle.unequip"); + + Sound ITEM_SHEARS_SNIP = getSound("item.shears.snip"); + Sound ITEM_SHIELD_BLOCK = getSound("item.shield.block"); Sound ITEM_SHIELD_BREAK = getSound("item.shield.break"); @@ -3399,6 +3447,8 @@ public interface Sound extends OldEnum, Keyed, net.kyori.adventure.sound. Sound MUSIC_DISC_STRAD = getSound("music_disc.strad"); + Sound MUSIC_DISC_TEARS = getSound("music_disc.tears"); + Sound MUSIC_DISC_WAIT = getSound("music_disc.wait"); Sound MUSIC_DISC_WARD = getSound("music_disc.ward"); diff --git a/paper-api/src/main/java/org/bukkit/SoundCategory.java b/paper-api/src/main/java/org/bukkit/SoundCategory.java index 2d91924b7f..eb7457dad0 100644 --- a/paper-api/src/main/java/org/bukkit/SoundCategory.java +++ b/paper-api/src/main/java/org/bukkit/SoundCategory.java @@ -1,10 +1,16 @@ package org.bukkit; +import net.kyori.adventure.sound.Sound; +import org.jspecify.annotations.NullMarked; + /** * An Enum of categories for sounds. */ -public enum SoundCategory implements net.kyori.adventure.sound.Sound.Source.Provider { // Paper - implement Sound.Source.Provider +@NullMarked +public enum SoundCategory implements Sound.Source.Provider { + // Start generate - SoundCategory + // @GeneratedFrom 1.21.6-rc1 MASTER, MUSIC, RECORDS, @@ -14,23 +20,24 @@ public enum SoundCategory implements net.kyori.adventure.sound.Sound.Source.Prov NEUTRAL, PLAYERS, AMBIENT, - VOICE; + VOICE, + UI; + // End generate - SoundCategory - // Paper start - implement Sound.Source.Provider @Override - public net.kyori.adventure.sound.Sound.@org.jetbrains.annotations.NotNull Source soundSource() { + public Sound.Source soundSource() { return switch (this) { - case MASTER -> net.kyori.adventure.sound.Sound.Source.MASTER; - case MUSIC -> net.kyori.adventure.sound.Sound.Source.MUSIC; - case RECORDS -> net.kyori.adventure.sound.Sound.Source.RECORD; - case WEATHER -> net.kyori.adventure.sound.Sound.Source.WEATHER; - case BLOCKS -> net.kyori.adventure.sound.Sound.Source.BLOCK; - case HOSTILE -> net.kyori.adventure.sound.Sound.Source.HOSTILE; - case NEUTRAL -> net.kyori.adventure.sound.Sound.Source.NEUTRAL; - case PLAYERS -> net.kyori.adventure.sound.Sound.Source.PLAYER; - case AMBIENT -> net.kyori.adventure.sound.Sound.Source.AMBIENT; - case VOICE -> net.kyori.adventure.sound.Sound.Source.VOICE; + case MASTER -> Sound.Source.MASTER; + case MUSIC -> Sound.Source.MUSIC; + case RECORDS -> Sound.Source.RECORD; + case WEATHER -> Sound.Source.WEATHER; + case BLOCKS -> Sound.Source.BLOCK; + case HOSTILE -> Sound.Source.HOSTILE; + case NEUTRAL -> Sound.Source.NEUTRAL; + case PLAYERS -> Sound.Source.PLAYER; + case AMBIENT -> Sound.Source.AMBIENT; + case VOICE -> Sound.Source.VOICE; + case UI -> throw new UnsupportedOperationException("Waiting on adventure release for the UI sound source"); // todo adventure }; } - // Paper end } diff --git a/paper-api/src/main/java/org/bukkit/Statistic.java b/paper-api/src/main/java/org/bukkit/Statistic.java index b07521166e..72e5c2f7e1 100644 --- a/paper-api/src/main/java/org/bukkit/Statistic.java +++ b/paper-api/src/main/java/org/bukkit/Statistic.java @@ -8,7 +8,7 @@ import org.jetbrains.annotations.NotNull; */ public enum Statistic implements Keyed { // Start generate - StatisticCustom - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 ANIMALS_BRED, AVIATE_ONE_CM, BELL_RING, @@ -33,6 +33,7 @@ public enum Statistic implements Keyed { CAULDRON_FILLED, FISH_CAUGHT, FLY_ONE_CM, + HAPPY_GHAST_ONE_CM, HORSE_ONE_CM, DISPENSER_INSPECTED, DROPPER_INSPECTED, @@ -86,7 +87,7 @@ public enum Statistic implements Keyed { WALK_UNDER_WATER_ONE_CM, // End generate - StatisticCustom // Start generate - StatisticType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 BREAK_ITEM(Type.ITEM), CRAFT_ITEM(Type.ITEM), DROP(Type.ITEM), diff --git a/paper-api/src/main/java/org/bukkit/Tag.java b/paper-api/src/main/java/org/bukkit/Tag.java index 1b2e400887..fb15471586 100644 --- a/paper-api/src/main/java/org/bukkit/Tag.java +++ b/paper-api/src/main/java/org/bukkit/Tag.java @@ -20,7 +20,7 @@ import org.jetbrains.annotations.NotNull; public interface Tag extends Keyed { // Start generate - Tag - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 String REGISTRY_BLOCKS = "blocks"; Tag ACACIA_LOGS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("acacia_logs"), Material.class); @@ -181,6 +181,8 @@ public interface Tag extends Keyed { Tag GUARDED_BY_PIGLINS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("guarded_by_piglins"), Material.class); + Tag HAPPY_GHAST_AVOIDS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("happy_ghast_avoids"), Material.class); + Tag HOGLIN_REPELLENTS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("hoglin_repellents"), Material.class); Tag ICE = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("ice"), Material.class); @@ -275,8 +277,6 @@ public interface Tag extends Keyed { Tag PLANKS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("planks"), Material.class); - Tag PLAYS_AMBIENT_DESERT_BLOCK_SOUNDS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("plays_ambient_desert_block_sounds"), Material.class); - Tag POLAR_BEARS_SPAWNABLE_ON_ALTERNATE = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("polar_bears_spawnable_on_alternate"), Material.class); Tag PORTALS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("portals"), Material.class); @@ -359,6 +359,12 @@ public interface Tag extends Keyed { Tag TRAPDOORS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("trapdoors"), Material.class); + Tag TRIGGERS_AMBIENT_DESERT_DRY_VEGETATION_BLOCK_SOUNDS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("triggers_ambient_desert_dry_vegetation_block_sounds"), Material.class); + + Tag TRIGGERS_AMBIENT_DESERT_SAND_BLOCK_SOUNDS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("triggers_ambient_desert_sand_block_sounds"), Material.class); + + Tag TRIGGERS_AMBIENT_DRIED_GHAST_BLOCK_SOUNDS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("triggers_ambient_dried_ghast_block_sounds"), Material.class); + Tag UNDERWATER_BONEMEALS = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("underwater_bonemeals"), Material.class); Tag UNSTABLE_BOTTOM_CENTER = Bukkit.getTag(REGISTRY_BLOCKS, NamespacedKey.minecraft("unstable_bottom_center"), Material.class); @@ -571,6 +577,12 @@ public interface Tag extends Keyed { Tag ITEMS_HANGING_SIGNS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("hanging_signs"), Material.class); + Tag ITEMS_HAPPY_GHAST_FOOD = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("happy_ghast_food"), Material.class); + + Tag ITEMS_HAPPY_GHAST_TEMPT_ITEMS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("happy_ghast_tempt_items"), Material.class); + + Tag ITEMS_HARNESSES = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("harnesses"), Material.class); + Tag ITEMS_HEAD_ARMOR = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("head_armor"), Material.class); Tag ITEMS_HOES = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("hoes"), Material.class); @@ -783,6 +795,8 @@ public interface Tag extends Keyed { Tag ENTITY_TYPES_CAN_BREATHE_UNDER_WATER = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_breathe_under_water"), EntityType.class); + Tag ENTITY_TYPES_CAN_EQUIP_HARNESS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_equip_harness"), EntityType.class); + Tag ENTITY_TYPES_CAN_EQUIP_SADDLE = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_equip_saddle"), EntityType.class); Tag ENTITY_TYPES_CAN_TURN_IN_BOATS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("can_turn_in_boats"), EntityType.class); @@ -795,6 +809,8 @@ public interface Tag extends Keyed { Tag ENTITY_TYPES_FALL_DAMAGE_IMMUNE = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("fall_damage_immune"), EntityType.class); + Tag ENTITY_TYPES_FOLLOWABLE_FRIENDLY_MOBS = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("followable_friendly_mobs"), EntityType.class); + Tag ENTITY_TYPES_FREEZE_HURTS_EXTRA_TYPES = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("freeze_hurts_extra_types"), EntityType.class); Tag ENTITY_TYPES_FREEZE_IMMUNE_ENTITY_TYPES = Bukkit.getTag(REGISTRY_ENTITY_TYPES, NamespacedKey.minecraft("freeze_immune_entity_types"), EntityType.class); @@ -865,6 +881,11 @@ public interface Tag extends Keyed { */ @Deprecated(since = "1.21.5", forRemoval = true) Tag DEAD_BUSH_MAY_PLACE_ON = DRY_VEGETATION_MAY_PLACE_ON; + /** + * @deprecated replaced by {@link #TRIGGERS_AMBIENT_DESERT_DRY_VEGETATION_BLOCK_SOUNDS} + */ + @Deprecated(since = "1.21.6", forRemoval = true) + Tag PLAYS_AMBIENT_DESERT_BLOCK_SOUNDS = TRIGGERS_AMBIENT_DESERT_DRY_VEGETATION_BLOCK_SOUNDS; /** * Vanilla block tag representing all blocks that are replaceable by * dripstone. diff --git a/paper-api/src/main/java/org/bukkit/Vibration.java b/paper-api/src/main/java/org/bukkit/Vibration.java index 2c0e18e8dd..b20c99f278 100644 --- a/paper-api/src/main/java/org/bukkit/Vibration.java +++ b/paper-api/src/main/java/org/bukkit/Vibration.java @@ -13,14 +13,13 @@ public class Vibration { private final Destination destination; private final int arrivalTime; - // Paper start public Vibration(@NotNull Destination destination, @NotNull int arrivalTime) { this.destination = destination; this.arrivalTime = arrivalTime; - this.origin = new Location(null, 0, 0, 0); // Dummy origin because getter expects null + this.origin = new Location(null, 0, 0, 0); // Dummy origin because getter expects not null } - @Deprecated(forRemoval = true) // Paper end + @Deprecated(forRemoval = true) public Vibration(@NotNull Location origin, @NotNull Destination destination, int arrivalTime) { this.origin = origin; this.destination = destination; diff --git a/paper-api/src/main/java/org/bukkit/World.java b/paper-api/src/main/java/org/bukkit/World.java index a8b64f78bf..04a1379f5f 100644 --- a/paper-api/src/main/java/org/bukkit/World.java +++ b/paper-api/src/main/java/org/bukkit/World.java @@ -729,7 +729,10 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param location Location to spawn the tree * @param type Type of the tree to create * @return true if the tree was created successfully, otherwise false + * @deprecated in favor of {@link #generateTree(Location, java.util.Random, TreeType)} to specify its own random instance + * and this method is not accessible through {@link RegionAccessor} */ + @Deprecated(since = "1.21.6") public boolean generateTree(@NotNull Location location, @NotNull TreeType type); /** @@ -850,6 +853,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient // Paper start - additional getNearbyEntities API /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param radius Radius * @return the collection of entities near location. This will always be a non-null collection. @@ -860,6 +864,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param xzRadius X/Z Radius * @param yRadius Y Radius @@ -871,6 +876,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param xRadius X Radius * @param yRadius Y Radius @@ -883,6 +889,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param radius X Radius * @param predicate a predicate used to filter results @@ -894,6 +901,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param xzRadius X/Z Radius * @param yRadius Y Radius @@ -906,6 +914,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby LivingEntities within the specified radius (bounding box) + * * @param loc Center location * @param xRadius X Radius * @param yRadius Y Radius @@ -919,6 +928,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param radius X/Y/Z Radius * @return the collection of living entities near location. This will always be a non-null collection. @@ -929,6 +939,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param xzRadius X/Z Radius * @param yRadius Y Radius @@ -940,6 +951,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param xRadius X Radius * @param yRadius Y Radius @@ -952,6 +964,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param radius X/Y/Z Radius * @param predicate a predicate used to filter results @@ -963,6 +976,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param xzRadius X/Z Radius * @param yRadius Y Radius @@ -975,6 +989,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets nearby players within the specified radius (bounding box) + * * @param loc Center location * @param xRadius X Radius * @param yRadius Y Radius @@ -988,6 +1003,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param radius X/Y/Z radius to search within @@ -1000,6 +1016,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param xzRadius X/Z radius to search within @@ -1013,6 +1030,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param xRadius X Radius @@ -1027,6 +1045,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param radius X/Y/Z radius to search within @@ -1040,6 +1059,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius, with x and x radius matching (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param xzRadius X/Z radius to search within @@ -1054,6 +1074,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient /** * Gets all nearby entities of the specified type, within the specified radius (bounding box) + * * @param clazz Type to filter by * @param loc Center location * @param xRadius X Radius @@ -1063,16 +1084,13 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient * @param the entity type * @return the collection of entities near location. This will always be a non-null collection. */ - default @NotNull Collection getNearbyEntitiesByType(@Nullable Class clazz, final @NotNull Location loc, final double xRadius, final double yRadius, final double zRadius, final @Nullable Predicate predicate) { - if (clazz == null) { - clazz = Entity.class; - } + default @NotNull Collection getNearbyEntitiesByType(@Nullable Class clazz, final @NotNull Location loc, final double xRadius, final double yRadius, final double zRadius, final @Nullable Predicate predicate) { final List nearby = new ArrayList<>(); - for (final Entity bukkitEntity : this.getNearbyEntities(loc, xRadius, yRadius, zRadius)) { + for (final Entity entity : this.getNearbyEntities(loc, xRadius, yRadius, zRadius)) { //noinspection unchecked - if (clazz.isAssignableFrom(bukkitEntity.getClass()) && (predicate == null || predicate.test((T) bukkitEntity))) { + if ((clazz == null || clazz.isInstance(entity)) && (predicate == null || predicate.test((T) entity))) { //noinspection unchecked - nearby.add((T) bukkitEntity); + nearby.add((T) entity); } } return nearby; diff --git a/paper-api/src/main/java/org/bukkit/attribute/Attribute.java b/paper-api/src/main/java/org/bukkit/attribute/Attribute.java index 978b0e779e..78361d62fd 100644 --- a/paper-api/src/main/java/org/bukkit/attribute/Attribute.java +++ b/paper-api/src/main/java/org/bukkit/attribute/Attribute.java @@ -93,6 +93,10 @@ public interface Attribute extends OldEnum, Keyed, Translatable, net. * How long an entity remains burning after ignition. */ Attribute BURNING_TIME = getAttribute("burning_time"); + /** + * The camera distance of a player to their own entity. + */ + Attribute CAMERA_DISTANCE = getAttribute("camera_distance"); /** * Resistance to knockback from explosions. */ @@ -145,6 +149,14 @@ public interface Attribute extends OldEnum, Keyed, Translatable, net. * Chance of a zombie to spawn reinforcements. */ Attribute SPAWN_REINFORCEMENTS = getAttribute("spawn_reinforcements"); + /** + * Attribute controlling the range an entity transmits itself as a waypoint. + */ + Attribute WAYPOINT_TRANSMIT_RANGE = getAttribute("waypoint_transmit_range"); + /** + * Attribute controlling the range an entity receives other waypoints from. + */ + Attribute WAYPOINT_RECEIVE_RANGE = getAttribute("waypoint_receive_range"); @NotNull private static Attribute getAttribute(@NotNull String key) { diff --git a/paper-api/src/main/java/org/bukkit/block/Biome.java b/paper-api/src/main/java/org/bukkit/block/Biome.java index 3ab2c73641..d2efec3ec3 100644 --- a/paper-api/src/main/java/org/bukkit/block/Biome.java +++ b/paper-api/src/main/java/org/bukkit/block/Biome.java @@ -25,7 +25,7 @@ import org.jetbrains.annotations.NotNull; public interface Biome extends OldEnum, Keyed, net.kyori.adventure.translation.Translatable { // Paper - Adventure translations // Start generate - Biome - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Biome BADLANDS = getBiome("badlands"); Biome BAMBOO_JUNGLE = getBiome("bamboo_jungle"); diff --git a/paper-api/src/main/java/org/bukkit/block/BlockType.java b/paper-api/src/main/java/org/bukkit/block/BlockType.java index ae42c2ddcd..88cf293c3e 100644 --- a/paper-api/src/main/java/org/bukkit/block/BlockType.java +++ b/paper-api/src/main/java/org/bukkit/block/BlockType.java @@ -53,6 +53,7 @@ import org.bukkit.block.data.type.DaylightDetector; import org.bukkit.block.data.type.DecoratedPot; import org.bukkit.block.data.type.Dispenser; import org.bukkit.block.data.type.Door; +import org.bukkit.block.data.type.DriedGhast; import org.bukkit.block.data.type.Dripleaf; import org.bukkit.block.data.type.EndPortalFrame; import org.bukkit.block.data.type.EnderChest; @@ -197,7 +198,7 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran // // Start generate - BlockType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 BlockType.Typed ACACIA_BUTTON = getBlockType("acacia_button"); BlockType.Typed ACACIA_DOOR = getBlockType("acacia_door"); @@ -898,6 +899,8 @@ public interface BlockType extends Keyed, Translatable, net.kyori.adventure.tran BlockType.Typed DRAGON_WALL_HEAD = getBlockType("dragon_wall_head"); + BlockType.Typed DRIED_GHAST = getBlockType("dried_ghast"); + BlockType.Typed DRIED_KELP_BLOCK = getBlockType("dried_kelp_block"); BlockType.Typed DRIPSTONE_BLOCK = getBlockType("dripstone_block"); diff --git a/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java b/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java index 15415ecbbc..38a6a449c1 100644 --- a/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java +++ b/paper-api/src/main/java/org/bukkit/block/banner/PatternType.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; public interface PatternType extends OldEnum, Keyed { // Start generate - PatternType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 PatternType BASE = getType("base"); PatternType BORDER = getType("border"); diff --git a/paper-api/src/main/java/org/bukkit/block/data/type/DriedGhast.java b/paper-api/src/main/java/org/bukkit/block/data/type/DriedGhast.java new file mode 100644 index 0000000000..8907aa9269 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/block/data/type/DriedGhast.java @@ -0,0 +1,32 @@ +package org.bukkit.block.data.type; + +import org.bukkit.block.data.Directional; +import org.bukkit.block.data.Waterlogged; + +/** + * Represents a dried ghast block data. + */ +public interface DriedGhast extends Directional, Waterlogged { + + /** + * Gets the hydration level of this dried ghast. + * + * @return the hydration level, reaching from 0 to {@link #getMaximumHydration()} + */ + int getHydration(); + + /** + * Sets the hydration level of this dried ghast. + * + * @param hydration the hydration level, reaching from 0 to {@link #getMaximumHydration()} + */ + void setHydration(final int hydration); + + /** + * Provides the maximum hydration level this dried ghast can reach. + * + * @return the maximum level. + */ + int getMaximumHydration(); + +} diff --git a/paper-api/src/main/java/org/bukkit/damage/DamageType.java b/paper-api/src/main/java/org/bukkit/damage/DamageType.java index 88a430b47a..d31e1512b4 100644 --- a/paper-api/src/main/java/org/bukkit/damage/DamageType.java +++ b/paper-api/src/main/java/org/bukkit/damage/DamageType.java @@ -22,7 +22,7 @@ import org.jetbrains.annotations.NotNull; public interface DamageType extends Keyed, Translatable { // Start generate - DamageType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 DamageType ARROW = getDamageType("arrow"); DamageType BAD_RESPAWN_POINT = getDamageType("bad_respawn_point"); diff --git a/paper-api/src/main/java/org/bukkit/entity/Armadillo.java b/paper-api/src/main/java/org/bukkit/entity/Armadillo.java index d4eacd26e4..92ae3daff7 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Armadillo.java +++ b/paper-api/src/main/java/org/bukkit/entity/Armadillo.java @@ -29,10 +29,13 @@ public interface Armadillo extends Animals { * Represents the current state of the armadillo. */ enum State { + // Start generate - ArmadilloState + // @GeneratedFrom 1.21.6-rc1 IDLE, ROLLING, SCARED, UNROLLING; + // End generate - ArmadilloState } } diff --git a/paper-api/src/main/java/org/bukkit/entity/Boat.java b/paper-api/src/main/java/org/bukkit/entity/Boat.java index 92e6bf855e..0e4ce1dff1 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Boat.java +++ b/paper-api/src/main/java/org/bukkit/entity/Boat.java @@ -177,7 +177,7 @@ public interface Boat extends Vehicle, io.papermc.paper.entity.Leashable { // Pa NOT_IN_WORLD, // Start generate - BoatStatus - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 IN_WATER, UNDER_WATER, UNDER_FLOWING_WATER, diff --git a/paper-api/src/main/java/org/bukkit/entity/Cat.java b/paper-api/src/main/java/org/bukkit/entity/Cat.java index 95b917ae64..20dd548e5c 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Cat.java +++ b/paper-api/src/main/java/org/bukkit/entity/Cat.java @@ -55,7 +55,7 @@ public interface Cat extends Tameable, Sittable, io.papermc.paper.entity.CollarC interface Type extends OldEnum, Keyed { // Start generate - CatType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Type ALL_BLACK = getType("all_black"); Type BLACK = getType("black"); diff --git a/paper-api/src/main/java/org/bukkit/entity/Chicken.java b/paper-api/src/main/java/org/bukkit/entity/Chicken.java index 2866e19ab6..5f33149f6c 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Chicken.java +++ b/paper-api/src/main/java/org/bukkit/entity/Chicken.java @@ -60,7 +60,7 @@ public interface Chicken extends Animals { interface Variant extends Keyed { // Start generate - ChickenVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Variant COLD = getVariant("cold"); Variant TEMPERATE = getVariant("temperate"); diff --git a/paper-api/src/main/java/org/bukkit/entity/Cow.java b/paper-api/src/main/java/org/bukkit/entity/Cow.java index 286c58104d..360512141c 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Cow.java +++ b/paper-api/src/main/java/org/bukkit/entity/Cow.java @@ -32,7 +32,7 @@ public interface Cow extends AbstractCow { interface Variant extends Keyed { // Start generate - CowVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Variant COLD = getVariant("cold"); Variant TEMPERATE = getVariant("temperate"); diff --git a/paper-api/src/main/java/org/bukkit/entity/EnderSignal.java b/paper-api/src/main/java/org/bukkit/entity/EnderSignal.java index c8c74651e1..35e0396667 100644 --- a/paper-api/src/main/java/org/bukkit/entity/EnderSignal.java +++ b/paper-api/src/main/java/org/bukkit/entity/EnderSignal.java @@ -15,7 +15,7 @@ public interface EnderSignal extends Entity { * * @return the {@link Location} this EnderSignal is moving towards. */ - @NotNull + @Nullable public Location getTargetLocation(); /** diff --git a/paper-api/src/main/java/org/bukkit/entity/Entity.java b/paper-api/src/main/java/org/bukkit/entity/Entity.java index 66a31c5d83..0aa51b777f 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Entity.java +++ b/paper-api/src/main/java/org/bukkit/entity/Entity.java @@ -328,7 +328,7 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent boolean isVisualFire(); /** - * Retrieves the visual fire state of the object. + * Retrieves the visual fire state of the entity. * * @return A TriState indicating the current visual fire state. */ diff --git a/paper-api/src/main/java/org/bukkit/entity/EntityType.java b/paper-api/src/main/java/org/bukkit/entity/EntityType.java index 4725b93f16..6a077d42eb 100644 --- a/paper-api/src/main/java/org/bukkit/entity/EntityType.java +++ b/paper-api/src/main/java/org/bukkit/entity/EntityType.java @@ -46,7 +46,7 @@ import org.jetbrains.annotations.Nullable; public enum EntityType implements Keyed, Translatable, net.kyori.adventure.translation.Translatable, io.papermc.paper.world.flag.FeatureDependant { // Paper - translatable // Start generate - EntityType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 ACACIA_BOAT("acacia_boat", AcaciaBoat.class, -1), ACACIA_CHEST_BOAT("acacia_chest_boat", AcaciaChestBoat.class, -1), ALLAY("allay", Allay.class, -1), @@ -109,6 +109,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans GLOW_SQUID("glow_squid", GlowSquid.class, -1), GOAT("goat", Goat.class, -1), GUARDIAN("guardian", Guardian.class, 68), + HAPPY_GHAST("happy_ghast", HappyGhast.class, -1), HOGLIN("hoglin", Hoglin.class, -1), HOPPER_MINECART("hopper_minecart", HopperMinecart.class, 46), HORSE("horse", Horse.class, 100), @@ -130,7 +131,7 @@ public enum EntityType implements Keyed, Translatable, net.kyori.adventure.trans MANGROVE_BOAT("mangrove_boat", MangroveBoat.class, -1), MANGROVE_CHEST_BOAT("mangrove_chest_boat", MangroveChestBoat.class, -1), MARKER("marker", Marker.class, -1), - MINECART("minecart", Minecart.class, 42), + MINECART("minecart", RideableMinecart.class, 42), MOOSHROOM("mooshroom", MushroomCow.class, 96), MULE("mule", Mule.class, 32), OAK_BOAT("oak_boat", OakBoat.class, -1), diff --git a/paper-api/src/main/java/org/bukkit/entity/Flying.java b/paper-api/src/main/java/org/bukkit/entity/Flying.java index 580ce18bf4..319b59845d 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Flying.java +++ b/paper-api/src/main/java/org/bukkit/entity/Flying.java @@ -2,5 +2,7 @@ package org.bukkit.entity; /** * Represents a Flying Entity. + * @deprecated Minecraft no longer has a distinction for these types of mobs. */ +@Deprecated(forRemoval = true, since = "1.21.6") public interface Flying extends Mob {} diff --git a/paper-api/src/main/java/org/bukkit/entity/Fox.java b/paper-api/src/main/java/org/bukkit/entity/Fox.java index 6944345881..64e8ff4fb0 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Fox.java +++ b/paper-api/src/main/java/org/bukkit/entity/Fox.java @@ -90,7 +90,7 @@ public interface Fox extends Animals, Sittable { */ public enum Type { // Start generate - FoxType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 RED, SNOW; // End generate - FoxType diff --git a/paper-api/src/main/java/org/bukkit/entity/Frog.java b/paper-api/src/main/java/org/bukkit/entity/Frog.java index 7115201bd6..808bc76b0b 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Frog.java +++ b/paper-api/src/main/java/org/bukkit/entity/Frog.java @@ -53,7 +53,7 @@ public interface Frog extends Animals { interface Variant extends OldEnum, Keyed { // Start generate - FrogVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Variant COLD = getVariant("cold"); Variant TEMPERATE = getVariant("temperate"); diff --git a/paper-api/src/main/java/org/bukkit/entity/HappyGhast.java b/paper-api/src/main/java/org/bukkit/entity/HappyGhast.java new file mode 100644 index 0000000000..eef512c105 --- /dev/null +++ b/paper-api/src/main/java/org/bukkit/entity/HappyGhast.java @@ -0,0 +1,7 @@ +package org.bukkit.entity; + +/** + * Represents a happy ghast. + */ +public interface HappyGhast extends Vehicle, Animals { +} diff --git a/paper-api/src/main/java/org/bukkit/entity/Panda.java b/paper-api/src/main/java/org/bukkit/entity/Panda.java index be66608e64..1dbd7ca356 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Panda.java +++ b/paper-api/src/main/java/org/bukkit/entity/Panda.java @@ -186,7 +186,7 @@ public interface Panda extends Animals, Sittable { public enum Gene { // Start generate - PandaGene - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 NORMAL(false), LAZY(false), WORRIED(false), diff --git a/paper-api/src/main/java/org/bukkit/entity/Pig.java b/paper-api/src/main/java/org/bukkit/entity/Pig.java index 9389bbc1e9..9374c2e358 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Pig.java +++ b/paper-api/src/main/java/org/bukkit/entity/Pig.java @@ -32,7 +32,7 @@ public interface Pig extends Steerable, Vehicle { interface Variant extends Keyed { // Start generate - PigVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Variant COLD = getVariant("cold"); Variant TEMPERATE = getVariant("temperate"); diff --git a/paper-api/src/main/java/org/bukkit/entity/Pose.java b/paper-api/src/main/java/org/bukkit/entity/Pose.java index d5e3384458..1a6dd2a36a 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Pose.java +++ b/paper-api/src/main/java/org/bukkit/entity/Pose.java @@ -5,9 +5,9 @@ package org.bukkit.entity; */ public enum Pose { + // Start generate - Pose /** * Entity is standing normally. - * */ STANDING, /** @@ -78,4 +78,5 @@ public enum Pose { * Entity is inhaling. */ INHALING; + // End generate - Pose } diff --git a/paper-api/src/main/java/org/bukkit/entity/Salmon.java b/paper-api/src/main/java/org/bukkit/entity/Salmon.java index 18e38e492a..d882e50afe 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Salmon.java +++ b/paper-api/src/main/java/org/bukkit/entity/Salmon.java @@ -28,7 +28,7 @@ public interface Salmon extends io.papermc.paper.entity.SchoolableFish { // Pape public enum Variant { // Start generate - SalmonVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 SMALL, MEDIUM, LARGE; diff --git a/paper-api/src/main/java/org/bukkit/entity/Sniffer.java b/paper-api/src/main/java/org/bukkit/entity/Sniffer.java index a2a06730d9..3b1fe9f6aa 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Sniffer.java +++ b/paper-api/src/main/java/org/bukkit/entity/Sniffer.java @@ -75,7 +75,7 @@ public interface Sniffer extends Animals { */ public enum State { // Start generate - SnifferState - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 IDLING, FEELING_HAPPY, SCENTING, diff --git a/paper-api/src/main/java/org/bukkit/entity/TropicalFish.java b/paper-api/src/main/java/org/bukkit/entity/TropicalFish.java index 0cabfb192f..6538fc1e73 100644 --- a/paper-api/src/main/java/org/bukkit/entity/TropicalFish.java +++ b/paper-api/src/main/java/org/bukkit/entity/TropicalFish.java @@ -61,7 +61,7 @@ public interface TropicalFish extends io.papermc.paper.entity.SchoolableFish { / public static enum Pattern { // Start generate - TropicalFishPattern - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 KOB, SUNSTREAK, SNOOPER, diff --git a/paper-api/src/main/java/org/bukkit/entity/Villager.java b/paper-api/src/main/java/org/bukkit/entity/Villager.java index 4d88bb2eaa..c3d37131fb 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Villager.java +++ b/paper-api/src/main/java/org/bukkit/entity/Villager.java @@ -172,7 +172,7 @@ public interface Villager extends AbstractVillager { interface Type extends OldEnum, Keyed { // Start generate - VillagerType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Type DESERT = getType("desert"); Type JUNGLE = getType("jungle"); @@ -224,7 +224,7 @@ public interface Villager extends AbstractVillager { interface Profession extends OldEnum, Keyed, net.kyori.adventure.translation.Translatable { // Start generate - VillagerProfession - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 /** * Armorer profession. Wears a black apron. Armorers primarily trade for * iron armor, chainmail armor, and sometimes diamond armor. diff --git a/paper-api/src/main/java/org/bukkit/entity/Wolf.java b/paper-api/src/main/java/org/bukkit/entity/Wolf.java index a6414ffc4a..693bc63cb9 100644 --- a/paper-api/src/main/java/org/bukkit/entity/Wolf.java +++ b/paper-api/src/main/java/org/bukkit/entity/Wolf.java @@ -142,7 +142,7 @@ public interface Wolf extends Tameable, Sittable, io.papermc.paper.entity.Collar interface SoundVariant extends Keyed { // Start generate - WolfSoundVariant - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 SoundVariant ANGRY = getSoundVariant("angry"); SoundVariant BIG = getSoundVariant("big"); diff --git a/paper-api/src/main/java/org/bukkit/entity/memory/MemoryKey.java b/paper-api/src/main/java/org/bukkit/entity/memory/MemoryKey.java index 4a4ddab67f..fafc1647dc 100644 --- a/paper-api/src/main/java/org/bukkit/entity/memory/MemoryKey.java +++ b/paper-api/src/main/java/org/bukkit/entity/memory/MemoryKey.java @@ -47,7 +47,7 @@ public final class MemoryKey implements Keyed { private static final Map> MEMORY_KEYS = new HashMap<>(); // Start generate - MemoryKey - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final MemoryKey ADMIRING_DISABLED = new MemoryKey<>(NamespacedKey.minecraft("admiring_disabled"), Boolean.class); public static final MemoryKey ADMIRING_ITEM = new MemoryKey<>(NamespacedKey.minecraft("admiring_item"), Boolean.class); diff --git a/paper-api/src/main/java/org/bukkit/event/block/SpongeAbsorbEvent.java b/paper-api/src/main/java/org/bukkit/event/block/SpongeAbsorbEvent.java index ae56902a84..07495ed6b8 100644 --- a/paper-api/src/main/java/org/bukkit/event/block/SpongeAbsorbEvent.java +++ b/paper-api/src/main/java/org/bukkit/event/block/SpongeAbsorbEvent.java @@ -32,12 +32,12 @@ public class SpongeAbsorbEvent extends BlockEvent implements Cancellable { } /** - * Get a list of all blocks to be removed by the sponge. + * Get a list of all blocks to be cleared by the sponge. *
* This list is mutable and contains the blocks in their removed state, i.e. - * having a type of {@link Material#AIR}. + * having a type of {@link Material#AIR} or not waterlogged. * - * @return list of the to be removed blocks. + * @return list of the cleared blocks. */ @NotNull public List getBlocks() { diff --git a/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java b/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java index e8a8c70dcd..be3fa8c1f2 100644 --- a/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java +++ b/paper-api/src/main/java/org/bukkit/generator/structure/Structure.java @@ -17,7 +17,7 @@ import org.jetbrains.annotations.NotNull; public abstract class Structure implements Keyed { // Start generate - Structure - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final Structure ANCIENT_CITY = getStructure("ancient_city"); public static final Structure BASTION_REMNANT = getStructure("bastion_remnant"); diff --git a/paper-api/src/main/java/org/bukkit/generator/structure/StructureType.java b/paper-api/src/main/java/org/bukkit/generator/structure/StructureType.java index 11e5c9e23c..8f0bd2950f 100644 --- a/paper-api/src/main/java/org/bukkit/generator/structure/StructureType.java +++ b/paper-api/src/main/java/org/bukkit/generator/structure/StructureType.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.NotNull; public abstract class StructureType implements Keyed { // Start generate - StructureType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final StructureType BURIED_TREASURE = getStructureType("buried_treasure"); public static final StructureType DESERT_PYRAMID = getStructureType("desert_pyramid"); diff --git a/paper-api/src/main/java/org/bukkit/inventory/EquipmentSlot.java b/paper-api/src/main/java/org/bukkit/inventory/EquipmentSlot.java index 71d95c164e..a5ea15f129 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/EquipmentSlot.java +++ b/paper-api/src/main/java/org/bukkit/inventory/EquipmentSlot.java @@ -13,7 +13,7 @@ public enum EquipmentSlot { CHEST(() -> EquipmentSlotGroup.CHEST), HEAD(() -> EquipmentSlotGroup.HEAD), /** - * Only for certain entities such as horses and wolves. + * Only for certain entities such as horses, happy ghasts and wolves. */ BODY(() -> EquipmentSlotGroup.BODY), /** diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemRarity.java b/paper-api/src/main/java/org/bukkit/inventory/ItemRarity.java index 3547e1578b..560470bfb9 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemRarity.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemRarity.java @@ -10,7 +10,7 @@ import net.kyori.adventure.text.format.TextColor; public enum ItemRarity { // Start generate - ItemRarity - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 COMMON(NamedTextColor.WHITE), UNCOMMON(NamedTextColor.YELLOW), RARE(NamedTextColor.AQUA), diff --git a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java index 23f8747d8e..50d0bb6582 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/ItemType.java +++ b/paper-api/src/main/java/org/bukkit/inventory/ItemType.java @@ -90,7 +90,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans // // Start generate - ItemType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-pre3 ItemType.Typed ACACIA_BOAT = getItemType("acacia_boat"); ItemType.Typed ACACIA_BUTTON = getItemType("acacia_button"); @@ -281,7 +281,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BLACK_BANNER = getItemType("black_banner"); - ItemType.Typed BLACK_BED = getItemType("black_bed"); + ItemType.Typed BLACK_BED = getItemType("black_bed"); ItemType.Typed BLACK_BUNDLE = getItemType("black_bundle"); @@ -297,6 +297,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BLACK_GLAZED_TERRACOTTA = getItemType("black_glazed_terracotta"); + ItemType.Typed BLACK_HARNESS = getItemType("black_harness"); + ItemType.Typed BLACK_SHULKER_BOX = getItemType("black_shulker_box"); ItemType.Typed BLACK_STAINED_GLASS = getItemType("black_stained_glass"); @@ -327,7 +329,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BLUE_BANNER = getItemType("blue_banner"); - ItemType.Typed BLUE_BED = getItemType("blue_bed"); + ItemType.Typed BLUE_BED = getItemType("blue_bed"); ItemType.Typed BLUE_BUNDLE = getItemType("blue_bundle"); @@ -345,6 +347,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BLUE_GLAZED_TERRACOTTA = getItemType("blue_glazed_terracotta"); + ItemType.Typed BLUE_HARNESS = getItemType("blue_harness"); + ItemType.Typed BLUE_ICE = getItemType("blue_ice"); ItemType.Typed BLUE_ORCHID = getItemType("blue_orchid"); @@ -407,7 +411,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BROWN_BANNER = getItemType("brown_banner"); - ItemType.Typed BROWN_BED = getItemType("brown_bed"); + ItemType.Typed BROWN_BED = getItemType("brown_bed"); ItemType.Typed BROWN_BUNDLE = getItemType("brown_bundle"); @@ -425,6 +429,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed BROWN_GLAZED_TERRACOTTA = getItemType("brown_glazed_terracotta"); + ItemType.Typed BROWN_HARNESS = getItemType("brown_harness"); + ItemType.Typed BROWN_MUSHROOM = getItemType("brown_mushroom"); ItemType.Typed BROWN_MUSHROOM_BLOCK = getItemType("brown_mushroom_block"); @@ -629,7 +635,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed COMPOSTER = getItemType("composter"); - ItemType.Typed CONDUIT = getItemType("conduit"); + ItemType.Typed CONDUIT = getItemType("conduit"); ItemType.Typed COOKED_BEEF = getItemType("cooked_beef"); @@ -741,7 +747,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed CYAN_BANNER = getItemType("cyan_banner"); - ItemType.Typed CYAN_BED = getItemType("cyan_bed"); + ItemType.Typed CYAN_BED = getItemType("cyan_bed"); ItemType.Typed CYAN_BUNDLE = getItemType("cyan_bundle"); @@ -757,6 +763,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed CYAN_GLAZED_TERRACOTTA = getItemType("cyan_glazed_terracotta"); + ItemType.Typed CYAN_HARNESS = getItemType("cyan_harness"); + ItemType.Typed CYAN_SHULKER_BOX = getItemType("cyan_shulker_box"); ItemType.Typed CYAN_STAINED_GLASS = getItemType("cyan_stained_glass"); @@ -925,26 +933,16 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed DIRT_PATH = getItemType("dirt_path"); - ItemType.Typed DOLPHIN_SPAWN_EGG = getItemType("dolphin_spawn_egg"); - - ItemType.Typed DONKEY_SPAWN_EGG = getItemType("donkey_spawn_egg"); - ItemType.Typed DRAGON_BREATH = getItemType("dragon_breath"); ItemType.Typed DRAGON_HEAD = getItemType("dragon_head"); - ItemType.Typed DROWNED_SPAWN_EGG = getItemType("drowned_spawn_egg"); - - ItemType.Typed ELDER_GUARDIAN_SPAWN_EGG = getItemType("elder_guardian_spawn_egg"); - ItemType.Typed ENCHANTED_BOOK = getItemType("enchanted_book"); ItemType.Typed END_CRYSTAL = getItemType("end_crystal"); ItemType.Typed ENDER_DRAGON_SPAWN_EGG = getItemType("ender_dragon_spawn_egg"); - ItemType.Typed ENDER_EYE = getItemType("ender_eye"); - ItemType.Typed ENDERMAN_SPAWN_EGG = getItemType("enderman_spawn_egg"); ItemType.Typed ENDERMITE_SPAWN_EGG = getItemType("endermite_spawn_egg"); @@ -953,8 +951,6 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed EXPERIENCE_BOTTLE = getItemType("experience_bottle"); - ItemType.Typed FERMENTED_SPIDER_EYE = getItemType("fermented_spider_eye"); - ItemType.Typed FIRE_CHARGE = getItemType("fire_charge"); ItemType.Typed FIREWORK_ROCKET = getItemType("firework_rocket"); @@ -963,8 +959,6 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed FLOW_BANNER_PATTERN = getItemType("flow_banner_pattern"); - ItemType.Typed FLOWER_BANNER_PATTERN = getItemType("flower_banner_pattern"); - ItemType.Typed FLOWER_POT = getItemType("flower_pot"); ItemType.Typed FOX_SPAWN_EGG = getItemType("fox_spawn_egg"); @@ -973,18 +967,12 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GHAST_SPAWN_EGG = getItemType("ghast_spawn_egg"); - ItemType.Typed GLASS_BOTTLE = getItemType("glass_bottle"); - - ItemType.Typed GLISTERING_MELON_SLICE = getItemType("glistering_melon_slice"); - ItemType.Typed GLOW_ITEM_FRAME = getItemType("glow_item_frame"); ItemType.Typed GLOW_SQUID_SPAWN_EGG = getItemType("glow_squid_spawn_egg"); ItemType.Typed GOAT_SPAWN_EGG = getItemType("goat_spawn_egg"); - ItemType.Typed GOLD_NUGGET = getItemType("gold_nugget"); - ItemType.Typed GOLDEN_CARROT = getItemType("golden_carrot"); ItemType.Typed GOLDEN_HORSE_ARMOR = getItemType("golden_horse_armor"); @@ -995,6 +983,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GUARDIAN_SPAWN_EGG = getItemType("guardian_spawn_egg"); + ItemType.Typed HAPPY_GHAST_SPAWN_EGG = getItemType("happy_ghast_spawn_egg"); + ItemType.Typed HOGLIN_SPAWN_EGG = getItemType("hoglin_spawn_egg"); ItemType.Typed HORSE_SPAWN_EGG = getItemType("horse_spawn_egg"); @@ -1023,8 +1013,6 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed MAGENTA_BANNER = getItemType("magenta_banner"); - ItemType.Typed MAGMA_CREAM = getItemType("magma_cream"); - ItemType.Typed MAGMA_CUBE_SPAWN_EGG = getItemType("magma_cube_spawn_egg"); ItemType.Typed MAP = getItemType("map"); @@ -1039,8 +1027,14 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed DISPENSER = getItemType("dispenser"); + ItemType.Typed DOLPHIN_SPAWN_EGG = getItemType("dolphin_spawn_egg"); + + ItemType.Typed DONKEY_SPAWN_EGG = getItemType("donkey_spawn_egg"); + ItemType.Typed DRAGON_EGG = getItemType("dragon_egg"); + ItemType.Typed DRIED_GHAST = getItemType("dried_ghast"); + ItemType.Typed DRIED_KELP = getItemType("dried_kelp"); ItemType.Typed DRIED_KELP_BLOCK = getItemType("dried_kelp_block"); @@ -1049,12 +1043,16 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed DROPPER = getItemType("dropper"); + ItemType.Typed DROWNED_SPAWN_EGG = getItemType("drowned_spawn_egg"); + ItemType.Typed DUNE_ARMOR_TRIM_SMITHING_TEMPLATE = getItemType("dune_armor_trim_smithing_template"); ItemType.Typed ECHO_SHARD = getItemType("echo_shard"); ItemType.Typed EGG = getItemType("egg"); + ItemType.Typed ELDER_GUARDIAN_SPAWN_EGG = getItemType("elder_guardian_spawn_egg"); + ItemType.Typed ELYTRA = getItemType("elytra"); ItemType.Typed EMERALD = getItemType("emerald"); @@ -1083,6 +1081,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed ENDER_CHEST = getItemType("ender_chest"); + ItemType.Typed ENDER_EYE = getItemType("ender_eye"); + ItemType.Typed ENDER_PEARL = getItemType("ender_pearl"); ItemType.Typed EXPLORER_POTTERY_SHERD = getItemType("explorer_pottery_sherd"); @@ -1111,6 +1111,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed FEATHER = getItemType("feather"); + ItemType.Typed FERMENTED_SPIDER_EYE = getItemType("fermented_spider_eye"); + ItemType.Typed FERN = getItemType("fern"); ItemType.Typed FIELD_MASONED_BANNER_PATTERN = getItemType("field_masoned_banner_pattern"); @@ -1137,6 +1139,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed FLOW_POTTERY_SHERD = getItemType("flow_pottery_sherd"); + ItemType.Typed FLOWER_BANNER_PATTERN = getItemType("flower_banner_pattern"); + ItemType.Typed FLOWERING_AZALEA = getItemType("flowering_azalea"); ItemType.Typed FLOWERING_AZALEA_LEAVES = getItemType("flowering_azalea_leaves"); @@ -1155,8 +1159,12 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GLASS = getItemType("glass"); + ItemType.Typed GLASS_BOTTLE = getItemType("glass_bottle"); + ItemType.Typed GLASS_PANE = getItemType("glass_pane"); + ItemType.Typed GLISTERING_MELON_SLICE = getItemType("glistering_melon_slice"); + ItemType.Typed GLOBE_BANNER_PATTERN = getItemType("globe_banner_pattern"); ItemType.Typed GLOW_BERRIES = getItemType("glow_berries"); @@ -1175,6 +1183,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GOLD_INGOT = getItemType("gold_ingot"); + ItemType.Typed GOLD_NUGGET = getItemType("gold_nugget"); + ItemType.Typed GOLD_ORE = getItemType("gold_ore"); ItemType.Typed GOLDEN_APPLE = getItemType("golden_apple"); @@ -1209,7 +1219,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GRAVEL = getItemType("gravel"); - ItemType.Typed GRAY_BED = getItemType("gray_bed"); + ItemType.Typed GRAY_BED = getItemType("gray_bed"); ItemType.Typed GRAY_BUNDLE = getItemType("gray_bundle"); @@ -1225,6 +1235,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GRAY_GLAZED_TERRACOTTA = getItemType("gray_glazed_terracotta"); + ItemType.Typed GRAY_HARNESS = getItemType("gray_harness"); + ItemType.Typed GRAY_SHULKER_BOX = getItemType("gray_shulker_box"); ItemType.Typed GRAY_STAINED_GLASS = getItemType("gray_stained_glass"); @@ -1235,7 +1247,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GRAY_WOOL = getItemType("gray_wool"); - ItemType.Typed GREEN_BED = getItemType("green_bed"); + ItemType.Typed GREEN_BED = getItemType("green_bed"); ItemType.Typed GREEN_BUNDLE = getItemType("green_bundle"); @@ -1251,6 +1263,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed GREEN_GLAZED_TERRACOTTA = getItemType("green_glazed_terracotta"); + ItemType.Typed GREEN_HARNESS = getItemType("green_harness"); + ItemType.Typed GREEN_SHULKER_BOX = getItemType("green_shulker_box"); ItemType.Typed GREEN_STAINED_GLASS = getItemType("green_stained_glass"); @@ -1433,7 +1447,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LIGHT = getItemType("light"); - ItemType.Typed LIGHT_BLUE_BED = getItemType("light_blue_bed"); + ItemType.Typed LIGHT_BLUE_BED = getItemType("light_blue_bed"); ItemType.Typed LIGHT_BLUE_BUNDLE = getItemType("light_blue_bundle"); @@ -1449,6 +1463,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LIGHT_BLUE_GLAZED_TERRACOTTA = getItemType("light_blue_glazed_terracotta"); + ItemType.Typed LIGHT_BLUE_HARNESS = getItemType("light_blue_harness"); + ItemType.Typed LIGHT_BLUE_SHULKER_BOX = getItemType("light_blue_shulker_box"); ItemType.Typed LIGHT_BLUE_STAINED_GLASS = getItemType("light_blue_stained_glass"); @@ -1459,7 +1475,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LIGHT_BLUE_WOOL = getItemType("light_blue_wool"); - ItemType.Typed LIGHT_GRAY_BED = getItemType("light_gray_bed"); + ItemType.Typed LIGHT_GRAY_BED = getItemType("light_gray_bed"); ItemType.Typed LIGHT_GRAY_BUNDLE = getItemType("light_gray_bundle"); @@ -1475,6 +1491,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LIGHT_GRAY_GLAZED_TERRACOTTA = getItemType("light_gray_glazed_terracotta"); + ItemType.Typed LIGHT_GRAY_HARNESS = getItemType("light_gray_harness"); + ItemType.Typed LIGHT_GRAY_SHULKER_BOX = getItemType("light_gray_shulker_box"); ItemType.Typed LIGHT_GRAY_STAINED_GLASS = getItemType("light_gray_stained_glass"); @@ -1495,7 +1513,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LILY_PAD = getItemType("lily_pad"); - ItemType.Typed LIME_BED = getItemType("lime_bed"); + ItemType.Typed LIME_BED = getItemType("lime_bed"); ItemType.Typed LIME_BUNDLE = getItemType("lime_bundle"); @@ -1511,6 +1529,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LIME_GLAZED_TERRACOTTA = getItemType("lime_glazed_terracotta"); + ItemType.Typed LIME_HARNESS = getItemType("lime_harness"); + ItemType.Typed LIME_SHULKER_BOX = getItemType("lime_shulker_box"); ItemType.Typed LIME_STAINED_GLASS = getItemType("lime_stained_glass"); @@ -1527,7 +1547,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed LOOM = getItemType("loom"); - ItemType.Typed MAGENTA_BED = getItemType("magenta_bed"); + ItemType.Typed MAGENTA_BED = getItemType("magenta_bed"); ItemType.Typed MAGENTA_BUNDLE = getItemType("magenta_bundle"); @@ -1543,6 +1563,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed MAGENTA_GLAZED_TERRACOTTA = getItemType("magenta_glazed_terracotta"); + ItemType.Typed MAGENTA_HARNESS = getItemType("magenta_harness"); + ItemType.Typed MAGENTA_SHULKER_BOX = getItemType("magenta_shulker_box"); ItemType.Typed MAGENTA_STAINED_GLASS = getItemType("magenta_stained_glass"); @@ -1555,6 +1577,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed MAGMA_BLOCK = getItemType("magma_block"); + ItemType.Typed MAGMA_CREAM = getItemType("magma_cream"); + ItemType.Typed MANGROVE_BOAT = getItemType("mangrove_boat"); ItemType.Typed MANGROVE_BUTTON = getItemType("mangrove_button"); @@ -1677,6 +1701,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed MUSIC_DISC_STRAD = getItemType("music_disc_strad"); + ItemType.Typed MUSIC_DISC_TEARS = getItemType("music_disc_tears"); + ItemType.Typed MUSIC_DISC_WAIT = getItemType("music_disc_wait"); ItemType.Typed MUSIC_DISC_WARD = getItemType("music_disc_ward"); @@ -1793,7 +1819,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed ORANGE_BANNER = getItemType("orange_banner"); - ItemType.Typed ORANGE_BED = getItemType("orange_bed"); + ItemType.Typed ORANGE_BED = getItemType("orange_bed"); ItemType.Typed ORANGE_BUNDLE = getItemType("orange_bundle"); @@ -1809,6 +1835,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed ORANGE_GLAZED_TERRACOTTA = getItemType("orange_glazed_terracotta"); + ItemType.Typed ORANGE_HARNESS = getItemType("orange_harness"); + ItemType.Typed ORANGE_SHULKER_BOX = getItemType("orange_shulker_box"); ItemType.Typed ORANGE_STAINED_GLASS = getItemType("orange_stained_glass"); @@ -1917,7 +1945,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed PINK_BANNER = getItemType("pink_banner"); - ItemType.Typed PINK_BED = getItemType("pink_bed"); + ItemType.Typed PINK_BED = getItemType("pink_bed"); ItemType.Typed PINK_BUNDLE = getItemType("pink_bundle"); @@ -1933,6 +1961,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed PINK_GLAZED_TERRACOTTA = getItemType("pink_glazed_terracotta"); + ItemType.Typed PINK_HARNESS = getItemType("pink_harness"); + ItemType.Typed PINK_PETALS = getItemType("pink_petals"); ItemType.Typed PINK_SHULKER_BOX = getItemType("pink_shulker_box"); @@ -2069,7 +2099,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed PURPLE_BANNER = getItemType("purple_banner"); - ItemType.Typed PURPLE_BED = getItemType("purple_bed"); + ItemType.Typed PURPLE_BED = getItemType("purple_bed"); ItemType.Typed PURPLE_BUNDLE = getItemType("purple_bundle"); @@ -2085,6 +2115,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed PURPLE_GLAZED_TERRACOTTA = getItemType("purple_glazed_terracotta"); + ItemType.Typed PURPLE_HARNESS = getItemType("purple_harness"); + ItemType.Typed PURPLE_SHULKER_BOX = getItemType("purple_shulker_box"); ItemType.Typed PURPLE_STAINED_GLASS = getItemType("purple_stained_glass"); @@ -2147,7 +2179,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed RED_BANNER = getItemType("red_banner"); - ItemType.Typed RED_BED = getItemType("red_bed"); + ItemType.Typed RED_BED = getItemType("red_bed"); ItemType.Typed RED_BUNDLE = getItemType("red_bundle"); @@ -2163,6 +2195,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed RED_GLAZED_TERRACOTTA = getItemType("red_glazed_terracotta"); + ItemType.Typed RED_HARNESS = getItemType("red_harness"); + ItemType.Typed RED_MUSHROOM = getItemType("red_mushroom"); ItemType.Typed RED_MUSHROOM_BLOCK = getItemType("red_mushroom_block"); @@ -2781,7 +2815,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed WHITE_BANNER = getItemType("white_banner"); - ItemType.Typed WHITE_BED = getItemType("white_bed"); + ItemType.Typed WHITE_BED = getItemType("white_bed"); ItemType.Typed WHITE_BUNDLE = getItemType("white_bundle"); @@ -2797,6 +2831,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed WHITE_GLAZED_TERRACOTTA = getItemType("white_glazed_terracotta"); + ItemType.Typed WHITE_HARNESS = getItemType("white_harness"); + ItemType.Typed WHITE_SHULKER_BOX = getItemType("white_shulker_box"); ItemType.Typed WHITE_STAINED_GLASS = getItemType("white_stained_glass"); @@ -2845,7 +2881,7 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed YELLOW_BANNER = getItemType("yellow_banner"); - ItemType.Typed YELLOW_BED = getItemType("yellow_bed"); + ItemType.Typed YELLOW_BED = getItemType("yellow_bed"); ItemType.Typed YELLOW_BUNDLE = getItemType("yellow_bundle"); @@ -2861,6 +2897,8 @@ public interface ItemType extends Keyed, Translatable, net.kyori.adventure.trans ItemType.Typed YELLOW_GLAZED_TERRACOTTA = getItemType("yellow_glazed_terracotta"); + ItemType.Typed YELLOW_HARNESS = getItemType("yellow_harness"); + ItemType.Typed YELLOW_SHULKER_BOX = getItemType("yellow_shulker_box"); ItemType.Typed YELLOW_STAINED_GLASS = getItemType("yellow_stained_glass"); diff --git a/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java b/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java index c31f1cebfd..0e6fa0d6a7 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/PlayerInventory.java @@ -74,12 +74,15 @@ public interface PlayerInventory extends Inventory { * Index 40 refers to the off hand (shield) item slot. Though you can set off hand with this method using this index, * you are encouraged to use the provided method for this slot. *

- * If you attempt to use this method with an index less than 0 or greater than 40, an ArrayIndexOutOfBounds + * Index 41 refers to the body item slot and 42 is the saddle item slot. Note that these are not visible in the player + * inventory menu. + *

+ * If you attempt to use this method with an index less than 0 or greater than 42, an ArrayIndexOutOfBounds * exception will be thrown. * * @param index The index where to put the ItemStack * @param item The ItemStack to set - * @throws ArrayIndexOutOfBoundsException when index < 0 || index > 40 + * @throws ArrayIndexOutOfBoundsException when index < 0 || index > 42 * @see #setBoots(ItemStack) * @see #setChestplate(ItemStack) * @see #setHelmet(ItemStack) diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java index 060b02b1fe..edc9e34cc7 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimMaterial.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; public interface TrimMaterial extends Keyed, Translatable { // Start generate - TrimMaterial - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 TrimMaterial AMETHYST = getTrimMaterial("amethyst"); TrimMaterial COPPER = getTrimMaterial("copper"); diff --git a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java index 252afa699d..27e57da1fe 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java +++ b/paper-api/src/main/java/org/bukkit/inventory/meta/trim/TrimPattern.java @@ -15,7 +15,7 @@ import org.jetbrains.annotations.NotNull; public interface TrimPattern extends Keyed, Translatable { // Start generate - TrimPattern - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 TrimPattern BOLT = getTrimPattern("bolt"); TrimPattern COAST = getTrimPattern("coast"); diff --git a/paper-api/src/main/java/org/bukkit/inventory/recipe/CookingBookCategory.java b/paper-api/src/main/java/org/bukkit/inventory/recipe/CookingBookCategory.java index 585cf467e4..10c28d2dd9 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/recipe/CookingBookCategory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/recipe/CookingBookCategory.java @@ -6,7 +6,7 @@ package org.bukkit.inventory.recipe; public enum CookingBookCategory { // Start generate - CookingBookCategory - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 FOOD, BLOCKS, MISC; diff --git a/paper-api/src/main/java/org/bukkit/inventory/recipe/CraftingBookCategory.java b/paper-api/src/main/java/org/bukkit/inventory/recipe/CraftingBookCategory.java index 51d41d8b7d..8ba51a57b9 100644 --- a/paper-api/src/main/java/org/bukkit/inventory/recipe/CraftingBookCategory.java +++ b/paper-api/src/main/java/org/bukkit/inventory/recipe/CraftingBookCategory.java @@ -6,7 +6,7 @@ package org.bukkit.inventory.recipe; public enum CraftingBookCategory { // Start generate - CraftingBookCategory - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 BUILDING, REDSTONE, EQUIPMENT, diff --git a/paper-api/src/main/java/org/bukkit/map/MapCursor.java b/paper-api/src/main/java/org/bukkit/map/MapCursor.java index 902402b7a9..f1ea5e0262 100644 --- a/paper-api/src/main/java/org/bukkit/map/MapCursor.java +++ b/paper-api/src/main/java/org/bukkit/map/MapCursor.java @@ -289,7 +289,7 @@ public final class MapCursor { public interface Type extends OldEnum, Keyed { // Start generate - MapCursorType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 Type BANNER_BLACK = getType("banner_black"); Type BANNER_BLUE = getType("banner_blue"); diff --git a/paper-api/src/main/java/org/bukkit/map/MapPalette.java b/paper-api/src/main/java/org/bukkit/map/MapPalette.java index fc9728342d..5bb3267f81 100644 --- a/paper-api/src/main/java/org/bukkit/map/MapPalette.java +++ b/paper-api/src/main/java/org/bukkit/map/MapPalette.java @@ -37,7 +37,7 @@ public final class MapPalette { @NotNull static final Color[] colors = { // Start generate - MapPalette#colors - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 new Color(0x00000000, true), new Color(0x00000000, true), new Color(0x00000000, true), diff --git a/paper-api/src/main/java/org/bukkit/material/Cake.java b/paper-api/src/main/java/org/bukkit/material/Cake.java index 0d0d41c184..110326721f 100644 --- a/paper-api/src/main/java/org/bukkit/material/Cake.java +++ b/paper-api/src/main/java/org/bukkit/material/Cake.java @@ -52,7 +52,7 @@ public class Cake extends MaterialData { public void setSlicesEaten(int n) { if (n < 6) { setData((byte) n); - } // TODO: else destroy the block? Probably not possible though + } } /** diff --git a/paper-api/src/main/java/org/bukkit/persistence/PersistentDataContainer.java b/paper-api/src/main/java/org/bukkit/persistence/PersistentDataContainer.java index 0f40eb52f6..3a48c597a3 100644 --- a/paper-api/src/main/java/org/bukkit/persistence/PersistentDataContainer.java +++ b/paper-api/src/main/java/org/bukkit/persistence/PersistentDataContainer.java @@ -48,7 +48,7 @@ public interface PersistentDataContainer extends io.papermc.paper.persistence.Pe // Paper start - byte array serialization // Paper - move to PersistentDataContainerView /** - * Read values from a serialised byte array into this + * Read values from a serialized byte array into this * {@link PersistentDataContainer} instance. * * @param bytes the byte array to read from @@ -59,7 +59,7 @@ public interface PersistentDataContainer extends io.papermc.paper.persistence.Pe void readFromBytes(byte @NotNull [] bytes, boolean clear) throws java.io.IOException; /** - * Read values from a serialised byte array into this + * Read values from a serialized byte array into this * {@link PersistentDataContainer} instance. * This method has the same effect as * PersistentDataContainer#readFromBytes(bytes, true) diff --git a/paper-api/src/main/java/org/bukkit/potion/PotionType.java b/paper-api/src/main/java/org/bukkit/potion/PotionType.java index c4ff2003d0..9ec61eb965 100644 --- a/paper-api/src/main/java/org/bukkit/potion/PotionType.java +++ b/paper-api/src/main/java/org/bukkit/potion/PotionType.java @@ -16,7 +16,7 @@ import org.jetbrains.annotations.Nullable; */ public enum PotionType implements Keyed, io.papermc.paper.world.flag.FeatureDependant { // Paper - feature flag API // Start generate - PotionType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 AWKWARD("awkward"), FIRE_RESISTANCE("fire_resistance"), HARMING("harming"), diff --git a/paper-api/src/main/java/org/bukkit/scoreboard/DisplaySlot.java b/paper-api/src/main/java/org/bukkit/scoreboard/DisplaySlot.java index 96bba09624..ed6fd69345 100644 --- a/paper-api/src/main/java/org/bukkit/scoreboard/DisplaySlot.java +++ b/paper-api/src/main/java/org/bukkit/scoreboard/DisplaySlot.java @@ -8,7 +8,7 @@ import org.jspecify.annotations.NullMarked; @NullMarked public enum DisplaySlot { // Start generate - DisplaySlot - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 PLAYER_LIST("list"), SIDEBAR("sidebar"), BELOW_NAME("below_name"), diff --git a/paper-api/src/main/java/org/bukkit/tag/DamageTypeTags.java b/paper-api/src/main/java/org/bukkit/tag/DamageTypeTags.java index 1296d98b6f..daac566f77 100644 --- a/paper-api/src/main/java/org/bukkit/tag/DamageTypeTags.java +++ b/paper-api/src/main/java/org/bukkit/tag/DamageTypeTags.java @@ -14,7 +14,7 @@ import org.jetbrains.annotations.Nullable; public final class DamageTypeTags { // Start generate - DamageTypeTags - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 public static final Tag ALWAYS_HURTS_ENDER_DRAGONS = getTag("always_hurts_ender_dragons"); public static final Tag ALWAYS_KILLS_ARMOR_STANDS = getTag("always_kills_armor_stands"); diff --git a/paper-generator/src/main/java/io/papermc/generator/Main.java b/paper-generator/src/main/java/io/papermc/generator/Main.java index 3ce0554693..a96fe8398a 100644 --- a/paper-generator/src/main/java/io/papermc/generator/Main.java +++ b/paper-generator/src/main/java/io/papermc/generator/Main.java @@ -1,6 +1,5 @@ package io.papermc.generator; -import com.google.common.util.concurrent.MoreExecutors; import com.mojang.logging.LogUtils; import io.papermc.generator.rewriter.registration.PaperPatternSourceSetRewriter; import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter; @@ -48,7 +47,7 @@ public class Main implements Callable { @CommandLine.Option(names = {"--sourceset"}, required = true) Path sourceSet; - @CommandLine.Option(names = {"-cp", "--classpath"}, split = ":", required = true) + @CommandLine.Option(names = {"-cp", "--classpath"}, split = "[;:]", required = true) Set classpath; @CommandLine.Option(names = {"--rewrite"}) @@ -84,11 +83,11 @@ public class Main implements Callable { resourceManager, layers, pendingTags, - FeatureFlags.VANILLA_SET, + FeatureFlags.REGISTRY.allFlags(), Commands.CommandSelection.DEDICATED, - 0, - MoreExecutors.directExecutor(), - MoreExecutors.directExecutor() + Commands.LEVEL_GAMEMASTERS, + Runnable::run, + Runnable::run ).whenComplete((result, ex) -> { if (ex != null) { resourceManager.close(); diff --git a/paper-generator/src/main/java/io/papermc/generator/Rewriters.java b/paper-generator/src/main/java/io/papermc/generator/Rewriters.java index 15b137264d..be47f326c3 100644 --- a/paper-generator/src/main/java/io/papermc/generator/Rewriters.java +++ b/paper-generator/src/main/java/io/papermc/generator/Rewriters.java @@ -6,6 +6,7 @@ import io.papermc.generator.rewriter.registration.PatternSourceSetRewriter; import io.papermc.generator.rewriter.types.Types; import io.papermc.generator.rewriter.types.registry.EnumRegistryRewriter; import io.papermc.generator.rewriter.types.registry.FeatureFlagRewriter; +import io.papermc.generator.rewriter.types.registry.PaperFeatureFlagMapping; import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter; import io.papermc.generator.rewriter.types.registry.RegistryTagRewriter; import io.papermc.generator.rewriter.types.registry.TagRewriter; @@ -17,7 +18,6 @@ import io.papermc.generator.rewriter.types.simple.EntityTypeRewriter; import io.papermc.generator.rewriter.types.simple.MapPaletteRewriter; import io.papermc.generator.rewriter.types.simple.MaterialRewriter; import io.papermc.generator.rewriter.types.simple.MemoryKeyRewriter; -import io.papermc.generator.rewriter.types.registry.PaperFeatureFlagMapping; import io.papermc.generator.rewriter.types.simple.StatisticRewriter; import io.papermc.generator.rewriter.types.simple.trial.VillagerProfessionRewriter; import io.papermc.generator.types.goal.MobGoalNames; @@ -25,14 +25,15 @@ import io.papermc.generator.utils.Formatting; import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation; import io.papermc.typewriter.preset.EnumCloneRewriter; import io.papermc.typewriter.preset.model.EnumValue; -import java.util.Map; -import java.util.function.Consumer; import io.papermc.typewriter.replace.SearchMetadata; import io.papermc.typewriter.replace.SearchReplaceRewriter; +import java.util.Map; +import java.util.function.Consumer; import javax.lang.model.SourceVersion; import net.kyori.adventure.text.format.NamedTextColor; import net.minecraft.core.Holder; import net.minecraft.core.registries.Registries; +import net.minecraft.sounds.SoundSource; import net.minecraft.world.entity.Mob; import net.minecraft.world.item.Rarity; import org.bukkit.Art; @@ -43,12 +44,14 @@ import org.bukkit.JukeboxSong; import org.bukkit.Material; import org.bukkit.MusicInstrument; import org.bukkit.Sound; +import org.bukkit.SoundCategory; import org.bukkit.Statistic; import org.bukkit.Tag; import org.bukkit.block.Biome; import org.bukkit.block.BlockType; import org.bukkit.block.banner.PatternType; import org.bukkit.damage.DamageType; +import org.bukkit.entity.Armadillo; import org.bukkit.entity.Boat; import org.bukkit.entity.Cat; import org.bukkit.entity.Chicken; @@ -67,7 +70,6 @@ import org.bukkit.entity.memory.MemoryKey; import org.bukkit.generator.structure.Structure; import org.bukkit.generator.structure.StructureType; import org.bukkit.inventory.ItemRarity; -import org.bukkit.inventory.ItemType; import org.bukkit.inventory.meta.trim.TrimMaterial; import org.bukkit.inventory.meta.trim.TrimPattern; import org.bukkit.inventory.recipe.CookingBookCategory; @@ -124,6 +126,8 @@ public final class Rewriters { .register("BoatStatus", Boat.Status.class, new EnumCloneRewriter<>(net.minecraft.world.entity.vehicle.Boat.Status.class)) .register("FoxType", Fox.Type.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.Fox.Variant.class)) .register("SalmonVariant", Salmon.Variant.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.Salmon.Variant.class)) + .register("ArmadilloState", Armadillo.State.class, new EnumCloneRewriter<>(net.minecraft.world.entity.animal.armadillo.Armadillo.ArmadilloState.class)) + .register("SoundCategory", SoundCategory.class, new EnumCloneRewriter<>(SoundSource.class)) .register("ItemUseAnimation", ItemUseAnimation.class, new EnumCloneRewriter<>(net.minecraft.world.item.ItemUseAnimation.class)) .register("ItemRarity", ItemRarity.class, new EnumCloneRewriter<>(Rarity.class) { @Override @@ -181,7 +185,6 @@ public final class Rewriters { .register("CowVariant", Cow.Variant.class, new RegistryFieldRewriter<>(Registries.COW_VARIANT, "getVariant")) .register("PigVariant", Pig.Variant.class, new RegistryFieldRewriter<>(Registries.PIG_VARIANT, "getVariant")) .register("MemoryKey", MemoryKey.class, new MemoryKeyRewriter()) - // .register("DataComponentTypes", DataComponentTypes.class, new DataComponentTypesRewriter()) - disable for now // .register("ItemType", ItemType.class, new ItemTypeRewriter()) - disable for now, lynx want the generic type .register("BlockType", BlockType.class, new BlockTypeRewriter()) .register("FeatureFlag", FeatureFlag.class, new FeatureFlagRewriter()) @@ -203,11 +206,11 @@ public final class Rewriters { holder("CraftPotionUtil#extendable", new CraftPotionUtilRewriter("long")) )) .register("PaperFeatureFlagProviderImpl#FLAGS", Types.PAPER_FEATURE_FLAG_PROVIDER_IMPL, new PaperFeatureFlagMapping()) - .register("MobGoalHelper#bukkitMap", Types.MOB_GOAL_HELPER, new SearchReplaceRewriter() { + .register("MobGoalHelper#BUKKIT_BRIDGE", Types.MOB_GOAL_HELPER, new SearchReplaceRewriter() { @Override protected void insert(SearchMetadata metadata, StringBuilder builder) { - for (Map.Entry, Class> entry : MobGoalNames.bukkitMap.entrySet()) { - builder.append(metadata.indent()).append("bukkitMap.put(%s.class, %s.class);".formatted( + for (Map.Entry, Class> entry : MobGoalNames.BUKKIT_BRIDGE.entrySet()) { + builder.append(metadata.indent()).append("map.put(%s.class, %s.class);".formatted( entry.getKey().getCanonicalName(), this.importCollector.getShortName(entry.getValue()) )); builder.append('\n'); diff --git a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java index a7e2de3e93..4dd1225461 100644 --- a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java +++ b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntries.java @@ -11,7 +11,11 @@ import io.papermc.paper.registry.data.DamageTypeRegistryEntry; import io.papermc.paper.registry.data.EnchantmentRegistryEntry; import io.papermc.paper.registry.data.FrogVariantRegistryEntry; import io.papermc.paper.registry.data.GameEventRegistryEntry; +import io.papermc.paper.registry.data.JukeboxSongRegistryEntry; import io.papermc.paper.registry.data.PaintingVariantRegistryEntry; +import io.papermc.paper.registry.data.PigVariantRegistryEntry; +import io.papermc.paper.registry.data.SoundEventRegistryEntry; +import io.papermc.paper.registry.data.WolfVariantRegistryEntry; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.lang.reflect.Type; @@ -24,8 +28,6 @@ import java.util.Objects; import java.util.Set; import java.util.function.Consumer; import java.util.stream.Collectors; -import io.papermc.paper.registry.data.PigVariantRegistryEntry; -import io.papermc.paper.registry.data.WolfVariantRegistryEntry; import net.minecraft.core.Registry; import net.minecraft.core.component.DataComponents; import net.minecraft.core.particles.ParticleTypes; @@ -146,7 +148,7 @@ public final class RegistryEntries { ); public static final List> BUILT_IN = List.of( - entry(Registries.GAME_EVENT, net.minecraft.world.level.gameevent.GameEvent.class, GameEvent.class).apiRegistryBuilder(GameEventRegistryEntry.Builder.class, "PaperGameEventRegistryEntry.PaperBuilder"), + entry(Registries.GAME_EVENT, net.minecraft.world.level.gameevent.GameEvent.class, GameEvent.class).writableApiRegistryBuilder(GameEventRegistryEntry.Builder.class, "PaperGameEventRegistryEntry.PaperBuilder"), entry(Registries.STRUCTURE_TYPE, net.minecraft.world.level.levelgen.structure.StructureType.class, StructureType.class), entry(Registries.MOB_EFFECT, MobEffects.class, PotionEffectType.class), entry(Registries.BLOCK, Blocks.class, BlockType.class), @@ -157,7 +159,7 @@ public final class RegistryEntries { entry(Registries.MENU, net.minecraft.world.inventory.MenuType.class, MenuType.class), entry(Registries.ATTRIBUTE, Attributes.class, Attribute.class).serializationUpdater("ATTRIBUTE_RENAME"), entry(Registries.FLUID, Fluids.class, Fluid.class), - entry(Registries.SOUND_EVENT, SoundEvents.class, Sound.class).allowDirect().apiRegistryField("SOUNDS"), + entry(Registries.SOUND_EVENT, SoundEvents.class, Sound.class).allowDirect().apiRegistryField("SOUNDS").apiRegistryBuilder(SoundEventRegistryEntry.Builder.class, "PaperSoundEventRegistryEntry.PaperBuilder", RegistryEntry.RegistryModificationApiSupport.NONE), entry(Registries.DATA_COMPONENT_TYPE, DataComponents.class, DataComponentType.class, "Paper").preload(DataComponentTypes.class).apiAccessName("of") ); @@ -166,19 +168,19 @@ public final class RegistryEntries { entry(Registries.STRUCTURE, BuiltinStructures.class, Structure.class).delayed(), entry(Registries.TRIM_MATERIAL, TrimMaterials.class, TrimMaterial.class).allowDirect().delayed(), entry(Registries.TRIM_PATTERN, TrimPatterns.class, TrimPattern.class).allowDirect().delayed(), - entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).apiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(), - entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).apiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(), + entry(Registries.DAMAGE_TYPE, DamageTypes.class, DamageType.class).writableApiRegistryBuilder(DamageTypeRegistryEntry.Builder.class, "PaperDamageTypeRegistryEntry.PaperBuilder").delayed(), + entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).writableApiRegistryBuilder(WolfVariantRegistryEntry.Builder.class, "PaperWolfVariantRegistryEntry.PaperBuilder").delayed(), entry(Registries.WOLF_SOUND_VARIANT, WolfSoundVariants.class, Wolf.SoundVariant.class), - entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).apiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(), - entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).delayed(), - entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().apiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(), - entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).allowDirect().apiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(), + entry(Registries.ENCHANTMENT, Enchantments.class, Enchantment.class).writableApiRegistryBuilder(EnchantmentRegistryEntry.Builder.class, "PaperEnchantmentRegistryEntry.PaperBuilder").serializationUpdater("ENCHANTMENT_RENAME").delayed(), + entry(Registries.JUKEBOX_SONG, JukeboxSongs.class, JukeboxSong.class).writableApiRegistryBuilder(JukeboxSongRegistryEntry.Builder.class, "PaperJukeboxSongRegistryEntry.PaperBuilder").delayed(), + entry(Registries.BANNER_PATTERN, BannerPatterns.class, PatternType.class).allowDirect().writableApiRegistryBuilder(BannerPatternRegistryEntry.Builder.class, "PaperBannerPatternRegistryEntry.PaperBuilder").delayed(), + entry(Registries.PAINTING_VARIANT, PaintingVariants.class, Art.class).writableApiRegistryBuilder(PaintingVariantRegistryEntry.Builder.class, "PaperPaintingVariantRegistryEntry.PaperBuilder").apiRegistryField("ART").delayed(), entry(Registries.INSTRUMENT, Instruments.class, MusicInstrument.class).allowDirect().delayed(), - entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).apiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(), - entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).apiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(), - entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).apiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"), - entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).apiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"), - entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).apiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder") + entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).writableApiRegistryBuilder(CatTypeRegistryEntry.Builder.class, "PaperCatTypeRegistryEntry.PaperBuilder").delayed(), + entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).writableApiRegistryBuilder(FrogVariantRegistryEntry.Builder.class, "PaperFrogVariantRegistryEntry.PaperBuilder").delayed(), + entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class).writableApiRegistryBuilder(ChickenVariantRegistryEntry.Builder.class, "PaperChickenVariantRegistryEntry.PaperBuilder"), + entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class).writableApiRegistryBuilder(CowVariantRegistryEntry.Builder.class, "PaperCowVariantRegistryEntry.PaperBuilder"), + entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class).writableApiRegistryBuilder(PigVariantRegistryEntry.Builder.class, "PaperPigVariantRegistryEntry.PaperBuilder") ); public static final List> API_ONLY = List.of( diff --git a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntry.java b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntry.java index 26cbd71ca5..86e8c53f56 100644 --- a/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntry.java +++ b/paper-generator/src/main/java/io/papermc/generator/registry/RegistryEntry.java @@ -33,6 +33,7 @@ public final class RegistryEntry { private Class preloadClass; private final String implClass; + private @Nullable RegistryModificationApiSupport modificationApiSupport; private @Nullable Class apiRegistryBuilder; private @Nullable String apiRegistryBuilderImpl; @@ -127,9 +128,18 @@ public final class RegistryEntry { return this.apiRegistryBuilderImpl; } - public RegistryEntry apiRegistryBuilder(Class builderClass, String builderImplClass) { + public @Nullable RegistryModificationApiSupport modificationApiSupport() { + return this.modificationApiSupport; + } + + public RegistryEntry writableApiRegistryBuilder(Class builderClass, String builderImplClass) { + return this.apiRegistryBuilder(builderClass, builderImplClass, RegistryModificationApiSupport.WRITABLE); + } + + public RegistryEntry apiRegistryBuilder(Class builderClass, String builderImplClass, RegistryModificationApiSupport modificationApiSupport) { this.apiRegistryBuilder = builderClass; this.apiRegistryBuilderImpl = builderImplClass; + this.modificationApiSupport = modificationApiSupport; return this; } @@ -151,7 +161,7 @@ public final class RegistryEntry { } public boolean allowCustomKeys() { - return this.apiRegistryBuilder != null || RegistryEntries.DATA_DRIVEN.contains(this); + return (this.apiRegistryBuilder != null && this.modificationApiSupport.canAdd()) || RegistryEntries.DATA_DRIVEN.contains(this); } private Map, TO> getFields(Map, TO> map, Function transform) { @@ -211,4 +221,15 @@ public final class RegistryEntry { "implClass=" + this.implClass + ", " + ']'; } + + public enum RegistryModificationApiSupport { + NONE, + ADDABLE, + MODIFIABLE, + WRITABLE; + + public boolean canAdd() { + return this != MODIFIABLE && this != NONE; + } + } } diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/registration/PaperPatternSourceSetRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/registration/PaperPatternSourceSetRewriter.java index 08f65d1620..566dec1905 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/registration/PaperPatternSourceSetRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/registration/PaperPatternSourceSetRewriter.java @@ -12,12 +12,10 @@ import io.papermc.typewriter.replace.CompositeRewriter; import io.papermc.typewriter.replace.ReplaceOptions; import io.papermc.typewriter.replace.ReplaceOptionsLike; import io.papermc.typewriter.replace.SearchReplaceRewriter; -import java.io.File; import java.nio.file.Path; import java.util.Arrays; import java.util.Collections; import java.util.Set; -import java.util.stream.Collectors; import net.minecraft.SharedConstants; import org.jetbrains.annotations.Contract; import org.jetbrains.annotations.VisibleForTesting; @@ -48,7 +46,7 @@ public class PaperPatternSourceSetRewriter extends SourceSetRewriterImpl extends EnumRewriter> { @Override protected Iterable> getValues() { - return this.registry.get().listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator; + return this.registry.get().listElements().sorted(Formatting.HOLDER_ORDER)::iterator; } @Override diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/PaperRegistriesRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/PaperRegistriesRewriter.java index fa481914fa..599356eba7 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/PaperRegistriesRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/PaperRegistriesRewriter.java @@ -18,6 +18,7 @@ import org.jspecify.annotations.NullMarked; @NullMarked public class PaperRegistriesRewriter extends SearchReplaceRewriter { + private void appendEntry(String indent, StringBuilder builder, RegistryEntry entry, boolean canBeDelayed, boolean apiOnly) { builder.append(indent); builder.append("start"); @@ -52,9 +53,18 @@ public class PaperRegistriesRewriter extends SearchReplaceRewriter { builder.append(".serializationUpdater(").append(Types.FIELD_RENAME.simpleName()).append('.').append(entry.fieldRename()).append(")"); } - if (entry.apiRegistryBuilderImpl() != null) { - builder.append(".writable("); + if (entry.apiRegistryBuilderImpl() != null && entry.modificationApiSupport() != null) { + switch (entry.modificationApiSupport()) { + case WRITABLE -> builder.append(".writable("); + case ADDABLE -> builder.append(".addable("); + case MODIFIABLE -> builder.append(".modifiable("); + case NONE -> builder.append(".create("); + } builder.append(this.importCollector.getShortName(this.classNamedView.findFirst(entry.apiRegistryBuilderImpl()).resolve(this.classResolver))).append("::new"); + if (entry.modificationApiSupport() == RegistryEntry.RegistryModificationApiSupport.NONE) { + builder.append(", "); + builder.append(Types.REGISTRY_MODIFICATION_API_SUPPORT.dottedNestedName()).append(".NONE"); + } builder.append(')'); } else { builder.append(".build()"); diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryEventsRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryEventsRewriter.java index 6d289d4d05..ef9735652c 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryEventsRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryEventsRewriter.java @@ -1,6 +1,7 @@ package io.papermc.generator.rewriter.types.registry; import io.papermc.generator.registry.RegistryEntries; +import io.papermc.generator.registry.RegistryEntry; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.event.RegistryEventProvider; import io.papermc.typewriter.replace.SearchMetadata; @@ -17,7 +18,7 @@ public class RegistryEventsRewriter extends SearchReplaceRewriter { @Override public void insert(SearchMetadata metadata, StringBuilder builder) { RegistryEntries.forEach(entry -> { - if (entry.apiRegistryBuilder() != null) { + if (entry.apiRegistryBuilder() != null && entry.modificationApiSupport() != RegistryEntry.RegistryModificationApiSupport.NONE) { builder.append(metadata.indent()); builder.append("%s %s %s ".formatted(PUBLIC, STATIC, FINAL)); builder.append(RegistryEventProvider.class.getSimpleName()); diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryFieldRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryFieldRewriter.java index 835c3fd1c0..5f9526d595 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryFieldRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryFieldRewriter.java @@ -71,7 +71,7 @@ public class RegistryFieldRewriter extends SearchReplaceRewriter { boolean isInterface = Objects.requireNonNull(this.fieldClass.knownClass()).isInterface(); Registry registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey); this.experimentalKeys = Suppliers.memoize(() -> ExperimentalCollector.collectDataDrivenElementIds(registry)); - Iterator> referenceIterator = registry.listElements().filter(this::canPrintField).sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).iterator(); + Iterator> referenceIterator = registry.listElements().filter(this::canPrintField).sorted(Formatting.HOLDER_ORDER).iterator(); while (referenceIterator.hasNext()) { Holder.Reference reference = referenceIterator.next(); diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryTagRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryTagRewriter.java index 0e28a8610b..99c99efe80 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryTagRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/RegistryTagRewriter.java @@ -57,7 +57,7 @@ public class RegistryTagRewriter extends SearchReplaceRewriter { @Override protected void insert(SearchMetadata metadata, StringBuilder builder) { Registry registry = Main.REGISTRY_ACCESS.lookupOrThrow(this.registryKey); - Iterator> keyIterator = registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(reference -> reference.location().getPath())).iterator(); + Iterator> keyIterator = registry.listTagIds().sorted(Formatting.TAG_ORDER).iterator(); while (keyIterator.hasNext()) { TagKey tagKey = keyIterator.next(); diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/TagRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/TagRewriter.java index fa553ad7c3..6bfc438ac8 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/TagRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/registry/TagRewriter.java @@ -62,7 +62,7 @@ public class TagRewriter extends SearchReplaceRewriter { builder.append('\n'); builder.append('\n'); - Iterator> keyIterator = registry.listTagIds().sorted(Formatting.alphabeticKeyOrder(tagKey -> tagKey.location().getPath())).iterator(); + Iterator> keyIterator = registry.listTagIds().sorted(Formatting.TAG_ORDER).iterator(); while (keyIterator.hasNext()) { TagKey tagKey = keyIterator.next(); diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/EntityTypeRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/EntityTypeRewriter.java index 7426838b87..d3e548ab0a 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/EntityTypeRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/EntityTypeRewriter.java @@ -44,6 +44,7 @@ public class EntityTypeRewriter extends EnumRegistryRewriter> { .put("LeashKnot", "LeashHitch") .put("LightningBolt", "LightningStrike") .put("Tnt", "TNTPrimed") + .put("Minecart", "RideableMinecart") .put("ChestMinecart", "StorageMinecart") .put("CommandBlockMinecart", "CommandMinecart") .put("TntMinecart", "ExplosiveMinecart") @@ -164,7 +165,7 @@ public class EntityTypeRewriter extends EnumRegistryRewriter> { private String toBukkitClass(Holder.Reference> reference) { Class internalClass = ENTITY_GENERIC_TYPES.get(reference.key()); if (Mob.class.isAssignableFrom(internalClass)) { - return this.importCollector.getShortName(MobGoalNames.bukkitMap.get((Class) internalClass)); + return this.importCollector.getShortName(MobGoalNames.BUKKIT_BRIDGE.get((Class) internalClass)); } String className = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, reference.key().location().getPath()); // use the key instead of the internal class name since name match a bit more diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/MaterialRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/MaterialRewriter.java index 9c17c66f7f..764fa4a506 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/MaterialRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/MaterialRewriter.java @@ -6,7 +6,6 @@ import io.papermc.generator.utils.Formatting; import io.papermc.typewriter.preset.model.EnumValue; import java.util.Optional; import net.minecraft.core.Holder; -import net.minecraft.core.component.DataComponents; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.world.item.Item; @@ -30,7 +29,7 @@ public class MaterialRewriter { @Override protected Iterable> getValues() { return BuiltInRegistries.BLOCK.listElements().filter(reference -> !reference.value().equals(net.minecraft.world.level.block.Blocks.AIR)) - .sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator; + .sorted(Formatting.HOLDER_ORDER)::iterator; } @Override @@ -86,7 +85,7 @@ public class MaterialRewriter { @Override protected Iterable> getValues() { return BuiltInRegistries.ITEM.listElements().filter(reference -> BuiltInRegistries.BLOCK.getOptional(reference.key().location()).isEmpty() || reference.value().equals(net.minecraft.world.item.Items.AIR)) - .sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator; + .sorted(Formatting.HOLDER_ORDER)::iterator; } @Override diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/StatisticRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/StatisticRewriter.java index fe67513b1b..8af0709727 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/StatisticRewriter.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/StatisticRewriter.java @@ -131,7 +131,7 @@ public class StatisticRewriter { @Override protected Iterable>> getValues() { return BuiltInRegistries.STAT_TYPE.listElements().filter(reference -> reference.value() != Stats.CUSTOM) - .sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator; + .sorted(Formatting.HOLDER_ORDER)::iterator; } @Override @@ -157,7 +157,7 @@ public class StatisticRewriter { @Override protected Iterable>> getValues() { return BuiltInRegistries.STAT_TYPE.listElements().filter(reference -> reference.value() != Stats.CUSTOM) - .sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath()))::iterator; + .sorted(Formatting.HOLDER_ORDER)::iterator; } @Override diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/DataComponentTypesRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/DataComponentTypesRewriter.java deleted file mode 100644 index 4a1f3fab4c..0000000000 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/DataComponentTypesRewriter.java +++ /dev/null @@ -1,261 +0,0 @@ -package io.papermc.generator.rewriter.types.simple.trial; - -import com.google.gson.internal.Primitives; -import com.mojang.serialization.Codec; -import io.papermc.generator.registry.RegistryEntries; -import io.papermc.generator.rewriter.types.registry.RegistryFieldRewriter; -import io.papermc.generator.utils.ClassHelper; -import io.papermc.paper.datacomponent.item.BlockItemDataProperties; -import io.papermc.paper.datacomponent.item.ItemAdventurePredicate; -import io.papermc.paper.datacomponent.item.ItemArmorTrim; -import io.papermc.typewriter.ClassNamed; -import io.papermc.typewriter.parser.Lexer; -import io.papermc.typewriter.parser.sequence.SequenceTokens; -import io.papermc.typewriter.parser.sequence.TokenTaskBuilder; -import io.papermc.typewriter.parser.token.CharSequenceBlockToken; -import io.papermc.typewriter.parser.token.CharSequenceToken; -import io.papermc.typewriter.parser.token.TokenType; -import io.papermc.typewriter.replace.SearchMetadata; -import java.lang.annotation.Annotation; -import java.lang.reflect.ParameterizedType; -import java.lang.reflect.Type; -import java.util.EnumSet; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.Set; -import java.util.function.Predicate; -import java.util.function.UnaryOperator; -import net.kyori.adventure.key.Key; -import net.minecraft.core.Holder; -import net.minecraft.core.component.DataComponentType; -import net.minecraft.core.component.DataComponents; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceKey; -import net.minecraft.resources.ResourceLocation; -import net.minecraft.util.ExtraCodecs; -import net.minecraft.util.Unit; -import net.minecraft.world.item.AdventureModePredicate; -import net.minecraft.world.item.Instrument; -import net.minecraft.world.item.Rarity; -import net.minecraft.world.item.component.BlockItemStateProperties; -import net.minecraft.world.item.component.FireworkExplosion; -import net.minecraft.world.item.crafting.Recipe; -import net.minecraft.world.item.equipment.trim.ArmorTrim; -import org.bukkit.FireworkEffect; -import org.bukkit.MusicInstrument; -import org.bukkit.inventory.ItemRarity; -import org.checkerframework.checker.index.qual.NonNegative; -import org.checkerframework.checker.index.qual.Positive; -import org.checkerframework.checker.nullness.qual.MonotonicNonNull; -import org.jspecify.annotations.Nullable; - -import static io.papermc.generator.utils.Formatting.quoted; - -public class DataComponentTypesRewriter extends RegistryFieldRewriter> { - - public DataComponentTypesRewriter() { - super(Registries.DATA_COMPONENT_TYPE, null); - } - - private static final Set FORMAT_TOKENS = EnumSet.of( - TokenType.COMMENT, - TokenType.SINGLE_COMMENT - ); - - private @MonotonicNonNull Map javadocsPerConstant; - - private Map parseConstantJavadocs(String content) { - Map map = new HashMap<>(); - - Lexer lex = new Lexer(content.toCharArray()); - lex.checkMarkdownDocComments = !this.sourcesMetadata.canSkipMarkdownDocComments(); - SequenceTokens.wrap(lex, FORMAT_TOKENS) - .group(action -> { - ProtoConstant constant = new ProtoConstant(); - action - .map(TokenType.JAVADOC, token -> { - constant.javadocs(((CharSequenceBlockToken) token)); - }, TokenTaskBuilder::asOptional) - .skip(TokenType.PUBLIC).skip(TokenType.STATIC).skip(TokenType.FINAL) - .skipQualifiedName(Predicate.isEqual(TokenType.JAVADOC)) - .skipClosure(TokenType.LT, TokenType.GT, true, TokenTaskBuilder::asOptional) // skip generic - .map(TokenType.IDENTIFIER, token -> { - constant.name(((CharSequenceToken) token).value()); - }) - .skip(TokenType.IDENTIFIER) - .skipClosure(TokenType.LPAREN, TokenType.RPAREN, true) - .map(TokenType.SECO, $ -> { - if (constant.isComplete()) { - map.put(constant.name(), constant.javadocs()); - } - }); - }, TokenTaskBuilder::asRepeatable) - .executeOrThrow(); - - return map; - } - - private static final Set> UNSUPPORTED_TYPES = Set.of( - DataComponents.CUSTOM_DATA, - DataComponents.CREATIVE_SLOT_LOCK, - DataComponents.DEBUG_STICK_STATE, - DataComponents.ENTITY_DATA, - DataComponents.BUCKET_ENTITY_DATA, - DataComponents.BLOCK_ENTITY_DATA, - DataComponents.BEES, - DataComponents.LOCK - ); - - private static final Map>, Type> COMPONENT_GENERIC_TYPES = RegistryEntries.byRegistryKey(Registries.DATA_COMPONENT_TYPE).getFields(field -> { - if (field.getGenericType() instanceof ParameterizedType complexType && complexType.getActualTypeArguments().length == 1) { - return complexType.getActualTypeArguments()[0]; - } - return null; - }); - - private static final Map, Class> API_BRIDGE = Map.of( - Component.class, net.kyori.adventure.text.Component.class, - ResourceLocation.class, Key.class, - Instrument.class, MusicInstrument.class, - FireworkExplosion.class, FireworkEffect.class, - Rarity.class, ItemRarity.class, - ArmorTrim.class, ItemArmorTrim.class, - // renames - BlockItemStateProperties.class, BlockItemDataProperties.class, - AdventureModePredicate.class, ItemAdventurePredicate.class - ); - - @Deprecated - private static final Map FIELD_RENAMES = Map.of( - "BLOCK_STATE", "BLOCK_DATA" - ); - - @Override - protected void insert(SearchMetadata metadata, StringBuilder builder) { - this.javadocsPerConstant = parseConstantJavadocs(metadata.replacedContent()); - super.insert(metadata, builder); - } - - @Override - protected boolean canPrintField(Holder.Reference> reference) { - return !UNSUPPORTED_TYPES.contains(reference.value()); - } - - @Override - protected void rewriteJavadocs(Holder.Reference> reference, String replacedContent, String indent, StringBuilder builder) { - String constantName = this.rewriteFieldName(reference); - if (this.javadocsPerConstant.containsKey(constantName)) { - CharSequenceBlockToken token = this.javadocsPerConstant.get(constantName); - builder.append(indent).append(replacedContent, token.pos(), token.endPos()).append('\n'); - } - } - - private boolean isValued; - - private Class handleParameterizedType(Type type) { - if (type instanceof ParameterizedType complexType) { - Type[] args = complexType.getActualTypeArguments(); - if (args.length != 1) { - throw new UnsupportedOperationException("Unsupported type " + complexType); - } - - Class baseClass = ClassHelper.eraseType(complexType); - if (baseClass == Holder.class) { - return ClassHelper.eraseType(args[0]); - } - if (baseClass == ResourceKey.class) { - Class componentClass = ClassHelper.eraseType(args[0]); - if (componentClass == Recipe.class) { - return ResourceLocation.class; // special case recipe registry is not really a thing - } - } - } - - throw new UnsupportedOperationException("Unsupported type " + type); - } - - @Override - protected String rewriteFieldType(Holder.Reference> reference) { - Type componentType = COMPONENT_GENERIC_TYPES.get(reference.key()); - this.isValued = componentType != Unit.class; - if (this.isValued) { - Class componentClass = null; - UnaryOperator tryToWrap = UnaryOperator.identity(); - if (!reference.value().isTransient()) { - final Class annotation = getEquivalentAnnotation(reference.value().codecOrThrow()); - if (annotation != null) { - tryToWrap = value -> "@%s %s".formatted(this.importCollector.getShortName(annotation), value); - } - } - - if (componentType instanceof Class clazz) { - componentClass = clazz; - } else if (componentType instanceof ParameterizedType complexType) { - Type[] args = complexType.getActualTypeArguments(); - if (args.length != 1) { - throw new UnsupportedOperationException("Unsupported type " + componentType); - } - - Class baseClass = ClassHelper.eraseType(complexType); - if (baseClass == List.class) { - tryToWrap = value -> "%s<%s>".formatted(this.importCollector.getShortName(List.class), value); - componentClass = this.handleParameterizedType(args[0]); - } else { - componentClass = this.handleParameterizedType(complexType); - } - } - - if (componentClass == null) { - throw new UnsupportedOperationException("Unsupported type " + componentType); - } - - Class apiComponentClass = null; - if (Primitives.isWrapperType(componentClass)) { - apiComponentClass = componentClass; - } else if (API_BRIDGE.containsKey(componentClass)) { - apiComponentClass = API_BRIDGE.get(componentClass); - } - - final ClassNamed finalClass; - if (apiComponentClass == null) { - finalClass = this.classNamedView.tryFindFirst(io.papermc.typewriter.util.ClassHelper.retrieveFullNestedName(componentClass)).orElse(null); - } else { - finalClass = new ClassNamed(apiComponentClass); - } - return "%s.%s<%s>".formatted( - io.papermc.paper.datacomponent.DataComponentType.class.getSimpleName(), - io.papermc.paper.datacomponent.DataComponentType.Valued.class.getSimpleName(), - tryToWrap.apply(Optional.ofNullable(finalClass).map(this.importCollector::getShortName).orElse(componentClass.getSimpleName())) - ); - } else { - return "%s.%s".formatted( - io.papermc.paper.datacomponent.DataComponentType.class.getSimpleName(), - io.papermc.paper.datacomponent.DataComponentType.NonValued.class.getSimpleName() - ); - } - } - - private @Nullable Class getEquivalentAnnotation(Codec codec) { - Class annotation = null; // int range maybe? - if (codec == ExtraCodecs.POSITIVE_INT || codec == ExtraCodecs.POSITIVE_FLOAT) { - annotation = Positive.class; - } else if (codec == ExtraCodecs.NON_NEGATIVE_INT || codec == ExtraCodecs.NON_NEGATIVE_FLOAT) { - annotation = NonNegative.class; - } - return annotation; - } - - @Override - protected String rewriteFieldName(Holder.Reference> reference) { - String keyedName = super.rewriteFieldName(reference); - return FIELD_RENAMES.getOrDefault(keyedName, keyedName); - } - - @Override - protected String rewriteFieldValue(Holder.Reference> reference) { - return "%s(%s)".formatted(this.isValued ? "valued" : "unvalued", quoted(reference.key().location().getPath())); - } -} diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/PoseRewriter.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/PoseRewriter.java new file mode 100644 index 0000000000..42dc3f8b0c --- /dev/null +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/types/simple/trial/PoseRewriter.java @@ -0,0 +1,93 @@ +package io.papermc.generator.rewriter.types.simple.trial; + +import io.papermc.typewriter.parser.Lexer; +import io.papermc.typewriter.parser.sequence.SequenceTokens; +import io.papermc.typewriter.parser.sequence.TokenTaskBuilder; +import io.papermc.typewriter.parser.token.CharSequenceBlockToken; +import io.papermc.typewriter.parser.token.CharSequenceToken; +import io.papermc.typewriter.parser.token.TokenType; +import io.papermc.typewriter.preset.EnumCloneRewriter; +import io.papermc.typewriter.preset.model.EnumValue; +import io.papermc.typewriter.replace.SearchMetadata; +import java.util.EnumSet; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import net.minecraft.world.entity.Pose; +import org.checkerframework.checker.nullness.qual.MonotonicNonNull; + +public class PoseRewriter extends EnumCloneRewriter { + + public PoseRewriter() { + super(Pose.class); + } + + private static final Set FORMAT_TOKENS = EnumSet.of( + TokenType.COMMENT, + TokenType.SINGLE_COMMENT + ); + + private static final Set END_VALUE_MARKERS = EnumSet.of( + TokenType.CO, + TokenType.SECO + ); + + private @MonotonicNonNull Map javadocsPerConstant; + + private Map parseConstantJavadocs(String content) { + Map map = new HashMap<>(); + + Lexer lex = new Lexer(content.toCharArray()); + lex.checkMarkdownDocComments = !this.sourcesMetadata.canSkipMarkdownDocComments(); + SequenceTokens.wrap(lex, FORMAT_TOKENS) + .group(action -> { + ProtoConstant constant = new ProtoConstant(); + action + .map(TokenType.JAVADOC, token -> { // /** */ + constant.javadocs(((CharSequenceBlockToken) token)); + }, TokenTaskBuilder::asOptional) + .map(TokenType.IDENTIFIER, token -> { // + constant.name(((CharSequenceToken) token).value()); + }) + .skipClosure(TokenType.LPAREN, TokenType.RPAREN, true, TokenTaskBuilder::asOptional) // (*)? + .skipClosure(TokenType.LSCOPE, TokenType.RSCOPE, true, TokenTaskBuilder::asOptional) // {*}? + .map(END_VALUE_MARKERS::contains, $ -> { // ;|, + // this part will fail for the last entry for enum without end (,;) + if (constant.isComplete()) { + map.put(constant.name(), constant.javadocs()); + } + }); + }, TokenTaskBuilder::asRepeatable) + .executeOrThrow(); + + return map; + } + + private @MonotonicNonNull SearchMetadata metadata; + + private static final Map RENAMES = Map.of( + Pose.CROUCHING.name(), "SNEAKING" + ); + + @Override + protected void insert(SearchMetadata metadata, StringBuilder builder) { + this.javadocsPerConstant = parseConstantJavadocs(metadata.replacedContent()); + this.metadata = metadata; + super.insert(metadata, builder); + } + + @Override + protected EnumValue.Builder rewriteEnumValue(Pose item) { + return super.rewriteEnumValue(item).rename(name -> RENAMES.getOrDefault(name, name)); + } + + @Override + protected void appendEnumValue(Pose item, StringBuilder builder, String indent, boolean reachEnd) { + String constantName = RENAMES.getOrDefault(item.name(), item.name()); + if (this.javadocsPerConstant.containsKey(constantName)) { + CharSequenceBlockToken token = this.javadocsPerConstant.get(constantName); + builder.append(indent).append(this.metadata.replacedContent(), token.pos(), token.endPos()).append('\n'); + } + super.appendEnumValue(item, builder, indent, reachEnd); + } +} diff --git a/paper-generator/src/main/java/io/papermc/generator/rewriter/utils/ScanOldGeneratedSourceCode.java b/paper-generator/src/main/java/io/papermc/generator/rewriter/utils/ScanOldGeneratedSourceCode.java index 3185a35dc7..22cb899dad 100644 --- a/paper-generator/src/main/java/io/papermc/generator/rewriter/utils/ScanOldGeneratedSourceCode.java +++ b/paper-generator/src/main/java/io/papermc/generator/rewriter/utils/ScanOldGeneratedSourceCode.java @@ -12,7 +12,6 @@ import io.papermc.typewriter.parser.StringReader; import io.papermc.typewriter.replace.CommentMarker; import io.papermc.typewriter.replace.SearchReplaceRewriter; import io.papermc.typewriter.replace.SearchReplaceRewriterBase; -import net.minecraft.SharedConstants; import java.io.IOException; import java.io.LineNumberReader; import java.nio.charset.StandardCharsets; @@ -21,6 +20,7 @@ import java.nio.file.Path; import java.util.HashSet; import java.util.Map; import java.util.Set; +import net.minecraft.SharedConstants; import static io.papermc.typewriter.replace.CommentMarker.EMPTY_MARKER; @@ -30,7 +30,7 @@ public class ScanOldGeneratedSourceCode { static { Main.bootStrap(false); - CURRENT_VERSION = SharedConstants.getCurrentVersion().getId(); + CURRENT_VERSION = SharedConstants.getCurrentVersion().id(); } public static void main(String[] args) throws IOException { diff --git a/paper-generator/src/main/java/io/papermc/generator/types/craftblockdata/property/holder/DataPropertyWriterBase.java b/paper-generator/src/main/java/io/papermc/generator/types/craftblockdata/property/holder/DataPropertyWriterBase.java index ef6aa97629..593e6bce3b 100644 --- a/paper-generator/src/main/java/io/papermc/generator/types/craftblockdata/property/holder/DataPropertyWriterBase.java +++ b/paper-generator/src/main/java/io/papermc/generator/types/craftblockdata/property/holder/DataPropertyWriterBase.java @@ -6,9 +6,11 @@ import io.papermc.generator.utils.Formatting; import it.unimi.dsi.fastutil.Pair; import java.lang.reflect.Field; import java.util.Collection; +import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.stream.Stream; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.properties.Property; import org.jspecify.annotations.NullMarked; @@ -16,11 +18,11 @@ import org.jspecify.annotations.NullMarked; @NullMarked public abstract class DataPropertyWriterBase implements DataPropertyMaker { - protected final Collection> properties; + protected final Stream> properties; protected final Class blockClass; protected DataPropertyWriterBase(Collection> properties, Class blockClass) { - this.properties = properties; + this.properties = properties.stream().sorted(Comparator.comparing(Property::getName)); this.blockClass = blockClass; } @@ -31,12 +33,12 @@ public abstract class DataPropertyWriterBase implements DataPropertyMaker { code.add("$T.of(\n", List.class); } code.indent(); - Iterator> it = this.properties.iterator(); - while (it.hasNext()) { - Property property = it.next(); + Iterator> properties = this.properties.iterator(); + while (properties.hasNext()) { + Property property = properties.next(); Pair, String> fieldName = PropertyWriter.referenceField(this.blockClass, property, fields); code.add("$T.$L", fieldName.left(), fieldName.right()); - if (it.hasNext()) { + if (properties.hasNext()) { code.add(","); } code.add("\n"); @@ -47,13 +49,13 @@ public abstract class DataPropertyWriterBase implements DataPropertyMaker { protected void createSyntheticMap(CodeBlock.Builder code, Class indexClass, Map, Field> fields) { // assume indexClass is an enum with its values matching the property names code.add("$T.of(\n", Map.class).indent(); - Iterator> it = this.properties.iterator(); - while (it.hasNext()) { - Property property = it.next(); + Iterator> properties = this.properties.iterator(); + while (properties.hasNext()) { + Property property = properties.next(); String name = Formatting.formatKeyAsField(property.getName()); Pair, String> fieldName = PropertyWriter.referenceField(this.blockClass, property, fields); code.add("$T.$L, $T.$L", indexClass, name, fieldName.left(), fieldName.right()); - if (it.hasNext()) { + if (properties.hasNext()) { code.add(","); } code.add("\n"); diff --git a/paper-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java b/paper-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java index 46f5f48c82..105dad1d01 100644 --- a/paper-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java +++ b/paper-generator/src/main/java/io/papermc/generator/types/goal/MobGoalNames.java @@ -5,201 +5,359 @@ import com.destroystokyo.paper.entity.ai.GoalKey; import com.google.common.base.CaseFormat; import io.papermc.generator.utils.Formatting; import io.papermc.paper.entity.SchoolableFish; +import io.papermc.typewriter.util.ClassHelper; +import it.unimi.dsi.fastutil.ints.Int2BooleanFunction; import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Comparator; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; +import net.minecraft.Util; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.monster.RangedAttackMob; import org.apache.commons.lang3.math.NumberUtils; import org.bukkit.NamespacedKey; -import org.bukkit.entity.*; +import org.bukkit.entity.AbstractCow; +import org.bukkit.entity.AbstractHorse; +import org.bukkit.entity.AbstractSkeleton; +import org.bukkit.entity.AbstractVillager; +import org.bukkit.entity.Ageable; +import org.bukkit.entity.Allay; +import org.bukkit.entity.Ambient; +import org.bukkit.entity.Animals; +import org.bukkit.entity.Armadillo; +import org.bukkit.entity.Axolotl; +import org.bukkit.entity.Bat; +import org.bukkit.entity.Bee; +import org.bukkit.entity.Blaze; +import org.bukkit.entity.Bogged; +import org.bukkit.entity.Breeze; +import org.bukkit.entity.Cat; +import org.bukkit.entity.CaveSpider; +import org.bukkit.entity.ChestedHorse; +import org.bukkit.entity.Chicken; +import org.bukkit.entity.Cod; +import org.bukkit.entity.Cow; +import org.bukkit.entity.Creaking; +import org.bukkit.entity.Creature; +import org.bukkit.entity.Creeper; +import org.bukkit.entity.Dolphin; +import org.bukkit.entity.Donkey; +import org.bukkit.entity.Drowned; +import org.bukkit.entity.ElderGuardian; +import org.bukkit.entity.EnderDragon; +import org.bukkit.entity.Enderman; +import org.bukkit.entity.Endermite; +import org.bukkit.entity.Evoker; +import org.bukkit.entity.Fish; +import org.bukkit.entity.Fox; +import org.bukkit.entity.Frog; +import org.bukkit.entity.Ghast; +import org.bukkit.entity.Giant; +import org.bukkit.entity.GlowSquid; +import org.bukkit.entity.Goat; +import org.bukkit.entity.Golem; +import org.bukkit.entity.Guardian; +import org.bukkit.entity.HappyGhast; +import org.bukkit.entity.Hoglin; +import org.bukkit.entity.Horse; +import org.bukkit.entity.Husk; +import org.bukkit.entity.Illager; +import org.bukkit.entity.Illusioner; +import org.bukkit.entity.IronGolem; +import org.bukkit.entity.Llama; +import org.bukkit.entity.MagmaCube; +import org.bukkit.entity.Mob; +import org.bukkit.entity.Monster; +import org.bukkit.entity.Mule; +import org.bukkit.entity.MushroomCow; +import org.bukkit.entity.Ocelot; +import org.bukkit.entity.Panda; +import org.bukkit.entity.Parrot; +import org.bukkit.entity.Phantom; +import org.bukkit.entity.Pig; +import org.bukkit.entity.PigZombie; +import org.bukkit.entity.Piglin; +import org.bukkit.entity.PiglinAbstract; +import org.bukkit.entity.PiglinBrute; +import org.bukkit.entity.Pillager; +import org.bukkit.entity.PolarBear; +import org.bukkit.entity.PufferFish; +import org.bukkit.entity.Rabbit; +import org.bukkit.entity.Raider; +import org.bukkit.entity.Ravager; +import org.bukkit.entity.Salmon; +import org.bukkit.entity.Sheep; +import org.bukkit.entity.Shulker; +import org.bukkit.entity.Silverfish; +import org.bukkit.entity.Skeleton; +import org.bukkit.entity.SkeletonHorse; +import org.bukkit.entity.Slime; +import org.bukkit.entity.Sniffer; +import org.bukkit.entity.Snowman; +import org.bukkit.entity.Spellcaster; +import org.bukkit.entity.Spider; +import org.bukkit.entity.Squid; +import org.bukkit.entity.Stray; +import org.bukkit.entity.Strider; +import org.bukkit.entity.Tadpole; +import org.bukkit.entity.Tameable; +import org.bukkit.entity.TraderLlama; +import org.bukkit.entity.TropicalFish; +import org.bukkit.entity.Turtle; +import org.bukkit.entity.Vex; +import org.bukkit.entity.Villager; +import org.bukkit.entity.Vindicator; +import org.bukkit.entity.WanderingTrader; +import org.bukkit.entity.Warden; +import org.bukkit.entity.WaterMob; +import org.bukkit.entity.Witch; +import org.bukkit.entity.Wither; +import org.bukkit.entity.WitherSkeleton; +import org.bukkit.entity.Wolf; +import org.bukkit.entity.Zoglin; +import org.bukkit.entity.Zombie; +import org.bukkit.entity.ZombieHorse; +import org.bukkit.entity.ZombieVillager; import org.jspecify.annotations.NullMarked; @NullMarked public final class MobGoalNames { // todo sync with MobGoalHelper ideally this should not be duplicated - private static final Map, Class> entityClassCache = new HashMap<>(); - public static final Map, Class> bukkitMap = new LinkedHashMap<>(); - - static { + private static final Map, Class> GENERIC_TYPE_CACHE = new HashMap<>(); + public static final Map, Class> BUKKIT_BRIDGE = Util.make(new LinkedHashMap<>(), map -> { // - bukkitMap.put(net.minecraft.world.entity.Mob.class, Mob.class); - bukkitMap.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class); - bukkitMap.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class); - bukkitMap.put(net.minecraft.world.entity.animal.Animal.class, Animals.class); - bukkitMap.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class); - bukkitMap.put(net.minecraft.world.entity.animal.Bee.class, Bee.class); - bukkitMap.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cat.class, Cat.class); - bukkitMap.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class); - bukkitMap.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cod.class, Cod.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cow.class, Cow.class); - bukkitMap.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class); - bukkitMap.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class); - bukkitMap.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class); - bukkitMap.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class); - bukkitMap.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class); - bukkitMap.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class); - bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); - bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); - bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class); - bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); - bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); - bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class); - bukkitMap.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class); - bukkitMap.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.camel.Camel.class, org.bukkit.entity.Camel.class); - bukkitMap.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class); - bukkitMap.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class); - bukkitMap.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class); - bukkitMap.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class); - bukkitMap.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class); - bukkitMap.put(net.minecraft.world.entity.monster.Monster.class, Monster.class); - bukkitMap.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); // close enough - bukkitMap.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class); - bukkitMap.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class); - bukkitMap.put(net.minecraft.world.entity.animal.Panda.class, Panda.class); - bukkitMap.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class); - bukkitMap.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); // close enough - bukkitMap.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class); - bukkitMap.put(net.minecraft.world.entity.animal.Pig.class, Pig.class); - bukkitMap.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class); - bukkitMap.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class); - bukkitMap.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class); - bukkitMap.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class); - bukkitMap.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class); - bukkitMap.put(net.minecraft.world.entity.raid.Raider.class, Raider.class); - bukkitMap.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class); - bukkitMap.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class); - bukkitMap.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class); - bukkitMap.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class); - bukkitMap.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class); - bukkitMap.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.Stray.class, Stray.class); - bukkitMap.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.Slime.class, Slime.class); - bukkitMap.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class); - bukkitMap.put(net.minecraft.world.entity.monster.Spider.class, Spider.class); - bukkitMap.put(net.minecraft.world.entity.animal.Squid.class, Squid.class); - bukkitMap.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class); - bukkitMap.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class); - bukkitMap.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class); - bukkitMap.put(net.minecraft.world.entity.monster.Vex.class, Vex.class); - bukkitMap.put(net.minecraft.world.entity.npc.Villager.class, Villager.class); - bukkitMap.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class); - bukkitMap.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class); - bukkitMap.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class); - bukkitMap.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class); - bukkitMap.put(net.minecraft.world.entity.monster.Witch.class, Witch.class); - bukkitMap.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class); - bukkitMap.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class); - bukkitMap.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class); - bukkitMap.put(net.minecraft.world.entity.monster.Husk.class, Husk.class); - bukkitMap.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class); - bukkitMap.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class); - bukkitMap.put(net.minecraft.world.entity.monster.Strider.class, Strider.class); - bukkitMap.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class); - bukkitMap.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class); - bukkitMap.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class); - bukkitMap.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class); - bukkitMap.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class); - bukkitMap.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class); - bukkitMap.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class); - bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class); - bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class); - bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class); - bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class); - bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class); - bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class); - bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); // close enough - bukkitMap.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class); + map.put(net.minecraft.world.entity.Mob.class, Mob.class); + map.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class); + map.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class); + map.put(net.minecraft.world.entity.animal.Animal.class, Animals.class); + map.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class); + map.put(net.minecraft.world.entity.animal.Bee.class, Bee.class); + map.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class); + map.put(net.minecraft.world.entity.animal.Cat.class, Cat.class); + map.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class); + map.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class); + map.put(net.minecraft.world.entity.animal.Cod.class, Cod.class); + map.put(net.minecraft.world.entity.animal.Cow.class, Cow.class); + map.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class); + map.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class); + map.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class); + map.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class); + map.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class); + map.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class); + map.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); + map.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); + map.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); + map.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); + map.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); + map.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); + map.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); + map.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class); + map.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class); + map.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class); + map.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class); + map.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class); + map.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class); + map.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class); + map.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class); + map.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class); + map.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class); + map.put(net.minecraft.world.entity.animal.camel.Camel.class, org.bukkit.entity.Camel.class); + map.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class); + map.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class); + map.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class); + map.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class); + map.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class); + map.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class); + map.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class); + map.put(net.minecraft.world.entity.monster.Monster.class, Monster.class); + map.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); // close enough + map.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class); + map.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class); + map.put(net.minecraft.world.entity.animal.Panda.class, Panda.class); + map.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class); + map.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); // close enough + map.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class); + map.put(net.minecraft.world.entity.animal.Pig.class, Pig.class); + map.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class); + map.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class); + map.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class); + map.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class); + map.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class); + map.put(net.minecraft.world.entity.raid.Raider.class, Raider.class); + map.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class); + map.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class); + map.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class); + map.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class); + map.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class); + map.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class); + map.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class); + map.put(net.minecraft.world.entity.monster.Stray.class, Stray.class); + map.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class); + map.put(net.minecraft.world.entity.monster.Slime.class, Slime.class); + map.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class); + map.put(net.minecraft.world.entity.monster.Spider.class, Spider.class); + map.put(net.minecraft.world.entity.animal.Squid.class, Squid.class); + map.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class); + map.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class); + map.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class); + map.put(net.minecraft.world.entity.monster.Vex.class, Vex.class); + map.put(net.minecraft.world.entity.npc.Villager.class, Villager.class); + map.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class); + map.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class); + map.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class); + map.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class); + map.put(net.minecraft.world.entity.monster.Witch.class, Witch.class); + map.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class); + map.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class); + map.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class); + map.put(net.minecraft.world.entity.monster.Husk.class, Husk.class); + map.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class); + map.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class); + map.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class); + map.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class); + map.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class); + map.put(net.minecraft.world.entity.monster.Strider.class, Strider.class); + map.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class); + map.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class); + map.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class); + map.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class); + map.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class); + map.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class); + map.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class); + map.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class); + map.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class); + map.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class); + map.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class); + map.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class); + map.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class); + map.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); // close enough + map.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class); + map.put(net.minecraft.world.entity.animal.HappyGhast.class, HappyGhast.class); // - } + }); - private static final Map deobfuscationMap = new HashMap<>(); + // TODO these kinda should be checked on each release, in case nested classes changes + private static final Map NESTED_CLASS_NAMES = Util.make(new HashMap<>(), map -> { + map.put("AbstractSkeleton$1", "AbstractSkeletonMelee"); - static { - // TODO these kinda should be checked on each release, in case obfuscation changes - deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee"); - } + // remove duplicate + map.put("TraderLlama$TraderLlamaDefendWanderingTraderGoal", "TraderLlamaDefendWanderingTraderGoal"); + map.put("AbstractIllager$RaiderOpenDoorGoal", "RaiderOpenDoorGoal"); - private static String getPathName(String name) { + // weird enderman case + map.put("EnderMan.EndermanFreezeWhenLookedAt", "EndermanFreezeWhenLookedAt"); + map.put("EnderMan.EndermanLeaveBlockGoal", "EndermanLeaveBlockGoal"); + map.put("EnderMan.EndermanTakeBlockGoal", "EndermanTakeBlockGoal"); + map.put("EnderMan.EndermanLookForPlayerGoal", "EndermanLookForPlayerGoal"); + }); + + private static final Set> NO_SPECIFIER = Set.of( + Mob.class, + Creature.class, + Animals.class, + RangedEntity.class, + Tameable.class, + Monster.class, + PufferFish.class // weird case + ); + + private static String getPathName(Class type, Class holderClass, String name) { String pathName = name.substring(name.lastIndexOf('.') + 1); - boolean needDeobfMap = false; + boolean needRename = false; // inner classes int firstInnerDelimiter = pathName.indexOf('$'); if (firstInnerDelimiter != -1) { - String innerClassName = pathName.substring(firstInnerDelimiter + 1); - for (String nestedClass : innerClassName.split("\\$")) { - if (NumberUtils.isDigits(nestedClass)) { - needDeobfMap = true; + String innerClassNames = pathName.substring(firstInnerDelimiter + 1); + for (String innerClassName : innerClassNames.split("\\$")) { + if (NumberUtils.isDigits(innerClassName)) { + needRename = true; break; } } - if (!needDeobfMap) { - pathName = innerClassName; + if (!needRename && !NESTED_CLASS_NAMES.containsKey(pathName)) { + pathName = innerClassNames; } - pathName = pathName.replace('$', '_'); - // mapped, wooo! + } + + if (!NESTED_CLASS_NAMES.containsKey(pathName)) { + if (needRename) { + throw new IllegalStateException("need to map " + name + " (" + pathName + ")"); + } + String prefix = null; + if (!NO_SPECIFIER.contains(type)) { + prefix = type.getSimpleName(); + } else if (!net.minecraft.world.entity.Mob.class.isAssignableFrom(holderClass)) { + prefix = holderClass.getSimpleName(); + } + if (prefix != null && !pathName.startsWith(prefix)) { + pathName = prefix + pathName; + } + } else { + pathName = NESTED_CLASS_NAMES.get(pathName); } pathName = Formatting.stripWordOfCamelCaseName(pathName, "TargetGoal", true); // replace last? reverse search? pathName = Formatting.stripWordOfCamelCaseName(pathName, "Goal", true); + pathName = Formatting.stripWordOfCamelCaseName(pathName, "Abstract", true); pathName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pathName); - if (needDeobfMap && !deobfuscationMap.containsKey(pathName)) { - System.err.println("need to map " + name + " (" + pathName + ")"); - } - - // did we rename this key? - return deobfuscationMap.getOrDefault(pathName, pathName); + return pathName; } public static GoalKey getKey(Class goalClass) { - String name = getPathName(goalClass.getName()); - return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name)); + Class type = getGenericType(goalClass); + Class holderClass = ClassHelper.getTopLevelClass(goalClass); + String name = getPathName(type, holderClass, goalClass.getName()); + return GoalKey.of(type, NamespacedKey.minecraft(name)); } - private static Class getEntity(Class goalClass) { + private static final Int2BooleanFunction[] VISIBILITY_SEARCH_STEP = { + Modifier::isPublic, + Modifier::isProtected, + mod -> (mod & 0b111) == 0, // package-private + Modifier::isPrivate, + }; + + private static final Comparator> VISIBILITY_ORDER = Comparator.comparingInt(constructor -> { + int mod = constructor.getModifiers(); + for (int i = 0; i < VISIBILITY_SEARCH_STEP.length; i++) { + Int2BooleanFunction visibility = VISIBILITY_SEARCH_STEP[i]; + if (visibility.test(mod)) { + return i; + } + } + throw new UnsupportedOperationException("Unknown visibility: " + mod); + }); + + private static Class getGenericType(Class goalClass) { //noinspection unchecked - return (Class) entityClassCache.computeIfAbsent(goalClass, key -> { - for (Constructor ctor : key.getDeclaredConstructors()) { - for (Class param : ctor.getParameterTypes()) { - if (net.minecraft.world.entity.Mob.class.isAssignableFrom(param)) { + return (Class) GENERIC_TYPE_CACHE.computeIfAbsent(goalClass, key -> { + Constructor[] constructors = key.getDeclaredConstructors(); + Arrays.sort(constructors, VISIBILITY_ORDER); + + for (Constructor constructor : constructors) { + for (Class paramType : constructor.getParameterTypes()) { + if (net.minecraft.world.entity.Mob.class.isAssignableFrom(paramType)) { //noinspection unchecked - return toBukkitClass((Class) param); - } else if (RangedAttackMob.class.isAssignableFrom(param)) { + return toBukkitClass((Class) paramType); + } else if (RangedAttackMob.class.isAssignableFrom(paramType)) { return RangedEntity.class; } } } - throw new RuntimeException("Can't figure out applicable entity for mob goal " + goalClass); // maybe just return Mob? + throw new IllegalStateException("Can't figure out applicable entity for mob goal " + goalClass); // maybe just return Mob? }); } - private static Class toBukkitClass(Class nmsClass) { - Class bukkitClass = bukkitMap.get(nmsClass); + private static Class toBukkitClass(Class internalClass) { + Class bukkitClass = BUKKIT_BRIDGE.get(internalClass); if (bukkitClass == null) { - throw new RuntimeException("Can't figure out applicable bukkit entity for nms entity " + nmsClass); // maybe just return Mob? + throw new IllegalStateException("Can't figure out applicable bukkit entity for internal entity " + internalClass); // maybe just return Mob? } return bukkitClass; } diff --git a/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedKeyType.java b/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedKeyType.java index 7dd3af4d33..2a64dbe6cd 100644 --- a/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedKeyType.java +++ b/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedKeyType.java @@ -84,7 +84,7 @@ public class GeneratedKeyType extends SimpleGenerator { MethodSpec.Builder createMethod = this.createMethod(typedKeyType); boolean allExperimental = true; - for (Holder.Reference reference : this.entry.registry().listElements().sorted(Formatting.alphabeticKeyOrder(reference -> reference.key().location().getPath())).toList()) { + for (Holder.Reference reference : this.entry.registry().listElements().sorted(Formatting.HOLDER_ORDER).toList()) { ResourceKey key = reference.key(); String keyPath = key.location().getPath(); String fieldName = Formatting.formatKeyAsField(keyPath); diff --git a/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedTagKeyType.java b/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedTagKeyType.java index e1c5cb71f0..76249ac8f8 100644 --- a/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedTagKeyType.java +++ b/paper-generator/src/main/java/io/papermc/generator/types/registry/GeneratedTagKeyType.java @@ -73,7 +73,7 @@ public class GeneratedTagKeyType extends SimpleGenerator { MethodSpec.Builder createMethod = this.createMethod(tagKeyType); AtomicBoolean allExperimental = new AtomicBoolean(true); - this.entry.registry().listTagIds().sorted(Formatting.alphabeticKeyOrder(tagKey -> tagKey.location().getPath())).forEach(tagKey -> { + this.entry.registry().listTagIds().sorted(Formatting.TAG_ORDER).forEach(tagKey -> { String fieldName = Formatting.formatKeyAsField(tagKey.location().getPath()); FieldSpec.Builder fieldBuilder = FieldSpec.builder(tagKeyType, fieldName, PUBLIC, STATIC, FINAL) .initializer("$N(key($S))", createMethod.build(), tagKey.location().getPath()) diff --git a/paper-generator/src/main/java/io/papermc/generator/utils/Annotations.java b/paper-generator/src/main/java/io/papermc/generator/utils/Annotations.java index 47a0781edd..4a781ff658 100644 --- a/paper-generator/src/main/java/io/papermc/generator/utils/Annotations.java +++ b/paper-generator/src/main/java/io/papermc/generator/utils/Annotations.java @@ -35,7 +35,7 @@ public final class Annotations { public static final AnnotationSpec NULL_MARKED = AnnotationSpec.builder(NullMarked.class).build(); public static final AnnotationSpec OVERRIDE = AnnotationSpec.builder(Override.class).build(); public static final AnnotationSpec GENERATED_FROM = AnnotationSpec.builder(GeneratedFrom.class) - .addMember("value", "$S", SharedConstants.getCurrentVersion().getId()) + .addMember("value", "$S", SharedConstants.getCurrentVersion().id()) .build(); public static final Iterable CLASS_HEADER = List.of( suppressWarnings("unused", "SpellCheckingInspection"), diff --git a/paper-generator/src/main/java/io/papermc/generator/utils/Formatting.java b/paper-generator/src/main/java/io/papermc/generator/utils/Formatting.java index 9974a2a362..7009304f57 100644 --- a/paper-generator/src/main/java/io/papermc/generator/utils/Formatting.java +++ b/paper-generator/src/main/java/io/papermc/generator/utils/Formatting.java @@ -1,17 +1,19 @@ package io.papermc.generator.utils; -import java.util.Optional; -import org.apache.commons.lang3.math.NumberUtils; import java.util.Comparator; import java.util.Locale; -import java.util.OptionalInt; +import java.util.Optional; import java.util.function.Function; import java.util.regex.Pattern; import java.util.stream.IntStream; +import net.minecraft.core.Holder; import net.minecraft.core.Registry; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; +import net.minecraft.tags.TagKey; +import org.apache.commons.lang3.math.NumberUtils; import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; @NullMarked public final class Formatting { @@ -73,33 +75,36 @@ public final class Formatting { return newName; } - public static final Comparator ALPHABETIC_KEY_ORDER = alphabeticKeyOrder(path -> path); + public static final Comparator> HOLDER_ORDER = alphabeticKeyOrder(reference -> reference.key().location().getPath()); + public static final Comparator> TAG_ORDER = alphabeticKeyOrder(tagKey -> tagKey.location().getPath()); - public static Comparator alphabeticKeyOrder(Function mapper) { - return (o1, o2) -> { - String path1 = mapper.apply(o1); - String path2 = mapper.apply(o2); + public static Comparator alphabeticKeyOrder(Function pathConverter) { + return Comparator.comparing(pathConverter, (path1, path2) -> { + TrailingInt trailingInt1 = tryParseTrailingInt(path1); + TrailingInt trailingInt2 = tryParseTrailingInt(path2); - OptionalInt trailingInt1 = tryParseTrailingInt(path1); - OptionalInt trailingInt2 = tryParseTrailingInt(path2); - - if (trailingInt1.isPresent() && trailingInt2.isPresent()) { - return Integer.compare(trailingInt1.getAsInt(), trailingInt2.getAsInt()); + if (trailingInt1 != null && trailingInt2 != null && + trailingInt1.prefix().equals(trailingInt2.prefix())) { + return Integer.compareUnsigned(trailingInt1.value(), trailingInt2.value()); } return path1.compareTo(path2); - }; + }); } - private static OptionalInt tryParseTrailingInt(String path) { + private static @Nullable TrailingInt tryParseTrailingInt(String path) { int delimiterIndex = path.lastIndexOf('_'); if (delimiterIndex != -1) { - String score = path.substring(delimiterIndex + 1); - if (NumberUtils.isDigits(score)) { - return OptionalInt.of(Integer.parseInt(score)); + String value = path.substring(delimiterIndex + 1); + if (NumberUtils.isDigits(value)) { + String prefix = path.substring(0, delimiterIndex); + return new TrailingInt(prefix, Integer.parseInt(value)); } } - return OptionalInt.empty(); + return null; + } + + private record TrailingInt(String prefix, int value) { } private Formatting() { diff --git a/paper-generator/src/test/java/io/papermc/generator/BlockStatePropertyTest.java b/paper-generator/src/test/java/io/papermc/generator/BlockStatePropertyTest.java index d0c6c2cfa2..32b5b56163 100644 --- a/paper-generator/src/test/java/io/papermc/generator/BlockStatePropertyTest.java +++ b/paper-generator/src/test/java/io/papermc/generator/BlockStatePropertyTest.java @@ -1,6 +1,7 @@ package io.papermc.generator; import io.papermc.generator.utils.BlockStateMapping; +import io.papermc.generator.utils.ClassHelper; import java.lang.invoke.MethodHandles; import java.lang.reflect.Field; import java.lang.reflect.Modifier; @@ -10,7 +11,6 @@ import java.util.IdentityHashMap; import java.util.List; import java.util.Map; import java.util.Set; -import io.papermc.generator.utils.ClassHelper; import net.minecraft.SharedConstants; import net.minecraft.server.Bootstrap; import net.minecraft.world.level.block.ChiseledBookShelfBlock; diff --git a/paper-generator/src/test/java/io/papermc/generator/MobGoalConverterTest.java b/paper-generator/src/test/java/io/papermc/generator/MobGoalConverterTest.java index 56052d6b58..0eed5bbf4a 100644 --- a/paper-generator/src/test/java/io/papermc/generator/MobGoalConverterTest.java +++ b/paper-generator/src/test/java/io/papermc/generator/MobGoalConverterTest.java @@ -25,7 +25,7 @@ public class MobGoalConverterTest { List missingClasses = new ArrayList<>(); for (Class nmsClass : classes) { - if (!MobGoalNames.bukkitMap.containsKey(nmsClass)) { + if (!MobGoalNames.BUKKIT_BRIDGE.containsKey(nmsClass)) { missingClasses.add(nmsClass.getCanonicalName()); } } diff --git a/paper-server/build.gradle.kts b/paper-server/build.gradle.kts index 64e5f530e8..5b25c4058f 100644 --- a/paper-server/build.gradle.kts +++ b/paper-server/build.gradle.kts @@ -15,7 +15,7 @@ plugins { val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/" dependencies { - mache("io.papermc:mache:1.21.5+build.2") + mache("io.papermc:mache:1.21.6-rc1+build.1") paperclip("io.papermc:paperclip:3.0.3") testRuntimeOnly("org.junit.platform:junit-platform-launcher") } @@ -24,11 +24,8 @@ paperweight { minecraftVersion = providers.gradleProperty("mcVersion") gitFilePatches = false - //updatingMinecraft { - // oldPaperCommit = "f4f275519f7c1fbe9db173b7144a4fe81440e365" - //} - spigot { + enabled = false buildDataRef = "702e1a0a5072b2c4082371d5228cb30525687efc" packageVersion = "v1_21_R4" // also needs to be updated in MappingEnvironment } @@ -230,6 +227,11 @@ tasks.compileTestJava { options.compilerArgs.add("-parameters") } +// Bump compile tasks to 1GB memory to avoid OOMs +tasks.withType().configureEach { + options.forkOptions.memoryMaximumSize = "1G" +} + val scanJarForBadCalls by tasks.registering(io.papermc.paperweight.tasks.ScanJarForBadCalls::class) { badAnnotations.add("Lio/papermc/paper/annotation/DoNotUse;") jarToScan.set(tasks.jar.flatMap { it.archiveFile }) diff --git a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch index 6a1de74016..296185dc6a 100644 --- a/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch +++ b/paper-server/patches/features/0001-Optimize-Network-Manager-and-add-advanced-packet-sup.patch @@ -28,7 +28,7 @@ and then catch exceptions and close if they fire. Part of this commit was authored by: Spottedleaf, sandtechnology diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42eafb96fa1 100644 +index 2252c7c3e78c1d6dc9b56c0f6f01aec04699f072..235a076f982247552fef6d86d7e1b141eb8c72b5 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java @@ -85,7 +85,7 @@ public class Connection extends SimpleChannelInboundHandler> { @@ -51,10 +51,10 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e public Connection(PacketFlow receiving) { this.receiving = receiving; -@@ -423,11 +427,38 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -419,11 +423,38 @@ public class Connection extends SimpleChannelInboundHandler> { } - public void send(Packet packet, @Nullable PacketSendListener listener, boolean flush) { + public void send(Packet packet, @Nullable ChannelFutureListener channelFutureListener, boolean flag) { - if (this.isConnected()) { - this.flushQueue(); + // Paper start - Optimize network: Handle oversized packets better @@ -67,14 +67,14 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e + if (connected && (InnerUtil.canSendImmediate(this, packet) + || (io.papermc.paper.util.MCUtil.isMainThread() && packet.isReady() && this.pendingActions.isEmpty() + && (packet.getExtraPackets() == null || packet.getExtraPackets().isEmpty())))) { - this.sendPacket(packet, listener, flush); + this.sendPacket(packet, channelFutureListener, flag); } else { -- this.pendingActions.add(connection -> connection.sendPacket(packet, listener, flush)); +- this.pendingActions.add(connection -> connection.sendPacket(packet, channelFutureListener, flag)); + // Write the packets to the queue, then flush - antixray hooks there already + final java.util.List> extraPackets = InnerUtil.buildExtraPackets(packet); + final boolean hasExtraPackets = extraPackets != null && !extraPackets.isEmpty(); + if (!hasExtraPackets) { -+ this.pendingActions.add(new PacketSendAction(packet, listener, flush)); ++ this.pendingActions.add(new PacketSendAction(packet, channelFutureListener, flag)); + } else { + final java.util.List actions = new java.util.ArrayList<>(1 + extraPackets.size()); + actions.add(new PacketSendAction(packet, null, false)); // Delay the future listener until the end of the extra packets @@ -82,7 +82,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e + for (int i = 0, len = extraPackets.size(); i < len;) { + final Packet extraPacket = extraPackets.get(i); + final boolean end = ++i == len; -+ actions.add(new PacketSendAction(extraPacket, end ? listener : null, end)); // Append listener to the end ++ actions.add(new PacketSendAction(extraPacket, end ? channelFutureListener : null, end)); // Append listener to the end + } + + this.pendingActions.addAll(actions); @@ -93,7 +93,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e } } -@@ -436,7 +467,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -432,7 +463,7 @@ public class Connection extends SimpleChannelInboundHandler> { this.flushQueue(); action.accept(this); } else { @@ -102,10 +102,10 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e } } -@@ -450,6 +481,14 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -446,21 +477,41 @@ public class Connection extends SimpleChannelInboundHandler> { } - private void doSendPacket(Packet packet, @Nullable PacketSendListener sendListener, boolean flush) { + private void doSendPacket(Packet packet, @Nullable ChannelFutureListener channelFutureListener, boolean flag) { + // Paper start - Optimize network + final net.minecraft.server.level.ServerPlayer player = this.getPlayer(); + if (!this.isConnected()) { @@ -113,24 +113,29 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e + return; + } + try { ++ final ChannelFuture channelFuture; + // Paper end - Optimize network - ChannelFuture channelFuture = flush ? this.channel.writeAndFlush(packet) : this.channel.write(packet); - if (sendListener != null) { - channelFuture.addListener(future -> { -@@ -465,14 +504,24 @@ public class Connection extends SimpleChannelInboundHandler> { - }); - } - + if (channelFutureListener != null) { +- ChannelFuture channelFuture = flag ? this.channel.writeAndFlush(packet) : this.channel.write(packet); ++ channelFuture = flag ? this.channel.writeAndFlush(packet) : this.channel.write(packet); // Paper - Optimize network + channelFuture.addListener(channelFutureListener); + } else if (flag) { +- this.channel.writeAndFlush(packet, this.channel.voidPromise()); ++ channelFuture = this.channel.writeAndFlush(packet, this.channel.voidPromise()); // Paper - Optimize network + } else { +- this.channel.write(packet, this.channel.voidPromise()); ++ channelFuture = this.channel.write(packet, this.channel.voidPromise()); // Paper - Optimize network ++ } ++ + // Paper start - Optimize network + if (packet.hasFinishListener()) { + channelFuture.addListener((ChannelFutureListener) future -> packet.onPacketDispatchFinish(player, future)); + } - channelFuture.addListener(ChannelFutureListener.FIRE_EXCEPTION_ON_FAILURE); + } catch (final Exception e) { + LOGGER.error("NetworkException: {}", player, e); + this.disconnect(Component.translatable("disconnect.genericReason", "Internal Exception: " + e.getMessage())); + packet.onPacketDispatchFinish(player, null); -+ } + } + // Paper end - Optimize network } @@ -143,7 +148,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e } } -@@ -484,16 +533,57 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -472,16 +523,57 @@ public class Connection extends SimpleChannelInboundHandler> { } } @@ -206,7 +211,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e private static final int MAX_PER_TICK = io.papermc.paper.configuration.GlobalConfiguration.get().misc.maxJoinsPerTick; // Paper - Buffer joins to world private static int joinAttemptsThisTick; // Paper - Buffer joins to world -@@ -563,6 +653,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -551,6 +643,7 @@ public class Connection extends SimpleChannelInboundHandler> { public void disconnect(DisconnectionDetails disconnectionDetails) { this.preparing = false; // Spigot @@ -214,7 +219,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e if (this.channel == null) { this.delayedDisconnect = disconnectionDetails; } -@@ -751,7 +842,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -739,7 +832,7 @@ public class Connection extends SimpleChannelInboundHandler> { public void handleDisconnection() { if (this.channel != null && !this.channel.isOpen()) { if (this.disconnectionHandled) { @@ -223,7 +228,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e } else { this.disconnectionHandled = true; PacketListener packetListener = this.getPacketListener(); -@@ -762,7 +853,7 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -750,7 +843,7 @@ public class Connection extends SimpleChannelInboundHandler> { ); packetListener1.onDisconnect(disconnectionDetails); } @@ -232,7 +237,7 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e // Paper start - Add PlayerConnectionCloseEvent if (packetListener instanceof net.minecraft.server.network.ServerCommonPacketListenerImpl commonPacketListener) { /* Player was logged in, either game listener or configuration listener */ -@@ -797,4 +888,97 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -785,4 +878,97 @@ public class Connection extends SimpleChannelInboundHandler> { public void setBandwidthLogger(LocalSampleLogger bandwithLogger) { this.bandwidthDebugMonitor = new BandwidthDebugMonitor(bandwithLogger); } @@ -323,8 +328,8 @@ index 42f44c7cb0bd55ddfacd18acb0e596e7a953870e..2040b9555c430420a8a8697cc131d42e + private static final class PacketSendAction extends WrappedConsumer { + private final Packet packet; + -+ private PacketSendAction(final Packet packet, @Nullable final PacketSendListener packetSendListener, final boolean flush) { -+ super(connection -> connection.sendPacket(packet, packetSendListener, flush)); ++ private PacketSendAction(final Packet packet, @Nullable final ChannelFutureListener channelFutureListener, final boolean flush) { ++ super(connection -> connection.sendPacket(packet, channelFutureListener, flush)); + this.packet = packet; + } + } diff --git a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch index db32284e15..bb84f65626 100644 --- a/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch +++ b/paper-server/patches/features/0003-Entity-Activation-Range-2.0.patch @@ -15,19 +15,20 @@ Adds villagers as separate config diff --git a/io/papermc/paper/entity/activation/ActivationRange.java b/io/papermc/paper/entity/activation/ActivationRange.java new file mode 100644 -index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae69f36157e +index 0000000000000000000000000000000000000000..ae2bb9a73106febfe5f0d090abd4252bbb5fd27e --- /dev/null +++ b/io/papermc/paper/entity/activation/ActivationRange.java -@@ -0,0 +1,318 @@ +@@ -0,0 +1,334 @@ +package io.papermc.paper.entity.activation; + +import net.minecraft.core.BlockPos; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.ExperienceOrb; -+import net.minecraft.world.entity.FlyingMob; +import net.minecraft.world.entity.LightningBolt; +import net.minecraft.world.entity.LivingEntity; ++import net.minecraft.world.entity.Marker; +import net.minecraft.world.entity.Mob; +import net.minecraft.world.entity.ai.Brain; +import net.minecraft.world.entity.animal.Animal; @@ -38,6 +39,7 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 +import net.minecraft.world.entity.boss.enderdragon.EndCrystal; +import net.minecraft.world.entity.boss.enderdragon.EnderDragon; +import net.minecraft.world.entity.boss.wither.WitherBoss; ++import net.minecraft.world.entity.item.FallingBlockEntity; +import net.minecraft.world.entity.item.ItemEntity; +import net.minecraft.world.entity.item.PrimedTnt; +import net.minecraft.world.entity.monster.Creeper; @@ -51,9 +53,13 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 +import net.minecraft.world.entity.projectile.ThrowableProjectile; +import net.minecraft.world.entity.projectile.ThrownTrident; +import net.minecraft.world.entity.schedule.Activity; ++import net.minecraft.world.entity.vehicle.AbstractBoat; ++import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import org.spigotmc.SpigotWorldConfig; ++import java.util.List; ++import java.util.Set; + +public final class ActivationRange { + @@ -121,9 +127,9 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 + || entity instanceof AbstractHurtingProjectile + || entity instanceof LightningBolt + || entity instanceof PrimedTnt -+ || entity instanceof net.minecraft.world.entity.item.FallingBlockEntity -+ || entity instanceof net.minecraft.world.entity.vehicle.AbstractMinecart -+ || entity instanceof net.minecraft.world.entity.vehicle.AbstractBoat ++ || entity instanceof FallingBlockEntity ++ || entity instanceof AbstractMinecart ++ || entity instanceof AbstractBoat + || entity instanceof EndCrystal + || entity instanceof FireworkRocketEntity + || entity instanceof ThrownTrident; @@ -172,10 +178,10 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 + ActivationType.FLYING_MONSTER.boundingBox = player.getBoundingBox().inflate(flyingActivationRange, worldHeight, flyingActivationRange); + ActivationType.VILLAGER.boundingBox = player.getBoundingBox().inflate(villagerActivationRange, worldHeight, villagerActivationRange); + -+ final java.util.List entities = world.getEntities((Entity) null, ActivationRange.maxBB, e -> true); ++ final List entities = world.getEntities((Entity) null, ActivationRange.maxBB, e -> true); + final boolean tickMarkers = world.paperConfig().entities.markers.tick; + for (final Entity entity : entities) { -+ if (!tickMarkers && entity instanceof net.minecraft.world.entity.Marker) { ++ if (!tickMarkers && entity instanceof Marker) { + continue; + } + @@ -228,7 +234,7 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 + return 100; + } + if (!(entity instanceof final AbstractArrow arrow)) { -+ if ((!entity.onGround() && !(entity instanceof FlyingMob))) { ++ if ((!entity.onGround() && !isEntityThatFlies(entity))) { + return 10; + } + } else if (!arrow.isInGround()) { @@ -336,9 +342,19 @@ index 0000000000000000000000000000000000000000..2ebee223085fe7926c7f3e555df19ae6 + // removed the original's dumb tick skipping for active entities + return isActive; + } ++ ++ private static Set> ENTITIES_THAT_FLY = Set.of( ++ EntityType.GHAST, ++ EntityType.HAPPY_GHAST, ++ EntityType.PHANTOM ++ ); ++ ++ private static boolean isEntityThatFlies(final Entity entity) { ++ return ENTITIES_THAT_FLY.contains(entity.getType()); ++ } +} diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index 88b81a5fbc88e6240f86c1e780d80eb4b601df8c..00a5ed09caa2689543bd47bcd93d5a6141d0af46 100644 +index 7b5ed00c9b2f22af5cbc44171192d674936dc7d7..5fe3c9a159908785e08fa874982bc1a82283bb1d 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableList; @@ -358,10 +374,10 @@ index 88b81a5fbc88e6240f86c1e780d80eb4b601df8c..00a5ed09caa2689543bd47bcd93d5a61 import java.io.Writer; import java.nio.file.Path; diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6719a16fc 100644 +index 18551bebb7e40c936de94c6d1b009db4752d3bba..e6f958b6128213fb9577406c6495148dccac40ca 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -544,6 +544,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -548,6 +548,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe profilerFiller.pop(); } @@ -369,7 +385,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6 this.entityTickList .forEach( entity -> { -@@ -982,12 +983,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -990,12 +991,15 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe entity.totalEntityAge++; // Paper - age-like counter for all entities profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(entity.getType()).toString()); profilerFiller.incrementCounter("tickNonPassenger"); @@ -386,7 +402,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6 } // Paper start - log detailed entity tick information } finally { -@@ -998,7 +1002,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1006,7 +1010,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // Paper end - log detailed entity tick information } @@ -395,7 +411,7 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6 if (passengerEntity.isRemoved() || passengerEntity.getVehicle() != ridingEntity) { passengerEntity.stopRiding(); } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) { -@@ -1008,12 +1012,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1016,12 +1020,21 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push(() -> BuiltInRegistries.ENTITY_TYPE.getKey(passengerEntity.getType()).toString()); profilerFiller.incrementCounter("tickPassenger"); @@ -419,10 +435,10 @@ index 81c615d00323bdf86bdb76db17bb47288cf3feba..6b67cc939851745718f919488c997eb6 } } diff --git a/net/minecraft/world/entity/AgeableMob.java b/net/minecraft/world/entity/AgeableMob.java -index f9cfa9dd17bd259cfbc0d96bf48a17556b365d8b..201c6d6e2f5799a7678b16f01c85508bc72e8af5 100644 +index 16c5ad1547eb383e40c9fbae9b1119afc418b3a4..04875840085541ebfc7014868beec49bb7ab9976 100644 --- a/net/minecraft/world/entity/AgeableMob.java +++ b/net/minecraft/world/entity/AgeableMob.java -@@ -129,6 +129,23 @@ public abstract class AgeableMob extends PathfinderMob { +@@ -130,6 +130,23 @@ public abstract class AgeableMob extends PathfinderMob { super.onSyncedDataUpdated(key); } @@ -447,10 +463,10 @@ index f9cfa9dd17bd259cfbc0d96bf48a17556b365d8b..201c6d6e2f5799a7678b16f01c85508b public void aiStep() { super.aiStep(); diff --git a/net/minecraft/world/entity/AreaEffectCloud.java b/net/minecraft/world/entity/AreaEffectCloud.java -index bf44f6b9c8710e0c9a85d44f6217501abc98a7b1..bfd904e468bbf2cc1a5b3353d3a69ad5087c81ae 100644 +index c70a58f5f633fa8e255f74c42f5e87c96b7b013a..ec20a5a6d7c8f65abda528fec36bec7bc71117f6 100644 --- a/net/minecraft/world/entity/AreaEffectCloud.java +++ b/net/minecraft/world/entity/AreaEffectCloud.java -@@ -144,6 +144,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { +@@ -142,6 +142,16 @@ public class AreaEffectCloud extends Entity implements TraceableEntity { this.duration = duration; } @@ -468,10 +484,10 @@ index bf44f6b9c8710e0c9a85d44f6217501abc98a7b1..bfd904e468bbf2cc1a5b3353d3a69ad5 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744b0434e94 100644 +index f961540a00bfb5e1c8eb0e739f8ae535e9eee8f3..7453ddb09f349b7836f966573e4933646a75cba6 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -388,6 +388,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -409,6 +409,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess private final int despawnTime; // Paper - entity despawn time limit public int totalEntityAge; // Paper - age-like counter for all entities public final io.papermc.paper.entity.activation.ActivationType activationType = io.papermc.paper.entity.activation.ActivationType.activationTypeFor(this); // Paper - EAR 2/tracking ranges @@ -487,7 +503,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744 // CraftBukkit end // Paper start -@@ -407,6 +416,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -424,6 +433,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.position = Vec3.ZERO; this.blockPosition = BlockPos.ZERO; this.chunkPosition = ChunkPos.ZERO; @@ -501,7 +517,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744 SynchedEntityData.Builder builder = new SynchedEntityData.Builder(this); builder.define(DATA_SHARED_FLAGS_ID, (byte)0); builder.define(DATA_AIR_SUPPLY_ID, this.getMaxAirSupply()); -@@ -962,6 +978,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -984,6 +1000,10 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { if (type == MoverType.PISTON) { @@ -512,7 +528,7 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744 movement = this.limitPistonMovement(movement); if (movement.equals(Vec3.ZERO)) { return; -@@ -975,6 +995,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -997,6 +1017,13 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stuckSpeedMultiplier = Vec3.ZERO; this.setDeltaMovement(Vec3.ZERO); } @@ -527,10 +543,10 @@ index a63873a0fe4335813cafe84cae2b2030c8f0e627..f0c72465a71dc5a51c22af5e614af744 movement = this.maybeBackOffFromEdge(movement, type); Vec3 vec3 = this.collide(movement); diff --git a/net/minecraft/world/entity/LivingEntity.java b/net/minecraft/world/entity/LivingEntity.java -index 267544f50fafd914566df1c4b2327bc64d673165..3e8f4f3c3d43c6875108295187023c48eece2788 100644 +index 13cf40918ead3e2cb2699398ac659a3e1806294b..1ba342a1a60951f828034d3ed535b577b3990bf6 100644 --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -3163,6 +3163,14 @@ public abstract class LivingEntity extends Entity implements Attackable { +@@ -3215,6 +3215,14 @@ public abstract class LivingEntity extends Entity implements Attackable, Waypoin return false; } @@ -546,10 +562,10 @@ index 267544f50fafd914566df1c4b2327bc64d673165..3e8f4f3c3d43c6875108295187023c48 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/Mob.java b/net/minecraft/world/entity/Mob.java -index 8f5c377540f83911c8d245fb00569f08dbc6a690..73ba442b9d39bc021cd5eb6c1c0f98aed94a5a02 100644 +index 3047763580fabd069db5e90a9a854396c6243763..0470c4bbf8be7e48ce8dfa4910c3b9f5ebb23360 100644 --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -203,6 +203,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab +@@ -206,6 +206,19 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashab return this.lookControl; } @@ -570,7 +586,7 @@ index 8f5c377540f83911c8d245fb00569f08dbc6a690..73ba442b9d39bc021cd5eb6c1c0f98ae return this.getControlledVehicle() instanceof Mob mob ? mob.getMoveControl() : this.moveControl; } diff --git a/net/minecraft/world/entity/PathfinderMob.java b/net/minecraft/world/entity/PathfinderMob.java -index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a2ac6c09b 100644 +index 60cc5cf40967eee8988cda8a45ff098e66e8ddf2..741b5078ab9ee9b8463c61ab66ba9b5c9cda0974 100644 --- a/net/minecraft/world/entity/PathfinderMob.java +++ b/net/minecraft/world/entity/PathfinderMob.java @@ -17,6 +17,8 @@ public abstract class PathfinderMob extends Mob { @@ -583,10 +599,10 @@ index 0caf50ec50f056b83a20bbc6a2fe0144593aef39..af59a700755654eb68d6bf57d0712c4a return this.getWalkTargetValue(pos, this.level()); } diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java -index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b97f7f1c71 100644 +index d552e47aa38c61a8f78ed114a3433603c9658a24..674966c580220a4e0c83a628c763aaea8bfd0b1c 100644 --- a/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -25,6 +25,7 @@ public class GoalSelector { +@@ -24,6 +24,7 @@ public class GoalSelector { private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); private final Set availableGoals = new ObjectLinkedOpenHashSet<>(); private final EnumSet disabledFlags = EnumSet.noneOf(Goal.Flag.class); @@ -594,7 +610,7 @@ index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b9 public void addGoal(int priority, Goal goal) { this.availableGoals.add(new WrappedGoal(priority, goal)); -@@ -35,6 +36,22 @@ public class GoalSelector { +@@ -33,6 +34,22 @@ public class GoalSelector { this.availableGoals.removeIf(wrappedGoal -> filter.test(wrappedGoal.getGoal())); } @@ -618,7 +634,7 @@ index 9338e63cc28413f5559bb0122ef5e04a84bd51d1..eeba224bd575451ba6023df65ef9d9b9 for (WrappedGoal wrappedGoal : this.availableGoals) { if (wrappedGoal.getGoal() == goal && wrappedGoal.isRunning()) { diff --git a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java -index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20ce822608 100644 +index 3f780276be6766ef253c50212e06fd93a96b0caa..7e70c7bee633c54497d1cd2854dd60f4fb5ff160 100644 --- a/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java +++ b/net/minecraft/world/entity/ai/goal/MoveToBlockGoal.java @@ -23,6 +23,14 @@ public abstract class MoveToBlockGoal extends Goal { @@ -638,17 +654,17 @@ index 789fea258d70e60d38271ebb31270562dc7eb3ab..d0ab3db7bbd2942db19f473474371b20 this.mob = mob; @@ -113,6 +121,7 @@ public abstract class MoveToBlockGoal extends Goal { mutableBlockPos.setWithOffset(blockPos, i4, i2 - 1, i5); - if (this.mob.isWithinRestriction(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) { + if (this.mob.isWithinHome(mutableBlockPos) && this.isValidTarget(this.mob.level(), mutableBlockPos)) { this.blockPos = mutableBlockPos; + this.mob.movingTarget = mutableBlockPos == BlockPos.ZERO ? null : mutableBlockPos.immutable(); // Paper return true; } } diff --git a/net/minecraft/world/entity/item/ItemEntity.java b/net/minecraft/world/entity/item/ItemEntity.java -index ea3afc27600cde05a17197b071f14972d2c832e6..6c0ebfb2be4e8b884456a2aa3d5fdc87e45a0e3c 100644 +index 548d7c8dc517da6c4db86b11f579ae63e6db56cf..a29860af4c37b2b45df49f9ba18f7e38921dfb02 100644 --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -131,6 +131,29 @@ public class ItemEntity extends Entity implements TraceableEntity { +@@ -121,6 +121,29 @@ public class ItemEntity extends Entity implements TraceableEntity { return 0.04; } @@ -679,10 +695,10 @@ index ea3afc27600cde05a17197b071f14972d2c832e6..6c0ebfb2be4e8b884456a2aa3d5fdc87 public void tick() { if (this.getItem().isEmpty()) { diff --git a/net/minecraft/world/entity/npc/Villager.java b/net/minecraft/world/entity/npc/Villager.java -index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca60263240 100644 +index b0607f4a9b35570b319423c7876bb904d5154e8e..98c8653647dc52059d8becfe38a74d4e62edf08f 100644 --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -268,11 +268,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -269,11 +269,35 @@ public class Villager extends AbstractVillager implements ReputationEventHandler return this.assignProfessionWhenSpawned; } @@ -719,7 +735,7 @@ index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca profilerFiller.pop(); if (this.assignProfessionWhenSpawned) { this.assignProfessionWhenSpawned = false; -@@ -296,7 +320,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -297,7 +321,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.lastTradedPlayer = null; } @@ -728,7 +744,7 @@ index 94032c60944f161519f0ddee69426cbfe3075170..e0e0d2ea7fc60e3142c675404d152eca Raid raidAt = level.getRaidAt(this.blockPosition()); if (raidAt != null && raidAt.isActive() && !raidAt.isOver()) { level.broadcastEntityEvent(this, (byte)42); -@@ -307,6 +331,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler +@@ -308,6 +332,7 @@ public class Villager extends AbstractVillager implements ReputationEventHandler this.stopTrading(); } @@ -758,10 +774,10 @@ index 1f22f44abb21d1ed9a4870f668779efb8fd9b295..91ead824718eeea2afba3bc0ef619b8a public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -index dcb7714b2edeab8cfb0358929d07bd04cead26bf..e0e193078e550225e163149638bf9e053c0531f8 100644 +index 7d5c6eec8e7c2448a3502255135dd9154b6ed2d8..d8dc196ef92e97f831cf97cd1536a46f81f9d5d1 100644 --- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -@@ -109,6 +109,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { +@@ -107,6 +107,21 @@ public class FireworkRocketEntity extends Projectile implements ItemSupplier { return super.shouldRender(x, y, z) && !this.isAttachedToEntity(); } @@ -784,10 +800,10 @@ index dcb7714b2edeab8cfb0358929d07bd04cead26bf..e0e193078e550225e163149638bf9e05 public void tick() { super.tick(); diff --git a/net/minecraft/world/entity/vehicle/MinecartHopper.java b/net/minecraft/world/entity/vehicle/MinecartHopper.java -index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98ae0a0989a 100644 +index 52acc72841f0c6980f5f3f8ef21d0b29dd472ce3..41a6ec508a10a49a37539d2f10171d15c233b280 100644 --- a/net/minecraft/world/entity/vehicle/MinecartHopper.java +++ b/net/minecraft/world/entity/vehicle/MinecartHopper.java -@@ -48,6 +48,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -49,6 +49,7 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper if (flag != this.isEnabled()) { this.setEnabled(flag); } @@ -795,7 +811,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a } public boolean isEnabled() { -@@ -101,11 +102,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -102,11 +103,13 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper public boolean suckInItems() { if (HopperBlockEntity.suckInItems(this.level(), this)) { @@ -809,7 +825,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a return true; } } -@@ -140,4 +143,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper +@@ -141,4 +144,11 @@ public class MinecartHopper extends AbstractMinecartContainer implements Hopper public AbstractContainerMenu createMenu(int id, Inventory playerInventory) { return new HopperMenu(id, playerInventory, this); } @@ -822,7 +838,7 @@ index 6162415095b030b4cc47364c56fa66236b3b0535..a56d9cdeb6589a053ffaaf2cd599a98a + } diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index fff4914de57dff26f66259a145d662ff5c96d840..1bb40f18b671d63719d96a58ff283767c2cfe383 100644 +index d26e4d85d8fd8bd4f0c7de30b50a2ce370b37bf5..bab28e7afb7b1249d40631aabff16fc18cf95ea0 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -143,6 +143,12 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @@ -839,10 +855,10 @@ index fff4914de57dff26f66259a145d662ff5c96d840..1bb40f18b671d63719d96a58ff283767 public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot // Paper start - add paper world config diff --git a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -index f8d10be7a0aa7f66f05126e75187025c040e3494..1669b76800756000a2f620610b3c8c8b6c48dd4a 100644 +index ba757b3accf0ee7e57f82507a6c04b90ae850d55..f1ce4cff1c03a0037ade2c8ef989cf327c973a7e 100644 --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -153,6 +153,10 @@ public class PistonMovingBlockEntity extends BlockEntity { +@@ -152,6 +152,10 @@ public class PistonMovingBlockEntity extends BlockEntity { } entity.setDeltaMovement(d1, d2, d3); diff --git a/paper-server/patches/features/0004-Anti-Xray.patch b/paper-server/patches/features/0004-Anti-Xray.patch index 75d6f68cfc..cd8fa3d530 100644 --- a/paper-server/patches/features/0004-Anti-Xray.patch +++ b/paper-server/patches/features/0004-Anti-Xray.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Anti-Xray diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java -index b9a838d638571bca1d00a620cedf169a3fa87e9d..329e9562e9c2b25228b04c21ff7353d2d8d6e5f6 100644 +index dce30842f6abab549f3abc25226604bb70ad0624..0a80ab83ca69b8b51fb1bb8c12ee6fcf439a3ac4 100644 --- a/io/papermc/paper/FeatureHooks.java +++ b/io/papermc/paper/FeatureHooks.java @@ -37,20 +37,25 @@ public final class FeatureHooks { @@ -39,7 +39,7 @@ index b9a838d638571bca1d00a620cedf169a3fa87e9d..329e9562e9c2b25228b04c21ff7353d2 public static Set getSentChunkKeys(final ServerPlayer player) { diff --git a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java -index d4872b7f4e9591b3b1c67406312905851303f521..cb41460e94161675e2ab43f4b1b5286ee38e2e13 100644 +index c9086bca5cbb780fd586f667e31a8fe1400ae58a..f828d07018d9a17aaa0142aac67ebed58dd84c3e 100644 --- a/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java +++ b/net/minecraft/network/protocol/game/ClientboundChunksBiomesPacket.java @@ -70,8 +70,10 @@ public record ClientboundChunksBiomesPacket(List 0) { new io.papermc.paper.event.packet.PlayerChunkLoadEvent(new org.bukkit.craftbukkit.CraftChunk(chunk), packetListener.getPlayer().getBukkitEntity()).callEvent(); diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index 9b2ee3e16e2c443e8ff03faec59dd55d729e9274..5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8 100644 +index b595fc3bd844eaf2a56f70f166523ee6254386b6..891d3e13057c6034c59a78e594935c433921de04 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -407,7 +407,7 @@ public abstract class PlayerList { +@@ -408,7 +408,7 @@ public abstract class PlayerList { .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); - player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( + player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains), - serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) + serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null, true) // Paper - Anti-Xray - ); - } - // Paper end - Send empty chunk + ); + } + // Paper end - Send empty chunk diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2064e5246 100644 +index 980eaba27ce2616c1573a4760cf4acc2dd251190..1eb8cb187d33510a4e99d229e721a2e7db4012ad 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -132,6 +132,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl @@ -237,10 +237,10 @@ index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2 if (blockState == null) { // CraftBukkit start - remove blockstate if failed (or the same) diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index c378f9e226df80ab0d4ebd06ae54ce556d0d94e7..97231db28146df56c727c9765f36277634d59a64 100644 +index f98ee299f5900b0a66c447d7970bd16a7ced1086..d1ae452f0aa96c36afe8b7ecddd3e06b06165878 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -115,14 +115,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } } @@ -259,10 +259,10 @@ index c378f9e226df80ab0d4ebd06ae54ce556d0d94e7..97231db28146df56c727c9765f362776 } } diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 8fa871512ad52c345f15b1f5fb1baf54bb2ec93b..08e2442f6965cc6eaab67bdf9340a5152c08db2a 100644 +index 1e60b295f8fa672ecee96a71fd1fea14339b7054..6f19586b4a39541c0fb895a18a0a4fd9b5da504c 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -110,7 +110,7 @@ public class LevelChunk extends ChunkAccess { +@@ -112,7 +112,7 @@ public class LevelChunk extends ChunkAccess { @Nullable LevelChunk.PostLoadProcessor postLoad, @Nullable BlendingData blendingData ) { @@ -313,10 +313,10 @@ index 2399a0f8839c0925a9923bae87362c2c9a217197..1aa4e39431a93a7789b74a2e3476a3e4 public int getSerializedSize() { diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java -index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a336a3ae55 100644 +index cd2b1240f13acaaecbb8e6d0f7f8b326ab24b5b0..9b0f17841230640f532ac33bb86e6585e88b5a57 100644 --- a/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -28,6 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -27,6 +27,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer private static final int MIN_PALETTE_BITS = 0; private final PaletteResize dummyPaletteResize = (bits, objectAdded) -> 0; public final IdMap registry; @@ -324,7 +324,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 private volatile PalettedContainer.Data data; private final PalettedContainer.Strategy strategy; //private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused -@@ -40,13 +41,21 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -39,13 +40,21 @@ public class PalettedContainer implements PaletteResize, PalettedContainer // this.threadingDetector.checkAndUnlock(); // Paper - disable this - use proper synchronization } @@ -348,7 +348,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 .map(container -> (PalettedContainerRO)container); return codec(registry, codec, strategy, value, unpacker); } -@@ -66,27 +75,66 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -65,27 +74,66 @@ public class PalettedContainer implements PaletteResize, PalettedContainer ); } @@ -418,7 +418,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 this.strategy = strategy; this.registry = registry; this.data = this.createOrReuseData(null, 0); -@@ -101,11 +149,30 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -100,11 +148,30 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public synchronized int onResize(int bits, T objectAdded) { // Paper - synchronize PalettedContainer.Data data = this.data; @@ -450,7 +450,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 public synchronized T getAndSet(int x, int y, int z, T state) { // Paper - synchronize this.acquire(); -@@ -172,24 +239,35 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -171,24 +238,35 @@ public class PalettedContainer implements PaletteResize, PalettedContainer data.palette.read(buffer); buffer.readFixedSizeLongArray(data.storage.getRaw()); this.data = data; @@ -489,7 +489,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 ) { List list = packedData.paletteEntries(); int size = strategy.size(); -@@ -222,7 +300,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -221,7 +299,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } @@ -498,7 +498,7 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 } @Override -@@ -280,12 +358,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -279,12 +357,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer @Override public PalettedContainer copy() { @@ -513,8 +513,8 @@ index 5a3ed1c2dd22434d96947580c4dff28a95eb8252..1491401ec94038450ea5eeb589fc33a3 } @Override -@@ -324,9 +402,16 @@ public class PalettedContainer implements PaletteResize, PalettedContainer - return 1 + this.palette.getSerializedSize() + VarInt.getByteSize(this.storage.getRaw().length) + this.storage.getRaw().length * 8; +@@ -323,9 +401,16 @@ public class PalettedContainer implements PaletteResize, PalettedContainer + return 1 + this.palette.getSerializedSize() + this.storage.getRaw().length * 8; } - public void write(FriendlyByteBuf buffer) { @@ -548,10 +548,10 @@ index bfbb1a2bb4abbb369a24f2f01439e9ea3e16794b..8d6ed8be4d93f7d4e6ea80c351020d88 int getSerializedSize(); diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f96d5f6ec 100644 +index e846bda9517f3325f0d343758d3235382bb8980d..15417fab103feec3c1f7d5bd5b332e89d3ace3f5 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -94,7 +94,7 @@ public record SerializableChunkData( +@@ -96,7 +96,7 @@ public record SerializableChunkData( , @Nullable net.minecraft.nbt.Tag persistentDataContainer // CraftBukkit - persistentDataContainer ) { public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW( @@ -560,7 +560,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f ); private static final Codec>> BLOCK_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.BLOCK.byNameCodec()).listOf(); private static final Codec>> FLUID_TICKS_CODEC = SavedTick.codec(BuiltInRegistries.FLUID.byNameCodec()).listOf(); -@@ -130,6 +130,7 @@ public record SerializableChunkData( +@@ -132,6 +132,7 @@ public record SerializableChunkData( @Nullable public static SerializableChunkData parse(LevelHeightAccessor levelHeightAccessor, RegistryAccess registries, CompoundTag tag) { @@ -568,7 +568,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f if (tag.getString("Status").isEmpty()) { return null; } else { -@@ -190,15 +191,17 @@ public record SerializableChunkData( +@@ -192,15 +193,17 @@ public record SerializableChunkData( int byteOr = compoundTag.getByteOr("Y", (byte)0); LevelChunkSection levelChunkSection; if (byteOr >= levelHeightAccessor.getMinSectionY() && byteOr <= levelHeightAccessor.getMaxSectionY()) { @@ -588,7 +588,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f ) ); PalettedContainer> palettedContainerRo = compoundTag.getCompound("biomes") // CraftBukkit - read/write -@@ -209,7 +212,7 @@ public record SerializableChunkData( +@@ -211,7 +214,7 @@ public record SerializableChunkData( ) .orElseGet( () -> new PalettedContainer<>( @@ -597,7 +597,7 @@ index 8efb5148a22b57ed090fb8fd20dd642223b3fb95..58bc96235f0149ea868da3bc3d20472f ) ); levelChunkSection = new LevelChunkSection(palettedContainer, palettedContainerRo); -@@ -382,7 +385,7 @@ public record SerializableChunkData( +@@ -384,7 +387,7 @@ public record SerializableChunkData( // CraftBukkit start - read/write private static Codec>> makeBiomeCodecRW(Registry biomeRegistry) { diff --git a/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch b/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch index 230782d7a8..2c16d1c118 100644 --- a/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch +++ b/paper-server/patches/features/0005-Use-Velocity-compression-and-cipher-natives.patch @@ -269,10 +269,10 @@ index bc674b08a41d5529fe06c6d3f077051cf4138f73..ea8a894158c44c2e7943dea43ecd8e1f + // Paper end - Use Velocity cipher } diff --git a/net/minecraft/network/Connection.java b/net/minecraft/network/Connection.java -index 2040b9555c430420a8a8697cc131d42eafb96fa1..4ed9611994c5c8da01fede690197527c5b3a5731 100644 +index 235a076f982247552fef6d86d7e1b141eb8c72b5..34524dc5a503bebcec99ada0d9560d6f4df48cdf 100644 --- a/net/minecraft/network/Connection.java +++ b/net/minecraft/network/Connection.java -@@ -772,11 +772,22 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -762,11 +762,22 @@ public class Connection extends SimpleChannelInboundHandler> { return connection; } @@ -299,7 +299,7 @@ index 2040b9555c430420a8a8697cc131d42eafb96fa1..4ed9611994c5c8da01fede690197527c public boolean isEncrypted() { return this.encrypted; -@@ -815,16 +826,17 @@ public class Connection extends SimpleChannelInboundHandler> { +@@ -805,16 +816,17 @@ public class Connection extends SimpleChannelInboundHandler> { // Paper end - add proper async disconnect public void setupCompression(int threshold, boolean validateDecompressed) { if (threshold >= 0) { diff --git a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch index 9a76d082d0..359fd9036a 100644 --- a/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch +++ b/paper-server/patches/features/0006-Optimize-Collision-to-not-load-chunks.patch @@ -14,10 +14,10 @@ movement will load only the chunk the player enters anyways and avoids loading massive amounts of surrounding chunks due to large AABB lookups. diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index a8eaccde3ec9ed912cbc6df0b29e9f8136a46578..0f6ca6ef161ac2934ba761a1eca3215290c7262b 100644 +index 7453ddb09f349b7836f966573e4933646a75cba6..58eda0d6426f30cda604f4120f1ddb012316c108 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -223,6 +223,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -229,6 +229,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper end - Share random for entities to make them more random public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason @@ -76,7 +76,7 @@ index ed6e4f9fd0c7ad1219e66bc1cb4038191dd6edd8..45a20dbb935b12d429153463dba5d6fd && (nextType != 2 || blockState.is(Blocks.MOVING_PISTON))) { VoxelShape collisionShape = this.context.getCollisionShape(blockState, this.collisionGetter, this.pos); diff --git a/net/minecraft/world/level/CollisionGetter.java b/net/minecraft/world/level/CollisionGetter.java -index 79af1e4dd1f84580e509ac3e9a77bcd5531c8da6..a031d39854eb049a701f3de9e11c73419883d5ca 100644 +index 8956e5d66481d8ca874999df8f38eb28651362db..056005f0728ba14c9d0dd9dd16400a35a9656243 100644 --- a/net/minecraft/world/level/CollisionGetter.java +++ b/net/minecraft/world/level/CollisionGetter.java @@ -50,11 +50,13 @@ public interface CollisionGetter extends BlockGetter { diff --git a/paper-server/patches/features/0007-Optimize-GoalSelector-Goal.Flag-Set-operations.patch b/paper-server/patches/features/0007-Optimize-GoalSelector-Goal.Flag-Set-operations.patch index 8d68059b74..79957e9faa 100644 --- a/paper-server/patches/features/0007-Optimize-GoalSelector-Goal.Flag-Set-operations.patch +++ b/paper-server/patches/features/0007-Optimize-GoalSelector-Goal.Flag-Set-operations.patch @@ -7,7 +7,7 @@ Optimise the stream.anyMatch statement to move to a bitset where we can replace the call with a single bitwise operation. diff --git a/net/minecraft/world/entity/ai/goal/Goal.java b/net/minecraft/world/entity/ai/goal/Goal.java -index d4f8387254a65b25fc808932a069298d0f8da091..5f5bf0e710ecff09a571091e5a923332be70cb74 100644 +index a66c86066ca2eda10f0ef62e5197a765a994f250..f54bbe2e65b18f214266769c7a64144baafa9a58 100644 --- a/net/minecraft/world/entity/ai/goal/Goal.java +++ b/net/minecraft/world/entity/ai/goal/Goal.java @@ -7,7 +7,15 @@ import net.minecraft.world.entity.Entity; @@ -69,10 +69,10 @@ index d4f8387254a65b25fc808932a069298d0f8da091..5f5bf0e710ecff09a571091e5a923332 // Paper end - Mob Goal API diff --git a/net/minecraft/world/entity/ai/goal/GoalSelector.java b/net/minecraft/world/entity/ai/goal/GoalSelector.java -index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b44817dd8 100644 +index 674966c580220a4e0c83a628c763aaea8bfd0b1c..859b859d29b637200cf7c9a0bd52d9f712413e3d 100644 --- a/net/minecraft/world/entity/ai/goal/GoalSelector.java +++ b/net/minecraft/world/entity/ai/goal/GoalSelector.java -@@ -24,7 +24,8 @@ public class GoalSelector { +@@ -23,7 +23,8 @@ public class GoalSelector { }; private final Map lockedFlags = new EnumMap<>(Goal.Flag.class); private final Set availableGoals = new ObjectLinkedOpenHashSet<>(); @@ -82,7 +82,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b private int curRate; // Paper - EAR 2 public void addGoal(int priority, Goal goal) { -@@ -62,18 +63,18 @@ public class GoalSelector { +@@ -60,18 +61,18 @@ public class GoalSelector { this.availableGoals.removeIf(wrappedGoal1 -> wrappedGoal1.getGoal() == goal); } @@ -110,7 +110,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b if (!flag.getOrDefault(flag1, NO_GOAL).canBeReplacedBy(goal)) { return false; } -@@ -87,7 +88,7 @@ public class GoalSelector { +@@ -85,7 +86,7 @@ public class GoalSelector { profilerFiller.push("goalCleanup"); for (WrappedGoal wrappedGoal : this.availableGoals) { @@ -119,7 +119,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b wrappedGoal.stop(); } } -@@ -97,11 +98,14 @@ public class GoalSelector { +@@ -95,11 +96,14 @@ public class GoalSelector { profilerFiller.push("goalUpdate"); for (WrappedGoal wrappedGoalx : this.availableGoals) { @@ -139,7 +139,7 @@ index eeba224bd575451ba6023df65ef9d9b97f7f1c71..a927c2790c8ab9ccaa7161b970e10b0b WrappedGoal wrappedGoal1 = this.lockedFlags.getOrDefault(flag, NO_GOAL); wrappedGoal1.stop(); this.lockedFlags.put(flag, wrappedGoalx); -@@ -133,11 +137,11 @@ public class GoalSelector { +@@ -131,11 +135,11 @@ public class GoalSelector { } public void disableControlFlag(Goal.Flag flag) { diff --git a/paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch b/paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch index e606141586..7cfde38621 100644 --- a/paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch +++ b/paper-server/patches/features/0009-Handle-Oversized-block-entities-in-chunks.patch @@ -9,7 +9,7 @@ creating too large of a packet to sed. Co-authored-by: Spottedleaf diff --git a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java -index 272da41db7ce4619a8e459a2f0a2221e42f58a40..526c117e0d53ad527eb610c79cdc46ec16b18c0c 100644 +index 83c4b454472714de6ebf99cd4e50867920d07509..9f6d7c5dc0e591488a8a3763d8a1f1b3671d5299 100644 --- a/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java +++ b/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java @@ -32,6 +32,14 @@ public class ClientboundLevelChunkPacketData { diff --git a/paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch b/paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch index 0f3b8b1fe7..bdc72cc8d8 100644 --- a/paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch +++ b/paper-server/patches/features/0011-Optimise-getChunkAt-calls-for-loaded-chunks.patch @@ -7,7 +7,7 @@ bypass the need to get a player chunk, then get the either, then unwrap it... diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 006d8abe66b2d66740b984d8ff7f56a41b9929f7..52104bcd74107bb9a475109230ca85dd2eba5b06 100644 +index b805b9964ca5bf6b3d13dae615cb49177d43ded3..17ec8224bf5c2eebc7d6bcbe25e275be4bdb0a45 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -224,6 +224,12 @@ public class ServerChunkCache extends ChunkSource { diff --git a/paper-server/patches/features/0015-Rewrite-dataconverter-system.patch b/paper-server/patches/features/0015-Rewrite-dataconverter-system.patch new file mode 100644 index 0000000000..1e4e03fad7 --- /dev/null +++ b/paper-server/patches/features/0015-Rewrite-dataconverter-system.patch @@ -0,0 +1,32538 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Spottedleaf +Date: Sat, 19 Jun 2021 10:43:01 -0700 +Subject: [PATCH] Rewrite dataconverter system + +Please see https://github.com/PaperMC/DataConverter +for details. + +diff --git a/ca/spottedleaf/dataconverter/converters/DataConverter.java b/ca/spottedleaf/dataconverter/converters/DataConverter.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1863c606be715683d53863a0c9293525d199c9cf +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/converters/DataConverter.java +@@ -0,0 +1,54 @@ ++package ca.spottedleaf.dataconverter.converters; ++ ++import java.util.Comparator; ++ ++public abstract class DataConverter { ++ ++ public static final Comparator> LOWEST_VERSION_COMPARATOR = (x, y) -> { ++ return Long.compare(x.getEncodedVersion(), y.getEncodedVersion()); ++ }; ++ ++ protected final int toVersion; ++ protected final int versionStep; ++ ++ public DataConverter(final int toVersion) { ++ this.toVersion = toVersion; ++ this.versionStep = 0; ++ } ++ ++ public DataConverter(final int toVersion, final int versionStep) { ++ this.toVersion = toVersion; ++ this.versionStep = versionStep; ++ } ++ ++ public final int getToVersion() { ++ return this.toVersion; ++ } ++ ++ public final int getVersionStep() { ++ return this.versionStep; ++ } ++ ++ public final long getEncodedVersion() { ++ return encodeVersions(this.toVersion, this.versionStep); ++ } ++ ++ public abstract R convert(final T data, final long sourceVersion, final long toVersion); ++ ++ // step must be in the lower bits, so that encodeVersions(version, step) < encodeVersions(version, step + 1) ++ public static long encodeVersions(final int version, final int step) { ++ return ((long)version << 32) | (step & 0xFFFFFFFFL); ++ } ++ ++ public static int getVersion(final long encoded) { ++ return (int)(encoded >>> 32); ++ } ++ ++ public static int getStep(final long encoded) { ++ return (int)encoded; ++ } ++ ++ public static String encodedToString(final long encoded) { ++ return getVersion(encoded) + "." + getStep(encoded); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/converters/datatypes/DataHook.java b/ca/spottedleaf/dataconverter/converters/datatypes/DataHook.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0b92c5c66ad3a5198873f98287a5ced71c231d09 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/converters/datatypes/DataHook.java +@@ -0,0 +1,9 @@ ++package ca.spottedleaf.dataconverter.converters.datatypes; ++ ++public interface DataHook { ++ ++ public R preHook(final T data, final long fromVersion, final long toVersion); ++ ++ public R postHook(final T data, final long fromVersion, final long toVersion); ++ ++} +diff --git a/ca/spottedleaf/dataconverter/converters/datatypes/DataType.java b/ca/spottedleaf/dataconverter/converters/datatypes/DataType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..52f2a3131f314e723a31194c517e7756983482b9 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/converters/datatypes/DataType.java +@@ -0,0 +1,15 @@ ++package ca.spottedleaf.dataconverter.converters.datatypes; ++ ++public abstract class DataType { ++ ++ public final R convertOrOriginal(final T data, final long fromVersion, final long toVersion) { ++ final R replaced = this.convert(data, fromVersion, toVersion); ++ if (replaced != null) { ++ return replaced; ++ } ++ return (R)data; ++ } ++ ++ public abstract R convert(final T data, final long fromVersion, final long toVersion); ++ ++} +diff --git a/ca/spottedleaf/dataconverter/converters/datatypes/DataWalker.java b/ca/spottedleaf/dataconverter/converters/datatypes/DataWalker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a57dd1e28fd7a1e7d832833f820186dacac407d4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/converters/datatypes/DataWalker.java +@@ -0,0 +1,15 @@ ++package ca.spottedleaf.dataconverter.converters.datatypes; ++ ++public interface DataWalker { ++ ++ public static final DataWalker NO_OP = (final Object data, final long fromVersion, final long toVersion) -> { ++ return null; ++ }; ++ ++ public static DataWalker noOp() { ++ return (DataWalker)NO_OP; ++ } ++ ++ public T walk(final T data, final long fromVersion, final long toVersion); ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/MCDataConverter.java b/ca/spottedleaf/dataconverter/minecraft/MCDataConverter.java +new file mode 100644 +index 0000000000000000000000000000000000000000..515f6691c72ffa82ac8b92646768be7a17931efb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/MCDataConverter.java +@@ -0,0 +1,86 @@ ++package ca.spottedleaf.dataconverter.minecraft; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCDataType; ++import ca.spottedleaf.dataconverter.minecraft.versions.V99; ++import ca.spottedleaf.dataconverter.types.json.JsonMapType; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import com.google.gson.JsonObject; ++import it.unimi.dsi.fastutil.longs.LongArrayList; ++import net.minecraft.nbt.CompoundTag; ++ ++public final class MCDataConverter { ++ ++ private static final LongArrayList BREAKPOINTS = MCVersionRegistry.getBreakpoints(); ++ ++ public static T copy(final T type) { ++ if (type instanceof CompoundTag) { ++ return (T)((CompoundTag)type).copy(); ++ } else if (type instanceof JsonObject) { ++ return (T)((JsonObject)type).deepCopy(); ++ } ++ ++ return type; ++ } ++ ++ public static CompoundTag convertTag(final MCDataType type, final CompoundTag data, final int fromVersion, final int toVersion) { ++ final NBTMapType wrapped = new NBTMapType(data); ++ ++ final NBTMapType replaced = (NBTMapType)convert(type, wrapped, fromVersion, toVersion); ++ ++ return replaced == null ? wrapped.getTag() : replaced.getTag(); ++ } ++ ++ public static JsonObject convertJson(final MCDataType type, final JsonObject data, final boolean compressed, final int fromVersion, final int toVersion) { ++ final JsonMapType wrapped = new JsonMapType(data, compressed); ++ ++ final JsonMapType replaced = (JsonMapType)convert(type, wrapped, fromVersion, toVersion); ++ ++ return replaced == null ? wrapped.getJson() : replaced.getJson(); ++ } ++ ++ public static R convert(final DataType type, final T data, final int fromVersion, final int toVersion) { ++ return convertWithSubVersion( ++ type, data, ++ DataConverter.encodeVersions(Math.max(fromVersion, V99.VERSION), Integer.MAX_VALUE), ++ DataConverter.encodeVersions(toVersion, Integer.MAX_VALUE) ++ ); ++ } ++ ++ public static R convertWithSubVersion(final DataType type, final T data, final long fromVersion, final long toVersion) { ++ Object ret = data; ++ ++ long currentVersion = fromVersion; ++ ++ for (int i = 0, len = BREAKPOINTS.size(); i < len; ++i) { ++ final long breakpoint = BREAKPOINTS.getLong(i); ++ ++ if (currentVersion >= breakpoint) { ++ continue; ++ } ++ ++ final Object converted = type.convert((T)ret, currentVersion, Math.min(toVersion, breakpoint - 1L)); ++ if (converted != null) { ++ ret = converted; ++ } ++ ++ currentVersion = Math.min(toVersion, breakpoint - 1L); ++ ++ if (currentVersion == toVersion) { ++ break; ++ } ++ } ++ ++ if (currentVersion != toVersion) { ++ final Object converted = type.convert((T)ret, currentVersion, toVersion); ++ if (converted != null) { ++ ret = converted; ++ } ++ } ++ ++ return (R)ret; ++ } ++ ++ private MCDataConverter() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java b/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ab0d941248c389fec08a5ca6e45f7f5bf72cae58 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/MCVersionRegistry.java +@@ -0,0 +1,485 @@ ++package ca.spottedleaf.dataconverter.minecraft; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.versions.V4290; ++import com.mojang.logging.LogUtils; ++import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; ++import it.unimi.dsi.fastutil.ints.IntArrayList; ++import it.unimi.dsi.fastutil.ints.IntLinkedOpenHashSet; ++import it.unimi.dsi.fastutil.ints.IntRBTreeSet; ++import it.unimi.dsi.fastutil.longs.LongArrayList; ++import it.unimi.dsi.fastutil.longs.LongComparator; ++import it.unimi.dsi.fastutil.longs.LongLinkedOpenHashSet; ++import org.slf4j.Logger; ++import java.lang.reflect.Field; ++import java.util.Arrays; ++import java.util.Locale; ++ ++public final class MCVersionRegistry { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final Int2ObjectLinkedOpenHashMap VERSION_NAMES = new Int2ObjectLinkedOpenHashMap<>(); ++ private static final IntArrayList VERSION_LIST; ++ private static final LongArrayList DATA_VERSION_LIST; ++ ++ private static final IntArrayList DATACONVERTER_VERSIONS_LIST; ++ private static final IntLinkedOpenHashSet DATACONVERTER_VERSIONS_MAJOR = new IntLinkedOpenHashSet(); ++ private static final LongLinkedOpenHashSet DATACONVERTER_VERSIONS = new LongLinkedOpenHashSet(); ++ private static final Int2ObjectLinkedOpenHashMap SUBVERSIONS = new Int2ObjectLinkedOpenHashMap<>(); ++ private static final LongArrayList BREAKPOINTS = new LongArrayList(); ++ static { ++ // Note: Some of these are nameless. ++ // Unless a data version is specified here, it will NOT have converters ran for it. Please add them on update! ++ final int[] converterVersions = new int[] { ++ 99, ++ 100, ++ 101, ++ 102, ++ 105, ++ 106, ++ 107, ++ 108, ++ 109, ++ 110, ++ 111, ++ 113, ++ 135, ++ 143, ++ 147, ++ 165, ++ 501, ++ 502, ++ 505, ++ 700, ++ 701, ++ 702, ++ 703, ++ 704, ++ 705, ++ 804, ++ 806, ++ 808, ++ 808, ++ 813, ++ 816, ++ 820, ++ 1022, ++ 1125, ++ 1344, ++ 1446, ++ 1450, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1451, ++ 1456, ++ 1458, ++ 1460, ++ 1466, ++ 1470, ++ 1474, ++ 1475, ++ 1480, ++ 1481, ++ 1483, ++ 1484, ++ 1486, ++ 1487, ++ 1488, ++ 1490, ++ 1492, ++ 1494, ++ 1496, ++ 1500, ++ 1501, ++ 1502, ++ 1506, ++ 1510, ++ 1514, ++ 1515, ++ 1624, ++ 1800, ++ 1801, ++ 1802, ++ 1803, ++ 1904, ++ 1905, ++ 1906, ++ 1909, ++ 1911, ++ 1914, ++ 1917, ++ 1918, ++ 1920, ++ 1925, ++ 1928, ++ 1929, ++ 1931, ++ 1936, ++ 1946, ++ 1948, ++ 1953, ++ 1955, ++ 1961, ++ 1963, ++ 2100, ++ 2202, ++ 2209, ++ 2211, ++ 2218, ++ 2501, ++ 2502, ++ 2503, ++ 2505, ++ 2508, ++ 2509, ++ 2511, ++ 2514, ++ 2516, ++ 2518, ++ 2519, ++ 2522, ++ 2523, ++ 2527, ++ 2528, ++ 2529, ++ 2531, ++ 2533, ++ 2535, ++ 2537, ++ 2538, ++ 2550, ++ 2551, ++ 2552, ++ 2553, ++ 2558, ++ 2568, ++ 2671, ++ 2679, ++ 2680, ++ 2684, ++ 2686, ++ 2688, ++ 2690, ++ 2691, ++ 2693, ++ 2696, ++ 2700, ++ 2701, ++ 2702, ++ 2704, ++ 2707, ++ 2710, ++ 2717, ++ 2825, ++ 2831, ++ 2832, ++ 2833, ++ 2838, ++ 2841, ++ 2842, ++ 2843, ++ 2846, ++ 2852, ++ 2967, ++ 2970, ++ 3077, ++ 3078, ++ 3081, ++ 3082, ++ 3083, ++ 3084, ++ 3086, ++ 3087, ++ 3088, ++ 3090, ++ 3093, ++ 3094, ++ 3097, ++ 3108, ++ 3201, ++ 3203, ++ 3204, ++ 3209, ++ 3214, ++ 3319, ++ 3322, ++ 3438, ++ 3439, ++ 3440, ++ 3441, ++ 3447, ++ 3448, ++ 3450, ++ 3451, ++ 3459, ++ 3564, ++ 3565, ++ 3566, ++ 3568, ++ 3683, ++ 3685, ++ 3692, ++ 3800, ++ 3803, ++ 3807, ++ 3808, ++ 3809, ++ 3812, ++ 3813, ++ 3814, ++ 3818, ++ 3820, ++ 3825, ++ 3828, ++ 3833, ++ 3939, ++ 3943, ++ 3945, ++ 4054, ++ 4055, ++ 4057, ++ 4059, ++ 4061, ++ 4064, ++ 4067, ++ 4068, ++ 4081, ++ 4173, ++ 4175, ++ 4176, ++ 4180, ++ 4181, ++ 4185, ++ 4187, ++ 4290, ++ 4291, ++ 4292, ++ 4293, ++ 4294, ++ 4295, ++ 4296, ++ 4297, ++ 4299, ++ 4300, ++ 4301, ++ 4302, ++ 4303, ++ 4305, ++ 4306, ++ 4307, ++ 4309, ++ 4311, ++ 4312, ++ 4314, ++ 4420, ++ 4424, ++ // All up to 1.21.6-pre2 ++ }; ++ Arrays.sort(converterVersions); ++ ++ DATACONVERTER_VERSIONS_MAJOR.addAll(DATACONVERTER_VERSIONS_LIST = new IntArrayList(converterVersions)); ++ ++ // add sub versions ++ registerSubVersion(MCVersions.V16W38A + 1, 1); ++ ++ registerSubVersion(MCVersions.V17W47A, 1); ++ registerSubVersion(MCVersions.V17W47A, 2); ++ registerSubVersion(MCVersions.V17W47A, 3); ++ registerSubVersion(MCVersions.V17W47A, 4); ++ registerSubVersion(MCVersions.V17W47A, 5); ++ registerSubVersion(MCVersions.V17W47A, 6); ++ registerSubVersion(MCVersions.V17W47A, 7); ++ ++ registerSubVersion(MCVersions.V24W04A + 1, 1); ++ registerSubVersion(MCVersions.V24W04A + 2, 1); ++ registerSubVersion(MCVersions.V24W04A + 2, 2); ++ ++ registerSubVersion(MCVersions.V24W07A + 1, 1); ++ registerSubVersion(MCVersions.V24W07A + 1, 2); ++ registerSubVersion(MCVersions.V24W07A + 1, 4); ++ registerSubVersion(MCVersions.V24W07A + 1, 5); ++ registerSubVersion(MCVersions.V24W07A + 1, 6); ++ ++ // register breakpoints here ++ // for all major releases after 1.16, add them. this reduces the work required to determine if a breakpoint ++ // is needed for new converters ++ ++ // Too much changed in this version. ++ registerBreakpoint(MCVersions.V17W47A); ++ registerBreakpointAfter(MCVersions.V17W47A, Integer.MAX_VALUE); ++ ++ // final release of major version ++ registerBreakpointAfter(MCVersions.V1_17_1, Integer.MAX_VALUE); ++ ++ // final release of major version ++ registerBreakpointAfter(MCVersions.V1_18_2, Integer.MAX_VALUE); ++ ++ // final release of major version ++ registerBreakpointAfter(MCVersions.V1_19_4, Integer.MAX_VALUE); ++ ++ // Too much changed in this version. ++ registerBreakpoint(MCVersions.V24W07A + 1, 5); ++ registerBreakpointAfter(MCVersions.V24W07A + 1, Integer.MAX_VALUE); ++ ++ // final release of major version ++ registerBreakpointAfter(MCVersions.V1_20_6, Integer.MAX_VALUE); ++ ++ // There is a read of entity sub data in V4299 (salmon) which was written to after V1_20_6 ++ // There is also a sub type read in V4290 as it reads and converts all data within a text component ++ registerBreakpointBefore(V4290.VERSION); ++ } ++ ++ static { ++ final Field[] fields = MCVersions.class.getDeclaredFields(); ++ for (final Field field : fields) { ++ final String name = field.getName(); ++ final int value; ++ try { ++ value = field.getInt(null); ++ } catch (final Exception ex) { ++ throw new RuntimeException(ex); ++ } ++ ++ // Mojang registered 15w33a and 15w33b under the same id. ++ // Mojang registered 1.21.5-pre2 and 1.21.5-pre3 under the same id. ++ if (VERSION_NAMES.containsKey(value) && value != MCVersions.V15W33B && value != MCVersions.V1_21_5_PRE3) { ++ LOGGER.warn("Error registering version \"" + name + "\", version number '" + value + "' is already associated with \"" + VERSION_NAMES.get(value) + "\""); ++ } ++ ++ VERSION_NAMES.put(value, name.substring(1).replace("_PRE", "-PRE").replace("_RC", "-RC").replace('_', '.').toLowerCase(Locale.ROOT)); ++ } ++ ++ for (final int version : DATACONVERTER_VERSIONS_MAJOR) { ++ if (VERSION_NAMES.containsKey(version)) { ++ continue; ++ } ++ ++ // find closest greatest version above this one ++ int closest = Integer.MAX_VALUE; ++ String closestName = null; ++ for (final int v : VERSION_NAMES.keySet()) { ++ if (v > version && v < closest) { ++ closest = v; ++ closestName = VERSION_NAMES.get(v); ++ } ++ } ++ ++ if (closestName == null) { ++ VERSION_NAMES.put(version, "unregistered_v" + version); ++ } else { ++ VERSION_NAMES.put(version, closestName + "-dev" + (closest - version)); ++ } ++ } ++ ++ // Explicit override for V99, as 99 is very special. ++ VERSION_NAMES.put(99, "pre_converter"); ++ ++ VERSION_LIST = new IntArrayList(new IntRBTreeSet(VERSION_NAMES.keySet())); ++ ++ DATA_VERSION_LIST = new LongArrayList(); ++ for (final int version : VERSION_LIST) { ++ DATA_VERSION_LIST.add(DataConverter.encodeVersions(version, 0)); ++ ++ final IntArrayList subVersions = SUBVERSIONS.get(version); ++ if (subVersions == null) { ++ continue; ++ } ++ ++ for (final int step : subVersions) { ++ DATA_VERSION_LIST.add(DataConverter.encodeVersions(version, step)); ++ } ++ } ++ ++ DATA_VERSION_LIST.sort((LongComparator)null); ++ ++ for (final int version : DATACONVERTER_VERSIONS_MAJOR) { ++ DATACONVERTER_VERSIONS.add(DataConverter.encodeVersions(version, 0)); ++ ++ final IntArrayList subVersions = SUBVERSIONS.get(version); ++ if (subVersions == null) { ++ continue; ++ } ++ ++ for (final int step : subVersions) { ++ DATACONVERTER_VERSIONS.add(DataConverter.encodeVersions(version, step)); ++ } ++ } ++ } ++ ++ private static void registerSubVersion(final int version, final int step) { ++ if (DATA_VERSION_LIST != null) { ++ throw new IllegalStateException("Added too late!"); ++ } ++ SUBVERSIONS.computeIfAbsent(version, (final int keyInMap) -> { ++ return new IntArrayList(); ++ }).add(step); ++ } ++ ++ private static void registerBreakpointBefore(final int version) { ++ registerBreakpointBefore(version, 0); ++ } ++ ++ private static void registerBreakpointBefore(final int version, final int step) { ++ BREAKPOINTS.add(DataConverter.encodeVersions(version, step) - 1L); ++ } ++ ++ private static void registerBreakpoint(final int version) { ++ registerBreakpoint(version, 0); ++ } ++ ++ private static void registerBreakpoint(final int version, final int step) { ++ BREAKPOINTS.add(DataConverter.encodeVersions(version, step)); ++ } ++ ++ private static void registerBreakpointAfter(final int version) { ++ registerBreakpointAfter(version, 0); ++ } ++ ++ private static void registerBreakpointAfter(final int version, final int step) { ++ BREAKPOINTS.add(DataConverter.encodeVersions(version, step) + 1L); ++ } ++ ++ // returns only versions that have dataconverters ++ public static boolean hasDataConverters(final int version) { ++ return DATACONVERTER_VERSIONS_MAJOR.contains(version); ++ } ++ ++ public String getVersionName(final int version) { ++ return VERSION_NAMES.get(version); ++ } ++ ++ public boolean isRegisteredVersion(final int version) { ++ return VERSION_NAMES.containsKey(version); ++ } ++ ++ public static IntArrayList getVersionList() { ++ return VERSION_LIST; ++ } ++ ++ public static LongArrayList getDataVersionList() { ++ return DATA_VERSION_LIST; ++ } ++ ++ public static int getMaxVersion() { ++ return VERSION_LIST.getInt(VERSION_LIST.size() - 1); ++ } ++ ++ public static LongArrayList getBreakpoints() { ++ return BREAKPOINTS; ++ } ++ ++ public static void checkVersion(final long version) { ++ if (!DATACONVERTER_VERSIONS.contains(version)) { ++ throw new IllegalStateException("Version " + DataConverter.encodedToString(version) + " is not registered to have dataconverters, yet has a dataconverter"); ++ } ++ } ++ ++ private MCVersionRegistry() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/MCVersions.java b/ca/spottedleaf/dataconverter/minecraft/MCVersions.java +new file mode 100644 +index 0000000000000000000000000000000000000000..94e115808e1d1895cf36c87acea179c09e3c3d5b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/MCVersions.java +@@ -0,0 +1,593 @@ ++package ca.spottedleaf.dataconverter.minecraft; ++ ++@SuppressWarnings("unused") ++public final class MCVersions { ++ ++ /* https://minecraft.wiki/w/Data_version */ ++ ++ public static final int V15W32A = 100; ++ public static final int V15W32B = 103; ++ public static final int V15W32C = 104; ++ public static final int V15W33A = 111; ++ public static final int V15W33B = 111; ++ public static final int V15W33C = 112; ++ public static final int V15W34A = 114; ++ public static final int V15W34B = 115; ++ public static final int V15W34C = 116; ++ public static final int V15W34D = 117; ++ public static final int V15W35A = 118; ++ public static final int V15W35B = 119; ++ public static final int V15W35C = 120; ++ public static final int V15W35D = 121; ++ public static final int V15W35E = 122; ++ public static final int V15W36A = 123; ++ public static final int V15W36B = 124; ++ public static final int V15W36C = 125; ++ public static final int V15W36D = 126; ++ public static final int V15W37A = 127; ++ public static final int V15W38A = 128; ++ public static final int V15W38B = 129; ++ public static final int V15W39A = 130; ++ public static final int V15W39B = 131; ++ public static final int V15W39C = 132; ++ public static final int V15W40A = 133; ++ public static final int V15W40B = 134; ++ public static final int V15W41A = 136; ++ public static final int V15W41B = 137; ++ public static final int V15W42A = 138; ++ public static final int V15W43A = 139; ++ public static final int V15W43B = 140; ++ public static final int V15W43C = 141; ++ public static final int V15W44A = 142; ++ public static final int V15W44B = 143; ++ public static final int V15W45A = 145; ++ public static final int V15W46A = 146; ++ public static final int V15W47A = 148; ++ public static final int V15W47B = 149; ++ public static final int V15W47C = 150; ++ public static final int V15W49A = 151; ++ public static final int V15W49B = 152; ++ public static final int V15W50A = 153; ++ public static final int V15W51A = 154; ++ public static final int V15W51B = 155; ++ public static final int V16W02A = 156; ++ public static final int V16W03A = 157; ++ public static final int V16W04A = 158; ++ public static final int V16W05A = 159; ++ public static final int V16W05B = 160; ++ public static final int V16W06A = 161; ++ public static final int V16W07A = 162; ++ public static final int V16W07B = 163; ++ public static final int V1_9_PRE1 = 164; ++ public static final int V1_9_PRE2 = 165; ++ public static final int V1_9_PRE3 = 167; ++ public static final int V1_9_PRE4 = 168; ++ public static final int V1_9 = 169; ++ public static final int V1_9_1_PRE1 = 170; ++ public static final int V1_9_1_PRE2 = 171; ++ public static final int V1_9_1_PRE3 = 172; ++ public static final int V1_9_1 = 175; ++ public static final int V1_9_2 = 176; ++ public static final int V16W14A = 177; ++ public static final int V16W15A = 178; ++ public static final int V16W15B = 179; ++ public static final int V1_9_3_PRE1 = 180; ++ public static final int V1_9_3_PRE2 = 181; ++ public static final int V1_9_3_PRE3 = 182; ++ public static final int V1_9_3 = 183; ++ public static final int V1_9_4 = 184; ++ public static final int V16W20A = 501; ++ public static final int V16W21A = 503; ++ public static final int V16W21B = 504; ++ public static final int V1_10_PRE1 = 506; ++ public static final int V1_10_PRE2 = 507; ++ public static final int V1_10 = 510; ++ public static final int V1_10_1 = 511; ++ public static final int V1_10_2 = 512; ++ public static final int V16W32A = 800; ++ public static final int V16W32B = 801; ++ public static final int V16W33A = 802; ++ public static final int V16W35A = 803; ++ public static final int V16W36A = 805; ++ public static final int V16W38A = 807; ++ public static final int V16W39A = 809; ++ public static final int V16W39B = 811; ++ public static final int V16W39C = 812; ++ public static final int V16W40A = 813; ++ public static final int V16W41A = 814; ++ public static final int V16W42A = 815; ++ public static final int V16W43A = 816; ++ public static final int V16W44A = 817; ++ public static final int V1_11_PRE1 = 818; ++ public static final int V1_11 = 819; ++ public static final int V16W50A = 920; ++ public static final int V1_11_1 = 921; ++ public static final int V1_11_2 = 922; ++ public static final int V17W06A = 1022; ++ public static final int V17W13A = 1122; ++ public static final int V17W13B = 1123; ++ public static final int V17W14A = 1124; ++ public static final int V17W15A = 1125; ++ public static final int V17W16A = 1126; ++ public static final int V17W16B = 1127; ++ public static final int V17W17A = 1128; ++ public static final int V17W17B = 1129; ++ public static final int V17W18A = 1130; ++ public static final int V17W18B = 1131; ++ public static final int V1_12_PRE1 = 1132; ++ public static final int V1_12_PRE2 = 1133; ++ public static final int V1_12_PRE3 = 1134; ++ public static final int V1_12_PRE4 = 1135; ++ public static final int V1_12_PRE5 = 1136; ++ public static final int V1_12_PRE6 = 1137; ++ public static final int V1_12_PRE7 = 1138; ++ public static final int V1_12 = 1139; ++ public static final int V17W31A = 1239; ++ public static final int V1_12_1_PRE1 = 1240; ++ public static final int V1_12_1 = 1241; ++ public static final int V1_12_2_PRE1 = 1341; ++ public static final int V1_12_2_PRE2 = 1342; ++ public static final int V1_12_2 = 1343; ++ public static final int V17W43A = 1444; ++ public static final int V17W43B = 1445; ++ public static final int V17W45A = 1447; ++ public static final int V17W45B = 1448; ++ public static final int V17W46A = 1449; ++ public static final int V17W47A = 1451; ++ public static final int V17W47B = 1452; ++ public static final int V17W48A = 1453; ++ public static final int V17W49A = 1454; ++ public static final int V17W49B = 1455; ++ public static final int V17W50A = 1457; ++ public static final int V18W01A = 1459; ++ public static final int V18W02A = 1461; ++ public static final int V18W03A = 1462; ++ public static final int V18W03B = 1463; ++ public static final int V18W05A = 1464; ++ public static final int V18W06A = 1466; ++ public static final int V18W07A = 1467; ++ public static final int V18W07B = 1468; ++ public static final int V18W07C = 1469; ++ public static final int V18W08A = 1470; ++ public static final int V18W08B = 1471; ++ public static final int V18W09A = 1472; ++ public static final int V18W10A = 1473; ++ public static final int V18W10B = 1474; ++ public static final int V18W10C = 1476; ++ public static final int V18W10D = 1477; ++ public static final int V18W11A = 1478; ++ public static final int V18W14A = 1479; ++ public static final int V18W14B = 1481; ++ public static final int V18W15A = 1482; ++ public static final int V18W16A = 1483; ++ public static final int V18W19A = 1484; ++ public static final int V18W19B = 1485; ++ public static final int V18W20A = 1489; ++ public static final int V18W20B = 1491; ++ public static final int V18W20C = 1493; ++ public static final int V18W21A = 1495; ++ public static final int V18W21B = 1496; ++ public static final int V18W22A = 1497; ++ public static final int V18W22B = 1498; ++ public static final int V18W22C = 1499; ++ public static final int V1_13_PRE1 = 1501; ++ public static final int V1_13_PRE2 = 1502; ++ public static final int V1_13_PRE3 = 1503; ++ public static final int V1_13_PRE4 = 1504; ++ public static final int V1_13_PRE5 = 1511; ++ public static final int V1_13_PRE6 = 1512; ++ public static final int V1_13_PRE7 = 1513; ++ public static final int V1_13_PRE8 = 1516; ++ public static final int V1_13_PRE9 = 1517; ++ public static final int V1_13_PRE10 = 1518; ++ public static final int V1_13 = 1519; ++ public static final int V18W30A = 1620; ++ public static final int V18W30B = 1621; ++ public static final int V18W31A = 1622; ++ public static final int V18W32A = 1623; ++ public static final int V18W33A = 1625; ++ public static final int V1_13_1_PRE1 = 1626; ++ public static final int V1_13_1_PRE2 = 1627; ++ public static final int V1_13_1 = 1628; ++ public static final int V1_13_2_PRE1 = 1629; ++ public static final int V1_13_2_PRE2 = 1630; ++ public static final int V1_13_2 = 1631; ++ public static final int V18W43A = 1901; ++ public static final int V18W43B = 1902; ++ public static final int V18W43C = 1903; ++ public static final int V18W44A = 1907; ++ public static final int V18W45A = 1908; ++ public static final int V18W46A = 1910; ++ public static final int V18W47A = 1912; ++ public static final int V18W47B = 1913; ++ public static final int V18W48A = 1914; ++ public static final int V18W48B = 1915; ++ public static final int V18W49A = 1916; ++ public static final int V18W50A = 1919; ++ public static final int V19W02A = 1921; ++ public static final int V19W03A = 1922; ++ public static final int V19W03B = 1923; ++ public static final int V19W03C = 1924; ++ public static final int V19W04A = 1926; ++ public static final int V19W04B = 1927; ++ public static final int V19W05A = 1930; ++ public static final int V19W06A = 1931; ++ public static final int V19W07A = 1932; ++ public static final int V19W08A = 1933; ++ public static final int V19W08B = 1934; ++ public static final int V19W09A = 1935; ++ public static final int V19W11A = 1937; ++ public static final int V19W11B = 1938; ++ public static final int V19W12A = 1940; ++ public static final int V19W12B = 1941; ++ public static final int V19W13A = 1942; ++ public static final int V19W13B = 1943; ++ public static final int V19W14A = 1944; ++ public static final int V19W14B = 1945; ++ public static final int V1_14_PRE1 = 1947; ++ public static final int V1_14_PRE2 = 1948; ++ public static final int V1_14_PRE3 = 1949; ++ public static final int V1_14_PRE4 = 1950; ++ public static final int V1_14_PRE5 = 1951; ++ public static final int V1_14 = 1952; ++ public static final int V1_14_1_PRE1 = 1955; ++ public static final int V1_14_1_PRE2 = 1956; ++ public static final int V1_14_1 = 1957; ++ public static final int V1_14_2_PRE1 = 1958; ++ public static final int V1_14_2_PRE2 = 1959; ++ public static final int V1_14_2_PRE3 = 1960; ++ public static final int V1_14_2_PRE4 = 1962; ++ public static final int V1_14_2 = 1963; ++ public static final int V1_14_3_PRE1 = 1964; ++ public static final int V1_14_3_PRE2 = 1965; ++ public static final int V1_14_3_PRE3 = 1966; ++ public static final int V1_14_3_PRE4 = 1967; ++ public static final int V1_14_3 = 1968; ++ public static final int V1_14_4_PRE1 = 1969; ++ public static final int V1_14_4_PRE2 = 1970; ++ public static final int V1_14_4_PRE3 = 1971; ++ public static final int V1_14_4_PRE4 = 1972; ++ public static final int V1_14_4_PRE5 = 1973; ++ public static final int V1_14_4_PRE6 = 1974; ++ public static final int V1_14_4_PRE7 = 1975; ++ public static final int V1_14_4 = 1976; ++ public static final int V19W34A = 2200; ++ public static final int V19W35A = 2201; ++ public static final int V19W36A = 2203; ++ public static final int V19W37A = 2204; ++ public static final int V19W38A = 2205; ++ public static final int V19W38B = 2206; ++ public static final int V19W39A = 2207; ++ public static final int V19W40A = 2208; ++ public static final int V19W41A = 2210; ++ public static final int V19W42A = 2212; ++ public static final int V19W44A = 2213; ++ public static final int V19W45A = 2214; ++ public static final int V19W45B = 2215; ++ public static final int V19W46A = 2216; ++ public static final int V19W46B = 2217; ++ public static final int V1_15_PRE1 = 2218; ++ public static final int V1_15_PRE2 = 2219; ++ public static final int V1_15_PRE3 = 2220; ++ public static final int V1_15_PRE4 = 2221; ++ public static final int V1_15_PRE5 = 2222; ++ public static final int V1_15_PRE6 = 2223; ++ public static final int V1_15_PRE7 = 2224; ++ public static final int V1_15 = 2225; ++ public static final int V1_15_1_PRE1 = 2226; ++ public static final int V1_15_1 = 2227; ++ public static final int V1_15_2_PRE1 = 2228; ++ public static final int V1_15_2_PRE2 = 2229; ++ public static final int V1_15_2 = 2230; ++ public static final int V20W06A = 2504; ++ public static final int V20W07A = 2506; ++ public static final int V20W08A = 2507; ++ public static final int V20W09A = 2510; ++ public static final int V20W10A = 2512; ++ public static final int V20W11A = 2513; ++ public static final int V20W12A = 2515; ++ public static final int V20W13A = 2520; ++ public static final int V20W13B = 2521; ++ public static final int V20W14A = 2524; ++ public static final int V20W15A = 2525; ++ public static final int V20W16A = 2526; ++ public static final int V20W17A = 2529; ++ public static final int V20W18A = 2532; ++ public static final int V20W19A = 2534; ++ public static final int V20W20A = 2536; ++ public static final int V20W20B = 2537; ++ public static final int V20W21A = 2554; ++ public static final int V20W22A = 2555; ++ public static final int V1_16_PRE1 = 2556; ++ public static final int V1_16_PRE2 = 2557; ++ public static final int V1_16_PRE3 = 2559; ++ public static final int V1_16_PRE4 = 2560; ++ public static final int V1_16_PRE5 = 2561; ++ public static final int V1_16_PRE6 = 2562; ++ public static final int V1_16_PRE7 = 2563; ++ public static final int V1_16_PRE8 = 2564; ++ public static final int V1_16_RC1 = 2565; ++ public static final int V1_16 = 2566; ++ public static final int V1_16_1 = 2567; ++ public static final int V20W27A = 2569; ++ public static final int V20W28A = 2570; ++ public static final int V20W29A = 2571; ++ public static final int V20W30A = 2572; ++ public static final int V1_16_2_PRE1 = 2573; ++ public static final int V1_16_2_PRE2 = 2574; ++ public static final int V1_16_2_PRE3 = 2575; ++ public static final int V1_16_2_RC1 = 2576; ++ public static final int V1_16_2_RC2 = 2577; ++ public static final int V1_16_2 = 2578; ++ public static final int V1_16_3_RC1 = 2579; ++ public static final int V1_16_3 = 2580; ++ public static final int V1_16_4_PRE1 = 2581; ++ public static final int V1_16_4_PRE2 = 2582; ++ public static final int V1_16_4_RC1 = 2583; ++ public static final int V1_16_4 = 2584; ++ public static final int V1_16_5_RC1 = 2585; ++ public static final int V1_16_5 = 2586; ++ public static final int V20W45A = 2681; ++ public static final int V20W46A = 2682; ++ public static final int V20W48A = 2683; ++ public static final int V20W49A = 2685; ++ public static final int V20W51A = 2687; ++ public static final int V21W03A = 2689; ++ public static final int V21W05A = 2690; ++ public static final int V21W05B = 2692; ++ public static final int V21W06A = 2694; ++ public static final int V21W07A = 2695; ++ public static final int V21W08A = 2697; ++ public static final int V21W08B = 2698; ++ public static final int V21W10A = 2699; ++ public static final int V21W11A = 2703; ++ public static final int V21W13A = 2705; ++ public static final int V21W14A = 2706; ++ public static final int V21W15A = 2709; ++ public static final int V21W16A = 2711; ++ public static final int V21W17A = 2712; ++ public static final int V21W18A = 2713; ++ public static final int V21W19A = 2714; ++ public static final int V21W20A = 2715; ++ public static final int V1_17_PRE1 = 2716; ++ public static final int V1_17_PRE2 = 2718; ++ public static final int V1_17_PRE3 = 2719; ++ public static final int V1_17_PRE4 = 2720; ++ public static final int V1_17_PRE5 = 2721; ++ public static final int V1_17_RC1 = 2722; ++ public static final int V1_17_RC2 = 2723; ++ public static final int V1_17 = 2724; ++ public static final int V1_17_1_PRE1 = 2725; ++ public static final int V1_17_1_PRE2 = 2726; ++ public static final int V1_17_1_PRE3 = 2727; ++ public static final int V1_17_1_RC1 = 2728; ++ public static final int V1_17_1_RC2 = 2729; ++ public static final int V1_17_1 = 2730; ++ public static final int V21W37A = 2834; ++ public static final int V21W38A = 2835; ++ public static final int V21W39A = 2836; ++ public static final int V21W40A = 2838; ++ public static final int V21W41A = 2839; ++ public static final int V21W42A = 2840; ++ public static final int V21W43A = 2844; ++ public static final int V21W44A = 2845; ++ public static final int V1_18_PRE1 = 2847; ++ public static final int V1_18_PRE2 = 2848; ++ public static final int V1_18_PRE3 = 2849; ++ public static final int V1_18_PRE4 = 2850; ++ public static final int V1_18_PRE5 = 2851; ++ public static final int V1_18_PRE6 = 2853; ++ public static final int V1_18_PRE7 = 2854; ++ public static final int V1_18_PRE8 = 2855; ++ public static final int V1_18_RC1 = 2856; ++ public static final int V1_18_RC2 = 2857; ++ public static final int V1_18_RC3 = 2858; ++ public static final int V1_18_RC4 = 2859; ++ public static final int V1_18 = 2860; ++ public static final int V1_18_1_PRE1 = 2861; ++ public static final int V1_18_1_RC1 = 2862; ++ public static final int V1_18_1_RC2 = 2863; ++ public static final int V1_18_1_RC3 = 2864; ++ public static final int V1_18_1 = 2865; ++ public static final int V22W03A = 2966; ++ public static final int V22W05A = 2967; ++ public static final int V22W06A = 2968; ++ public static final int V22W07A = 2969; ++ public static final int V1_18_2_PRE1 = 2971; ++ public static final int V1_18_2_PRE2 = 2972; ++ public static final int V1_18_2_PRE3 = 2973; ++ public static final int V1_18_2_RC1 = 2974; ++ public static final int V1_18_2 = 2975; ++ public static final int V22W11A = 3080; ++ public static final int V22W12A = 3082; ++ public static final int V22W13A = 3085; ++ public static final int V22W14A = 3088; ++ public static final int V22W15A = 3089; ++ public static final int V22W16A = 3091; ++ public static final int V22W16B = 3092; ++ public static final int V22W17A = 3093; ++ public static final int V22W18A = 3095; ++ public static final int V22W19A = 3096; ++ public static final int V1_19_PRE1 = 3098; ++ public static final int V1_19_PRE2 = 3099; ++ public static final int V1_19_PRE3 = 3100; ++ public static final int V1_19_PRE4 = 3101; ++ public static final int V1_19_PRE5 = 3102; ++ public static final int V1_19_RC1 = 3103; ++ public static final int V1_19_RC2 = 3104; ++ public static final int V1_19 = 3105; ++ public static final int V22W24A = 3106; ++ public static final int V1_19_1_PRE1 = 3107; ++ public static final int V1_19_1_RC1 = 3109; ++ public static final int V1_19_1_PRE2 = 3110; ++ public static final int V1_19_1_PRE3 = 3111; ++ public static final int V1_19_1_PRE4 = 3112; ++ public static final int V1_19_1_PRE5 = 3113; ++ public static final int V1_19_1_PRE6 = 3114; ++ public static final int V1_19_1_RC2 = 3115; ++ public static final int V1_19_1_RC3 = 3116; ++ public static final int V1_19_1 = 3117; ++ public static final int V1_19_2_RC1 = 3118; ++ public static final int V1_19_2_RC2 = 3119; ++ public static final int V1_19_2 = 3120; ++ public static final int V22W42A = 3205; ++ public static final int V22W43A = 3206; ++ public static final int V22W44A = 3207; ++ public static final int V22W45A = 3208; ++ public static final int V22W46A = 3210; ++ public static final int V1_19_3_PRE1 = 3211; ++ public static final int V1_19_3_PRE2 = 3212; ++ public static final int V1_19_3_PRE3 = 3213; ++ public static final int V1_19_3_RC1 = 3215; ++ public static final int V1_19_3 = 3218; ++ public static final int V23W03A = 3320; ++ public static final int V23W04A = 3321; ++ public static final int V23W05A = 3323; ++ public static final int V23W06A = 3326; ++ public static final int V23W07A = 3329; ++ public static final int V1_19_4_PRE1 = 3330; ++ public static final int V1_19_4_PRE2 = 3331; ++ public static final int V1_19_4_PRE3 = 3332; ++ public static final int V1_19_4_PRE4 = 3333; ++ public static final int V1_19_4_RC1 = 3334; ++ public static final int V1_19_4_RC2 = 3335; ++ public static final int V1_19_4_RC3 = 3336; ++ public static final int V1_19_4 = 3337; ++ public static final int V23W12A = 3442; ++ public static final int V23W13A = 3443; ++ public static final int V23W14A = 3445; ++ public static final int V23W16A = 3449; ++ public static final int V23W17A = 3452; ++ public static final int V23W19A = 3453; ++ public static final int V1_20_PRE1 = 3454; ++ public static final int V1_20_PRE2 = 3455; ++ public static final int V1_20_PRE3 = 3456; ++ public static final int V1_20_PRE4 = 3457; ++ public static final int V1_20_PRE5 = 3458; ++ public static final int V1_20_PRE6 = 3460; ++ public static final int V1_20_PRE7 = 3461; ++ public static final int V1_20_RC1 = 3462; ++ public static final int V1_20 = 3463; ++ public static final int V1_20_1_RC1 = 3464; ++ public static final int V1_20_1 = 3465; ++ public static final int V23W31A = 3567; ++ public static final int V23W32A = 3569; ++ public static final int V23W33A = 3570; ++ public static final int V23W35A = 3571; ++ public static final int V1_20_2_PRE1 = 3572; ++ public static final int V1_20_2_PRE2 = 3573; ++ public static final int V1_20_2_PRE3 = 3574; ++ public static final int V1_20_2_PRE4 = 3575; ++ public static final int V1_20_2_RC1 = 3576; ++ public static final int V1_20_2_RC2 = 3577; ++ public static final int V1_20_2 = 3578; ++ public static final int V23W40A = 3679; ++ public static final int V23W41A = 3681; ++ public static final int V23W42A = 3684; ++ public static final int V23W43A = 3686; ++ public static final int V23W43B = 3687; ++ public static final int V23W44A = 3688; ++ public static final int V23W45A = 3690; ++ public static final int V23W46A = 3691; ++ public static final int V1_20_3_PRE1 = 3693; ++ public static final int V1_20_3_PRE2 = 3694; ++ public static final int V1_20_3_PRE3 = 3695; ++ public static final int V1_20_3_PRE4 = 3696; ++ public static final int V1_20_3_RC1 = 3697; ++ public static final int V1_20_3 = 3698; ++ public static final int V1_20_4_RC1 = 3699; ++ public static final int V1_20_4 = 3700; ++ public static final int V23W51A = 3801; ++ public static final int V23W51B = 3802; ++ public static final int V24W03A = 3804; ++ public static final int V24W03B = 3805; ++ public static final int V24W04A = 3806; ++ public static final int V24W05A = 3809; ++ public static final int V24W05B = 3811; ++ public static final int V24W06A = 3815; ++ public static final int V24W07A = 3817; ++ public static final int V24W09A = 3819; ++ public static final int V24W10A = 3821; ++ public static final int V24W11A = 3823; ++ public static final int V24W12A = 3824; ++ public static final int V24W13A = 3826; ++ public static final int V24W14A = 3827; ++ public static final int V1_20_5_PRE1 = 3829; ++ public static final int V1_20_5_PRE2 = 3830; ++ public static final int V1_20_5_PRE3 = 3831; ++ public static final int V1_20_5_PRE4 = 3832; ++ public static final int V1_20_5_RC1 = 3834; ++ public static final int V1_20_5_RC2 = 3835; ++ public static final int V1_20_5_RC3 = 3836; ++ public static final int V1_20_5 = 3837; ++ public static final int V1_20_6_RC1 = 3838; ++ public static final int V1_20_6 = 3839; ++ public static final int V24W18A = 3940; ++ public static final int V24W19A = 3941; ++ public static final int V24W19B = 3942; ++ public static final int V24W20A = 3944; ++ public static final int V24W21A = 3946; ++ public static final int V24W21B = 3947; ++ public static final int V1_21_PRE1 = 3948; ++ public static final int V1_21_PRE2 = 3949; ++ public static final int V1_21_PRE3 = 3950; ++ public static final int V1_21_PRE4 = 3951; ++ public static final int V1_21_RC1 = 3952; ++ public static final int V1_21 = 3953; ++ public static final int V1_21_RC = 3954; ++ public static final int V1_21_1 = 3955; ++ public static final int V24W33A = 4058; ++ public static final int V24W34A = 4060; ++ public static final int V24W35A = 4062; ++ public static final int V24W36A = 4063; ++ public static final int V24W37A = 4065; ++ public static final int V24W38A = 4066; ++ public static final int V24W39A = 4069; ++ public static final int V24W40A = 4072; ++ public static final int V1_21_2_PRE1 = 4073; ++ public static final int V1_21_2_PRE2 = 4074; ++ public static final int V1_21_2_PRE3 = 4075; ++ public static final int V1_21_2_PRE4 = 4076; ++ public static final int V1_21_2_PRE5 = 4077; ++ public static final int V1_21_2_RC1 = 4078; ++ public static final int V1_21_2_RC2 = 4079; ++ public static final int V1_21_2 = 4080; ++ public static final int V1_21_3 = 4082; ++ public static final int V24W44A = 4174; ++ public static final int V24W45A = 4177; ++ public static final int V24W46A = 4178; ++ public static final int V1_21_4_PRE1 = 4179; ++ public static final int V1_21_4_PRE2 = 4182; ++ public static final int V1_21_4_PRE3 = 4183; ++ public static final int V1_21_4_RC1 = 4184; ++ public static final int V1_21_4_RC2 = 4186; ++ public static final int V1_21_4_RC3 = 4188; ++ public static final int V1_21_4 = 4189; ++ public static final int V25W02A = 4298; ++ public static final int V25W03A = 4304; ++ public static final int V25W04A = 4308; ++ public static final int V25W05A = 4310; ++ public static final int V25W06A = 4313; ++ public static final int V25W07A = 4315; ++ public static final int V25W08A = 4316; ++ public static final int V25W09A = 4317; ++ public static final int V25W09B = 4318; ++ public static final int V25W10A = 4319; ++ public static final int V1_21_5_PRE1 = 4320; ++ public static final int V1_21_5_PRE2 = 4321; ++ public static final int V1_21_5_PRE3 = 4321; ++ public static final int V1_21_5_RC1 = 4323; ++ public static final int V1_21_5_RC2 = 4324; ++ public static final int V1_21_5 = 4325; ++ public static final int V25W15A = 4422; ++ public static final int V25W16A = 4423; ++ public static final int V25W17A = 4425; ++ public static final int V25W18A = 4426; ++ public static final int V25W19A = 4427; ++ public static final int V25W20A = 4428; ++ public static final int V25W21A = 4429; ++ public static final int V1_21_6_PRE1 = 4430; ++ public static final int V1_21_6_PRE2 = 4431; ++ ++ private MCVersions() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterAbstractAdvancementsRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterAbstractAdvancementsRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9022385edc8dd887780aa0881741d6d042fe2bc4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterAbstractAdvancementsRename.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.advancements; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.ArrayList; ++import java.util.function.Function; ++ ++public final class ConverterAbstractAdvancementsRename { ++ ++ private ConverterAbstractAdvancementsRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.ADVANCEMENTS.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameKeys(data, renamer); ++ return null; ++ } ++ }); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterCriteriaRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterCriteriaRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..72d0d70b5ade04469aaecbf454b37a2643923a97 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/advancements/ConverterCriteriaRename.java +@@ -0,0 +1,42 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.advancements; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.Function; ++ ++public final class ConverterCriteriaRename extends DataConverter { ++ ++ public final String path; ++ public final Function conversion; ++ ++ public ConverterCriteriaRename(final int toVersion, final String path, final Function conversion) { ++ super(toVersion); ++ this.path = path; ++ this.conversion = conversion; ++ } ++ ++ public ConverterCriteriaRename(final int toVersion, final int versionStep, final String path, final Function conversion) { ++ super(toVersion, versionStep); ++ this.path = path; ++ this.conversion = conversion; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType advancement = data.getMap(this.path); ++ if (advancement == null) { ++ return null; ++ } ++ ++ final MapType criteria = advancement.getMap("criteria"); ++ if (criteria == null) { ++ return null; ++ } ++ ++ RenameHelper.renameKeys(criteria, this.conversion); ++ ++ return null; ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..75efa3e470e3d386f993064b3af7f67d82ca4b50 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractAttributesRename.java +@@ -0,0 +1,60 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.attributes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractAttributesRename { ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int versionStep, final Function renamer) { ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType attributeModifiers = data.getMap("minecraft:attribute_modifiers"); ++ if (attributeModifiers == null) { ++ return null; ++ } ++ ++ final ListType modifiers = attributeModifiers.getList("modifiers", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = modifiers.size(); i < len; ++i) { ++ RenameHelper.renameString(modifiers.getMap(i), "type", renamer); ++ } ++ ++ return null; ++ } ++ }); ++ ++ final DataConverter entityConverter = new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType modifiers = data.getList("attributes", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = modifiers.size(); i < len; ++i) { ++ RenameHelper.renameString(modifiers.getMap(i), "id", renamer); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(entityConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(entityConverter); ++ } ++ ++ private ConverterAbstractAttributesRename() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1a6d02df13f3461402fed429f7fbdb5acee877c4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterAbstractOldAttributesRename.java +@@ -0,0 +1,57 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.attributes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractOldAttributesRename { ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int versionStep, final Function renamer) { ++ final DataConverter entityConverter = new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType attributes = data.getList("Attributes", ObjectType.MAP); ++ ++ if (attributes == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ RenameHelper.renameString(attributes.getMap(i), "Name", renamer); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(entityConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(entityConverter); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(version, versionStep) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType attributes = data.getList("AttributeModifiers", ObjectType.MAP); ++ ++ if (attributes == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ RenameHelper.renameString(attributes.getMap(i), "AttributeName", renamer); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private ConverterAbstractOldAttributesRename() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterEntityAttributesBaseValueUpdater.java b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterEntityAttributesBaseValueUpdater.java +new file mode 100644 +index 0000000000000000000000000000000000000000..071272260593f834b03b195a1e4c71c81a051be5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/attributes/ConverterEntityAttributesBaseValueUpdater.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.attributes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import java.util.function.DoubleUnaryOperator; ++ ++public final class ConverterEntityAttributesBaseValueUpdater extends DataConverter { ++ ++ private final String targetId; ++ private final DoubleUnaryOperator updater; ++ ++ public ConverterEntityAttributesBaseValueUpdater(final int toVersion, final String targetId, final DoubleUnaryOperator updater) { ++ this(toVersion, 0, targetId, updater); ++ } ++ ++ public ConverterEntityAttributesBaseValueUpdater(final int toVersion, final int versionStep, final String targetId, ++ final DoubleUnaryOperator updater) { ++ super(toVersion, versionStep); ++ this.targetId = targetId; ++ this.updater = updater; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType modifiers = data.getList("attributes", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = modifiers.size(); i < len; ++i) { ++ final MapType modifier = modifiers.getMap(i); ++ ++ if (!this.targetId.equals(NamespaceUtil.correctNamespace(modifier.getString("id", "")))) { ++ continue; ++ } ++ ++ modifier.setDouble("base", this.updater.applyAsDouble(modifier.getDouble("base", 0.0))); ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/blockname/ConverterAbstractBlockRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/blockname/ConverterAbstractBlockRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..316bc54366bb1ba2273e52dc52aaef6c8e43a2c3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/blockname/ConverterAbstractBlockRename.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.blockname; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractBlockRename { ++ ++ private ConverterAbstractBlockRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ ConverterAbstractStringValueTypeRename.register(version, subVersion, MCTypeRegistry.BLOCK_NAME, renamer); ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String name = data.getString("Name"); ++ if (name != null) { ++ final String converted = renamer.apply(name); ++ if (converted != null) { ++ data.setString("Name", converted); ++ } ++ } ++ return null; ++ } ++ }); ++ MCTypeRegistry.FLAT_BLOCK_STATE.addConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (!(data instanceof String string)) { ++ return null; ++ } ++ ++ if (string.isEmpty()) { ++ return null; ++ } ++ ++ final int nbtStart1 = string.indexOf('['); ++ final int nbtStart2 = string.indexOf('{'); ++ int stateNameEnd = string.length(); ++ if (nbtStart1 > 0) { ++ stateNameEnd = nbtStart1; ++ } ++ ++ if (nbtStart2 > 0) { ++ stateNameEnd = Math.min(stateNameEnd, nbtStart2); ++ } ++ ++ final String blockStateName = string.substring(0, stateNameEnd); ++ final String converted = renamer.apply(blockStateName); ++ if (converted == null) { ++ return null; ++ } ++ ++ return converted.concat(string.substring(stateNameEnd)); ++ } ++ }); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterAddBlendingData.java b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterAddBlendingData.java +new file mode 100644 +index 0000000000000000000000000000000000000000..038f19b72870aee2b94e6691c03074e464e7d253 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterAddBlendingData.java +@@ -0,0 +1,65 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.chunk; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class ConverterAddBlendingData extends DataConverter { ++ ++ private static final Set STATUSES_TO_SKIP_BLENDING = new HashSet<>( ++ Arrays.asList( ++ "minecraft:empty", ++ "minecraft:structure_starts", ++ "minecraft:structure_references", ++ "minecraft:biomes" ++ ) ++ ); ++ ++ public ConverterAddBlendingData(final int toVersion) { ++ super(toVersion); ++ } ++ ++ public ConverterAddBlendingData(final int toVersion, final int versionStep) { ++ super(toVersion, versionStep); ++ } ++ ++ private static MapType createBlendingData(final int height, final int minY) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setInt("min_section", minY >> 4); ++ ret.setInt("max_section", (minY + height) >> 4); ++ ++ return ret; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.remove("blending_data"); ++ final MapType context = data.getMap("__context"); ++ if (!"minecraft:overworld".equals(context == null ? null : context.getString("dimension"))) { ++ return null; ++ } ++ ++ final String status = NamespaceUtil.correctNamespace(data.getString("Status")); ++ if (status == null) { ++ return null; ++ } ++ ++ final MapType belowZeroRetrogen = data.getMap("below_zero_retrogen"); ++ ++ if (!STATUSES_TO_SKIP_BLENDING.contains(status)) { ++ data.setMap("blending_data", createBlendingData(384, -64)); ++ } else if (belowZeroRetrogen != null) { ++ final String realStatus = NamespaceUtil.correctNamespace(belowZeroRetrogen.getString("target_status", "empty")); ++ if (!STATUSES_TO_SKIP_BLENDING.contains(realStatus)) { ++ data.setMap("blending_data", createBlendingData(256, 0)); ++ } ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterFlattenChunk.java b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterFlattenChunk.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ed7468f57047ad4ec7bf58680871848efe350182 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterFlattenChunk.java +@@ -0,0 +1,1016 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.chunk; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperBlockFlatteningV1450; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperItemNameV102; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.datafixers.DataFixUtils; ++import com.mojang.logging.LogUtils; ++import it.unimi.dsi.fastutil.ints.Int2ObjectLinkedOpenHashMap; ++import it.unimi.dsi.fastutil.ints.Int2ObjectMap; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import it.unimi.dsi.fastutil.ints.IntArrayList; ++import it.unimi.dsi.fastutil.ints.IntIterator; ++import it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap; ++import net.minecraft.util.datafix.PackedBitStorage; ++import org.slf4j.Logger; ++import java.util.Arrays; ++import java.util.BitSet; ++import java.util.HashMap; ++import java.util.Iterator; ++import java.util.Map; ++import java.util.Objects; ++ ++import static it.unimi.dsi.fastutil.HashCommon.arraySize; ++ ++public final class ConverterFlattenChunk extends DataConverter { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ static final BitSet VIRTUAL_SET = new BitSet(256); ++ static final BitSet IDS_NEEDING_FIX_SET = new BitSet(256); ++ ++ static { ++ IDS_NEEDING_FIX_SET.set(2); ++ IDS_NEEDING_FIX_SET.set(3); ++ IDS_NEEDING_FIX_SET.set(110); ++ IDS_NEEDING_FIX_SET.set(140); ++ IDS_NEEDING_FIX_SET.set(144); ++ IDS_NEEDING_FIX_SET.set(25); ++ IDS_NEEDING_FIX_SET.set(86); ++ IDS_NEEDING_FIX_SET.set(26); ++ IDS_NEEDING_FIX_SET.set(176); ++ IDS_NEEDING_FIX_SET.set(177); ++ IDS_NEEDING_FIX_SET.set(175); ++ IDS_NEEDING_FIX_SET.set(64); ++ IDS_NEEDING_FIX_SET.set(71); ++ IDS_NEEDING_FIX_SET.set(193); ++ IDS_NEEDING_FIX_SET.set(194); ++ IDS_NEEDING_FIX_SET.set(195); ++ IDS_NEEDING_FIX_SET.set(196); ++ IDS_NEEDING_FIX_SET.set(197); ++ ++ VIRTUAL_SET.set(54); ++ VIRTUAL_SET.set(146); ++ VIRTUAL_SET.set(25); ++ VIRTUAL_SET.set(26); ++ VIRTUAL_SET.set(51); ++ VIRTUAL_SET.set(53); ++ VIRTUAL_SET.set(67); ++ VIRTUAL_SET.set(108); ++ VIRTUAL_SET.set(109); ++ VIRTUAL_SET.set(114); ++ VIRTUAL_SET.set(128); ++ VIRTUAL_SET.set(134); ++ VIRTUAL_SET.set(135); ++ VIRTUAL_SET.set(136); ++ VIRTUAL_SET.set(156); ++ VIRTUAL_SET.set(163); ++ VIRTUAL_SET.set(164); ++ VIRTUAL_SET.set(180); ++ VIRTUAL_SET.set(203); ++ VIRTUAL_SET.set(55); ++ VIRTUAL_SET.set(85); ++ VIRTUAL_SET.set(113); ++ VIRTUAL_SET.set(188); ++ VIRTUAL_SET.set(189); ++ VIRTUAL_SET.set(190); ++ VIRTUAL_SET.set(191); ++ VIRTUAL_SET.set(192); ++ VIRTUAL_SET.set(93); ++ VIRTUAL_SET.set(94); ++ VIRTUAL_SET.set(101); ++ VIRTUAL_SET.set(102); ++ VIRTUAL_SET.set(160); ++ VIRTUAL_SET.set(106); ++ VIRTUAL_SET.set(107); ++ VIRTUAL_SET.set(183); ++ VIRTUAL_SET.set(184); ++ VIRTUAL_SET.set(185); ++ VIRTUAL_SET.set(186); ++ VIRTUAL_SET.set(187); ++ VIRTUAL_SET.set(132); ++ VIRTUAL_SET.set(139); ++ VIRTUAL_SET.set(199); ++ } ++ ++ static final boolean[] VIRTUAL = toBooleanArray(VIRTUAL_SET); ++ static final boolean[] IDS_NEEDING_FIX = toBooleanArray(IDS_NEEDING_FIX_SET); ++ ++ private static boolean[] toBooleanArray(final BitSet set) { ++ final boolean[] ret = new boolean[4096]; ++ for (int i = 0; i < 4096; ++i) { ++ ret[i] = set.get(i); ++ } ++ ++ return ret; ++ } ++ ++ static final MapType PUMPKIN = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:pumpkin'}"); ++ static final MapType SNOWY_PODZOL = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:podzol',Properties:{snowy:'true'}}"); ++ static final MapType SNOWY_GRASS = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:grass_block',Properties:{snowy:'true'}}"); ++ static final MapType SNOWY_MYCELIUM = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:mycelium',Properties:{snowy:'true'}}"); ++ static final MapType UPPER_SUNFLOWER = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:sunflower',Properties:{half:'upper'}}"); ++ static final MapType UPPER_LILAC = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:lilac',Properties:{half:'upper'}}"); ++ static final MapType UPPER_TALL_GRASS = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:tall_grass',Properties:{half:'upper'}}"); ++ static final MapType UPPER_LARGE_FERN = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:large_fern',Properties:{half:'upper'}}"); ++ static final MapType UPPER_ROSE_BUSH = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:rose_bush',Properties:{half:'upper'}}"); ++ static final MapType UPPER_PEONY = HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:peony',Properties:{half:'upper'}}"); ++ ++ static final Map FLOWER_POT_MAP = new HashMap<>(); ++ static { ++ FLOWER_POT_MAP.put("minecraft:air0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:flower_pot'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_poppy'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower1", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_blue_orchid'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower2", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_allium'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower3", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_azure_bluet'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower4", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_red_tulip'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower5", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_orange_tulip'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower6", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_white_tulip'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower7", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_pink_tulip'}")); ++ FLOWER_POT_MAP.put("minecraft:red_flower8", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_oxeye_daisy'}")); ++ FLOWER_POT_MAP.put("minecraft:yellow_flower0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_dandelion'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_oak_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling1", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_spruce_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling2", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_birch_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling3", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_jungle_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling4", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_acacia_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:sapling5", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_dark_oak_sapling'}")); ++ FLOWER_POT_MAP.put("minecraft:red_mushroom0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_red_mushroom'}")); ++ FLOWER_POT_MAP.put("minecraft:brown_mushroom0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_brown_mushroom'}")); ++ FLOWER_POT_MAP.put("minecraft:deadbush0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_dead_bush'}")); ++ FLOWER_POT_MAP.put("minecraft:tallgrass2", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_fern'}")); ++ FLOWER_POT_MAP.put("minecraft:cactus0", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:potted_cactus'}")); // we change default to empty ++ } ++ ++ static final Map SKULL_MAP = new HashMap<>(); ++ static { ++ mapSkull(SKULL_MAP, 0, "skeleton", "skull"); ++ mapSkull(SKULL_MAP, 1, "wither_skeleton", "skull"); ++ mapSkull(SKULL_MAP, 2, "zombie", "head"); ++ mapSkull(SKULL_MAP, 3, "player", "head"); ++ mapSkull(SKULL_MAP, 4, "creeper", "head"); ++ mapSkull(SKULL_MAP, 5, "dragon", "head"); ++ }; ++ ++ private static void mapSkull(final Map into, final int oldId, final String newId, final String skullType) { ++ into.put(oldId + "north", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + newId + "_wall_" + skullType + "',Properties:{facing:'north'}}")); ++ into.put(oldId + "east", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + newId + "_wall_" + skullType + "',Properties:{facing:'east'}}")); ++ into.put(oldId + "south", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + newId + "_wall_" + skullType + "',Properties:{facing:'south'}}")); ++ into.put(oldId + "west", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + newId + "_wall_" + skullType + "',Properties:{facing:'west'}}")); ++ ++ for (int rotation = 0; rotation < 16; ++rotation) { ++ into.put(oldId + "" + rotation, ++ HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + newId + "_" + skullType + "',Properties:{rotation:'" + rotation + "'}}")); ++ } ++ } ++ ++ static final Map DOOR_MAP = new HashMap<>(); ++ static { ++ mapDoor(DOOR_MAP, "oak_door", 1024); ++ mapDoor(DOOR_MAP, "iron_door", 1136); ++ mapDoor(DOOR_MAP, "spruce_door", 3088); ++ mapDoor(DOOR_MAP, "birch_door", 3104); ++ mapDoor(DOOR_MAP, "jungle_door", 3120); ++ mapDoor(DOOR_MAP, "acacia_door", 3136); ++ mapDoor(DOOR_MAP, "dark_oak_door", 3152); ++ }; ++ ++ private static void mapDoor(final Map into, final String type, final int oldId) { ++ into.put("minecraft:" + type + "eastlowerleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "eastlowerleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "eastlowerlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "eastlowerlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "eastlowerrightfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId))); ++ into.put("minecraft:" + type + "eastlowerrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "eastlowerrighttruefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 4))); ++ into.put("minecraft:" + type + "eastlowerrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "eastupperleftfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 8))); ++ into.put("minecraft:" + type + "eastupperleftfalsetrue", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 10))); ++ into.put("minecraft:" + type + "eastupperlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "eastupperlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "eastupperrightfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 9))); ++ into.put("minecraft:" + type + "eastupperrightfalsetrue", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 11))); ++ into.put("minecraft:" + type + "eastupperrighttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "eastupperrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "northlowerleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "northlowerleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "northlowerlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "northlowerlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "northlowerrightfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 3))); ++ into.put("minecraft:" + type + "northlowerrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "northlowerrighttruefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 7))); ++ into.put("minecraft:" + type + "northlowerrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "northupperleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "northupperleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "northupperlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "northupperlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "northupperrightfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "northupperrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "northupperrighttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "northupperrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "southlowerleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "southlowerleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "southlowerlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "southlowerlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "southlowerrightfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 1))); ++ into.put("minecraft:" + type + "southlowerrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "southlowerrighttruefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 5))); ++ into.put("minecraft:" + type + "southlowerrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "southupperleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "southupperleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "southupperlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "southupperlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "southupperrightfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "southupperrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "southupperrighttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "southupperrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "westlowerleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "westlowerleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "westlowerlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "westlowerlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "westlowerrightfalsefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 2))); ++ into.put("minecraft:" + type + "westlowerrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "westlowerrighttruefalse", Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(oldId + 6))); ++ into.put("minecraft:" + type + "westlowerrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "westupperleftfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "westupperleftfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "westupperlefttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "westupperlefttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}")); ++ into.put("minecraft:" + type + "westupperrightfalsefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}")); ++ into.put("minecraft:" + type + "westupperrightfalsetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}")); ++ into.put("minecraft:" + type + "westupperrighttruefalse", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}")); ++ into.put("minecraft:" + type + "westupperrighttruetrue", HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + type + "',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}")); ++ } ++ ++ static final Map NOTE_BLOCK_MAP = new HashMap<>(); ++ static { ++ for(int note = 0; note < 26; ++note) { ++ NOTE_BLOCK_MAP.put("true" + note, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:note_block',Properties:{powered:'true',note:'" + note + "'}}")); ++ NOTE_BLOCK_MAP.put("false" + note, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:note_block',Properties:{powered:'false',note:'" + note + "'}}")); ++ } ++ } ++ ++ static final Int2ObjectOpenHashMap DYE_COLOR_MAP = new Int2ObjectOpenHashMap<>(); ++ static { ++ DYE_COLOR_MAP.put(0, "white"); ++ DYE_COLOR_MAP.put(1, "orange"); ++ DYE_COLOR_MAP.put(2, "magenta"); ++ DYE_COLOR_MAP.put(3, "light_blue"); ++ DYE_COLOR_MAP.put(4, "yellow"); ++ DYE_COLOR_MAP.put(5, "lime"); ++ DYE_COLOR_MAP.put(6, "pink"); ++ DYE_COLOR_MAP.put(7, "gray"); ++ DYE_COLOR_MAP.put(8, "light_gray"); ++ DYE_COLOR_MAP.put(9, "cyan"); ++ DYE_COLOR_MAP.put(10, "purple"); ++ DYE_COLOR_MAP.put(11, "blue"); ++ DYE_COLOR_MAP.put(12, "brown"); ++ DYE_COLOR_MAP.put(13, "green"); ++ DYE_COLOR_MAP.put(14, "red"); ++ DYE_COLOR_MAP.put(15, "black"); ++ } ++ ++ static final Map BED_BLOCK_MAP = new HashMap<>(); ++ ++ static { ++ for (final Int2ObjectMap.Entry entry : DYE_COLOR_MAP.int2ObjectEntrySet()) { ++ if (!Objects.equals(entry.getValue(), "red")) { ++ addBeds(BED_BLOCK_MAP, entry.getIntKey(), entry.getValue()); ++ } ++ } ++ } ++ ++ private static void addBeds(final Map into, final int colourId, final String colourName) { ++ into.put("southfalsefoot" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'south',occupied:'false',part:'foot'}}")); ++ into.put("westfalsefoot" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'west',occupied:'false',part:'foot'}}")); ++ into.put("northfalsefoot" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'north',occupied:'false',part:'foot'}}")); ++ into.put("eastfalsefoot" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'east',occupied:'false',part:'foot'}}")); ++ into.put("southfalsehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'south',occupied:'false',part:'head'}}")); ++ into.put("westfalsehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'west',occupied:'false',part:'head'}}")); ++ into.put("northfalsehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'north',occupied:'false',part:'head'}}")); ++ into.put("eastfalsehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'east',occupied:'false',part:'head'}}")); ++ into.put("southtruehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'south',occupied:'true',part:'head'}}")); ++ into.put("westtruehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'west',occupied:'true',part:'head'}}")); ++ into.put("northtruehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'north',occupied:'true',part:'head'}}")); ++ into.put("easttruehead" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_bed',Properties:{facing:'east',occupied:'true',part:'head'}}")); ++ } ++ ++ static final Map BANNER_BLOCK_MAP = new HashMap<>(); ++ ++ static { ++ for (final Int2ObjectMap.Entry entry : DYE_COLOR_MAP.int2ObjectEntrySet()) { ++ if (!Objects.equals(entry.getValue(), "white")) { ++ addBanners(BANNER_BLOCK_MAP, 15 - entry.getIntKey(), entry.getValue()); ++ } ++ } ++ } ++ ++ private static void addBanners(final Map into, final int colourId, final String colourName) { ++ for(int rotation = 0; rotation < 16; ++rotation) { ++ into.put("" + rotation + "_" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_banner',Properties:{rotation:'" + rotation + "'}}")); ++ } ++ ++ into.put("north_" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_wall_banner',Properties:{facing:'north'}}")); ++ into.put("south_" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_wall_banner',Properties:{facing:'south'}}")); ++ into.put("west_" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_wall_banner',Properties:{facing:'west'}}")); ++ into.put("east_" + colourId, HelperBlockFlatteningV1450.parseTag("{Name:'minecraft:" + colourName + "_wall_banner',Properties:{facing:'east'}}")); ++ } ++ ++ static final MapType AIR = Objects.requireNonNull(HelperBlockFlatteningV1450.getNBTForId(0)); ++ ++ public ConverterFlattenChunk() { ++ super(MCVersions.V17W47A, 1); ++ } ++ ++ static String getName(final MapType blockState) { ++ return blockState.getString("Name"); ++ } ++ ++ static String getProperty(final MapType blockState, final String propertyName) { ++ final MapType properties = blockState.getMap("Properties"); ++ if (properties == null) { ++ return ""; ++ } ++ ++ return properties.getString(propertyName, ""); ++ } ++ ++ static int getSideMask(final boolean noLeft, final boolean noRight, final boolean noBack, final boolean noForward) { ++ if (noBack) { ++ if (noRight) { ++ return 2; ++ } else if (noLeft) { ++ return 128; ++ } else { ++ return 1; ++ } ++ } else if (noForward) { ++ if (noLeft) { ++ return 32; ++ } else if (noRight) { ++ return 8; ++ } else { ++ return 16; ++ } ++ } else if (noRight) { ++ return 4; ++ } else if (noLeft) { ++ return 64; ++ } else { ++ return 0; ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ if (!level.hasKey("Sections", ObjectType.LIST)) { ++ return null; ++ } ++ ++ data.setMap("Level", new UpgradeChunk(level).writeBackToLevel()); ++ ++ return null; ++ } ++ ++ static enum Direction { ++ DOWN(AxisDirection.NEGATIVE, Axis.Y), ++ UP(AxisDirection.POSITIVE, Axis.Y), ++ NORTH(AxisDirection.NEGATIVE, Axis.Z), ++ SOUTH(AxisDirection.POSITIVE, Axis.Z), ++ WEST(AxisDirection.NEGATIVE, Axis.X), ++ EAST(AxisDirection.POSITIVE, Axis.X); ++ ++ private final Axis axis; ++ private final AxisDirection axisDirection; ++ ++ private Direction(final AxisDirection axisDirection, final Axis axis) { ++ this.axis = axis; ++ this.axisDirection = axisDirection; ++ } ++ ++ public AxisDirection getAxisDirection() { ++ return this.axisDirection; ++ } ++ ++ public Axis getAxis() { ++ return this.axis; ++ } ++ ++ public static enum AxisDirection { ++ POSITIVE(1), ++ NEGATIVE(-1); ++ ++ private final int step; ++ ++ private AxisDirection(final int step) { ++ this.step = step; ++ } ++ ++ public int getStep() { ++ return this.step; ++ } ++ } ++ ++ public static enum Axis { ++ X, Y, Z; ++ } ++ } ++ ++ static class DataLayer { ++ private final byte[] data; ++ ++ public DataLayer() { ++ this.data = new byte[2048]; ++ } ++ ++ public DataLayer(final byte[] data) { ++ this.data = data; ++ if (data.length != 2048) { ++ throw new IllegalArgumentException("ChunkNibbleArrays should be 2048 bytes not: " + data.length); ++ } ++ } ++ ++ public static DataLayer getOrNull(final byte[] data) { ++ return data == null ? null : new DataLayer(data); ++ } ++ ++ public static DataLayer getOrCreate(final byte[] data) { ++ return data == null ? new DataLayer() : new DataLayer(data); ++ } ++ ++ public int get(final int index) { ++ final byte value = this.data[index >>> 1]; ++ ++ // if we are an even index, we want lower 4 bits ++ // if we are an odd index, we want upper 4 bits ++ return ((value >>> ((index & 1) << 2)) & 0xF); ++ } ++ ++ public int get(final int x, final int y, final int z) { ++ final int index = y << 8 | z << 4 | x; ++ final byte value = this.data[index >>> 1]; ++ ++ // if we are an even index, we want lower 4 bits ++ // if we are an odd index, we want upper 4 bits ++ return ((value >>> ((index & 1) << 2)) & 0xF); ++ } ++ } ++ ++ static final class UpgradeChunk { ++ int sides; ++ ++ final Section[] sections = new Section[16]; ++ final MapType level; ++ final int blockX; ++ final int blockZ; ++ final Int2ObjectLinkedOpenHashMap tileEntities = new Int2ObjectLinkedOpenHashMap<>(16); ++ ++ public UpgradeChunk(final MapType level) { ++ this.level = level; ++ this.blockX = level.getInt("xPos") << 4; ++ this.blockZ = level.getInt("zPos") << 4; ++ ++ final ListType tileEntities = level.getList("TileEntities", ObjectType.MAP); ++ if (tileEntities != null) { ++ for (int i = 0, len = tileEntities.size(); i < len; ++i) { ++ final MapType tileEntity = tileEntities.getMap(i); ++ ++ final int x = (tileEntity.getInt("x") - this.blockX) & 15; ++ final int y = tileEntity.getInt("y"); ++ final int z = (tileEntity.getInt("z") - this.blockZ) & 15; ++ final int index = (y << 8) | (z << 4) | x; ++ if (this.tileEntities.put(index, tileEntity) != null) { ++ LOGGER.warn("In chunk: {}x{} found a duplicate block entity at position (ConverterFlattenChunk): [{}, {}, {}]", this.blockX, this.blockZ, x, y, z); ++ } ++ } ++ } ++ ++ final boolean convertedFromAlphaFormat = level.getBoolean("convertedFromAlphaFormat"); ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType sectionData = sections.getMap(i); ++ final Section section = new Section(sectionData); ++ ++ if (section.y < 0 || section.y > 15) { ++ LOGGER.warn("In chunk: {}x{} found an invalid chunk section y (ConverterFlattenChunk): {}", this.blockX, this.blockZ, section.y); ++ continue; ++ } ++ ++ if (this.sections[section.y] != null) { ++ LOGGER.warn("In chunk: {}x{} found a duplicate chunk section (ConverterFlattenChunk): {}", this.blockX, this.blockZ, section.y); ++ } ++ ++ this.sides = section.upgrade(this.sides); ++ this.sections[section.y] = section; ++ } ++ } ++ ++ for (final Section section : this.sections) { ++ if (section == null) { ++ continue; ++ } ++ ++ final int yIndex = section.y << (8 + 4); ++ ++ for (final Iterator> iterator = section.toFix.int2ObjectEntrySet().fastIterator(); iterator.hasNext();) { ++ final Int2ObjectMap.Entry fixEntry = iterator.next(); ++ final IntIterator positionIterator = fixEntry.getValue().iterator(); ++ switch (fixEntry.getIntKey()) { ++ case 2: { // grass block ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ if (!"minecraft:grass_block".equals(getName(blockState))) { ++ continue; ++ } ++ ++ final String blockAbove = getName(getBlock(relative(position, Direction.UP))); ++ if ("minecraft:snow".equals(blockAbove) || "minecraft:snow_layer".equals(blockAbove)) { ++ this.setBlock(position, SNOWY_GRASS); ++ } ++ } ++ break; ++ } ++ case 3: { // dirt ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ if (!"minecraft:podzol".equals(getName(blockState))) { ++ continue; ++ } ++ ++ final String blockAbove = getName(getBlock(relative(position, Direction.UP))); ++ if ("minecraft:snow".equals(blockAbove) || "minecraft:snow_layer".equals(blockAbove)) { ++ this.setBlock(position, SNOWY_PODZOL); ++ } ++ } ++ break; ++ } ++ case 25: { // note block ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType tile = this.removeBlockEntity(position); ++ if (tile != null) { ++ final String state = Boolean.toString(tile.getBoolean("powered")) + (byte) Math.min(Math.max(tile.getInt("note"), 0), 24); ++ this.setBlock(position, NOTE_BLOCK_MAP.getOrDefault(state, NOTE_BLOCK_MAP.get("false0"))); ++ } ++ } ++ break; ++ } ++ case 26: { // bed ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType tile = this.getBlockEntity(position); ++ ++ if (tile == null) { ++ continue; ++ } ++ ++ final MapType blockState = this.getBlock(position); ++ ++ final int colour = tile.getInt("color"); ++ if (colour != 14 && colour >= 0 && colour < 16) { ++ final String state = getProperty(blockState, "facing") + getProperty(blockState, "occupied") + getProperty(blockState, "part") + colour; ++ ++ final MapType update = BED_BLOCK_MAP.get(state); ++ if (update != null) { ++ this.setBlock(position, update); ++ } ++ } ++ } ++ break; ++ } ++ case 64: // oak door ++ case 71: // iron door ++ case 193: // spruce door ++ case 194: // birch door ++ case 195: // jungle door ++ case 196: // acacia door ++ case 197: { // dark oak door ++ // aka the door updater ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ if (!getName(blockState).endsWith("_door")) { ++ continue; ++ } ++ ++ if (!"lower".equals(getProperty(blockState, "half"))) { ++ continue; ++ } ++ ++ final int positionAbove = relative(position, Direction.UP); ++ final MapType blockStateAbove = this.getBlock(positionAbove); ++ ++ final String name = getName(blockState); ++ if (name.equals(getName(blockStateAbove))) { ++ final String facingBelow = getProperty(blockState, "facing"); ++ final String openBelow = getProperty(blockState, "open"); ++ final String hingeAbove = convertedFromAlphaFormat ? "left" : getProperty(blockStateAbove, "hinge"); ++ final String poweredAbove = convertedFromAlphaFormat ? "false" : getProperty(blockStateAbove, "powered"); ++ ++ this.setBlock(position, DOOR_MAP.get(name + facingBelow + "lower" + hingeAbove + openBelow + poweredAbove)); ++ this.setBlock(positionAbove, DOOR_MAP.get(name + facingBelow + "upper" + hingeAbove + openBelow + poweredAbove)); ++ } ++ } ++ break; ++ } ++ case 86: { // pumpkin ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ ++ // I guess this is some terrible hack to convert carved pumpkins from world gen into ++ // regular pumpkins? ++ ++ if ("minecraft:carved_pumpkin".equals(getName(blockState))) { ++ final String downName = getName(this.getBlock(relative(position, Direction.DOWN))); ++ if ("minecraft:grass_block".equals(downName) || "minecraft:dirt".equals(downName)) { ++ this.setBlock(position, PUMPKIN); ++ } ++ } ++ } ++ break; ++ } ++ case 110: { // mycelium ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ if ("minecraft:mycelium".equals(getName(blockState))) { ++ final String nameAbove = getName(this.getBlock(relative(position, Direction.UP))); ++ if ("minecraft:snow".equals(nameAbove) || "minecraft:snow_layer".equals(nameAbove)) { ++ this.setBlock(position, SNOWY_MYCELIUM); ++ } ++ } ++ } ++ break; ++ } ++ case 140: { // flower pot ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType tile = this.removeBlockEntity(position); ++ if (tile == null) { ++ continue; ++ } ++ ++ final String item; ++ if (tile.hasKey("Item", ObjectType.NUMBER)) { ++ // the item name converter should have migrated to number, however no legacy converter ++ // ever did this. so we can get data with versions above v102 (old worlds, converted prior to DFU) ++ // that didn't convert. so just do it here. ++ item = HelperItemNameV102.getNameFromId(tile.getInt("Item")); ++ } else { ++ item = tile.getString("Item", ""); ++ } ++ ++ final String state = item + tile.getInt("Data"); ++ this.setBlock(position, FLOWER_POT_MAP.getOrDefault(state, FLOWER_POT_MAP.get("minecraft:air0"))); ++ } ++ break; ++ } ++ case 144: { // mob head ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType tile = this.getBlockEntity(position); ++ if (tile == null) { ++ continue; ++ } ++ ++ final String typeString = Integer.toString(tile.getInt("SkullType")); ++ final String facing = getProperty(this.getBlock(position), "facing"); ++ final String state; ++ if (!"up".equals(facing) && !"down".equals(facing)) { ++ state = typeString + facing; ++ } else { ++ state = typeString + tile.getInt("Rot"); ++ } ++ ++ tile.remove("SkullType"); ++ tile.remove("facing"); ++ tile.remove("Rot"); ++ ++ this.setBlock(position, SKULL_MAP.getOrDefault(state, SKULL_MAP.get("0north"))); ++ } ++ break; ++ } ++ case 175: { // sunflower ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType blockState = this.getBlock(position); ++ if (!"upper".equals(getProperty(blockState, "half"))) { ++ continue; ++ } ++ ++ final MapType blockStateBelow = this.getBlock(relative(position, Direction.DOWN)); ++ final String nameBelow = getName(blockStateBelow); ++ switch (nameBelow) { ++ case "minecraft:sunflower": ++ this.setBlock(position, UPPER_SUNFLOWER); ++ break; ++ case "minecraft:lilac": ++ this.setBlock(position, UPPER_LILAC); ++ break; ++ case "minecraft:tall_grass": ++ this.setBlock(position, UPPER_TALL_GRASS); ++ break; ++ case "minecraft:large_fern": ++ this.setBlock(position, UPPER_LARGE_FERN); ++ break; ++ case "minecraft:rose_bush": ++ this.setBlock(position, UPPER_ROSE_BUSH); ++ break; ++ case "minecraft:peony": ++ this.setBlock(position, UPPER_PEONY); ++ break; ++ } ++ } ++ break; ++ } ++ case 176: // free standing banner ++ case 177: { // wall mounted banner ++ while (positionIterator.hasNext()) { ++ final int position = positionIterator.nextInt() | yIndex; ++ final MapType tile = this.getBlockEntity(position); ++ ++ if (tile == null) { ++ continue; ++ } ++ ++ final MapType blockState = this.getBlock(position); ++ ++ final int base = tile.getInt("Base"); ++ if (base != 15 && base >= 0 && base < 16) { ++ final String state = getProperty(blockState, fixEntry.getIntKey() == 176 ? "rotation" : "facing") + "_" + base; ++ final MapType update = BANNER_BLOCK_MAP.get(state); ++ if (update != null) { ++ this.setBlock(position, update); ++ } ++ } ++ } ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ private MapType getBlockEntity(final int index) { ++ return this.tileEntities.get(index); ++ } ++ ++ private MapType removeBlockEntity(final int index) { ++ return this.tileEntities.remove(index); ++ } ++ ++ public static int relative(final int index, final Direction direction) { ++ switch (direction.getAxis()) { ++ case X: ++ int j = (index & 15) + direction.getAxisDirection().getStep(); ++ return j >= 0 && j <= 15 ? index & -16 | j : -1; ++ case Y: ++ int k = (index >> 8) + direction.getAxisDirection().getStep(); ++ return k >= 0 && k <= 255 ? index & 255 | k << 8 : -1; ++ case Z: ++ int l = (index >> 4 & 15) + direction.getAxisDirection().getStep(); ++ return l >= 0 && l <= 15 ? index & -241 | l << 4 : -1; ++ default: ++ return -1; ++ } ++ } ++ ++ private void setBlock(final int index, final MapType blockState) { ++ if (index >= 0 && index <= 65535) { ++ final Section section = this.getSection(index); ++ if (section != null) { ++ section.setBlock(index & 4095, blockState); ++ } ++ } ++ } ++ ++ private Section getSection(final int index) { ++ final int y = index >> 12; ++ return y < this.sections.length ? this.sections[y] : null; ++ } ++ ++ public MapType getBlock(int i) { ++ if (i >= 0 && i <= 65535) { ++ final Section section = this.getSection(i); ++ return section == null ? AIR : section.getBlock(i & 4095); ++ } else { ++ return AIR; ++ } ++ } ++ ++ public MapType writeBackToLevel() { ++ if (this.tileEntities.isEmpty()) { ++ this.level.remove("TileEntities"); ++ } else { ++ final ListType tileEntities = Types.NBT.createEmptyList(); ++ this.tileEntities.values().forEach(tileEntities::addMap); ++ this.level.setList("TileEntities", tileEntities); ++ } ++ ++ final MapType indices = Types.NBT.createEmptyMap(); ++ final ListType sections = Types.NBT.createEmptyList(); ++ for (final Section section : this.sections) { ++ if (section == null) { ++ continue; ++ } ++ ++ sections.addMap(section.writeBackToSection()); ++ indices.setInts(Integer.toString(section.y), Arrays.copyOf(section.update.elements(), section.update.size())); ++ } ++ ++ this.level.setList("Sections", sections); ++ ++ final MapType upgradeData = Types.NBT.createEmptyMap(); ++ upgradeData.setByte("Sides", (byte)this.sides); ++ upgradeData.setMap("Indices", indices); ++ ++ this.level.setMap("UpgradeData", upgradeData); ++ ++ return this.level; ++ } ++ } ++ ++ static class Section { ++ final Palette palette = new Palette(); ++ ++ static final class Palette extends Reference2IntOpenHashMap { ++ ++ final ListType paletteStates = Types.NBT.createEmptyList(); ++ ++ private int find(final MapType k) { ++ if (((k) == (null))) ++ return containsNullKey ? n : -(n + 1); ++ MapType curr; ++ final Object[] key = this.key; ++ int pos; ++ // The starting point. ++ if (((curr = (MapType)key[pos = (it.unimi.dsi.fastutil.HashCommon.mix(System.identityHashCode(k))) & mask]) == (null))) ++ return -(pos + 1); ++ if (((k) == (curr))) ++ return pos; ++ // There's always an unused entry. ++ while (true) { ++ if (((curr = (MapType)key[pos = (pos + 1) & mask]) == (null))) ++ return -(pos + 1); ++ if (((k) == (curr))) ++ return pos; ++ } ++ } ++ ++ private void insert(final int pos, final MapType k, final int v) { ++ if (pos == n) ++ containsNullKey = true; ++ ((Object[])key)[pos] = k; ++ value[pos] = v; ++ if (size++ >= maxFill) ++ rehash(arraySize(size + 1, f)); ++ } ++ ++ private MapType[] byId = new MapType[4]; ++ private MapType last = null; ++ ++ public int getOrCreateId(final MapType k) { ++ if (k == this.last) { ++ return this.size - 1; ++ } ++ final int pos = find(k); ++ if (pos >= 0) { ++ return this.value[pos]; ++ } ++ ++ final int insert = this.size; ++ MapType inPalette = k; ++ ++ if ("%%FILTER_ME%%".equals(getName(k))) { ++ inPalette = AIR; ++ } ++ ++ if (insert >= this.byId.length) { ++ this.byId = Arrays.copyOf(this.byId, this.byId.length * 2); ++ this.byId[insert] = k; ++ } else { ++ this.byId[insert] = k; ++ } ++ this.paletteStates.addMap(inPalette); ++ ++ this.last = k; ++ ++ this.insert(-pos - 1, k, insert); ++ ++ return insert; ++ } ++ ++ } ++ ++ final MapType section; ++ final boolean hasData; ++ final Int2ObjectLinkedOpenHashMap toFix = new Int2ObjectLinkedOpenHashMap<>(); ++ final IntArrayList update = new IntArrayList(); ++ final int y; ++ final int[] buffer = new int[4096]; ++ ++ public Section(final MapType section) { ++ this.section = section; ++ this.y = section.getInt("Y"); ++ this.hasData = section.hasKey("Blocks", ObjectType.BYTE_ARRAY); ++ } ++ ++ public MapType getBlock(final int index) { ++ if (index >= 0 && index <= 4095) { ++ final MapType state = this.palette.byId[this.buffer[index]]; ++ return state == null ? AIR : state; ++ } else { ++ return AIR; ++ } ++ } ++ ++ public void setBlock(final int index, final MapType blockState) { ++ this.buffer[index] = this.palette.getOrCreateId(blockState); ++ } ++ ++ public int upgrade(int sides) { ++ if (!this.hasData) { ++ return sides; ++ } ++ ++ final byte[] blocks = this.section.getBytes("Blocks"); ++ final DataLayer data = DataLayer.getOrNull(this.section.getBytes("Data")); ++ final DataLayer add = DataLayer.getOrNull(this.section.getBytes("Add")); ++ ++ this.palette.getOrCreateId(AIR); ++ ++ for (int index = 0; index < 4096; ++index) { ++ final int x = index & 15; ++ final int z = index >> 4 & 15; ++ ++ int blockStateId = (blocks[index] & 255) << 4; ++ if (data != null) { ++ blockStateId |= data.get(index); ++ } ++ if (add != null) { ++ blockStateId |= add.get(index) << 12; ++ } ++ if (IDS_NEEDING_FIX[blockStateId >>> 4]) { ++ this.addFix(blockStateId >>> 4, index); ++ } ++ ++ if (VIRTUAL[blockStateId >>> 4]) { ++ final int additionalSides = getSideMask(x == 0, x == 15, z == 0, z == 15); ++ if (additionalSides == 0) { ++ this.update.add(index); ++ } else { ++ sides |= additionalSides; ++ } ++ } ++ ++ this.setBlock(index, HelperBlockFlatteningV1450.getNBTForId(blockStateId)); ++ } ++ ++ return sides; ++ } ++ ++ private void addFix(final int block, final int index) { ++ this.toFix.computeIfAbsent(block, (final int keyInMap) -> { ++ return new IntArrayList(); ++ }).add(index); ++ } ++ ++ // Note: modifies the current section and returns it. ++ public MapType writeBackToSection() { ++ if (!this.hasData) { ++ return this.section; ++ } ++ ++ this.section.setList("Palette", this.palette.paletteStates.copy()); // deep copy to ensure palette compound tags are NOT shared ++ ++ final int bitSize = Math.max(4, DataFixUtils.ceillog2(this.palette.size())); ++ final PackedBitStorage packedIds = new PackedBitStorage(bitSize, 4096); ++ ++ for(int index = 0; index < this.buffer.length; ++index) { ++ packedIds.set(index, this.buffer[index]); ++ } ++ ++ this.section.setLongs("BlockStates", packedIds.getRaw()); ++ ++ this.section.remove("Blocks"); ++ this.section.remove("Data"); ++ this.section.remove("Add"); ++ ++ return this.section; ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterRenameStatus.java b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterRenameStatus.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5ba45909b5e60655f83ba96a8dc9ae43077c9fa4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/chunk/ConverterRenameStatus.java +@@ -0,0 +1,32 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.chunk; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import java.util.function.Function; ++ ++public final class ConverterRenameStatus extends DataConverter { ++ ++ private final Function renamer; ++ ++ public ConverterRenameStatus(final int toVersion, final Function renamer) { ++ this(toVersion, 0, renamer); ++ } ++ ++ public ConverterRenameStatus(final int toVersion, final int versionStep, final Function renamer) { ++ super(toVersion, versionStep); ++ this.renamer = renamer; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // Note: DFU technically enforces namespace due to how they wrote their converter, so we will do the same. ++ NamespaceUtil.enforceForPath(data, "Status"); ++ RenameHelper.renameString(data, "Status", this.renamer); ++ ++ NamespaceUtil.enforceForPath(data.getMap("below_zero_retrogen"), "target_status"); ++ RenameHelper.renameString(data.getMap("below_zero_retrogen"), "target_status", this.renamer); ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterAbstractEntityRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterAbstractEntityRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e7e34dd98541f28a9d9abd43c65c0772062e6de2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterAbstractEntityRename.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.entity; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractEntityRename { ++ ++ private ConverterAbstractEntityRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (id == null) { ++ return null; ++ } ++ ++ final String converted = renamer.apply(id); ++ ++ if (converted != null) { ++ data.setString("id", converted); ++ } ++ ++ return null; ++ } ++ }); ++ ConverterAbstractStringValueTypeRename.register(version, subVersion, MCTypeRegistry.ENTITY_NAME, renamer); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityToVariant.java b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityToVariant.java +new file mode 100644 +index 0000000000000000000000000000000000000000..915df90809ca5614393c851da2603920893c4251 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityToVariant.java +@@ -0,0 +1,44 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.entity; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.IntFunction; ++ ++public final class ConverterEntityToVariant extends DataConverter { ++ ++ public final String path; ++ public final IntFunction conversion; ++ ++ public ConverterEntityToVariant(final int toVersion, final String path, final IntFunction conversion) { ++ super(toVersion); ++ this.path = path; ++ this.conversion = conversion; ++ } ++ ++ public ConverterEntityToVariant(final int toVersion, final int versionStep, final String path, final IntFunction conversion) { ++ super(toVersion, versionStep); ++ this.path = path; ++ this.conversion = conversion; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Number value = data.getNumber(this.path); ++ if (value == null) { ++ // nothing to do, DFU does the same ++ return null; ++ } ++ ++ final String converted = this.conversion.apply(value.intValue()); ++ ++ if (converted == null) { ++ throw new NullPointerException("Conversion " + this.conversion + " cannot return null value!"); ++ } ++ ++ // DFU doesn't appear to remove the old field, so why should we? ++ ++ data.setString("variant", converted); ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityVariantRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityVariantRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..81385ba3acb471437eb36cd289ad0548cb59b93b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterEntityVariantRename.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.entity; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.Function; ++ ++public final class ConverterEntityVariantRename extends DataConverter { ++ ++ private final Function renamer; ++ ++ public ConverterEntityVariantRename(final int toVersion, final Function renamer) { ++ super(toVersion); ++ this.renamer = renamer; ++ } ++ ++ public ConverterEntityVariantRename(final int toVersion, final int versionStep, final Function renamer) { ++ super(toVersion, versionStep); ++ this.renamer = renamer; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String variant = data.getString("variant"); ++ ++ if (variant == null) { ++ return null; ++ } ++ ++ final String rename = this.renamer.apply(variant); ++ ++ if (rename != null) { ++ data.setString("variant", rename); ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterFlattenEntity.java b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterFlattenEntity.java +new file mode 100644 +index 0000000000000000000000000000000000000000..610cafc176ca951b49b0db1b9f9386d3c3fa2ce3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/entity/ConverterFlattenEntity.java +@@ -0,0 +1,371 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.entity; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperBlockFlatteningV1450; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class ConverterFlattenEntity extends DataConverter { ++ ++ private static final Map BLOCK_NAME_TO_ID = new HashMap<>(); ++ static { ++ BLOCK_NAME_TO_ID.put("minecraft:air", 0); ++ BLOCK_NAME_TO_ID.put("minecraft:stone", 1); ++ BLOCK_NAME_TO_ID.put("minecraft:grass", 2); ++ BLOCK_NAME_TO_ID.put("minecraft:dirt", 3); ++ BLOCK_NAME_TO_ID.put("minecraft:cobblestone", 4); ++ BLOCK_NAME_TO_ID.put("minecraft:planks", 5); ++ BLOCK_NAME_TO_ID.put("minecraft:sapling", 6); ++ BLOCK_NAME_TO_ID.put("minecraft:bedrock", 7); ++ BLOCK_NAME_TO_ID.put("minecraft:flowing_water", 8); ++ BLOCK_NAME_TO_ID.put("minecraft:water", 9); ++ BLOCK_NAME_TO_ID.put("minecraft:flowing_lava", 10); ++ BLOCK_NAME_TO_ID.put("minecraft:lava", 11); ++ BLOCK_NAME_TO_ID.put("minecraft:sand", 12); ++ BLOCK_NAME_TO_ID.put("minecraft:gravel", 13); ++ BLOCK_NAME_TO_ID.put("minecraft:gold_ore", 14); ++ BLOCK_NAME_TO_ID.put("minecraft:iron_ore", 15); ++ BLOCK_NAME_TO_ID.put("minecraft:coal_ore", 16); ++ BLOCK_NAME_TO_ID.put("minecraft:log", 17); ++ BLOCK_NAME_TO_ID.put("minecraft:leaves", 18); ++ BLOCK_NAME_TO_ID.put("minecraft:sponge", 19); ++ BLOCK_NAME_TO_ID.put("minecraft:glass", 20); ++ BLOCK_NAME_TO_ID.put("minecraft:lapis_ore", 21); ++ BLOCK_NAME_TO_ID.put("minecraft:lapis_block", 22); ++ BLOCK_NAME_TO_ID.put("minecraft:dispenser", 23); ++ BLOCK_NAME_TO_ID.put("minecraft:sandstone", 24); ++ BLOCK_NAME_TO_ID.put("minecraft:noteblock", 25); ++ BLOCK_NAME_TO_ID.put("minecraft:bed", 26); ++ BLOCK_NAME_TO_ID.put("minecraft:golden_rail", 27); ++ BLOCK_NAME_TO_ID.put("minecraft:detector_rail", 28); ++ BLOCK_NAME_TO_ID.put("minecraft:sticky_piston", 29); ++ BLOCK_NAME_TO_ID.put("minecraft:web", 30); ++ BLOCK_NAME_TO_ID.put("minecraft:tallgrass", 31); ++ BLOCK_NAME_TO_ID.put("minecraft:deadbush", 32); ++ BLOCK_NAME_TO_ID.put("minecraft:piston", 33); ++ BLOCK_NAME_TO_ID.put("minecraft:piston_head", 34); ++ BLOCK_NAME_TO_ID.put("minecraft:wool", 35); ++ BLOCK_NAME_TO_ID.put("minecraft:piston_extension", 36); ++ BLOCK_NAME_TO_ID.put("minecraft:yellow_flower", 37); ++ BLOCK_NAME_TO_ID.put("minecraft:red_flower", 38); ++ BLOCK_NAME_TO_ID.put("minecraft:brown_mushroom", 39); ++ BLOCK_NAME_TO_ID.put("minecraft:red_mushroom", 40); ++ BLOCK_NAME_TO_ID.put("minecraft:gold_block", 41); ++ BLOCK_NAME_TO_ID.put("minecraft:iron_block", 42); ++ BLOCK_NAME_TO_ID.put("minecraft:double_stone_slab", 43); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_slab", 44); ++ BLOCK_NAME_TO_ID.put("minecraft:brick_block", 45); ++ BLOCK_NAME_TO_ID.put("minecraft:tnt", 46); ++ BLOCK_NAME_TO_ID.put("minecraft:bookshelf", 47); ++ BLOCK_NAME_TO_ID.put("minecraft:mossy_cobblestone", 48); ++ BLOCK_NAME_TO_ID.put("minecraft:obsidian", 49); ++ BLOCK_NAME_TO_ID.put("minecraft:torch", 50); ++ BLOCK_NAME_TO_ID.put("minecraft:fire", 51); ++ BLOCK_NAME_TO_ID.put("minecraft:mob_spawner", 52); ++ BLOCK_NAME_TO_ID.put("minecraft:oak_stairs", 53); ++ BLOCK_NAME_TO_ID.put("minecraft:chest", 54); ++ BLOCK_NAME_TO_ID.put("minecraft:redstone_wire", 55); ++ BLOCK_NAME_TO_ID.put("minecraft:diamond_ore", 56); ++ BLOCK_NAME_TO_ID.put("minecraft:diamond_block", 57); ++ BLOCK_NAME_TO_ID.put("minecraft:crafting_table", 58); ++ BLOCK_NAME_TO_ID.put("minecraft:wheat", 59); ++ BLOCK_NAME_TO_ID.put("minecraft:farmland", 60); ++ BLOCK_NAME_TO_ID.put("minecraft:furnace", 61); ++ BLOCK_NAME_TO_ID.put("minecraft:lit_furnace", 62); ++ BLOCK_NAME_TO_ID.put("minecraft:standing_sign", 63); ++ BLOCK_NAME_TO_ID.put("minecraft:wooden_door", 64); ++ BLOCK_NAME_TO_ID.put("minecraft:ladder", 65); ++ BLOCK_NAME_TO_ID.put("minecraft:rail", 66); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_stairs", 67); ++ BLOCK_NAME_TO_ID.put("minecraft:wall_sign", 68); ++ BLOCK_NAME_TO_ID.put("minecraft:lever", 69); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_pressure_plate", 70); ++ BLOCK_NAME_TO_ID.put("minecraft:iron_door", 71); ++ BLOCK_NAME_TO_ID.put("minecraft:wooden_pressure_plate", 72); ++ BLOCK_NAME_TO_ID.put("minecraft:redstone_ore", 73); ++ BLOCK_NAME_TO_ID.put("minecraft:lit_redstone_ore", 74); ++ BLOCK_NAME_TO_ID.put("minecraft:unlit_redstone_torch", 75); ++ BLOCK_NAME_TO_ID.put("minecraft:redstone_torch", 76); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_button", 77); ++ BLOCK_NAME_TO_ID.put("minecraft:snow_layer", 78); ++ BLOCK_NAME_TO_ID.put("minecraft:ice", 79); ++ BLOCK_NAME_TO_ID.put("minecraft:snow", 80); ++ BLOCK_NAME_TO_ID.put("minecraft:cactus", 81); ++ BLOCK_NAME_TO_ID.put("minecraft:clay", 82); ++ BLOCK_NAME_TO_ID.put("minecraft:reeds", 83); ++ BLOCK_NAME_TO_ID.put("minecraft:jukebox", 84); ++ BLOCK_NAME_TO_ID.put("minecraft:fence", 85); ++ BLOCK_NAME_TO_ID.put("minecraft:pumpkin", 86); ++ BLOCK_NAME_TO_ID.put("minecraft:netherrack", 87); ++ BLOCK_NAME_TO_ID.put("minecraft:soul_sand", 88); ++ BLOCK_NAME_TO_ID.put("minecraft:glowstone", 89); ++ BLOCK_NAME_TO_ID.put("minecraft:portal", 90); ++ BLOCK_NAME_TO_ID.put("minecraft:lit_pumpkin", 91); ++ BLOCK_NAME_TO_ID.put("minecraft:cake", 92); ++ BLOCK_NAME_TO_ID.put("minecraft:unpowered_repeater", 93); ++ BLOCK_NAME_TO_ID.put("minecraft:powered_repeater", 94); ++ BLOCK_NAME_TO_ID.put("minecraft:stained_glass", 95); ++ BLOCK_NAME_TO_ID.put("minecraft:trapdoor", 96); ++ BLOCK_NAME_TO_ID.put("minecraft:monster_egg", 97); ++ BLOCK_NAME_TO_ID.put("minecraft:stonebrick", 98); ++ BLOCK_NAME_TO_ID.put("minecraft:brown_mushroom_block", 99); ++ BLOCK_NAME_TO_ID.put("minecraft:red_mushroom_block", 100); ++ BLOCK_NAME_TO_ID.put("minecraft:iron_bars", 101); ++ BLOCK_NAME_TO_ID.put("minecraft:glass_pane", 102); ++ BLOCK_NAME_TO_ID.put("minecraft:melon_block", 103); ++ BLOCK_NAME_TO_ID.put("minecraft:pumpkin_stem", 104); ++ BLOCK_NAME_TO_ID.put("minecraft:melon_stem", 105); ++ BLOCK_NAME_TO_ID.put("minecraft:vine", 106); ++ BLOCK_NAME_TO_ID.put("minecraft:fence_gate", 107); ++ BLOCK_NAME_TO_ID.put("minecraft:brick_stairs", 108); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_brick_stairs", 109); ++ BLOCK_NAME_TO_ID.put("minecraft:mycelium", 110); ++ BLOCK_NAME_TO_ID.put("minecraft:waterlily", 111); ++ BLOCK_NAME_TO_ID.put("minecraft:nether_brick", 112); ++ BLOCK_NAME_TO_ID.put("minecraft:nether_brick_fence", 113); ++ BLOCK_NAME_TO_ID.put("minecraft:nether_brick_stairs", 114); ++ BLOCK_NAME_TO_ID.put("minecraft:nether_wart", 115); ++ BLOCK_NAME_TO_ID.put("minecraft:enchanting_table", 116); ++ BLOCK_NAME_TO_ID.put("minecraft:brewing_stand", 117); ++ BLOCK_NAME_TO_ID.put("minecraft:cauldron", 118); ++ BLOCK_NAME_TO_ID.put("minecraft:end_portal", 119); ++ BLOCK_NAME_TO_ID.put("minecraft:end_portal_frame", 120); ++ BLOCK_NAME_TO_ID.put("minecraft:end_stone", 121); ++ BLOCK_NAME_TO_ID.put("minecraft:dragon_egg", 122); ++ BLOCK_NAME_TO_ID.put("minecraft:redstone_lamp", 123); ++ BLOCK_NAME_TO_ID.put("minecraft:lit_redstone_lamp", 124); ++ BLOCK_NAME_TO_ID.put("minecraft:double_wooden_slab", 125); ++ BLOCK_NAME_TO_ID.put("minecraft:wooden_slab", 126); ++ BLOCK_NAME_TO_ID.put("minecraft:cocoa", 127); ++ BLOCK_NAME_TO_ID.put("minecraft:sandstone_stairs", 128); ++ BLOCK_NAME_TO_ID.put("minecraft:emerald_ore", 129); ++ BLOCK_NAME_TO_ID.put("minecraft:ender_chest", 130); ++ BLOCK_NAME_TO_ID.put("minecraft:tripwire_hook", 131); ++ BLOCK_NAME_TO_ID.put("minecraft:tripwire", 132); ++ BLOCK_NAME_TO_ID.put("minecraft:emerald_block", 133); ++ BLOCK_NAME_TO_ID.put("minecraft:spruce_stairs", 134); ++ BLOCK_NAME_TO_ID.put("minecraft:birch_stairs", 135); ++ BLOCK_NAME_TO_ID.put("minecraft:jungle_stairs", 136); ++ BLOCK_NAME_TO_ID.put("minecraft:command_block", 137); ++ BLOCK_NAME_TO_ID.put("minecraft:beacon", 138); ++ BLOCK_NAME_TO_ID.put("minecraft:cobblestone_wall", 139); ++ BLOCK_NAME_TO_ID.put("minecraft:flower_pot", 140); ++ BLOCK_NAME_TO_ID.put("minecraft:carrots", 141); ++ BLOCK_NAME_TO_ID.put("minecraft:potatoes", 142); ++ BLOCK_NAME_TO_ID.put("minecraft:wooden_button", 143); ++ BLOCK_NAME_TO_ID.put("minecraft:skull", 144); ++ BLOCK_NAME_TO_ID.put("minecraft:anvil", 145); ++ BLOCK_NAME_TO_ID.put("minecraft:trapped_chest", 146); ++ BLOCK_NAME_TO_ID.put("minecraft:light_weighted_pressure_plate", 147); ++ BLOCK_NAME_TO_ID.put("minecraft:heavy_weighted_pressure_plate", 148); ++ BLOCK_NAME_TO_ID.put("minecraft:unpowered_comparator", 149); ++ BLOCK_NAME_TO_ID.put("minecraft:powered_comparator", 150); ++ BLOCK_NAME_TO_ID.put("minecraft:daylight_detector", 151); ++ BLOCK_NAME_TO_ID.put("minecraft:redstone_block", 152); ++ BLOCK_NAME_TO_ID.put("minecraft:quartz_ore", 153); ++ BLOCK_NAME_TO_ID.put("minecraft:hopper", 154); ++ BLOCK_NAME_TO_ID.put("minecraft:quartz_block", 155); ++ BLOCK_NAME_TO_ID.put("minecraft:quartz_stairs", 156); ++ BLOCK_NAME_TO_ID.put("minecraft:activator_rail", 157); ++ BLOCK_NAME_TO_ID.put("minecraft:dropper", 158); ++ BLOCK_NAME_TO_ID.put("minecraft:stained_hardened_clay", 159); ++ BLOCK_NAME_TO_ID.put("minecraft:stained_glass_pane", 160); ++ BLOCK_NAME_TO_ID.put("minecraft:leaves2", 161); ++ BLOCK_NAME_TO_ID.put("minecraft:log2", 162); ++ BLOCK_NAME_TO_ID.put("minecraft:acacia_stairs", 163); ++ BLOCK_NAME_TO_ID.put("minecraft:dark_oak_stairs", 164); ++ BLOCK_NAME_TO_ID.put("minecraft:slime", 165); ++ BLOCK_NAME_TO_ID.put("minecraft:barrier", 166); ++ BLOCK_NAME_TO_ID.put("minecraft:iron_trapdoor", 167); ++ BLOCK_NAME_TO_ID.put("minecraft:prismarine", 168); ++ BLOCK_NAME_TO_ID.put("minecraft:sea_lantern", 169); ++ BLOCK_NAME_TO_ID.put("minecraft:hay_block", 170); ++ BLOCK_NAME_TO_ID.put("minecraft:carpet", 171); ++ BLOCK_NAME_TO_ID.put("minecraft:hardened_clay", 172); ++ BLOCK_NAME_TO_ID.put("minecraft:coal_block", 173); ++ BLOCK_NAME_TO_ID.put("minecraft:packed_ice", 174); ++ BLOCK_NAME_TO_ID.put("minecraft:double_plant", 175); ++ BLOCK_NAME_TO_ID.put("minecraft:standing_banner", 176); ++ BLOCK_NAME_TO_ID.put("minecraft:wall_banner", 177); ++ BLOCK_NAME_TO_ID.put("minecraft:daylight_detector_inverted", 178); ++ BLOCK_NAME_TO_ID.put("minecraft:red_sandstone", 179); ++ BLOCK_NAME_TO_ID.put("minecraft:red_sandstone_stairs", 180); ++ BLOCK_NAME_TO_ID.put("minecraft:double_stone_slab2", 181); ++ BLOCK_NAME_TO_ID.put("minecraft:stone_slab2", 182); ++ BLOCK_NAME_TO_ID.put("minecraft:spruce_fence_gate", 183); ++ BLOCK_NAME_TO_ID.put("minecraft:birch_fence_gate", 184); ++ BLOCK_NAME_TO_ID.put("minecraft:jungle_fence_gate", 185); ++ BLOCK_NAME_TO_ID.put("minecraft:dark_oak_fence_gate", 186); ++ BLOCK_NAME_TO_ID.put("minecraft:acacia_fence_gate", 187); ++ BLOCK_NAME_TO_ID.put("minecraft:spruce_fence", 188); ++ BLOCK_NAME_TO_ID.put("minecraft:birch_fence", 189); ++ BLOCK_NAME_TO_ID.put("minecraft:jungle_fence", 190); ++ BLOCK_NAME_TO_ID.put("minecraft:dark_oak_fence", 191); ++ BLOCK_NAME_TO_ID.put("minecraft:acacia_fence", 192); ++ BLOCK_NAME_TO_ID.put("minecraft:spruce_door", 193); ++ BLOCK_NAME_TO_ID.put("minecraft:birch_door", 194); ++ BLOCK_NAME_TO_ID.put("minecraft:jungle_door", 195); ++ BLOCK_NAME_TO_ID.put("minecraft:acacia_door", 196); ++ BLOCK_NAME_TO_ID.put("minecraft:dark_oak_door", 197); ++ BLOCK_NAME_TO_ID.put("minecraft:end_rod", 198); ++ BLOCK_NAME_TO_ID.put("minecraft:chorus_plant", 199); ++ BLOCK_NAME_TO_ID.put("minecraft:chorus_flower", 200); ++ BLOCK_NAME_TO_ID.put("minecraft:purpur_block", 201); ++ BLOCK_NAME_TO_ID.put("minecraft:purpur_pillar", 202); ++ BLOCK_NAME_TO_ID.put("minecraft:purpur_stairs", 203); ++ BLOCK_NAME_TO_ID.put("minecraft:purpur_double_slab", 204); ++ BLOCK_NAME_TO_ID.put("minecraft:purpur_slab", 205); ++ BLOCK_NAME_TO_ID.put("minecraft:end_bricks", 206); ++ BLOCK_NAME_TO_ID.put("minecraft:beetroots", 207); ++ BLOCK_NAME_TO_ID.put("minecraft:grass_path", 208); ++ BLOCK_NAME_TO_ID.put("minecraft:end_gateway", 209); ++ BLOCK_NAME_TO_ID.put("minecraft:repeating_command_block", 210); ++ BLOCK_NAME_TO_ID.put("minecraft:chain_command_block", 211); ++ BLOCK_NAME_TO_ID.put("minecraft:frosted_ice", 212); ++ BLOCK_NAME_TO_ID.put("minecraft:magma", 213); ++ BLOCK_NAME_TO_ID.put("minecraft:nether_wart_block", 214); ++ BLOCK_NAME_TO_ID.put("minecraft:red_nether_brick", 215); ++ BLOCK_NAME_TO_ID.put("minecraft:bone_block", 216); ++ BLOCK_NAME_TO_ID.put("minecraft:structure_void", 217); ++ BLOCK_NAME_TO_ID.put("minecraft:observer", 218); ++ BLOCK_NAME_TO_ID.put("minecraft:white_shulker_box", 219); ++ BLOCK_NAME_TO_ID.put("minecraft:orange_shulker_box", 220); ++ BLOCK_NAME_TO_ID.put("minecraft:magenta_shulker_box", 221); ++ BLOCK_NAME_TO_ID.put("minecraft:light_blue_shulker_box", 222); ++ BLOCK_NAME_TO_ID.put("minecraft:yellow_shulker_box", 223); ++ BLOCK_NAME_TO_ID.put("minecraft:lime_shulker_box", 224); ++ BLOCK_NAME_TO_ID.put("minecraft:pink_shulker_box", 225); ++ BLOCK_NAME_TO_ID.put("minecraft:gray_shulker_box", 226); ++ BLOCK_NAME_TO_ID.put("minecraft:silver_shulker_box", 227); ++ BLOCK_NAME_TO_ID.put("minecraft:cyan_shulker_box", 228); ++ BLOCK_NAME_TO_ID.put("minecraft:purple_shulker_box", 229); ++ BLOCK_NAME_TO_ID.put("minecraft:blue_shulker_box", 230); ++ BLOCK_NAME_TO_ID.put("minecraft:brown_shulker_box", 231); ++ BLOCK_NAME_TO_ID.put("minecraft:green_shulker_box", 232); ++ BLOCK_NAME_TO_ID.put("minecraft:red_shulker_box", 233); ++ BLOCK_NAME_TO_ID.put("minecraft:black_shulker_box", 234); ++ BLOCK_NAME_TO_ID.put("minecraft:white_glazed_terracotta", 235); ++ BLOCK_NAME_TO_ID.put("minecraft:orange_glazed_terracotta", 236); ++ BLOCK_NAME_TO_ID.put("minecraft:magenta_glazed_terracotta", 237); ++ BLOCK_NAME_TO_ID.put("minecraft:light_blue_glazed_terracotta", 238); ++ BLOCK_NAME_TO_ID.put("minecraft:yellow_glazed_terracotta", 239); ++ BLOCK_NAME_TO_ID.put("minecraft:lime_glazed_terracotta", 240); ++ BLOCK_NAME_TO_ID.put("minecraft:pink_glazed_terracotta", 241); ++ BLOCK_NAME_TO_ID.put("minecraft:gray_glazed_terracotta", 242); ++ BLOCK_NAME_TO_ID.put("minecraft:silver_glazed_terracotta", 243); ++ BLOCK_NAME_TO_ID.put("minecraft:cyan_glazed_terracotta", 244); ++ BLOCK_NAME_TO_ID.put("minecraft:purple_glazed_terracotta", 245); ++ BLOCK_NAME_TO_ID.put("minecraft:blue_glazed_terracotta", 246); ++ BLOCK_NAME_TO_ID.put("minecraft:brown_glazed_terracotta", 247); ++ BLOCK_NAME_TO_ID.put("minecraft:green_glazed_terracotta", 248); ++ BLOCK_NAME_TO_ID.put("minecraft:red_glazed_terracotta", 249); ++ BLOCK_NAME_TO_ID.put("minecraft:black_glazed_terracotta", 250); ++ BLOCK_NAME_TO_ID.put("minecraft:concrete", 251); ++ BLOCK_NAME_TO_ID.put("minecraft:concrete_powder", 252); ++ BLOCK_NAME_TO_ID.put("minecraft:structure_block", 255); ++ } ++ ++ protected static final int VERSION = MCVersions.V17W47A; ++ ++ protected final String[] paths; ++ ++ public ConverterFlattenEntity(final String... paths) { ++ super(VERSION, 3); ++ this.paths = paths; ++ } ++ ++ private static void register(final String id, final String... paths) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, new ConverterFlattenEntity(paths)); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:falling_block", new DataConverter<>(VERSION, 3) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int blockId; ++ if (data.hasKey("Block")) { ++ final Number id = data.getNumber("Block"); ++ if (id != null) { ++ blockId = id.intValue(); ++ } else { ++ blockId = getBlockId(data.getString("Block")); ++ } ++ } else { ++ final Number tileId = data.getNumber("TileID"); ++ if (tileId != null) { ++ blockId = tileId.intValue(); ++ } else { ++ blockId = data.getByte("Tile") & 255; ++ } ++ } ++ ++ final int blockData = data.getInt("Data") & 15; ++ ++ data.remove("Block"); // from type update ++ data.remove("Data"); ++ data.remove("TileID"); ++ data.remove("Tile"); ++ ++ // key is from type update ++ data.setMap("BlockState", HelperBlockFlatteningV1450.getNBTForId((blockId << 4) | blockData).copy()); // copy to avoid problems with later state datafixers ++ ++ return null; ++ } ++ }); ++ register("minecraft:enderman", "carried", "carriedData", "carriedBlockState"); ++ register("minecraft:arrow", "inTile", "inData", "inBlockState"); ++ register("minecraft:spectral_arrow", "inTile", "inData", "inBlockState"); ++ register("minecraft:egg", "inTile"); ++ register("minecraft:ender_pearl", "inTile"); ++ register("minecraft:fireball", "inTile"); ++ register("minecraft:potion", "inTile"); ++ register("minecraft:small_fireball", "inTile"); ++ register("minecraft:snowball", "inTile"); ++ register("minecraft:wither_skull", "inTile"); ++ register("minecraft:xp_bottle", "inTile"); ++ register("minecraft:commandblock_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:chest_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:furnace_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:tnt_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:hopper_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ register("minecraft:spawner_minecart", "DisplayTile", "DisplayData", "DisplayState"); ++ } ++ ++ public static int getBlockId(final String block) { ++ final Integer ret = BLOCK_NAME_TO_ID.get(block); ++ return ret == null ? 0 : ret.intValue(); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (this.paths.length == 1) { ++ data.remove(this.paths[0]); ++ return null; ++ } ++ final String idPath = this.paths[0]; ++ final String dataPath = this.paths[1]; ++ final String outputStatePath = this.paths[2]; ++ ++ final int blockId; ++ if (data.hasKey(idPath, ObjectType.NUMBER)) { ++ blockId = data.getInt(idPath); ++ } else { ++ blockId = getBlockId(data.getString(idPath)); ++ } ++ ++ final int blockData = data.getInt(dataPath) & 15; ++ ++ data.remove(idPath); // from type update ++ data.remove(dataPath); ++ ++ data.setMap(outputStatePath, HelperBlockFlatteningV1450.getNBTForId((blockId << 4) | blockData).copy()); // copy to avoid problems with later state datafixers ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/AddFlagIfAbsent.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/AddFlagIfAbsent.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3ebc450551fe75bc3d22c8162eda91bd4105b80a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/AddFlagIfAbsent.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class AddFlagIfAbsent extends DataConverter { ++ ++ public final String path; ++ public final boolean dfl; ++ ++ public AddFlagIfAbsent(final int toVersion, final String path, final boolean dfl) { ++ super(toVersion); ++ this.path = path; ++ this.dfl = dfl; ++ } ++ ++ public AddFlagIfAbsent(final int toVersion, final int versionStep, final String path, final boolean dfl) { ++ super(toVersion, versionStep); ++ this.path = path; ++ this.dfl = dfl; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.hasKey(this.path)) { ++ data.setBoolean(this.path, this.dfl); ++ } ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/ConverterAbstractStringValueTypeRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/ConverterAbstractStringValueTypeRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bc79670f47aaa413ea3e96ef6a32e14099ad8a58 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/ConverterAbstractStringValueTypeRename.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCValueType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractStringValueTypeRename { ++ ++ private ConverterAbstractStringValueTypeRename() {} ++ ++ public static void register(final int version, final MCValueType type, final Function renamer) { ++ register(version, 0, type, renamer); ++ } ++ public static void register(final int version, final int subVersion, final MCValueType type, final Function renamer) { ++ type.addConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ final String ret = (data instanceof String) ? renamer.apply((String)data) : null; ++ return ret == data ? null : ret; ++ } ++ }); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/CopyHelper.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/CopyHelper.java +new file mode 100644 +index 0000000000000000000000000000000000000000..549c997463df2d5c9e0d1c29a6df8ba8eeecfce8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/CopyHelper.java +@@ -0,0 +1,79 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class CopyHelper { ++ ++ // sets value at dstPath in dst to a copied value of the value at srcPath in src ++ public static boolean copy(final MapType src, final String srcPath, final MapType dst, final String dstPath) { ++ final Object val = src.getGeneric(srcPath); ++ if (val == null) { ++ dst.remove(dstPath); ++ return false; ++ } ++ ++ dst.setGeneric(dstPath, copyGeneric(val)); ++ return true; ++ } ++ ++ // moves the value at dstPath in dst to srcPath in src ++ public static boolean move(final MapType src, final String srcPath, final MapType dst, final String dstPath) { ++ final Object val = src.getGeneric(srcPath); ++ src.remove(srcPath); ++ if (val == null) { ++ dst.remove(dstPath); ++ return false; ++ } ++ ++ dst.setGeneric(dstPath, val); ++ return true; ++ } ++ ++ public static Number sanitizeNumber(final Number input) { ++ return switch (input) { ++ case Byte b -> b; ++ case Short s -> s; ++ case Integer i -> i; ++ case Long l -> l; ++ case Float f -> f; ++ case Double d -> d; ++ default -> null; ++ }; ++ } ++ ++ public static Object copyGeneric(final Object value) { ++ if (value == null || value instanceof String || value instanceof Boolean) { ++ // immutable ++ return value; ++ } ++ if (value instanceof Number number) { ++ if (sanitizeNumber(number) == null) { ++ throw new IllegalArgumentException("Unknown type: " + value.getClass()); ++ } ++ return number; ++ } ++ ++ if (value instanceof MapType mapType) { ++ return mapType.copy(); ++ } ++ ++ if (value instanceof ListType listType) { ++ return listType.copy(); ++ } ++ ++ if (value.getClass().isArray()) { ++ if (value instanceof byte[] bytes) { ++ return bytes.clone(); ++ } else if (value instanceof short[] shorts) { ++ return shorts.clone(); ++ } else if (value instanceof int[] ints) { ++ return ints.clone(); ++ } else if (value instanceof long[] longs) { ++ return longs.clone(); ++ } // else: fall through to throw ++ } ++ ++ throw new IllegalArgumentException("Unknown type: " + value.getClass()); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperBlockFlatteningV1450.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperBlockFlatteningV1450.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f632da9870305e96d51f7b5abd33749a4a15916d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperBlockFlatteningV1450.java +@@ -0,0 +1,1829 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; ++import net.minecraft.nbt.TagParser; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class HelperBlockFlatteningV1450 { ++ ++ protected static final MapType[] FLATTENED_BY_ID = new MapType[4096]; ++ protected static final MapType[] BLOCK_DEFAULTS = new MapType[4096]; ++ ++ private static final Object2IntOpenHashMap ID_BY_OLD_NBT = new Object2IntOpenHashMap(64, 0.7f) { ++ @Override ++ public int put(final MapType o, final int v) { ++ if (this.containsKey(o)) { ++ throw new RuntimeException("Already contains mapping for " + o); ++ } ++ ++ return super.put(o, v); ++ } ++ }; ++ static { ++ ID_BY_OLD_NBT.defaultReturnValue(-1); ++ } ++ ++ private static final Object2IntOpenHashMap ID_BY_OLD_NAME = new Object2IntOpenHashMap(64, 0.7f) { ++ @Override ++ public int put(final String o, final int v) { ++ if (this.containsKey(o)) { ++ throw new RuntimeException("Already contains mapping for " + o); ++ } ++ ++ return super.put(o, v); ++ } ++ }; ++ static { ++ ID_BY_OLD_NAME.defaultReturnValue(-1); ++ } ++ ++ // map used to ensure that each parsed block state contains no duplicates ++ protected static final Map IDENTITY_ENSURE = new HashMap<>(); ++ ++ public static MapType parseTag(final String blockstate) { ++ try { ++ final MapType ret = new NBTMapType(TagParser.parseCompoundFully(blockstate.replace('\'', '"'))); ++ ++ synchronized (IDENTITY_ENSURE) { ++ final MapType identity = IDENTITY_ENSURE.putIfAbsent(ret, ret); ++ ++ return identity == null ? ret : identity; ++ } ++ ++ } catch (final Exception ex) { ++ throw new RuntimeException("Exception parsing " + blockstate, ex); ++ } ++ } ++ ++ private static void register(final int id, final String flattened, final String... preFlattenings) { ++ final MapType flattenedNBT = parseTag(flattened); ++ if (FLATTENED_BY_ID[id] != null) { ++ throw new RuntimeException("Mapping already exists for id " + id); ++ } ++ FLATTENED_BY_ID[id] = flattenedNBT; ++ ++ // it's important that we register ids from smallest to largest, so that ++ // the default is going to be correct ++ final int block = id >> 4; ++ if (BLOCK_DEFAULTS[block] == null) { ++ BLOCK_DEFAULTS[block] = flattenedNBT; ++ } ++ ++ for (final String preFlattening : preFlattenings) { ++ final MapType preFlatteningNBT = parseTag(preFlattening); ++ final String name = preFlatteningNBT.getString("Name"); ++ if (name == null) { ++ throw new RuntimeException("Name does not exist for pre flattenings for id " + id); ++ } ++ ++ // putIfAbsent so we default to the lowest id, which is going to be the block default ++ ID_BY_OLD_NAME.putIfAbsent(name, id); ++ ID_BY_OLD_NBT.put(preFlatteningNBT, id); ++ } ++ } ++ ++ private static void finalizeMaps() { ++ for(int i = 0; i < FLATTENED_BY_ID.length; ++i) { ++ if (FLATTENED_BY_ID[i] == null) { ++ FLATTENED_BY_ID[i] = BLOCK_DEFAULTS[i >> 4]; ++ } ++ } ++ } ++ ++ public static MapType flattenNBT(final MapType old) { ++ final int id = ID_BY_OLD_NBT.getInt(old); ++ final MapType ret = getNBTForIdRaw(id); ++ ++ return ret == null ? old : ret; ++ } ++ ++ public static String getNewBlockName(final String old) { ++ final int id = ID_BY_OLD_NAME.getInt(old); ++ final MapType ret = getNBTForIdRaw(id); ++ return ret == null ? old : ret.getString("Name"); ++ } ++ ++ public static String getNameForId(final int block) { ++ final MapType nbt = getNBTForIdRaw(block); ++ return nbt == null ? "minecraft:air" : nbt.getString("Name"); ++ } ++ ++ protected static MapType getNBTForIdRaw(final int block) { ++ return block >= 0 && block < FLATTENED_BY_ID.length ? FLATTENED_BY_ID[block] : null; ++ } ++ ++ public static MapType getNBTForId(final int block) { ++ MapType ret = getNBTForIdRaw(block); ++ return ret == null ? FLATTENED_BY_ID[0] : ret; ++ } ++ ++ private HelperBlockFlatteningV1450() {} ++ ++ static { ++ ID_BY_OLD_NBT.defaultReturnValue(-1); ++ register(0, "{Name:'minecraft:air'}", "{Name:'minecraft:air'}"); ++ register(16, "{Name:'minecraft:stone'}", "{Name:'minecraft:stone',Properties:{variant:'stone'}}"); ++ register(17, "{Name:'minecraft:granite'}", "{Name:'minecraft:stone',Properties:{variant:'granite'}}"); ++ register(18, "{Name:'minecraft:polished_granite'}", "{Name:'minecraft:stone',Properties:{variant:'smooth_granite'}}"); ++ register(19, "{Name:'minecraft:diorite'}", "{Name:'minecraft:stone',Properties:{variant:'diorite'}}"); ++ register(20, "{Name:'minecraft:polished_diorite'}", "{Name:'minecraft:stone',Properties:{variant:'smooth_diorite'}}"); ++ register(21, "{Name:'minecraft:andesite'}", "{Name:'minecraft:stone',Properties:{variant:'andesite'}}"); ++ register(22, "{Name:'minecraft:polished_andesite'}", "{Name:'minecraft:stone',Properties:{variant:'smooth_andesite'}}"); ++ register(32, "{Name:'minecraft:grass_block',Properties:{snowy:'false'}}", "{Name:'minecraft:grass',Properties:{snowy:'false'}}", "{Name:'minecraft:grass',Properties:{snowy:'true'}}"); ++ register(48, "{Name:'minecraft:dirt'}", "{Name:'minecraft:dirt',Properties:{snowy:'false',variant:'dirt'}}", "{Name:'minecraft:dirt',Properties:{snowy:'true',variant:'dirt'}}"); ++ register(49, "{Name:'minecraft:coarse_dirt'}", "{Name:'minecraft:dirt',Properties:{snowy:'false',variant:'coarse_dirt'}}", "{Name:'minecraft:dirt',Properties:{snowy:'true',variant:'coarse_dirt'}}"); ++ register(50, "{Name:'minecraft:podzol',Properties:{snowy:'false'}}", "{Name:'minecraft:dirt',Properties:{snowy:'false',variant:'podzol'}}", "{Name:'minecraft:dirt',Properties:{snowy:'true',variant:'podzol'}}"); ++ register(64, "{Name:'minecraft:cobblestone'}", "{Name:'minecraft:cobblestone'}"); ++ register(80, "{Name:'minecraft:oak_planks'}", "{Name:'minecraft:planks',Properties:{variant:'oak'}}"); ++ register(81, "{Name:'minecraft:spruce_planks'}", "{Name:'minecraft:planks',Properties:{variant:'spruce'}}"); ++ register(82, "{Name:'minecraft:birch_planks'}", "{Name:'minecraft:planks',Properties:{variant:'birch'}}"); ++ register(83, "{Name:'minecraft:jungle_planks'}", "{Name:'minecraft:planks',Properties:{variant:'jungle'}}"); ++ register(84, "{Name:'minecraft:acacia_planks'}", "{Name:'minecraft:planks',Properties:{variant:'acacia'}}"); ++ register(85, "{Name:'minecraft:dark_oak_planks'}", "{Name:'minecraft:planks',Properties:{variant:'dark_oak'}}"); ++ register(96, "{Name:'minecraft:oak_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'oak'}}"); ++ register(97, "{Name:'minecraft:spruce_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'spruce'}}"); ++ register(98, "{Name:'minecraft:birch_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'birch'}}"); ++ register(99, "{Name:'minecraft:jungle_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'jungle'}}"); ++ register(100, "{Name:'minecraft:acacia_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'acacia'}}"); ++ register(101, "{Name:'minecraft:dark_oak_sapling',Properties:{stage:'0'}}", "{Name:'minecraft:sapling',Properties:{stage:'0',type:'dark_oak'}}"); ++ register(104, "{Name:'minecraft:oak_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'oak'}}"); ++ register(105, "{Name:'minecraft:spruce_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'spruce'}}"); ++ register(106, "{Name:'minecraft:birch_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'birch'}}"); ++ register(107, "{Name:'minecraft:jungle_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'jungle'}}"); ++ register(108, "{Name:'minecraft:acacia_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'acacia'}}"); ++ register(109, "{Name:'minecraft:dark_oak_sapling',Properties:{stage:'1'}}", "{Name:'minecraft:sapling',Properties:{stage:'1',type:'dark_oak'}}"); ++ register(112, "{Name:'minecraft:bedrock'}", "{Name:'minecraft:bedrock'}"); ++ register(128, "{Name:'minecraft:water',Properties:{level:'0'}}", "{Name:'minecraft:flowing_water',Properties:{level:'0'}}"); ++ register(129, "{Name:'minecraft:water',Properties:{level:'1'}}", "{Name:'minecraft:flowing_water',Properties:{level:'1'}}"); ++ register(130, "{Name:'minecraft:water',Properties:{level:'2'}}", "{Name:'minecraft:flowing_water',Properties:{level:'2'}}"); ++ register(131, "{Name:'minecraft:water',Properties:{level:'3'}}", "{Name:'minecraft:flowing_water',Properties:{level:'3'}}"); ++ register(132, "{Name:'minecraft:water',Properties:{level:'4'}}", "{Name:'minecraft:flowing_water',Properties:{level:'4'}}"); ++ register(133, "{Name:'minecraft:water',Properties:{level:'5'}}", "{Name:'minecraft:flowing_water',Properties:{level:'5'}}"); ++ register(134, "{Name:'minecraft:water',Properties:{level:'6'}}", "{Name:'minecraft:flowing_water',Properties:{level:'6'}}"); ++ register(135, "{Name:'minecraft:water',Properties:{level:'7'}}", "{Name:'minecraft:flowing_water',Properties:{level:'7'}}"); ++ register(136, "{Name:'minecraft:water',Properties:{level:'8'}}", "{Name:'minecraft:flowing_water',Properties:{level:'8'}}"); ++ register(137, "{Name:'minecraft:water',Properties:{level:'9'}}", "{Name:'minecraft:flowing_water',Properties:{level:'9'}}"); ++ register(138, "{Name:'minecraft:water',Properties:{level:'10'}}", "{Name:'minecraft:flowing_water',Properties:{level:'10'}}"); ++ register(139, "{Name:'minecraft:water',Properties:{level:'11'}}", "{Name:'minecraft:flowing_water',Properties:{level:'11'}}"); ++ register(140, "{Name:'minecraft:water',Properties:{level:'12'}}", "{Name:'minecraft:flowing_water',Properties:{level:'12'}}"); ++ register(141, "{Name:'minecraft:water',Properties:{level:'13'}}", "{Name:'minecraft:flowing_water',Properties:{level:'13'}}"); ++ register(142, "{Name:'minecraft:water',Properties:{level:'14'}}", "{Name:'minecraft:flowing_water',Properties:{level:'14'}}"); ++ register(143, "{Name:'minecraft:water',Properties:{level:'15'}}", "{Name:'minecraft:flowing_water',Properties:{level:'15'}}"); ++ register(144, "{Name:'minecraft:water',Properties:{level:'0'}}", "{Name:'minecraft:water',Properties:{level:'0'}}"); ++ register(145, "{Name:'minecraft:water',Properties:{level:'1'}}", "{Name:'minecraft:water',Properties:{level:'1'}}"); ++ register(146, "{Name:'minecraft:water',Properties:{level:'2'}}", "{Name:'minecraft:water',Properties:{level:'2'}}"); ++ register(147, "{Name:'minecraft:water',Properties:{level:'3'}}", "{Name:'minecraft:water',Properties:{level:'3'}}"); ++ register(148, "{Name:'minecraft:water',Properties:{level:'4'}}", "{Name:'minecraft:water',Properties:{level:'4'}}"); ++ register(149, "{Name:'minecraft:water',Properties:{level:'5'}}", "{Name:'minecraft:water',Properties:{level:'5'}}"); ++ register(150, "{Name:'minecraft:water',Properties:{level:'6'}}", "{Name:'minecraft:water',Properties:{level:'6'}}"); ++ register(151, "{Name:'minecraft:water',Properties:{level:'7'}}", "{Name:'minecraft:water',Properties:{level:'7'}}"); ++ register(152, "{Name:'minecraft:water',Properties:{level:'8'}}", "{Name:'minecraft:water',Properties:{level:'8'}}"); ++ register(153, "{Name:'minecraft:water',Properties:{level:'9'}}", "{Name:'minecraft:water',Properties:{level:'9'}}"); ++ register(154, "{Name:'minecraft:water',Properties:{level:'10'}}", "{Name:'minecraft:water',Properties:{level:'10'}}"); ++ register(155, "{Name:'minecraft:water',Properties:{level:'11'}}", "{Name:'minecraft:water',Properties:{level:'11'}}"); ++ register(156, "{Name:'minecraft:water',Properties:{level:'12'}}", "{Name:'minecraft:water',Properties:{level:'12'}}"); ++ register(157, "{Name:'minecraft:water',Properties:{level:'13'}}", "{Name:'minecraft:water',Properties:{level:'13'}}"); ++ register(158, "{Name:'minecraft:water',Properties:{level:'14'}}", "{Name:'minecraft:water',Properties:{level:'14'}}"); ++ register(159, "{Name:'minecraft:water',Properties:{level:'15'}}", "{Name:'minecraft:water',Properties:{level:'15'}}"); ++ register(160, "{Name:'minecraft:lava',Properties:{level:'0'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'0'}}"); ++ register(161, "{Name:'minecraft:lava',Properties:{level:'1'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'1'}}"); ++ register(162, "{Name:'minecraft:lava',Properties:{level:'2'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'2'}}"); ++ register(163, "{Name:'minecraft:lava',Properties:{level:'3'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'3'}}"); ++ register(164, "{Name:'minecraft:lava',Properties:{level:'4'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'4'}}"); ++ register(165, "{Name:'minecraft:lava',Properties:{level:'5'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'5'}}"); ++ register(166, "{Name:'minecraft:lava',Properties:{level:'6'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'6'}}"); ++ register(167, "{Name:'minecraft:lava',Properties:{level:'7'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'7'}}"); ++ register(168, "{Name:'minecraft:lava',Properties:{level:'8'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'8'}}"); ++ register(169, "{Name:'minecraft:lava',Properties:{level:'9'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'9'}}"); ++ register(170, "{Name:'minecraft:lava',Properties:{level:'10'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'10'}}"); ++ register(171, "{Name:'minecraft:lava',Properties:{level:'11'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'11'}}"); ++ register(172, "{Name:'minecraft:lava',Properties:{level:'12'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'12'}}"); ++ register(173, "{Name:'minecraft:lava',Properties:{level:'13'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'13'}}"); ++ register(174, "{Name:'minecraft:lava',Properties:{level:'14'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'14'}}"); ++ register(175, "{Name:'minecraft:lava',Properties:{level:'15'}}", "{Name:'minecraft:flowing_lava',Properties:{level:'15'}}"); ++ register(176, "{Name:'minecraft:lava',Properties:{level:'0'}}", "{Name:'minecraft:lava',Properties:{level:'0'}}"); ++ register(177, "{Name:'minecraft:lava',Properties:{level:'1'}}", "{Name:'minecraft:lava',Properties:{level:'1'}}"); ++ register(178, "{Name:'minecraft:lava',Properties:{level:'2'}}", "{Name:'minecraft:lava',Properties:{level:'2'}}"); ++ register(179, "{Name:'minecraft:lava',Properties:{level:'3'}}", "{Name:'minecraft:lava',Properties:{level:'3'}}"); ++ register(180, "{Name:'minecraft:lava',Properties:{level:'4'}}", "{Name:'minecraft:lava',Properties:{level:'4'}}"); ++ register(181, "{Name:'minecraft:lava',Properties:{level:'5'}}", "{Name:'minecraft:lava',Properties:{level:'5'}}"); ++ register(182, "{Name:'minecraft:lava',Properties:{level:'6'}}", "{Name:'minecraft:lava',Properties:{level:'6'}}"); ++ register(183, "{Name:'minecraft:lava',Properties:{level:'7'}}", "{Name:'minecraft:lava',Properties:{level:'7'}}"); ++ register(184, "{Name:'minecraft:lava',Properties:{level:'8'}}", "{Name:'minecraft:lava',Properties:{level:'8'}}"); ++ register(185, "{Name:'minecraft:lava',Properties:{level:'9'}}", "{Name:'minecraft:lava',Properties:{level:'9'}}"); ++ register(186, "{Name:'minecraft:lava',Properties:{level:'10'}}", "{Name:'minecraft:lava',Properties:{level:'10'}}"); ++ register(187, "{Name:'minecraft:lava',Properties:{level:'11'}}", "{Name:'minecraft:lava',Properties:{level:'11'}}"); ++ register(188, "{Name:'minecraft:lava',Properties:{level:'12'}}", "{Name:'minecraft:lava',Properties:{level:'12'}}"); ++ register(189, "{Name:'minecraft:lava',Properties:{level:'13'}}", "{Name:'minecraft:lava',Properties:{level:'13'}}"); ++ register(190, "{Name:'minecraft:lava',Properties:{level:'14'}}", "{Name:'minecraft:lava',Properties:{level:'14'}}"); ++ register(191, "{Name:'minecraft:lava',Properties:{level:'15'}}", "{Name:'minecraft:lava',Properties:{level:'15'}}"); ++ register(192, "{Name:'minecraft:sand'}", "{Name:'minecraft:sand',Properties:{variant:'sand'}}"); ++ register(193, "{Name:'minecraft:red_sand'}", "{Name:'minecraft:sand',Properties:{variant:'red_sand'}}"); ++ register(208, "{Name:'minecraft:gravel'}", "{Name:'minecraft:gravel'}"); ++ register(224, "{Name:'minecraft:gold_ore'}", "{Name:'minecraft:gold_ore'}"); ++ register(240, "{Name:'minecraft:iron_ore'}", "{Name:'minecraft:iron_ore'}"); ++ register(256, "{Name:'minecraft:coal_ore'}", "{Name:'minecraft:coal_ore'}"); ++ register(272, "{Name:'minecraft:oak_log',Properties:{axis:'y'}}", "{Name:'minecraft:log',Properties:{axis:'y',variant:'oak'}}"); ++ register(273, "{Name:'minecraft:spruce_log',Properties:{axis:'y'}}", "{Name:'minecraft:log',Properties:{axis:'y',variant:'spruce'}}"); ++ register(274, "{Name:'minecraft:birch_log',Properties:{axis:'y'}}", "{Name:'minecraft:log',Properties:{axis:'y',variant:'birch'}}"); ++ register(275, "{Name:'minecraft:jungle_log',Properties:{axis:'y'}}", "{Name:'minecraft:log',Properties:{axis:'y',variant:'jungle'}}"); ++ register(276, "{Name:'minecraft:oak_log',Properties:{axis:'x'}}", "{Name:'minecraft:log',Properties:{axis:'x',variant:'oak'}}"); ++ register(277, "{Name:'minecraft:spruce_log',Properties:{axis:'x'}}", "{Name:'minecraft:log',Properties:{axis:'x',variant:'spruce'}}"); ++ register(278, "{Name:'minecraft:birch_log',Properties:{axis:'x'}}", "{Name:'minecraft:log',Properties:{axis:'x',variant:'birch'}}"); ++ register(279, "{Name:'minecraft:jungle_log',Properties:{axis:'x'}}", "{Name:'minecraft:log',Properties:{axis:'x',variant:'jungle'}}"); ++ register(280, "{Name:'minecraft:oak_log',Properties:{axis:'z'}}", "{Name:'minecraft:log',Properties:{axis:'z',variant:'oak'}}"); ++ register(281, "{Name:'minecraft:spruce_log',Properties:{axis:'z'}}", "{Name:'minecraft:log',Properties:{axis:'z',variant:'spruce'}}"); ++ register(282, "{Name:'minecraft:birch_log',Properties:{axis:'z'}}", "{Name:'minecraft:log',Properties:{axis:'z',variant:'birch'}}"); ++ register(283, "{Name:'minecraft:jungle_log',Properties:{axis:'z'}}", "{Name:'minecraft:log',Properties:{axis:'z',variant:'jungle'}}"); ++ register(284, "{Name:'minecraft:oak_bark'}", "{Name:'minecraft:log',Properties:{axis:'none',variant:'oak'}}"); ++ register(285, "{Name:'minecraft:spruce_bark'}", "{Name:'minecraft:log',Properties:{axis:'none',variant:'spruce'}}"); ++ register(286, "{Name:'minecraft:birch_bark'}", "{Name:'minecraft:log',Properties:{axis:'none',variant:'birch'}}"); ++ register(287, "{Name:'minecraft:jungle_bark'}", "{Name:'minecraft:log',Properties:{axis:'none',variant:'jungle'}}"); ++ register(288, "{Name:'minecraft:oak_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'true',variant:'oak'}}"); ++ register(289, "{Name:'minecraft:spruce_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'true',variant:'spruce'}}"); ++ register(290, "{Name:'minecraft:birch_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'true',variant:'birch'}}"); ++ register(291, "{Name:'minecraft:jungle_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'true',variant:'jungle'}}"); ++ register(292, "{Name:'minecraft:oak_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'false',variant:'oak'}}"); ++ register(293, "{Name:'minecraft:spruce_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'false',variant:'spruce'}}"); ++ register(294, "{Name:'minecraft:birch_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'false',variant:'birch'}}"); ++ register(295, "{Name:'minecraft:jungle_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'false',decayable:'false',variant:'jungle'}}"); ++ register(296, "{Name:'minecraft:oak_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'true',variant:'oak'}}"); ++ register(297, "{Name:'minecraft:spruce_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'true',variant:'spruce'}}"); ++ register(298, "{Name:'minecraft:birch_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'true',variant:'birch'}}"); ++ register(299, "{Name:'minecraft:jungle_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'true',variant:'jungle'}}"); ++ register(300, "{Name:'minecraft:oak_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'false',variant:'oak'}}"); ++ register(301, "{Name:'minecraft:spruce_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'false',variant:'spruce'}}"); ++ register(302, "{Name:'minecraft:birch_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'false',variant:'birch'}}"); ++ register(303, "{Name:'minecraft:jungle_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves',Properties:{check_decay:'true',decayable:'false',variant:'jungle'}}"); ++ register(304, "{Name:'minecraft:sponge'}", "{Name:'minecraft:sponge',Properties:{wet:'false'}}"); ++ register(305, "{Name:'minecraft:wet_sponge'}", "{Name:'minecraft:sponge',Properties:{wet:'true'}}"); ++ register(320, "{Name:'minecraft:glass'}", "{Name:'minecraft:glass'}"); ++ register(336, "{Name:'minecraft:lapis_ore'}", "{Name:'minecraft:lapis_ore'}"); ++ register(352, "{Name:'minecraft:lapis_block'}", "{Name:'minecraft:lapis_block'}"); ++ register(368, "{Name:'minecraft:dispenser',Properties:{facing:'down',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'down',triggered:'false'}}"); ++ register(369, "{Name:'minecraft:dispenser',Properties:{facing:'up',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'up',triggered:'false'}}"); ++ register(370, "{Name:'minecraft:dispenser',Properties:{facing:'north',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'north',triggered:'false'}}"); ++ register(371, "{Name:'minecraft:dispenser',Properties:{facing:'south',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'south',triggered:'false'}}"); ++ register(372, "{Name:'minecraft:dispenser',Properties:{facing:'west',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'west',triggered:'false'}}"); ++ register(373, "{Name:'minecraft:dispenser',Properties:{facing:'east',triggered:'false'}}", "{Name:'minecraft:dispenser',Properties:{facing:'east',triggered:'false'}}"); ++ register(376, "{Name:'minecraft:dispenser',Properties:{facing:'down',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'down',triggered:'true'}}"); ++ register(377, "{Name:'minecraft:dispenser',Properties:{facing:'up',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'up',triggered:'true'}}"); ++ register(378, "{Name:'minecraft:dispenser',Properties:{facing:'north',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'north',triggered:'true'}}"); ++ register(379, "{Name:'minecraft:dispenser',Properties:{facing:'south',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'south',triggered:'true'}}"); ++ register(380, "{Name:'minecraft:dispenser',Properties:{facing:'west',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'west',triggered:'true'}}"); ++ register(381, "{Name:'minecraft:dispenser',Properties:{facing:'east',triggered:'true'}}", "{Name:'minecraft:dispenser',Properties:{facing:'east',triggered:'true'}}"); ++ register(384, "{Name:'minecraft:sandstone'}", "{Name:'minecraft:sandstone',Properties:{type:'sandstone'}}"); ++ register(385, "{Name:'minecraft:chiseled_sandstone'}", "{Name:'minecraft:sandstone',Properties:{type:'chiseled_sandstone'}}"); ++ register(386, "{Name:'minecraft:cut_sandstone'}", "{Name:'minecraft:sandstone',Properties:{type:'smooth_sandstone'}}"); ++ register(400, "{Name:'minecraft:note_block'}", "{Name:'minecraft:noteblock'}"); ++ register(416, "{Name:'minecraft:red_bed',Properties:{facing:'south',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'south',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'south',occupied:'true',part:'foot'}}"); ++ register(417, "{Name:'minecraft:red_bed',Properties:{facing:'west',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'west',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'west',occupied:'true',part:'foot'}}"); ++ register(418, "{Name:'minecraft:red_bed',Properties:{facing:'north',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'north',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'north',occupied:'true',part:'foot'}}"); ++ register(419, "{Name:'minecraft:red_bed',Properties:{facing:'east',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'east',occupied:'false',part:'foot'}}", "{Name:'minecraft:bed',Properties:{facing:'east',occupied:'true',part:'foot'}}"); ++ register(424, "{Name:'minecraft:red_bed',Properties:{facing:'south',occupied:'false',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'south',occupied:'false',part:'head'}}"); ++ register(425, "{Name:'minecraft:red_bed',Properties:{facing:'west',occupied:'false',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'west',occupied:'false',part:'head'}}"); ++ register(426, "{Name:'minecraft:red_bed',Properties:{facing:'north',occupied:'false',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'north',occupied:'false',part:'head'}}"); ++ register(427, "{Name:'minecraft:red_bed',Properties:{facing:'east',occupied:'false',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'east',occupied:'false',part:'head'}}"); ++ register(428, "{Name:'minecraft:red_bed',Properties:{facing:'south',occupied:'true',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'south',occupied:'true',part:'head'}}"); ++ register(429, "{Name:'minecraft:red_bed',Properties:{facing:'west',occupied:'true',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'west',occupied:'true',part:'head'}}"); ++ register(430, "{Name:'minecraft:red_bed',Properties:{facing:'north',occupied:'true',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'north',occupied:'true',part:'head'}}"); ++ register(431, "{Name:'minecraft:red_bed',Properties:{facing:'east',occupied:'true',part:'head'}}", "{Name:'minecraft:bed',Properties:{facing:'east',occupied:'true',part:'head'}}"); ++ register(432, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'north_south'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'north_south'}}"); ++ register(433, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'east_west'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'east_west'}}"); ++ register(434, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'ascending_east'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'ascending_east'}}"); ++ register(435, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'ascending_west'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'ascending_west'}}"); ++ register(436, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'ascending_north'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'ascending_north'}}"); ++ register(437, "{Name:'minecraft:powered_rail',Properties:{powered:'false',shape:'ascending_south'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'false',shape:'ascending_south'}}"); ++ register(440, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'north_south'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'north_south'}}"); ++ register(441, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'east_west'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'east_west'}}"); ++ register(442, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'ascending_east'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'ascending_east'}}"); ++ register(443, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'ascending_west'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'ascending_west'}}"); ++ register(444, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'ascending_north'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'ascending_north'}}"); ++ register(445, "{Name:'minecraft:powered_rail',Properties:{powered:'true',shape:'ascending_south'}}", "{Name:'minecraft:golden_rail',Properties:{powered:'true',shape:'ascending_south'}}"); ++ register(448, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'north_south'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'north_south'}}"); ++ register(449, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'east_west'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'east_west'}}"); ++ register(450, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_east'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_east'}}"); ++ register(451, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_west'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_west'}}"); ++ register(452, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_north'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_north'}}"); ++ register(453, "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_south'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'false',shape:'ascending_south'}}"); ++ register(456, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'north_south'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'north_south'}}"); ++ register(457, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'east_west'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'east_west'}}"); ++ register(458, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_east'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_east'}}"); ++ register(459, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_west'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_west'}}"); ++ register(460, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_north'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_north'}}"); ++ register(461, "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_south'}}", "{Name:'minecraft:detector_rail',Properties:{powered:'true',shape:'ascending_south'}}"); ++ register(464, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'down'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'down'}}"); ++ register(465, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'up'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'up'}}"); ++ register(466, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'north'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'north'}}"); ++ register(467, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'south'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'south'}}"); ++ register(468, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'west'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'west'}}"); ++ register(469, "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'east'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'false',facing:'east'}}"); ++ register(472, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'down'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'down'}}"); ++ register(473, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'up'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'up'}}"); ++ register(474, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'north'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'north'}}"); ++ register(475, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'south'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'south'}}"); ++ register(476, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'west'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'west'}}"); ++ register(477, "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'east'}}", "{Name:'minecraft:sticky_piston',Properties:{extended:'true',facing:'east'}}"); ++ register(480, "{Name:'minecraft:cobweb'}", "{Name:'minecraft:web'}"); ++ register(496, "{Name:'minecraft:dead_bush'}", "{Name:'minecraft:tallgrass',Properties:{type:'dead_bush'}}"); ++ register(497, "{Name:'minecraft:grass'}", "{Name:'minecraft:tallgrass',Properties:{type:'tall_grass'}}"); ++ register(498, "{Name:'minecraft:fern'}", "{Name:'minecraft:tallgrass',Properties:{type:'fern'}}"); ++ register(512, "{Name:'minecraft:dead_bush'}", "{Name:'minecraft:deadbush'}"); ++ register(528, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'down'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'down'}}"); ++ register(529, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'up'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'up'}}"); ++ register(530, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'north'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'north'}}"); ++ register(531, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'south'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'south'}}"); ++ register(532, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'west'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'west'}}"); ++ register(533, "{Name:'minecraft:piston',Properties:{extended:'false',facing:'east'}}", "{Name:'minecraft:piston',Properties:{extended:'false',facing:'east'}}"); ++ register(536, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'down'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'down'}}"); ++ register(537, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'up'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'up'}}"); ++ register(538, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'north'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'north'}}"); ++ register(539, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'south'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'south'}}"); ++ register(540, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'west'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'west'}}"); ++ register(541, "{Name:'minecraft:piston',Properties:{extended:'true',facing:'east'}}", "{Name:'minecraft:piston',Properties:{extended:'true',facing:'east'}}"); ++ register(544, "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'true',type:'normal'}}"); ++ register(545, "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'true',type:'normal'}}"); ++ register(546, "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'true',type:'normal'}}"); ++ register(547, "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'true',type:'normal'}}"); ++ register(548, "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'true',type:'normal'}}"); ++ register(549, "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'false',type:'normal'}}", "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'true',type:'normal'}}"); ++ register(552, "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'down',short:'true',type:'sticky'}}"); ++ register(553, "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'up',short:'true',type:'sticky'}}"); ++ register(554, "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'north',short:'true',type:'sticky'}}"); ++ register(555, "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'south',short:'true',type:'sticky'}}"); ++ register(556, "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'west',short:'true',type:'sticky'}}"); ++ register(557, "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'false',type:'sticky'}}", "{Name:'minecraft:piston_head',Properties:{facing:'east',short:'true',type:'sticky'}}"); ++ register(560, "{Name:'minecraft:white_wool'}", "{Name:'minecraft:wool',Properties:{color:'white'}}"); ++ register(561, "{Name:'minecraft:orange_wool'}", "{Name:'minecraft:wool',Properties:{color:'orange'}}"); ++ register(562, "{Name:'minecraft:magenta_wool'}", "{Name:'minecraft:wool',Properties:{color:'magenta'}}"); ++ register(563, "{Name:'minecraft:light_blue_wool'}", "{Name:'minecraft:wool',Properties:{color:'light_blue'}}"); ++ register(564, "{Name:'minecraft:yellow_wool'}", "{Name:'minecraft:wool',Properties:{color:'yellow'}}"); ++ register(565, "{Name:'minecraft:lime_wool'}", "{Name:'minecraft:wool',Properties:{color:'lime'}}"); ++ register(566, "{Name:'minecraft:pink_wool'}", "{Name:'minecraft:wool',Properties:{color:'pink'}}"); ++ register(567, "{Name:'minecraft:gray_wool'}", "{Name:'minecraft:wool',Properties:{color:'gray'}}"); ++ register(568, "{Name:'minecraft:light_gray_wool'}", "{Name:'minecraft:wool',Properties:{color:'silver'}}"); ++ register(569, "{Name:'minecraft:cyan_wool'}", "{Name:'minecraft:wool',Properties:{color:'cyan'}}"); ++ register(570, "{Name:'minecraft:purple_wool'}", "{Name:'minecraft:wool',Properties:{color:'purple'}}"); ++ register(571, "{Name:'minecraft:blue_wool'}", "{Name:'minecraft:wool',Properties:{color:'blue'}}"); ++ register(572, "{Name:'minecraft:brown_wool'}", "{Name:'minecraft:wool',Properties:{color:'brown'}}"); ++ register(573, "{Name:'minecraft:green_wool'}", "{Name:'minecraft:wool',Properties:{color:'green'}}"); ++ register(574, "{Name:'minecraft:red_wool'}", "{Name:'minecraft:wool',Properties:{color:'red'}}"); ++ register(575, "{Name:'minecraft:black_wool'}", "{Name:'minecraft:wool',Properties:{color:'black'}}"); ++ register(576, "{Name:'minecraft:moving_piston',Properties:{facing:'down',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'down',type:'normal'}}"); ++ register(577, "{Name:'minecraft:moving_piston',Properties:{facing:'up',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'up',type:'normal'}}"); ++ register(578, "{Name:'minecraft:moving_piston',Properties:{facing:'north',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'north',type:'normal'}}"); ++ register(579, "{Name:'minecraft:moving_piston',Properties:{facing:'south',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'south',type:'normal'}}"); ++ register(580, "{Name:'minecraft:moving_piston',Properties:{facing:'west',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'west',type:'normal'}}"); ++ register(581, "{Name:'minecraft:moving_piston',Properties:{facing:'east',type:'normal'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'east',type:'normal'}}"); ++ register(584, "{Name:'minecraft:moving_piston',Properties:{facing:'down',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'down',type:'sticky'}}"); ++ register(585, "{Name:'minecraft:moving_piston',Properties:{facing:'up',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'up',type:'sticky'}}"); ++ register(586, "{Name:'minecraft:moving_piston',Properties:{facing:'north',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'north',type:'sticky'}}"); ++ register(587, "{Name:'minecraft:moving_piston',Properties:{facing:'south',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'south',type:'sticky'}}"); ++ register(588, "{Name:'minecraft:moving_piston',Properties:{facing:'west',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'west',type:'sticky'}}"); ++ register(589, "{Name:'minecraft:moving_piston',Properties:{facing:'east',type:'sticky'}}", "{Name:'minecraft:piston_extension',Properties:{facing:'east',type:'sticky'}}"); ++ register(592, "{Name:'minecraft:dandelion'}", "{Name:'minecraft:yellow_flower',Properties:{type:'dandelion'}}"); ++ register(608, "{Name:'minecraft:poppy'}", "{Name:'minecraft:red_flower',Properties:{type:'poppy'}}"); ++ register(609, "{Name:'minecraft:blue_orchid'}", "{Name:'minecraft:red_flower',Properties:{type:'blue_orchid'}}"); ++ register(610, "{Name:'minecraft:allium'}", "{Name:'minecraft:red_flower',Properties:{type:'allium'}}"); ++ register(611, "{Name:'minecraft:azure_bluet'}", "{Name:'minecraft:red_flower',Properties:{type:'houstonia'}}"); ++ register(612, "{Name:'minecraft:red_tulip'}", "{Name:'minecraft:red_flower',Properties:{type:'red_tulip'}}"); ++ register(613, "{Name:'minecraft:orange_tulip'}", "{Name:'minecraft:red_flower',Properties:{type:'orange_tulip'}}"); ++ register(614, "{Name:'minecraft:white_tulip'}", "{Name:'minecraft:red_flower',Properties:{type:'white_tulip'}}"); ++ register(615, "{Name:'minecraft:pink_tulip'}", "{Name:'minecraft:red_flower',Properties:{type:'pink_tulip'}}"); ++ register(616, "{Name:'minecraft:oxeye_daisy'}", "{Name:'minecraft:red_flower',Properties:{type:'oxeye_daisy'}}"); ++ register(624, "{Name:'minecraft:brown_mushroom'}", "{Name:'minecraft:brown_mushroom'}"); ++ register(640, "{Name:'minecraft:red_mushroom'}", "{Name:'minecraft:red_mushroom'}"); ++ register(656, "{Name:'minecraft:gold_block'}", "{Name:'minecraft:gold_block'}"); ++ register(672, "{Name:'minecraft:iron_block'}", "{Name:'minecraft:iron_block'}"); ++ register(688, "{Name:'minecraft:stone_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'stone'}}"); ++ register(689, "{Name:'minecraft:sandstone_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'sandstone'}}"); ++ register(690, "{Name:'minecraft:petrified_oak_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'wood_old'}}"); ++ register(691, "{Name:'minecraft:cobblestone_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'cobblestone'}}"); ++ register(692, "{Name:'minecraft:brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'brick'}}"); ++ register(693, "{Name:'minecraft:stone_brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'stone_brick'}}"); ++ register(694, "{Name:'minecraft:nether_brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'nether_brick'}}"); ++ register(695, "{Name:'minecraft:quartz_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'false',variant:'quartz'}}"); ++ register(696, "{Name:'minecraft:smooth_stone'}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'stone'}}"); ++ register(697, "{Name:'minecraft:smooth_sandstone'}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'sandstone'}}"); ++ register(698, "{Name:'minecraft:petrified_oak_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'wood_old'}}"); ++ register(699, "{Name:'minecraft:cobblestone_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'cobblestone'}}"); ++ register(700, "{Name:'minecraft:brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'brick'}}"); ++ register(701, "{Name:'minecraft:stone_brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'stone_brick'}}"); ++ register(702, "{Name:'minecraft:nether_brick_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'nether_brick'}}"); ++ register(703, "{Name:'minecraft:smooth_quartz'}", "{Name:'minecraft:double_stone_slab',Properties:{seamless:'true',variant:'quartz'}}"); ++ register(704, "{Name:'minecraft:stone_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'stone'}}"); ++ register(705, "{Name:'minecraft:sandstone_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'sandstone'}}"); ++ register(706, "{Name:'minecraft:petrified_oak_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'wood_old'}}"); ++ register(707, "{Name:'minecraft:cobblestone_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'cobblestone'}}"); ++ register(708, "{Name:'minecraft:brick_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'brick'}}"); ++ register(709, "{Name:'minecraft:stone_brick_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'stone_brick'}}"); ++ register(710, "{Name:'minecraft:nether_brick_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'nether_brick'}}"); ++ register(711, "{Name:'minecraft:quartz_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab',Properties:{half:'bottom',variant:'quartz'}}"); ++ register(712, "{Name:'minecraft:stone_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'stone'}}"); ++ register(713, "{Name:'minecraft:sandstone_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'sandstone'}}"); ++ register(714, "{Name:'minecraft:petrified_oak_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'wood_old'}}"); ++ register(715, "{Name:'minecraft:cobblestone_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'cobblestone'}}"); ++ register(716, "{Name:'minecraft:brick_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'brick'}}"); ++ register(717, "{Name:'minecraft:stone_brick_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'stone_brick'}}"); ++ register(718, "{Name:'minecraft:nether_brick_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'nether_brick'}}"); ++ register(719, "{Name:'minecraft:quartz_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab',Properties:{half:'top',variant:'quartz'}}"); ++ register(720, "{Name:'minecraft:bricks'}", "{Name:'minecraft:brick_block'}"); ++ register(736, "{Name:'minecraft:tnt',Properties:{unstable:'false'}}", "{Name:'minecraft:tnt',Properties:{explode:'false'}}"); ++ register(737, "{Name:'minecraft:tnt',Properties:{unstable:'true'}}", "{Name:'minecraft:tnt',Properties:{explode:'true'}}"); ++ register(752, "{Name:'minecraft:bookshelf'}", "{Name:'minecraft:bookshelf'}"); ++ register(768, "{Name:'minecraft:mossy_cobblestone'}", "{Name:'minecraft:mossy_cobblestone'}"); ++ register(784, "{Name:'minecraft:obsidian'}", "{Name:'minecraft:obsidian'}"); ++ register(801, "{Name:'minecraft:wall_torch',Properties:{facing:'east'}}", "{Name:'minecraft:torch',Properties:{facing:'east'}}"); ++ register(802, "{Name:'minecraft:wall_torch',Properties:{facing:'west'}}", "{Name:'minecraft:torch',Properties:{facing:'west'}}"); ++ register(803, "{Name:'minecraft:wall_torch',Properties:{facing:'south'}}", "{Name:'minecraft:torch',Properties:{facing:'south'}}"); ++ register(804, "{Name:'minecraft:wall_torch',Properties:{facing:'north'}}", "{Name:'minecraft:torch',Properties:{facing:'north'}}"); ++ register(805, "{Name:'minecraft:torch'}", "{Name:'minecraft:torch',Properties:{facing:'up'}}"); ++ register(816, "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'0',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(817, "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'1',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(818, "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'2',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(819, "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'3',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(820, "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'4',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(821, "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'5',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(822, "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'6',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(823, "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'7',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(824, "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'8',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(825, "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'9',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(826, "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'10',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(827, "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'11',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(828, "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'12',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(829, "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'13',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(830, "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'14',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(831, "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:fire',Properties:{age:'15',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(832, "{Name:'minecraft:mob_spawner'}", "{Name:'minecraft:mob_spawner'}"); ++ register(848, "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(849, "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(850, "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(851, "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(852, "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(853, "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(854, "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(855, "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:oak_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(866, "{Name:'minecraft:chest',Properties:{facing:'north',type:'single'}}", "{Name:'minecraft:chest',Properties:{facing:'north'}}"); ++ register(867, "{Name:'minecraft:chest',Properties:{facing:'south',type:'single'}}", "{Name:'minecraft:chest',Properties:{facing:'south'}}"); ++ register(868, "{Name:'minecraft:chest',Properties:{facing:'west',type:'single'}}", "{Name:'minecraft:chest',Properties:{facing:'west'}}"); ++ register(869, "{Name:'minecraft:chest',Properties:{facing:'east',type:'single'}}", "{Name:'minecraft:chest',Properties:{facing:'east'}}"); ++ register(880, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'0',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'0',south:'up',west:'up'}}"); ++ register(881, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'1',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'1',south:'up',west:'up'}}"); ++ register(882, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'2',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'2',south:'up',west:'up'}}"); ++ register(883, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'3',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'3',south:'up',west:'up'}}"); ++ register(884, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'4',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'4',south:'up',west:'up'}}"); ++ register(885, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'5',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'5',south:'up',west:'up'}}"); ++ register(886, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'6',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'6',south:'up',west:'up'}}"); ++ register(887, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'7',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'7',south:'up',west:'up'}}"); ++ register(888, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'8',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'8',south:'up',west:'up'}}"); ++ register(889, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'9',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'9',south:'up',west:'up'}}"); ++ register(890, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'10',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'10',south:'up',west:'up'}}"); ++ register(891, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'11',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'11',south:'up',west:'up'}}"); ++ register(892, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'12',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'12',south:'up',west:'up'}}"); ++ register(893, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'13',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'13',south:'up',west:'up'}}"); ++ register(894, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'14',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'14',south:'up',west:'up'}}"); ++ register(895, "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'none',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'side',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'none',north:'up',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'none',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'side',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'side',north:'up',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'none',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'side',power:'15',south:'up',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'none',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'none',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'none',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'side',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'side',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'side',west:'up'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'up',west:'none'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'up',west:'side'}}", "{Name:'minecraft:redstone_wire',Properties:{east:'up',north:'up',power:'15',south:'up',west:'up'}}"); ++ register(896, "{Name:'minecraft:diamond_ore'}", "{Name:'minecraft:diamond_ore'}"); ++ register(912, "{Name:'minecraft:diamond_block'}", "{Name:'minecraft:diamond_block'}"); ++ register(928, "{Name:'minecraft:crafting_table'}", "{Name:'minecraft:crafting_table'}"); ++ register(944, "{Name:'minecraft:wheat',Properties:{age:'0'}}", "{Name:'minecraft:wheat',Properties:{age:'0'}}"); ++ register(945, "{Name:'minecraft:wheat',Properties:{age:'1'}}", "{Name:'minecraft:wheat',Properties:{age:'1'}}"); ++ register(946, "{Name:'minecraft:wheat',Properties:{age:'2'}}", "{Name:'minecraft:wheat',Properties:{age:'2'}}"); ++ register(947, "{Name:'minecraft:wheat',Properties:{age:'3'}}", "{Name:'minecraft:wheat',Properties:{age:'3'}}"); ++ register(948, "{Name:'minecraft:wheat',Properties:{age:'4'}}", "{Name:'minecraft:wheat',Properties:{age:'4'}}"); ++ register(949, "{Name:'minecraft:wheat',Properties:{age:'5'}}", "{Name:'minecraft:wheat',Properties:{age:'5'}}"); ++ register(950, "{Name:'minecraft:wheat',Properties:{age:'6'}}", "{Name:'minecraft:wheat',Properties:{age:'6'}}"); ++ register(951, "{Name:'minecraft:wheat',Properties:{age:'7'}}", "{Name:'minecraft:wheat',Properties:{age:'7'}}"); ++ register(960, "{Name:'minecraft:farmland',Properties:{moisture:'0'}}", "{Name:'minecraft:farmland',Properties:{moisture:'0'}}"); ++ register(961, "{Name:'minecraft:farmland',Properties:{moisture:'1'}}", "{Name:'minecraft:farmland',Properties:{moisture:'1'}}"); ++ register(962, "{Name:'minecraft:farmland',Properties:{moisture:'2'}}", "{Name:'minecraft:farmland',Properties:{moisture:'2'}}"); ++ register(963, "{Name:'minecraft:farmland',Properties:{moisture:'3'}}", "{Name:'minecraft:farmland',Properties:{moisture:'3'}}"); ++ register(964, "{Name:'minecraft:farmland',Properties:{moisture:'4'}}", "{Name:'minecraft:farmland',Properties:{moisture:'4'}}"); ++ register(965, "{Name:'minecraft:farmland',Properties:{moisture:'5'}}", "{Name:'minecraft:farmland',Properties:{moisture:'5'}}"); ++ register(966, "{Name:'minecraft:farmland',Properties:{moisture:'6'}}", "{Name:'minecraft:farmland',Properties:{moisture:'6'}}"); ++ register(967, "{Name:'minecraft:farmland',Properties:{moisture:'7'}}", "{Name:'minecraft:farmland',Properties:{moisture:'7'}}"); ++ register(978, "{Name:'minecraft:furnace',Properties:{facing:'north',lit:'false'}}", "{Name:'minecraft:furnace',Properties:{facing:'north'}}"); ++ register(979, "{Name:'minecraft:furnace',Properties:{facing:'south',lit:'false'}}", "{Name:'minecraft:furnace',Properties:{facing:'south'}}"); ++ register(980, "{Name:'minecraft:furnace',Properties:{facing:'west',lit:'false'}}", "{Name:'minecraft:furnace',Properties:{facing:'west'}}"); ++ register(981, "{Name:'minecraft:furnace',Properties:{facing:'east',lit:'false'}}", "{Name:'minecraft:furnace',Properties:{facing:'east'}}"); ++ register(994, "{Name:'minecraft:furnace',Properties:{facing:'north',lit:'true'}}", "{Name:'minecraft:lit_furnace',Properties:{facing:'north'}}"); ++ register(995, "{Name:'minecraft:furnace',Properties:{facing:'south',lit:'true'}}", "{Name:'minecraft:lit_furnace',Properties:{facing:'south'}}"); ++ register(996, "{Name:'minecraft:furnace',Properties:{facing:'west',lit:'true'}}", "{Name:'minecraft:lit_furnace',Properties:{facing:'west'}}"); ++ register(997, "{Name:'minecraft:furnace',Properties:{facing:'east',lit:'true'}}", "{Name:'minecraft:lit_furnace',Properties:{facing:'east'}}"); ++ register(1008, "{Name:'minecraft:sign',Properties:{rotation:'0'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'0'}}"); ++ register(1009, "{Name:'minecraft:sign',Properties:{rotation:'1'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'1'}}"); ++ register(1010, "{Name:'minecraft:sign',Properties:{rotation:'2'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'2'}}"); ++ register(1011, "{Name:'minecraft:sign',Properties:{rotation:'3'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'3'}}"); ++ register(1012, "{Name:'minecraft:sign',Properties:{rotation:'4'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'4'}}"); ++ register(1013, "{Name:'minecraft:sign',Properties:{rotation:'5'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'5'}}"); ++ register(1014, "{Name:'minecraft:sign',Properties:{rotation:'6'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'6'}}"); ++ register(1015, "{Name:'minecraft:sign',Properties:{rotation:'7'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'7'}}"); ++ register(1016, "{Name:'minecraft:sign',Properties:{rotation:'8'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'8'}}"); ++ register(1017, "{Name:'minecraft:sign',Properties:{rotation:'9'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'9'}}"); ++ register(1018, "{Name:'minecraft:sign',Properties:{rotation:'10'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'10'}}"); ++ register(1019, "{Name:'minecraft:sign',Properties:{rotation:'11'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'11'}}"); ++ register(1020, "{Name:'minecraft:sign',Properties:{rotation:'12'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'12'}}"); ++ register(1021, "{Name:'minecraft:sign',Properties:{rotation:'13'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'13'}}"); ++ register(1022, "{Name:'minecraft:sign',Properties:{rotation:'14'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'14'}}"); ++ register(1023, "{Name:'minecraft:sign',Properties:{rotation:'15'}}", "{Name:'minecraft:standing_sign',Properties:{rotation:'15'}}"); ++ register(1024, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1025, "{Name:'minecraft:oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1026, "{Name:'minecraft:oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1027, "{Name:'minecraft:oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1028, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1029, "{Name:'minecraft:oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1030, "{Name:'minecraft:oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1031, "{Name:'minecraft:oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1032, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1033, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(1034, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(1035, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:wooden_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(1036, "{Name:'minecraft:oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1037, "{Name:'minecraft:oak_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1038, "{Name:'minecraft:oak_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1039, "{Name:'minecraft:oak_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1042, "{Name:'minecraft:ladder',Properties:{facing:'north'}}", "{Name:'minecraft:ladder',Properties:{facing:'north'}}"); ++ register(1043, "{Name:'minecraft:ladder',Properties:{facing:'south'}}", "{Name:'minecraft:ladder',Properties:{facing:'south'}}"); ++ register(1044, "{Name:'minecraft:ladder',Properties:{facing:'west'}}", "{Name:'minecraft:ladder',Properties:{facing:'west'}}"); ++ register(1045, "{Name:'minecraft:ladder',Properties:{facing:'east'}}", "{Name:'minecraft:ladder',Properties:{facing:'east'}}"); ++ register(1056, "{Name:'minecraft:rail',Properties:{shape:'north_south'}}", "{Name:'minecraft:rail',Properties:{shape:'north_south'}}"); ++ register(1057, "{Name:'minecraft:rail',Properties:{shape:'east_west'}}", "{Name:'minecraft:rail',Properties:{shape:'east_west'}}"); ++ register(1058, "{Name:'minecraft:rail',Properties:{shape:'ascending_east'}}", "{Name:'minecraft:rail',Properties:{shape:'ascending_east'}}"); ++ register(1059, "{Name:'minecraft:rail',Properties:{shape:'ascending_west'}}", "{Name:'minecraft:rail',Properties:{shape:'ascending_west'}}"); ++ register(1060, "{Name:'minecraft:rail',Properties:{shape:'ascending_north'}}", "{Name:'minecraft:rail',Properties:{shape:'ascending_north'}}"); ++ register(1061, "{Name:'minecraft:rail',Properties:{shape:'ascending_south'}}", "{Name:'minecraft:rail',Properties:{shape:'ascending_south'}}"); ++ register(1062, "{Name:'minecraft:rail',Properties:{shape:'south_east'}}", "{Name:'minecraft:rail',Properties:{shape:'south_east'}}"); ++ register(1063, "{Name:'minecraft:rail',Properties:{shape:'south_west'}}", "{Name:'minecraft:rail',Properties:{shape:'south_west'}}"); ++ register(1064, "{Name:'minecraft:rail',Properties:{shape:'north_west'}}", "{Name:'minecraft:rail',Properties:{shape:'north_west'}}"); ++ register(1065, "{Name:'minecraft:rail',Properties:{shape:'north_east'}}", "{Name:'minecraft:rail',Properties:{shape:'north_east'}}"); ++ register(1072, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(1073, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(1074, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(1075, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(1076, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(1077, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(1078, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(1079, "{Name:'minecraft:cobblestone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(1090, "{Name:'minecraft:wall_sign',Properties:{facing:'north'}}", "{Name:'minecraft:wall_sign',Properties:{facing:'north'}}"); ++ register(1091, "{Name:'minecraft:wall_sign',Properties:{facing:'south'}}", "{Name:'minecraft:wall_sign',Properties:{facing:'south'}}"); ++ register(1092, "{Name:'minecraft:wall_sign',Properties:{facing:'west'}}", "{Name:'minecraft:wall_sign',Properties:{facing:'west'}}"); ++ register(1093, "{Name:'minecraft:wall_sign',Properties:{facing:'east'}}", "{Name:'minecraft:wall_sign',Properties:{facing:'east'}}"); ++ register(1104, "{Name:'minecraft:lever',Properties:{face:'ceiling',facing:'west',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'down_x',powered:'false'}}"); ++ register(1105, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'east',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'east',powered:'false'}}"); ++ register(1106, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'west',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'west',powered:'false'}}"); ++ register(1107, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'south',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'south',powered:'false'}}"); ++ register(1108, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'north',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'north',powered:'false'}}"); ++ register(1109, "{Name:'minecraft:lever',Properties:{face:'floor',facing:'north',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'up_z',powered:'false'}}"); ++ register(1110, "{Name:'minecraft:lever',Properties:{face:'floor',facing:'west',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'up_x',powered:'false'}}"); ++ register(1111, "{Name:'minecraft:lever',Properties:{face:'ceiling',facing:'north',powered:'false'}}", "{Name:'minecraft:lever',Properties:{facing:'down_z',powered:'false'}}"); ++ register(1112, "{Name:'minecraft:lever',Properties:{face:'ceiling',facing:'west',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'down_x',powered:'true'}}"); ++ register(1113, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'east',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'east',powered:'true'}}"); ++ register(1114, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'west',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'west',powered:'true'}}"); ++ register(1115, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'south',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'south',powered:'true'}}"); ++ register(1116, "{Name:'minecraft:lever',Properties:{face:'wall',facing:'north',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'north',powered:'true'}}"); ++ register(1117, "{Name:'minecraft:lever',Properties:{face:'floor',facing:'north',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'up_z',powered:'true'}}"); ++ register(1118, "{Name:'minecraft:lever',Properties:{face:'floor',facing:'west',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'up_x',powered:'true'}}"); ++ register(1119, "{Name:'minecraft:lever',Properties:{face:'ceiling',facing:'north',powered:'true'}}", "{Name:'minecraft:lever',Properties:{facing:'down_z',powered:'true'}}"); ++ register(1120, "{Name:'minecraft:stone_pressure_plate',Properties:{powered:'false'}}", "{Name:'minecraft:stone_pressure_plate',Properties:{powered:'false'}}"); ++ register(1121, "{Name:'minecraft:stone_pressure_plate',Properties:{powered:'true'}}", "{Name:'minecraft:stone_pressure_plate',Properties:{powered:'true'}}"); ++ register(1136, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1137, "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1138, "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1139, "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(1140, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1141, "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1142, "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1143, "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(1144, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1145, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(1146, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(1147, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(1148, "{Name:'minecraft:iron_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1149, "{Name:'minecraft:iron_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1150, "{Name:'minecraft:iron_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1151, "{Name:'minecraft:iron_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(1152, "{Name:'minecraft:oak_pressure_plate',Properties:{powered:'false'}}", "{Name:'minecraft:wooden_pressure_plate',Properties:{powered:'false'}}"); ++ register(1153, "{Name:'minecraft:oak_pressure_plate',Properties:{powered:'true'}}", "{Name:'minecraft:wooden_pressure_plate',Properties:{powered:'true'}}"); ++ register(1168, "{Name:'minecraft:redstone_ore',Properties:{lit:'false'}}", "{Name:'minecraft:redstone_ore'}"); ++ register(1184, "{Name:'minecraft:redstone_ore',Properties:{lit:'true'}}", "{Name:'minecraft:lit_redstone_ore'}"); ++ register(1201, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'east',lit:'false'}}", "{Name:'minecraft:unlit_redstone_torch',Properties:{facing:'east'}}"); ++ register(1202, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'west',lit:'false'}}", "{Name:'minecraft:unlit_redstone_torch',Properties:{facing:'west'}}"); ++ register(1203, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'south',lit:'false'}}", "{Name:'minecraft:unlit_redstone_torch',Properties:{facing:'south'}}"); ++ register(1204, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'north',lit:'false'}}", "{Name:'minecraft:unlit_redstone_torch',Properties:{facing:'north'}}"); ++ register(1205, "{Name:'minecraft:redstone_torch',Properties:{lit:'false'}}", "{Name:'minecraft:unlit_redstone_torch',Properties:{facing:'up'}}"); ++ register(1217, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'east',lit:'true'}}", "{Name:'minecraft:redstone_torch',Properties:{facing:'east'}}"); ++ register(1218, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'west',lit:'true'}}", "{Name:'minecraft:redstone_torch',Properties:{facing:'west'}}"); ++ register(1219, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'south',lit:'true'}}", "{Name:'minecraft:redstone_torch',Properties:{facing:'south'}}"); ++ register(1220, "{Name:'minecraft:redstone_wall_torch',Properties:{facing:'north',lit:'true'}}", "{Name:'minecraft:redstone_torch',Properties:{facing:'north'}}"); ++ register(1221, "{Name:'minecraft:redstone_torch',Properties:{lit:'true'}}", "{Name:'minecraft:redstone_torch',Properties:{facing:'up'}}"); ++ register(1232, "{Name:'minecraft:stone_button',Properties:{face:'ceiling',facing:'north',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'down',powered:'false'}}"); ++ register(1233, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'east',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'east',powered:'false'}}"); ++ register(1234, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'west',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'west',powered:'false'}}"); ++ register(1235, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'south',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'south',powered:'false'}}"); ++ register(1236, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'north',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'north',powered:'false'}}"); ++ register(1237, "{Name:'minecraft:stone_button',Properties:{face:'floor',facing:'north',powered:'false'}}", "{Name:'minecraft:stone_button',Properties:{facing:'up',powered:'false'}}"); ++ register(1240, "{Name:'minecraft:stone_button',Properties:{face:'ceiling',facing:'north',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'down',powered:'true'}}"); ++ register(1241, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'east',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'east',powered:'true'}}"); ++ register(1242, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'west',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'west',powered:'true'}}"); ++ register(1243, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'south',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'south',powered:'true'}}"); ++ register(1244, "{Name:'minecraft:stone_button',Properties:{face:'wall',facing:'north',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'north',powered:'true'}}"); ++ register(1245, "{Name:'minecraft:stone_button',Properties:{face:'floor',facing:'north',powered:'true'}}", "{Name:'minecraft:stone_button',Properties:{facing:'up',powered:'true'}}"); ++ register(1248, "{Name:'minecraft:snow',Properties:{layers:'1'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'1'}}"); ++ register(1249, "{Name:'minecraft:snow',Properties:{layers:'2'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'2'}}"); ++ register(1250, "{Name:'minecraft:snow',Properties:{layers:'3'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'3'}}"); ++ register(1251, "{Name:'minecraft:snow',Properties:{layers:'4'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'4'}}"); ++ register(1252, "{Name:'minecraft:snow',Properties:{layers:'5'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'5'}}"); ++ register(1253, "{Name:'minecraft:snow',Properties:{layers:'6'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'6'}}"); ++ register(1254, "{Name:'minecraft:snow',Properties:{layers:'7'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'7'}}"); ++ register(1255, "{Name:'minecraft:snow',Properties:{layers:'8'}}", "{Name:'minecraft:snow_layer',Properties:{layers:'8'}}"); ++ register(1264, "{Name:'minecraft:ice'}", "{Name:'minecraft:ice'}"); ++ register(1280, "{Name:'minecraft:snow_block'}", "{Name:'minecraft:snow'}"); ++ register(1296, "{Name:'minecraft:cactus',Properties:{age:'0'}}", "{Name:'minecraft:cactus',Properties:{age:'0'}}"); ++ register(1297, "{Name:'minecraft:cactus',Properties:{age:'1'}}", "{Name:'minecraft:cactus',Properties:{age:'1'}}"); ++ register(1298, "{Name:'minecraft:cactus',Properties:{age:'2'}}", "{Name:'minecraft:cactus',Properties:{age:'2'}}"); ++ register(1299, "{Name:'minecraft:cactus',Properties:{age:'3'}}", "{Name:'minecraft:cactus',Properties:{age:'3'}}"); ++ register(1300, "{Name:'minecraft:cactus',Properties:{age:'4'}}", "{Name:'minecraft:cactus',Properties:{age:'4'}}"); ++ register(1301, "{Name:'minecraft:cactus',Properties:{age:'5'}}", "{Name:'minecraft:cactus',Properties:{age:'5'}}"); ++ register(1302, "{Name:'minecraft:cactus',Properties:{age:'6'}}", "{Name:'minecraft:cactus',Properties:{age:'6'}}"); ++ register(1303, "{Name:'minecraft:cactus',Properties:{age:'7'}}", "{Name:'minecraft:cactus',Properties:{age:'7'}}"); ++ register(1304, "{Name:'minecraft:cactus',Properties:{age:'8'}}", "{Name:'minecraft:cactus',Properties:{age:'8'}}"); ++ register(1305, "{Name:'minecraft:cactus',Properties:{age:'9'}}", "{Name:'minecraft:cactus',Properties:{age:'9'}}"); ++ register(1306, "{Name:'minecraft:cactus',Properties:{age:'10'}}", "{Name:'minecraft:cactus',Properties:{age:'10'}}"); ++ register(1307, "{Name:'minecraft:cactus',Properties:{age:'11'}}", "{Name:'minecraft:cactus',Properties:{age:'11'}}"); ++ register(1308, "{Name:'minecraft:cactus',Properties:{age:'12'}}", "{Name:'minecraft:cactus',Properties:{age:'12'}}"); ++ register(1309, "{Name:'minecraft:cactus',Properties:{age:'13'}}", "{Name:'minecraft:cactus',Properties:{age:'13'}}"); ++ register(1310, "{Name:'minecraft:cactus',Properties:{age:'14'}}", "{Name:'minecraft:cactus',Properties:{age:'14'}}"); ++ register(1311, "{Name:'minecraft:cactus',Properties:{age:'15'}}", "{Name:'minecraft:cactus',Properties:{age:'15'}}"); ++ register(1312, "{Name:'minecraft:clay'}", "{Name:'minecraft:clay'}"); ++ register(1328, "{Name:'minecraft:sugar_cane',Properties:{age:'0'}}", "{Name:'minecraft:reeds',Properties:{age:'0'}}"); ++ register(1329, "{Name:'minecraft:sugar_cane',Properties:{age:'1'}}", "{Name:'minecraft:reeds',Properties:{age:'1'}}"); ++ register(1330, "{Name:'minecraft:sugar_cane',Properties:{age:'2'}}", "{Name:'minecraft:reeds',Properties:{age:'2'}}"); ++ register(1331, "{Name:'minecraft:sugar_cane',Properties:{age:'3'}}", "{Name:'minecraft:reeds',Properties:{age:'3'}}"); ++ register(1332, "{Name:'minecraft:sugar_cane',Properties:{age:'4'}}", "{Name:'minecraft:reeds',Properties:{age:'4'}}"); ++ register(1333, "{Name:'minecraft:sugar_cane',Properties:{age:'5'}}", "{Name:'minecraft:reeds',Properties:{age:'5'}}"); ++ register(1334, "{Name:'minecraft:sugar_cane',Properties:{age:'6'}}", "{Name:'minecraft:reeds',Properties:{age:'6'}}"); ++ register(1335, "{Name:'minecraft:sugar_cane',Properties:{age:'7'}}", "{Name:'minecraft:reeds',Properties:{age:'7'}}"); ++ register(1336, "{Name:'minecraft:sugar_cane',Properties:{age:'8'}}", "{Name:'minecraft:reeds',Properties:{age:'8'}}"); ++ register(1337, "{Name:'minecraft:sugar_cane',Properties:{age:'9'}}", "{Name:'minecraft:reeds',Properties:{age:'9'}}"); ++ register(1338, "{Name:'minecraft:sugar_cane',Properties:{age:'10'}}", "{Name:'minecraft:reeds',Properties:{age:'10'}}"); ++ register(1339, "{Name:'minecraft:sugar_cane',Properties:{age:'11'}}", "{Name:'minecraft:reeds',Properties:{age:'11'}}"); ++ register(1340, "{Name:'minecraft:sugar_cane',Properties:{age:'12'}}", "{Name:'minecraft:reeds',Properties:{age:'12'}}"); ++ register(1341, "{Name:'minecraft:sugar_cane',Properties:{age:'13'}}", "{Name:'minecraft:reeds',Properties:{age:'13'}}"); ++ register(1342, "{Name:'minecraft:sugar_cane',Properties:{age:'14'}}", "{Name:'minecraft:reeds',Properties:{age:'14'}}"); ++ register(1343, "{Name:'minecraft:sugar_cane',Properties:{age:'15'}}", "{Name:'minecraft:reeds',Properties:{age:'15'}}"); ++ register(1344, "{Name:'minecraft:jukebox',Properties:{has_record:'false'}}", "{Name:'minecraft:jukebox',Properties:{has_record:'false'}}"); ++ register(1345, "{Name:'minecraft:jukebox',Properties:{has_record:'true'}}", "{Name:'minecraft:jukebox',Properties:{has_record:'true'}}"); ++ register(1360, "{Name:'minecraft:oak_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(1376, "{Name:'minecraft:carved_pumpkin',Properties:{facing:'south'}}", "{Name:'minecraft:pumpkin',Properties:{facing:'south'}}"); ++ register(1377, "{Name:'minecraft:carved_pumpkin',Properties:{facing:'west'}}", "{Name:'minecraft:pumpkin',Properties:{facing:'west'}}"); ++ register(1378, "{Name:'minecraft:carved_pumpkin',Properties:{facing:'north'}}", "{Name:'minecraft:pumpkin',Properties:{facing:'north'}}"); ++ register(1379, "{Name:'minecraft:carved_pumpkin',Properties:{facing:'east'}}", "{Name:'minecraft:pumpkin',Properties:{facing:'east'}}"); ++ register(1392, "{Name:'minecraft:netherrack'}", "{Name:'minecraft:netherrack'}"); ++ register(1408, "{Name:'minecraft:soul_sand'}", "{Name:'minecraft:soul_sand'}"); ++ register(1424, "{Name:'minecraft:glowstone'}", "{Name:'minecraft:glowstone'}"); ++ register(1441, "{Name:'minecraft:portal',Properties:{axis:'x'}}", "{Name:'minecraft:portal',Properties:{axis:'x'}}"); ++ register(1442, "{Name:'minecraft:portal',Properties:{axis:'z'}}", "{Name:'minecraft:portal',Properties:{axis:'z'}}"); ++ register(1456, "{Name:'minecraft:jack_o_lantern',Properties:{facing:'south'}}", "{Name:'minecraft:lit_pumpkin',Properties:{facing:'south'}}"); ++ register(1457, "{Name:'minecraft:jack_o_lantern',Properties:{facing:'west'}}", "{Name:'minecraft:lit_pumpkin',Properties:{facing:'west'}}"); ++ register(1458, "{Name:'minecraft:jack_o_lantern',Properties:{facing:'north'}}", "{Name:'minecraft:lit_pumpkin',Properties:{facing:'north'}}"); ++ register(1459, "{Name:'minecraft:jack_o_lantern',Properties:{facing:'east'}}", "{Name:'minecraft:lit_pumpkin',Properties:{facing:'east'}}"); ++ register(1472, "{Name:'minecraft:cake',Properties:{bites:'0'}}", "{Name:'minecraft:cake',Properties:{bites:'0'}}"); ++ register(1473, "{Name:'minecraft:cake',Properties:{bites:'1'}}", "{Name:'minecraft:cake',Properties:{bites:'1'}}"); ++ register(1474, "{Name:'minecraft:cake',Properties:{bites:'2'}}", "{Name:'minecraft:cake',Properties:{bites:'2'}}"); ++ register(1475, "{Name:'minecraft:cake',Properties:{bites:'3'}}", "{Name:'minecraft:cake',Properties:{bites:'3'}}"); ++ register(1476, "{Name:'minecraft:cake',Properties:{bites:'4'}}", "{Name:'minecraft:cake',Properties:{bites:'4'}}"); ++ register(1477, "{Name:'minecraft:cake',Properties:{bites:'5'}}", "{Name:'minecraft:cake',Properties:{bites:'5'}}"); ++ register(1478, "{Name:'minecraft:cake',Properties:{bites:'6'}}", "{Name:'minecraft:cake',Properties:{bites:'6'}}"); ++ register(1488, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'south',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'south',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'south',locked:'true'}}"); ++ register(1489, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'west',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'west',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'west',locked:'true'}}"); ++ register(1490, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'north',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'north',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'north',locked:'true'}}"); ++ register(1491, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'east',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'east',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'1',facing:'east',locked:'true'}}"); ++ register(1492, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'south',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'south',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'south',locked:'true'}}"); ++ register(1493, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'west',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'west',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'west',locked:'true'}}"); ++ register(1494, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'north',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'north',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'north',locked:'true'}}"); ++ register(1495, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'east',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'east',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'2',facing:'east',locked:'true'}}"); ++ register(1496, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'south',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'south',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'south',locked:'true'}}"); ++ register(1497, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'west',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'west',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'west',locked:'true'}}"); ++ register(1498, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'north',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'north',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'north',locked:'true'}}"); ++ register(1499, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'east',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'east',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'3',facing:'east',locked:'true'}}"); ++ register(1500, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'south',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'south',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'south',locked:'true'}}"); ++ register(1501, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'west',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'west',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'west',locked:'true'}}"); ++ register(1502, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'north',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'north',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'north',locked:'true'}}"); ++ register(1503, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'east',locked:'false',powered:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'east',locked:'false'}}", "{Name:'minecraft:unpowered_repeater',Properties:{delay:'4',facing:'east',locked:'true'}}"); ++ register(1504, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'south',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'south',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'south',locked:'true'}}"); ++ register(1505, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'west',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'west',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'west',locked:'true'}}"); ++ register(1506, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'north',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'north',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'north',locked:'true'}}"); ++ register(1507, "{Name:'minecraft:repeater',Properties:{delay:'1',facing:'east',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'east',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'1',facing:'east',locked:'true'}}"); ++ register(1508, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'south',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'south',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'south',locked:'true'}}"); ++ register(1509, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'west',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'west',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'west',locked:'true'}}"); ++ register(1510, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'north',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'north',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'north',locked:'true'}}"); ++ register(1511, "{Name:'minecraft:repeater',Properties:{delay:'2',facing:'east',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'east',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'2',facing:'east',locked:'true'}}"); ++ register(1512, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'south',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'south',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'south',locked:'true'}}"); ++ register(1513, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'west',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'west',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'west',locked:'true'}}"); ++ register(1514, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'north',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'north',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'north',locked:'true'}}"); ++ register(1515, "{Name:'minecraft:repeater',Properties:{delay:'3',facing:'east',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'east',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'3',facing:'east',locked:'true'}}"); ++ register(1516, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'south',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'south',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'south',locked:'true'}}"); ++ register(1517, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'west',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'west',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'west',locked:'true'}}"); ++ register(1518, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'north',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'north',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'north',locked:'true'}}"); ++ register(1519, "{Name:'minecraft:repeater',Properties:{delay:'4',facing:'east',locked:'false',powered:'true'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'east',locked:'false'}}", "{Name:'minecraft:powered_repeater',Properties:{delay:'4',facing:'east',locked:'true'}}"); ++ register(1520, "{Name:'minecraft:white_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'white'}}"); ++ register(1521, "{Name:'minecraft:orange_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'orange'}}"); ++ register(1522, "{Name:'minecraft:magenta_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'magenta'}}"); ++ register(1523, "{Name:'minecraft:light_blue_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'light_blue'}}"); ++ register(1524, "{Name:'minecraft:yellow_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'yellow'}}"); ++ register(1525, "{Name:'minecraft:lime_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'lime'}}"); ++ register(1526, "{Name:'minecraft:pink_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'pink'}}"); ++ register(1527, "{Name:'minecraft:gray_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'gray'}}"); ++ register(1528, "{Name:'minecraft:light_gray_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'silver'}}"); ++ register(1529, "{Name:'minecraft:cyan_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'cyan'}}"); ++ register(1530, "{Name:'minecraft:purple_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'purple'}}"); ++ register(1531, "{Name:'minecraft:blue_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'blue'}}"); ++ register(1532, "{Name:'minecraft:brown_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'brown'}}"); ++ register(1533, "{Name:'minecraft:green_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'green'}}"); ++ register(1534, "{Name:'minecraft:red_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'red'}}"); ++ register(1535, "{Name:'minecraft:black_stained_glass'}", "{Name:'minecraft:stained_glass',Properties:{color:'black'}}"); ++ register(1536, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'north',half:'bottom',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'north',half:'bottom',open:'false'}}"); ++ register(1537, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'south',half:'bottom',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'south',half:'bottom',open:'false'}}"); ++ register(1538, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'west',half:'bottom',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'west',half:'bottom',open:'false'}}"); ++ register(1539, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'east',half:'bottom',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'east',half:'bottom',open:'false'}}"); ++ register(1540, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'north',half:'bottom',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'north',half:'bottom',open:'true'}}"); ++ register(1541, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'south',half:'bottom',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'south',half:'bottom',open:'true'}}"); ++ register(1542, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'west',half:'bottom',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'west',half:'bottom',open:'true'}}"); ++ register(1543, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'east',half:'bottom',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'east',half:'bottom',open:'true'}}"); ++ register(1544, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'north',half:'top',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'north',half:'top',open:'false'}}"); ++ register(1545, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'south',half:'top',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'south',half:'top',open:'false'}}"); ++ register(1546, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'west',half:'top',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'west',half:'top',open:'false'}}"); ++ register(1547, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'east',half:'top',open:'false'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'east',half:'top',open:'false'}}"); ++ register(1548, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'north',half:'top',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'north',half:'top',open:'true'}}"); ++ register(1549, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'south',half:'top',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'south',half:'top',open:'true'}}"); ++ register(1550, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'west',half:'top',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'west',half:'top',open:'true'}}"); ++ register(1551, "{Name:'minecraft:oak_trapdoor',Properties:{facing:'east',half:'top',open:'true'}}", "{Name:'minecraft:trapdoor',Properties:{facing:'east',half:'top',open:'true'}}"); ++ register(1552, "{Name:'minecraft:infested_stone'}", "{Name:'minecraft:monster_egg',Properties:{variant:'stone'}}"); ++ register(1553, "{Name:'minecraft:infested_cobblestone'}", "{Name:'minecraft:monster_egg',Properties:{variant:'cobblestone'}}"); ++ register(1554, "{Name:'minecraft:infested_stone_bricks'}", "{Name:'minecraft:monster_egg',Properties:{variant:'stone_brick'}}"); ++ register(1555, "{Name:'minecraft:infested_mossy_stone_bricks'}", "{Name:'minecraft:monster_egg',Properties:{variant:'mossy_brick'}}"); ++ register(1556, "{Name:'minecraft:infested_cracked_stone_bricks'}", "{Name:'minecraft:monster_egg',Properties:{variant:'cracked_brick'}}"); ++ register(1557, "{Name:'minecraft:infested_chiseled_stone_bricks'}", "{Name:'minecraft:monster_egg',Properties:{variant:'chiseled_brick'}}"); ++ register(1568, "{Name:'minecraft:stone_bricks'}", "{Name:'minecraft:stonebrick',Properties:{variant:'stonebrick'}}"); ++ register(1569, "{Name:'minecraft:mossy_stone_bricks'}", "{Name:'minecraft:stonebrick',Properties:{variant:'mossy_stonebrick'}}"); ++ register(1570, "{Name:'minecraft:cracked_stone_bricks'}", "{Name:'minecraft:stonebrick',Properties:{variant:'cracked_stonebrick'}}"); ++ register(1571, "{Name:'minecraft:chiseled_stone_bricks'}", "{Name:'minecraft:stonebrick',Properties:{variant:'chiseled_stonebrick'}}"); ++ register(1584, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'all_inside'}}"); ++ register(1585, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'true',east:'false',south:'false',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'north_west'}}"); ++ register(1586, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'true',east:'false',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'north'}}"); ++ register(1587, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'true',east:'true',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'north_east'}}"); ++ register(1588, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'west'}}"); ++ register(1589, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'center'}}"); ++ register(1590, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'true',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'east'}}"); ++ register(1591, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'true',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'south_west'}}"); ++ register(1592, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'true',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'south'}}"); ++ register(1593, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'true',south:'true',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'south_east'}}"); ++ register(1594, "{Name:'minecraft:mushroom_stem',Properties:{north:'true',east:'true',south:'true',west:'true',up:'false',down:'false'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'stem'}}"); ++ register(1595, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1596, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1597, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1598, "{Name:'minecraft:brown_mushroom_block',Properties:{north:'true',east:'true',south:'true',west:'true',up:'true',down:'true'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'all_outside'}}"); ++ register(1599, "{Name:'minecraft:mushroom_stem',Properties:{north:'true',east:'true',south:'true',west:'true',up:'true',down:'true'}}", "{Name:'minecraft:brown_mushroom_block',Properties:{variant:'all_stem'}}"); ++ register(1600, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'all_inside'}}"); ++ register(1601, "{Name:'minecraft:red_mushroom_block',Properties:{north:'true',east:'false',south:'false',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'north_west'}}"); ++ register(1602, "{Name:'minecraft:red_mushroom_block',Properties:{north:'true',east:'false',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'north'}}"); ++ register(1603, "{Name:'minecraft:red_mushroom_block',Properties:{north:'true',east:'true',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'north_east'}}"); ++ register(1604, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'west'}}"); ++ register(1605, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'center'}}"); ++ register(1606, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'true',south:'false',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'east'}}"); ++ register(1607, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'true',west:'true',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'south_west'}}"); ++ register(1608, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'true',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'south'}}"); ++ register(1609, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'true',south:'true',west:'false',up:'true',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'south_east'}}"); ++ register(1610, "{Name:'minecraft:mushroom_stem',Properties:{north:'true',east:'true',south:'true',west:'true',up:'false',down:'false'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'stem'}}"); ++ register(1611, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1612, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1613, "{Name:'minecraft:red_mushroom_block',Properties:{north:'false',east:'false',south:'false',west:'false',up:'false',down:'false'}}"); ++ register(1614, "{Name:'minecraft:red_mushroom_block',Properties:{north:'true',east:'true',south:'true',west:'true',up:'true',down:'true'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'all_outside'}}"); ++ register(1615, "{Name:'minecraft:mushroom_stem',Properties:{north:'true',east:'true',south:'true',west:'true',up:'true',down:'true'}}", "{Name:'minecraft:red_mushroom_block',Properties:{variant:'all_stem'}}"); ++ register(1616, "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:iron_bars',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(1632, "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:glass_pane',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(1648, "{Name:'minecraft:melon_block'}", "{Name:'minecraft:melon_block'}"); ++ register(1664, "{Name:'minecraft:pumpkin_stem',Properties:{age:'0'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'0',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'0',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'0',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'0',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'0',facing:'west'}}"); ++ register(1665, "{Name:'minecraft:pumpkin_stem',Properties:{age:'1'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'1',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'1',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'1',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'1',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'1',facing:'west'}}"); ++ register(1666, "{Name:'minecraft:pumpkin_stem',Properties:{age:'2'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'2',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'2',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'2',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'2',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'2',facing:'west'}}"); ++ register(1667, "{Name:'minecraft:pumpkin_stem',Properties:{age:'3'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'3',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'3',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'3',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'3',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'3',facing:'west'}}"); ++ register(1668, "{Name:'minecraft:pumpkin_stem',Properties:{age:'4'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'4',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'4',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'4',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'4',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'4',facing:'west'}}"); ++ register(1669, "{Name:'minecraft:pumpkin_stem',Properties:{age:'5'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'5',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'5',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'5',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'5',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'5',facing:'west'}}"); ++ register(1670, "{Name:'minecraft:pumpkin_stem',Properties:{age:'6'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'6',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'6',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'6',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'6',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'6',facing:'west'}}"); ++ register(1671, "{Name:'minecraft:pumpkin_stem',Properties:{age:'7'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'7',facing:'east'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'7',facing:'north'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'7',facing:'south'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'7',facing:'up'}}", "{Name:'minecraft:pumpkin_stem',Properties:{age:'7',facing:'west'}}"); ++ register(1680, "{Name:'minecraft:melon_stem',Properties:{age:'0'}}", "{Name:'minecraft:melon_stem',Properties:{age:'0',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'0',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'0',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'0',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'0',facing:'west'}}"); ++ register(1681, "{Name:'minecraft:melon_stem',Properties:{age:'1'}}", "{Name:'minecraft:melon_stem',Properties:{age:'1',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'1',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'1',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'1',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'1',facing:'west'}}"); ++ register(1682, "{Name:'minecraft:melon_stem',Properties:{age:'2'}}", "{Name:'minecraft:melon_stem',Properties:{age:'2',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'2',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'2',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'2',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'2',facing:'west'}}"); ++ register(1683, "{Name:'minecraft:melon_stem',Properties:{age:'3'}}", "{Name:'minecraft:melon_stem',Properties:{age:'3',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'3',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'3',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'3',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'3',facing:'west'}}"); ++ register(1684, "{Name:'minecraft:melon_stem',Properties:{age:'4'}}", "{Name:'minecraft:melon_stem',Properties:{age:'4',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'4',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'4',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'4',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'4',facing:'west'}}"); ++ register(1685, "{Name:'minecraft:melon_stem',Properties:{age:'5'}}", "{Name:'minecraft:melon_stem',Properties:{age:'5',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'5',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'5',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'5',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'5',facing:'west'}}"); ++ register(1686, "{Name:'minecraft:melon_stem',Properties:{age:'6'}}", "{Name:'minecraft:melon_stem',Properties:{age:'6',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'6',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'6',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'6',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'6',facing:'west'}}"); ++ register(1687, "{Name:'minecraft:melon_stem',Properties:{age:'7'}}", "{Name:'minecraft:melon_stem',Properties:{age:'7',facing:'east'}}", "{Name:'minecraft:melon_stem',Properties:{age:'7',facing:'north'}}", "{Name:'minecraft:melon_stem',Properties:{age:'7',facing:'south'}}", "{Name:'minecraft:melon_stem',Properties:{age:'7',facing:'up'}}", "{Name:'minecraft:melon_stem',Properties:{age:'7',facing:'west'}}"); ++ register(1696, "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'true',west:'false'}}"); ++ register(1697, "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'true',west:'false'}}"); ++ register(1698, "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'false',up:'true',west:'true'}}"); ++ register(1699, "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'false',south:'true',up:'true',west:'true'}}"); ++ register(1700, "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'true',west:'false'}}"); ++ register(1701, "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'true',west:'false'}}"); ++ register(1702, "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'false',up:'true',west:'true'}}"); ++ register(1703, "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'false',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(1704, "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'true',west:'false'}}"); ++ register(1705, "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'true',west:'false'}}"); ++ register(1706, "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'false',up:'true',west:'true'}}"); ++ register(1707, "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'false',south:'true',up:'true',west:'true'}}"); ++ register(1708, "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'true',west:'false'}}"); ++ register(1709, "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'true',west:'false'}}"); ++ register(1710, "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'false',up:'true',west:'true'}}"); ++ register(1711, "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:vine',Properties:{east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(1712, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(1713, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(1714, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(1715, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(1716, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(1717, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(1718, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(1719, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(1720, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(1721, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(1722, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(1723, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(1724, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(1725, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(1726, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(1727, "{Name:'minecraft:oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(1728, "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(1729, "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(1730, "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(1731, "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(1732, "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(1733, "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(1734, "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(1735, "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(1744, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(1745, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(1746, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(1747, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(1748, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(1749, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(1750, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(1751, "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:stone_brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(1760, "{Name:'minecraft:mycelium',Properties:{snowy:'false'}}", "{Name:'minecraft:mycelium',Properties:{snowy:'false'}}", "{Name:'minecraft:mycelium',Properties:{snowy:'true'}}"); ++ register(1776, "{Name:'minecraft:lily_pad'}", "{Name:'minecraft:waterlily'}"); ++ register(1792, "{Name:'minecraft:nether_bricks'}", "{Name:'minecraft:nether_brick'}"); ++ register(1808, "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:nether_brick_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(1824, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(1825, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(1826, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(1827, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(1828, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(1829, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(1830, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(1831, "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:nether_brick_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(1840, "{Name:'minecraft:nether_wart',Properties:{age:'0'}}", "{Name:'minecraft:nether_wart',Properties:{age:'0'}}"); ++ register(1841, "{Name:'minecraft:nether_wart',Properties:{age:'1'}}", "{Name:'minecraft:nether_wart',Properties:{age:'1'}}"); ++ register(1842, "{Name:'minecraft:nether_wart',Properties:{age:'2'}}", "{Name:'minecraft:nether_wart',Properties:{age:'2'}}"); ++ register(1843, "{Name:'minecraft:nether_wart',Properties:{age:'3'}}", "{Name:'minecraft:nether_wart',Properties:{age:'3'}}"); ++ register(1856, "{Name:'minecraft:enchanting_table'}", "{Name:'minecraft:enchanting_table'}"); ++ register(1872, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'false',has_bottle_2:'false'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'false',has_bottle_2:'false'}}"); ++ register(1873, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'false',has_bottle_2:'false'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'false',has_bottle_2:'false'}}"); ++ register(1874, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'true',has_bottle_2:'false'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'true',has_bottle_2:'false'}}"); ++ register(1875, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'true',has_bottle_2:'false'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'true',has_bottle_2:'false'}}"); ++ register(1876, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'false',has_bottle_2:'true'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'false',has_bottle_2:'true'}}"); ++ register(1877, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'false',has_bottle_2:'true'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'false',has_bottle_2:'true'}}"); ++ register(1878, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'true',has_bottle_2:'true'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'false',has_bottle_1:'true',has_bottle_2:'true'}}"); ++ register(1879, "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'true',has_bottle_2:'true'}}", "{Name:'minecraft:brewing_stand',Properties:{has_bottle_0:'true',has_bottle_1:'true',has_bottle_2:'true'}}"); ++ register(1888, "{Name:'minecraft:cauldron',Properties:{level:'0'}}", "{Name:'minecraft:cauldron',Properties:{level:'0'}}"); ++ register(1889, "{Name:'minecraft:cauldron',Properties:{level:'1'}}", "{Name:'minecraft:cauldron',Properties:{level:'1'}}"); ++ register(1890, "{Name:'minecraft:cauldron',Properties:{level:'2'}}", "{Name:'minecraft:cauldron',Properties:{level:'2'}}"); ++ register(1891, "{Name:'minecraft:cauldron',Properties:{level:'3'}}", "{Name:'minecraft:cauldron',Properties:{level:'3'}}"); ++ register(1904, "{Name:'minecraft:end_portal'}", "{Name:'minecraft:end_portal'}"); ++ register(1920, "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'south'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'south'}}"); ++ register(1921, "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'west'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'west'}}"); ++ register(1922, "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'north'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'north'}}"); ++ register(1923, "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'east'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'false',facing:'east'}}"); ++ register(1924, "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'south'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'south'}}"); ++ register(1925, "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'west'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'west'}}"); ++ register(1926, "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'north'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'north'}}"); ++ register(1927, "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'east'}}", "{Name:'minecraft:end_portal_frame',Properties:{eye:'true',facing:'east'}}"); ++ register(1936, "{Name:'minecraft:end_stone'}", "{Name:'minecraft:end_stone'}"); ++ register(1952, "{Name:'minecraft:dragon_egg'}", "{Name:'minecraft:dragon_egg'}"); ++ register(1968, "{Name:'minecraft:redstone_lamp',Properties:{lit:'false'}}", "{Name:'minecraft:redstone_lamp'}"); ++ register(1984, "{Name:'minecraft:redstone_lamp',Properties:{lit:'true'}}", "{Name:'minecraft:lit_redstone_lamp'}"); ++ register(2000, "{Name:'minecraft:oak_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'oak'}}"); ++ register(2001, "{Name:'minecraft:spruce_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'spruce'}}"); ++ register(2002, "{Name:'minecraft:birch_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'birch'}}"); ++ register(2003, "{Name:'minecraft:jungle_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'jungle'}}"); ++ register(2004, "{Name:'minecraft:acacia_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'acacia'}}"); ++ register(2005, "{Name:'minecraft:dark_oak_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_wooden_slab',Properties:{variant:'dark_oak'}}"); ++ register(2016, "{Name:'minecraft:oak_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'oak'}}"); ++ register(2017, "{Name:'minecraft:spruce_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'spruce'}}"); ++ register(2018, "{Name:'minecraft:birch_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'birch'}}"); ++ register(2019, "{Name:'minecraft:jungle_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'jungle'}}"); ++ register(2020, "{Name:'minecraft:acacia_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'acacia'}}"); ++ register(2021, "{Name:'minecraft:dark_oak_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'bottom',variant:'dark_oak'}}"); ++ register(2024, "{Name:'minecraft:oak_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'oak'}}"); ++ register(2025, "{Name:'minecraft:spruce_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'spruce'}}"); ++ register(2026, "{Name:'minecraft:birch_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'birch'}}"); ++ register(2027, "{Name:'minecraft:jungle_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'jungle'}}"); ++ register(2028, "{Name:'minecraft:acacia_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'acacia'}}"); ++ register(2029, "{Name:'minecraft:dark_oak_slab',Properties:{type:'top'}}", "{Name:'minecraft:wooden_slab',Properties:{half:'top',variant:'dark_oak'}}"); ++ register(2032, "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'south'}}", "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'south'}}"); ++ register(2033, "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'west'}}", "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'west'}}"); ++ register(2034, "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'north'}}", "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'north'}}"); ++ register(2035, "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'east'}}", "{Name:'minecraft:cocoa',Properties:{age:'0',facing:'east'}}"); ++ register(2036, "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'south'}}", "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'south'}}"); ++ register(2037, "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'west'}}", "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'west'}}"); ++ register(2038, "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'north'}}", "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'north'}}"); ++ register(2039, "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'east'}}", "{Name:'minecraft:cocoa',Properties:{age:'1',facing:'east'}}"); ++ register(2040, "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'south'}}", "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'south'}}"); ++ register(2041, "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'west'}}", "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'west'}}"); ++ register(2042, "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'north'}}", "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'north'}}"); ++ register(2043, "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'east'}}", "{Name:'minecraft:cocoa',Properties:{age:'2',facing:'east'}}"); ++ register(2048, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2049, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2050, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2051, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2052, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2053, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2054, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2055, "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:sandstone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2064, "{Name:'minecraft:emerald_ore'}", "{Name:'minecraft:emerald_ore'}"); ++ register(2082, "{Name:'minecraft:ender_chest',Properties:{facing:'north'}}", "{Name:'minecraft:ender_chest',Properties:{facing:'north'}}"); ++ register(2083, "{Name:'minecraft:ender_chest',Properties:{facing:'south'}}", "{Name:'minecraft:ender_chest',Properties:{facing:'south'}}"); ++ register(2084, "{Name:'minecraft:ender_chest',Properties:{facing:'west'}}", "{Name:'minecraft:ender_chest',Properties:{facing:'west'}}"); ++ register(2085, "{Name:'minecraft:ender_chest',Properties:{facing:'east'}}", "{Name:'minecraft:ender_chest',Properties:{facing:'east'}}"); ++ register(2096, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'south',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'south',powered:'false'}}"); ++ register(2097, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'west',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'west',powered:'false'}}"); ++ register(2098, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'north',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'north',powered:'false'}}"); ++ register(2099, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'east',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'east',powered:'false'}}"); ++ register(2100, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'south',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'south',powered:'false'}}"); ++ register(2101, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'west',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'west',powered:'false'}}"); ++ register(2102, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'north',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'north',powered:'false'}}"); ++ register(2103, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'east',powered:'false'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'east',powered:'false'}}"); ++ register(2104, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'south',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'south',powered:'true'}}"); ++ register(2105, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'west',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'west',powered:'true'}}"); ++ register(2106, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'north',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'north',powered:'true'}}"); ++ register(2107, "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'east',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'false',facing:'east',powered:'true'}}"); ++ register(2108, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'south',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'south',powered:'true'}}"); ++ register(2109, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'west',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'west',powered:'true'}}"); ++ register(2110, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'north',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'north',powered:'true'}}"); ++ register(2111, "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'east',powered:'true'}}", "{Name:'minecraft:tripwire_hook',Properties:{attached:'true',facing:'east',powered:'true'}}"); ++ register(2112, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'false',south:'true',west:'true'}}"); ++ register(2113, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'true',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'true',north:'true',powered:'true',south:'true',west:'true'}}"); ++ register(2114, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}"); ++ register(2115, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}"); ++ register(2116, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'false',south:'true',west:'true'}}"); ++ register(2117, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'true',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'true',north:'true',powered:'true',south:'true',west:'true'}}"); ++ register(2118, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'false',south:'false',west:'false'}}"); ++ register(2119, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'false',east:'false',north:'false',powered:'true',south:'false',west:'false'}}"); ++ register(2120, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'false',south:'true',west:'true'}}"); ++ register(2121, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'true',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'true',north:'true',powered:'true',south:'true',west:'true'}}"); ++ register(2122, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}"); ++ register(2123, "{Name:'minecraft:tripwire',Properties:{attached:'false',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'false'}}"); ++ register(2124, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'false',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'false',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'false',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'false',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'false',south:'true',west:'true'}}"); ++ register(2125, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'true',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'false',powered:'true',south:'true',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'true',south:'false',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'true',south:'false',west:'true'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'true',south:'true',west:'false'}}", "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'true',north:'true',powered:'true',south:'true',west:'true'}}"); ++ register(2126, "{Name:'minecraft:tripwire',Properties:{attached:'true',disarmed:'true',east:'false',north:'false',powered:'false',south:'false',west:'false'}}"); ++ register(2128, "{Name:'minecraft:emerald_block'}", "{Name:'minecraft:emerald_block'}"); ++ register(2144, "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2145, "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2146, "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2147, "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2148, "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2149, "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2150, "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2151, "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:spruce_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2160, "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2161, "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2162, "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2163, "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2164, "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2165, "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2166, "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2167, "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:birch_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2176, "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2177, "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2178, "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2179, "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2180, "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2181, "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2182, "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2183, "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:jungle_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2192, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'down'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'down'}}"); ++ register(2193, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'up'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'up'}}"); ++ register(2194, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'north'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'north'}}"); ++ register(2195, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'south'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'south'}}"); ++ register(2196, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'west'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'west'}}"); ++ register(2197, "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'east'}}", "{Name:'minecraft:command_block',Properties:{conditional:'false',facing:'east'}}"); ++ register(2200, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'down'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'down'}}"); ++ register(2201, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'up'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'up'}}"); ++ register(2202, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'north'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'north'}}"); ++ register(2203, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'south'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'south'}}"); ++ register(2204, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'west'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'west'}}"); ++ register(2205, "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'east'}}", "{Name:'minecraft:command_block',Properties:{conditional:'true',facing:'east'}}"); ++ register(2208, "{Name:'minecraft:beacon'}", "{Name:'minecraft:beacon'}"); ++ register(2224, "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'true',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'false',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'false',variant:'cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'true',variant:'cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'true',variant:'cobblestone',west:'true'}}"); ++ register(2225, "{Name:'minecraft:mossy_cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'false',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'false',south:'true',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'false',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'false',north:'true',south:'true',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'false',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'false',south:'true',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'false',up:'true',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'false',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'false',variant:'mossy_cobblestone',west:'true'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'true',variant:'mossy_cobblestone',west:'false'}}", "{Name:'minecraft:cobblestone_wall',Properties:{east:'true',north:'true',south:'true',up:'true',variant:'mossy_cobblestone',west:'true'}}"); ++ // There are a few changes made to flower pot here, notably handling how legacy data is handled. ++ // The TE itself should contain the target item and from there the proper state can be determined. However, there are ++ // blocks that do not contain a TE. So we need to make sure there is a default to fall on. ++ // I simply followed the legacy handling from BlockFlowerPot from 1.8.8 to find what legacy data mapped to what. ++ // It's better than defaulting everything to a cactus. ++ register(2240, "{Name:'minecraft:flower_pot'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'0'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'0'}}"); ++ register(2241, "{Name:'minecraft:potted_poppy'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'1'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'1'}}"); ++ register(2242, "{Name:'minecraft:potted_dandelion'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'2'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'2'}}"); ++ register(2243, "{Name:'minecraft:potted_oak_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'3'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'3'}}"); ++ register(2244, "{Name:'minecraft:potted_spruce_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'4'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'4'}}"); ++ register(2245, "{Name:'minecraft:potted_birch_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'5'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'5'}}"); ++ register(2246, "{Name:'minecraft:potted_jungle_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'6'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'6'}}"); ++ register(2247, "{Name:'minecraft:potted_red_mushroom'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'7'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'7'}}"); ++ register(2248, "{Name:'minecraft:potted_brown_mushroom'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'8'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'8'}}"); ++ register(2249, "{Name:'minecraft:potted_cactus'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'9'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'9'}}"); ++ register(2250, "{Name:'minecraft:potted_dead_bush'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'10'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'10'}}"); ++ register(2251, "{Name:'minecraft:potted_fern'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'11'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'11'}}"); ++ register(2252, "{Name:'minecraft:potted_acacia_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'12'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'12'}}"); ++ register(2253, "{Name:'minecraft:potted_dark_oak_sapling'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'13'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'13'}}"); ++ register(2254, "{Name:'minecraft:flower_pot'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'14'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'14'}}"); ++ register(2255, "{Name:'minecraft:flower_pot'}", "{Name:'minecraft:flower_pot',Properties:{contents:'acacia_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'allium',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'birch_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'blue_orchid',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'cactus',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dandelion',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dark_oak_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'dead_bush',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'empty',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'fern',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'houstonia',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'jungle_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_brown',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'mushroom_red',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oak_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'orange_tulip',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'oxeye_daisy',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'pink_tulip',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'red_tulip',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'rose',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'spruce_sapling',legacy_data:'15'}}", "{Name:'minecraft:flower_pot',Properties:{contents:'white_tulip',legacy_data:'15'}}"); ++ register(2256, "{Name:'minecraft:carrots',Properties:{age:'0'}}", "{Name:'minecraft:carrots',Properties:{age:'0'}}"); ++ register(2257, "{Name:'minecraft:carrots',Properties:{age:'1'}}", "{Name:'minecraft:carrots',Properties:{age:'1'}}"); ++ register(2258, "{Name:'minecraft:carrots',Properties:{age:'2'}}", "{Name:'minecraft:carrots',Properties:{age:'2'}}"); ++ register(2259, "{Name:'minecraft:carrots',Properties:{age:'3'}}", "{Name:'minecraft:carrots',Properties:{age:'3'}}"); ++ register(2260, "{Name:'minecraft:carrots',Properties:{age:'4'}}", "{Name:'minecraft:carrots',Properties:{age:'4'}}"); ++ register(2261, "{Name:'minecraft:carrots',Properties:{age:'5'}}", "{Name:'minecraft:carrots',Properties:{age:'5'}}"); ++ register(2262, "{Name:'minecraft:carrots',Properties:{age:'6'}}", "{Name:'minecraft:carrots',Properties:{age:'6'}}"); ++ register(2263, "{Name:'minecraft:carrots',Properties:{age:'7'}}", "{Name:'minecraft:carrots',Properties:{age:'7'}}"); ++ register(2272, "{Name:'minecraft:potatoes',Properties:{age:'0'}}", "{Name:'minecraft:potatoes',Properties:{age:'0'}}"); ++ register(2273, "{Name:'minecraft:potatoes',Properties:{age:'1'}}", "{Name:'minecraft:potatoes',Properties:{age:'1'}}"); ++ register(2274, "{Name:'minecraft:potatoes',Properties:{age:'2'}}", "{Name:'minecraft:potatoes',Properties:{age:'2'}}"); ++ register(2275, "{Name:'minecraft:potatoes',Properties:{age:'3'}}", "{Name:'minecraft:potatoes',Properties:{age:'3'}}"); ++ register(2276, "{Name:'minecraft:potatoes',Properties:{age:'4'}}", "{Name:'minecraft:potatoes',Properties:{age:'4'}}"); ++ register(2277, "{Name:'minecraft:potatoes',Properties:{age:'5'}}", "{Name:'minecraft:potatoes',Properties:{age:'5'}}"); ++ register(2278, "{Name:'minecraft:potatoes',Properties:{age:'6'}}", "{Name:'minecraft:potatoes',Properties:{age:'6'}}"); ++ register(2279, "{Name:'minecraft:potatoes',Properties:{age:'7'}}", "{Name:'minecraft:potatoes',Properties:{age:'7'}}"); ++ register(2288, "{Name:'minecraft:oak_button',Properties:{face:'ceiling',facing:'north',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'down',powered:'false'}}"); ++ register(2289, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'east',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'east',powered:'false'}}"); ++ register(2290, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'west',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'west',powered:'false'}}"); ++ register(2291, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'south',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'south',powered:'false'}}"); ++ register(2292, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'north',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'north',powered:'false'}}"); ++ register(2293, "{Name:'minecraft:oak_button',Properties:{face:'floor',facing:'north',powered:'false'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'up',powered:'false'}}"); ++ register(2296, "{Name:'minecraft:oak_button',Properties:{face:'ceiling',facing:'north',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'down',powered:'true'}}"); ++ register(2297, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'east',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'east',powered:'true'}}"); ++ register(2298, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'west',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'west',powered:'true'}}"); ++ register(2299, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'south',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'south',powered:'true'}}"); ++ register(2300, "{Name:'minecraft:oak_button',Properties:{face:'wall',facing:'north',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'north',powered:'true'}}"); ++ register(2301, "{Name:'minecraft:oak_button',Properties:{face:'floor',facing:'north',powered:'true'}}", "{Name:'minecraft:wooden_button',Properties:{facing:'up',powered:'true'}}"); ++ register(2304, "{Name:'%%FILTER_ME%%',Properties:{facing:'down',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'down',nodrop:'false'}}"); ++ register(2305, "{Name:'%%FILTER_ME%%',Properties:{facing:'up',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'up',nodrop:'false'}}"); ++ register(2306, "{Name:'%%FILTER_ME%%',Properties:{facing:'north',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'north',nodrop:'false'}}"); ++ register(2307, "{Name:'%%FILTER_ME%%',Properties:{facing:'south',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'south',nodrop:'false'}}"); ++ register(2308, "{Name:'%%FILTER_ME%%',Properties:{facing:'west',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'west',nodrop:'false'}}"); ++ register(2309, "{Name:'%%FILTER_ME%%',Properties:{facing:'east',nodrop:'false'}}", "{Name:'minecraft:skull',Properties:{facing:'east',nodrop:'false'}}"); ++ register(2312, "{Name:'%%FILTER_ME%%',Properties:{facing:'down',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'down',nodrop:'true'}}"); ++ register(2313, "{Name:'%%FILTER_ME%%',Properties:{facing:'up',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'up',nodrop:'true'}}"); ++ register(2314, "{Name:'%%FILTER_ME%%',Properties:{facing:'north',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'north',nodrop:'true'}}"); ++ register(2315, "{Name:'%%FILTER_ME%%',Properties:{facing:'south',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'south',nodrop:'true'}}"); ++ register(2316, "{Name:'%%FILTER_ME%%',Properties:{facing:'west',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'west',nodrop:'true'}}"); ++ register(2317, "{Name:'%%FILTER_ME%%',Properties:{facing:'east',nodrop:'true'}}", "{Name:'minecraft:skull',Properties:{facing:'east',nodrop:'true'}}"); ++ register(2320, "{Name:'minecraft:anvil',Properties:{facing:'south'}}", "{Name:'minecraft:anvil',Properties:{damage:'0',facing:'south'}}"); ++ register(2321, "{Name:'minecraft:anvil',Properties:{facing:'west'}}", "{Name:'minecraft:anvil',Properties:{damage:'0',facing:'west'}}"); ++ register(2322, "{Name:'minecraft:anvil',Properties:{facing:'north'}}", "{Name:'minecraft:anvil',Properties:{damage:'0',facing:'north'}}"); ++ register(2323, "{Name:'minecraft:anvil',Properties:{facing:'east'}}", "{Name:'minecraft:anvil',Properties:{damage:'0',facing:'east'}}"); ++ register(2324, "{Name:'minecraft:chipped_anvil',Properties:{facing:'south'}}", "{Name:'minecraft:anvil',Properties:{damage:'1',facing:'south'}}"); ++ register(2325, "{Name:'minecraft:chipped_anvil',Properties:{facing:'west'}}", "{Name:'minecraft:anvil',Properties:{damage:'1',facing:'west'}}"); ++ register(2326, "{Name:'minecraft:chipped_anvil',Properties:{facing:'north'}}", "{Name:'minecraft:anvil',Properties:{damage:'1',facing:'north'}}"); ++ register(2327, "{Name:'minecraft:chipped_anvil',Properties:{facing:'east'}}", "{Name:'minecraft:anvil',Properties:{damage:'1',facing:'east'}}"); ++ register(2328, "{Name:'minecraft:damaged_anvil',Properties:{facing:'south'}}", "{Name:'minecraft:anvil',Properties:{damage:'2',facing:'south'}}"); ++ register(2329, "{Name:'minecraft:damaged_anvil',Properties:{facing:'west'}}", "{Name:'minecraft:anvil',Properties:{damage:'2',facing:'west'}}"); ++ register(2330, "{Name:'minecraft:damaged_anvil',Properties:{facing:'north'}}", "{Name:'minecraft:anvil',Properties:{damage:'2',facing:'north'}}"); ++ register(2331, "{Name:'minecraft:damaged_anvil',Properties:{facing:'east'}}", "{Name:'minecraft:anvil',Properties:{damage:'2',facing:'east'}}"); ++ register(2338, "{Name:'minecraft:trapped_chest',Properties:{facing:'north',type:'single'}}", "{Name:'minecraft:trapped_chest',Properties:{facing:'north'}}"); ++ register(2339, "{Name:'minecraft:trapped_chest',Properties:{facing:'south',type:'single'}}", "{Name:'minecraft:trapped_chest',Properties:{facing:'south'}}"); ++ register(2340, "{Name:'minecraft:trapped_chest',Properties:{facing:'west',type:'single'}}", "{Name:'minecraft:trapped_chest',Properties:{facing:'west'}}"); ++ register(2341, "{Name:'minecraft:trapped_chest',Properties:{facing:'east',type:'single'}}", "{Name:'minecraft:trapped_chest',Properties:{facing:'east'}}"); ++ register(2352, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'0'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'0'}}"); ++ register(2353, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'1'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'1'}}"); ++ register(2354, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'2'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'2'}}"); ++ register(2355, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'3'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'3'}}"); ++ register(2356, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'4'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'4'}}"); ++ register(2357, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'5'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'5'}}"); ++ register(2358, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'6'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'6'}}"); ++ register(2359, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'7'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'7'}}"); ++ register(2360, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'8'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'8'}}"); ++ register(2361, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'9'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'9'}}"); ++ register(2362, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'10'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'10'}}"); ++ register(2363, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'11'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'11'}}"); ++ register(2364, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'12'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'12'}}"); ++ register(2365, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'13'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'13'}}"); ++ register(2366, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'14'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'14'}}"); ++ register(2367, "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'15'}}", "{Name:'minecraft:light_weighted_pressure_plate',Properties:{power:'15'}}"); ++ register(2368, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'0'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'0'}}"); ++ register(2369, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'1'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'1'}}"); ++ register(2370, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'2'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'2'}}"); ++ register(2371, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'3'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'3'}}"); ++ register(2372, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'4'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'4'}}"); ++ register(2373, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'5'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'5'}}"); ++ register(2374, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'6'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'6'}}"); ++ register(2375, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'7'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'7'}}"); ++ register(2376, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'8'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'8'}}"); ++ register(2377, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'9'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'9'}}"); ++ register(2378, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'10'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'10'}}"); ++ register(2379, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'11'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'11'}}"); ++ register(2380, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'12'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'12'}}"); ++ register(2381, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'13'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'13'}}"); ++ register(2382, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'14'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'14'}}"); ++ register(2383, "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'15'}}", "{Name:'minecraft:heavy_weighted_pressure_plate',Properties:{power:'15'}}"); ++ register(2384, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'compare',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'south',mode:'compare',powered:'false'}}"); ++ register(2385, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'compare',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'west',mode:'compare',powered:'false'}}"); ++ register(2386, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'compare',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'north',mode:'compare',powered:'false'}}"); ++ register(2387, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'compare',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'east',mode:'compare',powered:'false'}}"); ++ register(2388, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'subtract',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'south',mode:'subtract',powered:'false'}}"); ++ register(2389, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'subtract',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'west',mode:'subtract',powered:'false'}}"); ++ register(2390, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'subtract',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'north',mode:'subtract',powered:'false'}}"); ++ register(2391, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'subtract',powered:'false'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'east',mode:'subtract',powered:'false'}}"); ++ register(2392, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'compare',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'south',mode:'compare',powered:'true'}}"); ++ register(2393, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'compare',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'west',mode:'compare',powered:'true'}}"); ++ register(2394, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'compare',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'north',mode:'compare',powered:'true'}}"); ++ register(2395, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'compare',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'east',mode:'compare',powered:'true'}}"); ++ register(2396, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'subtract',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'south',mode:'subtract',powered:'true'}}"); ++ register(2397, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'subtract',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'west',mode:'subtract',powered:'true'}}"); ++ register(2398, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'subtract',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'north',mode:'subtract',powered:'true'}}"); ++ register(2399, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'subtract',powered:'true'}}", "{Name:'minecraft:unpowered_comparator',Properties:{facing:'east',mode:'subtract',powered:'true'}}"); ++ register(2400, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'compare',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'south',mode:'compare',powered:'false'}}"); ++ register(2401, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'compare',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'west',mode:'compare',powered:'false'}}"); ++ register(2402, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'compare',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'north',mode:'compare',powered:'false'}}"); ++ register(2403, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'compare',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'east',mode:'compare',powered:'false'}}"); ++ register(2404, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'subtract',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'south',mode:'subtract',powered:'false'}}"); ++ register(2405, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'subtract',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'west',mode:'subtract',powered:'false'}}"); ++ register(2406, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'subtract',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'north',mode:'subtract',powered:'false'}}"); ++ register(2407, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'subtract',powered:'false'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'east',mode:'subtract',powered:'false'}}"); ++ register(2408, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'compare',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'south',mode:'compare',powered:'true'}}"); ++ register(2409, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'compare',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'west',mode:'compare',powered:'true'}}"); ++ register(2410, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'compare',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'north',mode:'compare',powered:'true'}}"); ++ register(2411, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'compare',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'east',mode:'compare',powered:'true'}}"); ++ register(2412, "{Name:'minecraft:comparator',Properties:{facing:'south',mode:'subtract',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'south',mode:'subtract',powered:'true'}}"); ++ register(2413, "{Name:'minecraft:comparator',Properties:{facing:'west',mode:'subtract',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'west',mode:'subtract',powered:'true'}}"); ++ register(2414, "{Name:'minecraft:comparator',Properties:{facing:'north',mode:'subtract',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'north',mode:'subtract',powered:'true'}}"); ++ register(2415, "{Name:'minecraft:comparator',Properties:{facing:'east',mode:'subtract',powered:'true'}}", "{Name:'minecraft:powered_comparator',Properties:{facing:'east',mode:'subtract',powered:'true'}}"); ++ register(2416, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'0'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'0'}}"); ++ register(2417, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'1'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'1'}}"); ++ register(2418, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'2'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'2'}}"); ++ register(2419, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'3'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'3'}}"); ++ register(2420, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'4'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'4'}}"); ++ register(2421, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'5'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'5'}}"); ++ register(2422, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'6'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'6'}}"); ++ register(2423, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'7'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'7'}}"); ++ register(2424, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'8'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'8'}}"); ++ register(2425, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'9'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'9'}}"); ++ register(2426, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'10'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'10'}}"); ++ register(2427, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'11'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'11'}}"); ++ register(2428, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'12'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'12'}}"); ++ register(2429, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'13'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'13'}}"); ++ register(2430, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'14'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'14'}}"); ++ register(2431, "{Name:'minecraft:daylight_detector',Properties:{inverted:'false',power:'15'}}", "{Name:'minecraft:daylight_detector',Properties:{power:'15'}}"); ++ register(2432, "{Name:'minecraft:redstone_block'}", "{Name:'minecraft:redstone_block'}"); ++ register(2448, "{Name:'minecraft:nether_quartz_ore'}", "{Name:'minecraft:quartz_ore'}"); ++ register(2464, "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'down'}}", "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'down'}}"); ++ register(2466, "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'north'}}", "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'north'}}"); ++ register(2467, "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'south'}}", "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'south'}}"); ++ register(2468, "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'west'}}", "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'west'}}"); ++ register(2469, "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'east'}}", "{Name:'minecraft:hopper',Properties:{enabled:'true',facing:'east'}}"); ++ register(2472, "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'down'}}", "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'down'}}"); ++ register(2474, "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'north'}}", "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'north'}}"); ++ register(2475, "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'south'}}", "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'south'}}"); ++ register(2476, "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'west'}}", "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'west'}}"); ++ register(2477, "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'east'}}", "{Name:'minecraft:hopper',Properties:{enabled:'false',facing:'east'}}"); ++ register(2480, "{Name:'minecraft:quartz_block'}", "{Name:'minecraft:quartz_block',Properties:{variant:'default'}}"); ++ register(2481, "{Name:'minecraft:chiseled_quartz_block'}", "{Name:'minecraft:quartz_block',Properties:{variant:'chiseled'}}"); ++ register(2482, "{Name:'minecraft:quartz_pillar',Properties:{axis:'y'}}", "{Name:'minecraft:quartz_block',Properties:{variant:'lines_y'}}"); ++ register(2483, "{Name:'minecraft:quartz_pillar',Properties:{axis:'x'}}", "{Name:'minecraft:quartz_block',Properties:{variant:'lines_x'}}"); ++ register(2484, "{Name:'minecraft:quartz_pillar',Properties:{axis:'z'}}", "{Name:'minecraft:quartz_block',Properties:{variant:'lines_z'}}"); ++ register(2496, "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2497, "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2498, "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2499, "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2500, "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2501, "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2502, "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2503, "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:quartz_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2512, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'north_south'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'north_south'}}"); ++ register(2513, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'east_west'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'east_west'}}"); ++ register(2514, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_east'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_east'}}"); ++ register(2515, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_west'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_west'}}"); ++ register(2516, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_north'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_north'}}"); ++ register(2517, "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_south'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'false',shape:'ascending_south'}}"); ++ register(2520, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'north_south'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'north_south'}}"); ++ register(2521, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'east_west'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'east_west'}}"); ++ register(2522, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_east'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_east'}}"); ++ register(2523, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_west'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_west'}}"); ++ register(2524, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_north'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_north'}}"); ++ register(2525, "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_south'}}", "{Name:'minecraft:activator_rail',Properties:{powered:'true',shape:'ascending_south'}}"); ++ register(2528, "{Name:'minecraft:dropper',Properties:{facing:'down',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'down',triggered:'false'}}"); ++ register(2529, "{Name:'minecraft:dropper',Properties:{facing:'up',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'up',triggered:'false'}}"); ++ register(2530, "{Name:'minecraft:dropper',Properties:{facing:'north',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'north',triggered:'false'}}"); ++ register(2531, "{Name:'minecraft:dropper',Properties:{facing:'south',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'south',triggered:'false'}}"); ++ register(2532, "{Name:'minecraft:dropper',Properties:{facing:'west',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'west',triggered:'false'}}"); ++ register(2533, "{Name:'minecraft:dropper',Properties:{facing:'east',triggered:'false'}}", "{Name:'minecraft:dropper',Properties:{facing:'east',triggered:'false'}}"); ++ register(2536, "{Name:'minecraft:dropper',Properties:{facing:'down',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'down',triggered:'true'}}"); ++ register(2537, "{Name:'minecraft:dropper',Properties:{facing:'up',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'up',triggered:'true'}}"); ++ register(2538, "{Name:'minecraft:dropper',Properties:{facing:'north',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'north',triggered:'true'}}"); ++ register(2539, "{Name:'minecraft:dropper',Properties:{facing:'south',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'south',triggered:'true'}}"); ++ register(2540, "{Name:'minecraft:dropper',Properties:{facing:'west',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'west',triggered:'true'}}"); ++ register(2541, "{Name:'minecraft:dropper',Properties:{facing:'east',triggered:'true'}}", "{Name:'minecraft:dropper',Properties:{facing:'east',triggered:'true'}}"); ++ register(2544, "{Name:'minecraft:white_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'white'}}"); ++ register(2545, "{Name:'minecraft:orange_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'orange'}}"); ++ register(2546, "{Name:'minecraft:magenta_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'magenta'}}"); ++ register(2547, "{Name:'minecraft:light_blue_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'light_blue'}}"); ++ register(2548, "{Name:'minecraft:yellow_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'yellow'}}"); ++ register(2549, "{Name:'minecraft:lime_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'lime'}}"); ++ register(2550, "{Name:'minecraft:pink_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'pink'}}"); ++ register(2551, "{Name:'minecraft:gray_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'gray'}}"); ++ register(2552, "{Name:'minecraft:light_gray_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'silver'}}"); ++ register(2553, "{Name:'minecraft:cyan_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'cyan'}}"); ++ register(2554, "{Name:'minecraft:purple_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'purple'}}"); ++ register(2555, "{Name:'minecraft:blue_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'blue'}}"); ++ register(2556, "{Name:'minecraft:brown_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'brown'}}"); ++ register(2557, "{Name:'minecraft:green_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'green'}}"); ++ register(2558, "{Name:'minecraft:red_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'red'}}"); ++ register(2559, "{Name:'minecraft:black_terracotta'}", "{Name:'minecraft:stained_hardened_clay',Properties:{color:'black'}}"); ++ register(2560, "{Name:'minecraft:white_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'white',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2561, "{Name:'minecraft:orange_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'orange',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2562, "{Name:'minecraft:magenta_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'magenta',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2563, "{Name:'minecraft:light_blue_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'light_blue',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2564, "{Name:'minecraft:yellow_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'yellow',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2565, "{Name:'minecraft:lime_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'lime',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2566, "{Name:'minecraft:pink_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'pink',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2567, "{Name:'minecraft:gray_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'gray',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2568, "{Name:'minecraft:light_gray_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'silver',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2569, "{Name:'minecraft:cyan_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'cyan',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2570, "{Name:'minecraft:purple_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'purple',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2571, "{Name:'minecraft:blue_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'blue',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2572, "{Name:'minecraft:brown_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'brown',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2573, "{Name:'minecraft:green_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'green',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2574, "{Name:'minecraft:red_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'red',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2575, "{Name:'minecraft:black_stained_glass_pane',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:stained_glass_pane',Properties:{color:'black',east:'true',north:'true',south:'true',west:'true'}}"); ++ register(2576, "{Name:'minecraft:acacia_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'false',decayable:'true',variant:'acacia'}}"); ++ register(2577, "{Name:'minecraft:dark_oak_leaves',Properties:{check_decay:'false',decayable:'true'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'false',decayable:'true',variant:'dark_oak'}}"); ++ register(2580, "{Name:'minecraft:acacia_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'false',decayable:'false',variant:'acacia'}}"); ++ register(2581, "{Name:'minecraft:dark_oak_leaves',Properties:{check_decay:'false',decayable:'false'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'false',decayable:'false',variant:'dark_oak'}}"); ++ register(2584, "{Name:'minecraft:acacia_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'true',decayable:'true',variant:'acacia'}}"); ++ register(2585, "{Name:'minecraft:dark_oak_leaves',Properties:{check_decay:'true',decayable:'true'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'true',decayable:'true',variant:'dark_oak'}}"); ++ register(2588, "{Name:'minecraft:acacia_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'true',decayable:'false',variant:'acacia'}}"); ++ register(2589, "{Name:'minecraft:dark_oak_leaves',Properties:{check_decay:'true',decayable:'false'}}", "{Name:'minecraft:leaves2',Properties:{check_decay:'true',decayable:'false',variant:'dark_oak'}}"); ++ register(2592, "{Name:'minecraft:acacia_log',Properties:{axis:'y'}}", "{Name:'minecraft:log2',Properties:{axis:'y',variant:'acacia'}}"); ++ register(2593, "{Name:'minecraft:dark_oak_log',Properties:{axis:'y'}}", "{Name:'minecraft:log2',Properties:{axis:'y',variant:'dark_oak'}}"); ++ register(2596, "{Name:'minecraft:acacia_log',Properties:{axis:'x'}}", "{Name:'minecraft:log2',Properties:{axis:'x',variant:'acacia'}}"); ++ register(2597, "{Name:'minecraft:dark_oak_log',Properties:{axis:'x'}}", "{Name:'minecraft:log2',Properties:{axis:'x',variant:'dark_oak'}}"); ++ register(2600, "{Name:'minecraft:acacia_log',Properties:{axis:'z'}}", "{Name:'minecraft:log2',Properties:{axis:'z',variant:'acacia'}}"); ++ register(2601, "{Name:'minecraft:dark_oak_log',Properties:{axis:'z'}}", "{Name:'minecraft:log2',Properties:{axis:'z',variant:'dark_oak'}}"); ++ register(2604, "{Name:'minecraft:acacia_bark'}", "{Name:'minecraft:log2',Properties:{axis:'none',variant:'acacia'}}"); ++ register(2605, "{Name:'minecraft:dark_oak_bark'}", "{Name:'minecraft:log2',Properties:{axis:'none',variant:'dark_oak'}}"); ++ register(2608, "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2609, "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2610, "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2611, "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2612, "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2613, "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2614, "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2615, "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:acacia_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2624, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2625, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2626, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2627, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2628, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2629, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2630, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2631, "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:dark_oak_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2640, "{Name:'minecraft:slime_block'}", "{Name:'minecraft:slime'}"); ++ register(2656, "{Name:'minecraft:barrier'}", "{Name:'minecraft:barrier'}"); ++ register(2672, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'bottom',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'bottom',open:'false'}}"); ++ register(2673, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'bottom',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'bottom',open:'false'}}"); ++ register(2674, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'bottom',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'bottom',open:'false'}}"); ++ register(2675, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'bottom',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'bottom',open:'false'}}"); ++ register(2676, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'bottom',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'bottom',open:'true'}}"); ++ register(2677, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'bottom',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'bottom',open:'true'}}"); ++ register(2678, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'bottom',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'bottom',open:'true'}}"); ++ register(2679, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'bottom',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'bottom',open:'true'}}"); ++ register(2680, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'top',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'top',open:'false'}}"); ++ register(2681, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'top',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'top',open:'false'}}"); ++ register(2682, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'top',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'top',open:'false'}}"); ++ register(2683, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'top',open:'false'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'top',open:'false'}}"); ++ register(2684, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'top',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'north',half:'top',open:'true'}}"); ++ register(2685, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'top',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'south',half:'top',open:'true'}}"); ++ register(2686, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'top',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'west',half:'top',open:'true'}}"); ++ register(2687, "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'top',open:'true'}}", "{Name:'minecraft:iron_trapdoor',Properties:{facing:'east',half:'top',open:'true'}}"); ++ register(2688, "{Name:'minecraft:prismarine'}", "{Name:'minecraft:prismarine',Properties:{variant:'prismarine'}}"); ++ register(2689, "{Name:'minecraft:prismarine_bricks'}", "{Name:'minecraft:prismarine',Properties:{variant:'prismarine_bricks'}}"); ++ register(2690, "{Name:'minecraft:dark_prismarine'}", "{Name:'minecraft:prismarine',Properties:{variant:'dark_prismarine'}}"); ++ register(2704, "{Name:'minecraft:sea_lantern'}", "{Name:'minecraft:sea_lantern'}"); ++ register(2720, "{Name:'minecraft:hay_block',Properties:{axis:'y'}}", "{Name:'minecraft:hay_block',Properties:{axis:'y'}}"); ++ register(2724, "{Name:'minecraft:hay_block',Properties:{axis:'x'}}", "{Name:'minecraft:hay_block',Properties:{axis:'x'}}"); ++ register(2728, "{Name:'minecraft:hay_block',Properties:{axis:'z'}}", "{Name:'minecraft:hay_block',Properties:{axis:'z'}}"); ++ register(2736, "{Name:'minecraft:white_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'white'}}"); ++ register(2737, "{Name:'minecraft:orange_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'orange'}}"); ++ register(2738, "{Name:'minecraft:magenta_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'magenta'}}"); ++ register(2739, "{Name:'minecraft:light_blue_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'light_blue'}}"); ++ register(2740, "{Name:'minecraft:yellow_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'yellow'}}"); ++ register(2741, "{Name:'minecraft:lime_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'lime'}}"); ++ register(2742, "{Name:'minecraft:pink_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'pink'}}"); ++ register(2743, "{Name:'minecraft:gray_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'gray'}}"); ++ register(2744, "{Name:'minecraft:light_gray_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'silver'}}"); ++ register(2745, "{Name:'minecraft:cyan_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'cyan'}}"); ++ register(2746, "{Name:'minecraft:purple_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'purple'}}"); ++ register(2747, "{Name:'minecraft:blue_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'blue'}}"); ++ register(2748, "{Name:'minecraft:brown_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'brown'}}"); ++ register(2749, "{Name:'minecraft:green_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'green'}}"); ++ register(2750, "{Name:'minecraft:red_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'red'}}"); ++ register(2751, "{Name:'minecraft:black_carpet'}", "{Name:'minecraft:carpet',Properties:{color:'black'}}"); ++ register(2752, "{Name:'minecraft:terracotta'}", "{Name:'minecraft:hardened_clay'}"); ++ register(2768, "{Name:'minecraft:coal_block'}", "{Name:'minecraft:coal_block'}"); ++ register(2784, "{Name:'minecraft:packed_ice'}", "{Name:'minecraft:packed_ice'}"); ++ register(2800, "{Name:'minecraft:sunflower',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'sunflower'}}"); ++ register(2801, "{Name:'minecraft:lilac',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'syringa'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'syringa'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'syringa'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'syringa'}}"); ++ register(2802, "{Name:'minecraft:tall_grass',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'double_grass'}}"); ++ register(2803, "{Name:'minecraft:large_fern',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'double_fern'}}"); ++ register(2804, "{Name:'minecraft:rose_bush',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'double_rose'}}"); ++ register(2805, "{Name:'minecraft:peony',Properties:{half:'lower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'lower',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'lower',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'lower',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'lower',variant:'paeonia'}}"); ++ register(2808, "{Name:'minecraft:peony',Properties:{half:'upper'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'south',half:'upper',variant:'syringa'}}"); ++ register(2809, "{Name:'minecraft:peony',Properties:{half:'upper'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'west',half:'upper',variant:'syringa'}}"); ++ register(2810, "{Name:'minecraft:peony',Properties:{half:'upper'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'north',half:'upper',variant:'syringa'}}"); ++ register(2811, "{Name:'minecraft:peony',Properties:{half:'upper'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'double_fern'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'double_grass'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'double_rose'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'paeonia'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'sunflower'}}", "{Name:'minecraft:double_plant',Properties:{facing:'east',half:'upper',variant:'syringa'}}"); ++ register(2816, "{Name:'minecraft:white_banner',Properties:{rotation:'0'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'0'}}"); ++ register(2817, "{Name:'minecraft:white_banner',Properties:{rotation:'1'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'1'}}"); ++ register(2818, "{Name:'minecraft:white_banner',Properties:{rotation:'2'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'2'}}"); ++ register(2819, "{Name:'minecraft:white_banner',Properties:{rotation:'3'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'3'}}"); ++ register(2820, "{Name:'minecraft:white_banner',Properties:{rotation:'4'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'4'}}"); ++ register(2821, "{Name:'minecraft:white_banner',Properties:{rotation:'5'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'5'}}"); ++ register(2822, "{Name:'minecraft:white_banner',Properties:{rotation:'6'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'6'}}"); ++ register(2823, "{Name:'minecraft:white_banner',Properties:{rotation:'7'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'7'}}"); ++ register(2824, "{Name:'minecraft:white_banner',Properties:{rotation:'8'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'8'}}"); ++ register(2825, "{Name:'minecraft:white_banner',Properties:{rotation:'9'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'9'}}"); ++ register(2826, "{Name:'minecraft:white_banner',Properties:{rotation:'10'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'10'}}"); ++ register(2827, "{Name:'minecraft:white_banner',Properties:{rotation:'11'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'11'}}"); ++ register(2828, "{Name:'minecraft:white_banner',Properties:{rotation:'12'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'12'}}"); ++ register(2829, "{Name:'minecraft:white_banner',Properties:{rotation:'13'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'13'}}"); ++ register(2830, "{Name:'minecraft:white_banner',Properties:{rotation:'14'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'14'}}"); ++ register(2831, "{Name:'minecraft:white_banner',Properties:{rotation:'15'}}", "{Name:'minecraft:standing_banner',Properties:{rotation:'15'}}"); ++ register(2834, "{Name:'minecraft:white_wall_banner',Properties:{facing:'north'}}", "{Name:'minecraft:wall_banner',Properties:{facing:'north'}}"); ++ register(2835, "{Name:'minecraft:white_wall_banner',Properties:{facing:'south'}}", "{Name:'minecraft:wall_banner',Properties:{facing:'south'}}"); ++ register(2836, "{Name:'minecraft:white_wall_banner',Properties:{facing:'west'}}", "{Name:'minecraft:wall_banner',Properties:{facing:'west'}}"); ++ register(2837, "{Name:'minecraft:white_wall_banner',Properties:{facing:'east'}}", "{Name:'minecraft:wall_banner',Properties:{facing:'east'}}"); ++ register(2848, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'0'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'0'}}"); ++ register(2849, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'1'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'1'}}"); ++ register(2850, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'2'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'2'}}"); ++ register(2851, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'3'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'3'}}"); ++ register(2852, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'4'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'4'}}"); ++ register(2853, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'5'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'5'}}"); ++ register(2854, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'6'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'6'}}"); ++ register(2855, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'7'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'7'}}"); ++ register(2856, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'8'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'8'}}"); ++ register(2857, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'9'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'9'}}"); ++ register(2858, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'10'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'10'}}"); ++ register(2859, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'11'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'11'}}"); ++ register(2860, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'12'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'12'}}"); ++ register(2861, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'13'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'13'}}"); ++ register(2862, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'14'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'14'}}"); ++ register(2863, "{Name:'minecraft:daylight_detector',Properties:{inverted:'true',power:'15'}}", "{Name:'minecraft:daylight_detector_inverted',Properties:{power:'15'}}"); ++ register(2864, "{Name:'minecraft:red_sandstone'}", "{Name:'minecraft:red_sandstone',Properties:{type:'red_sandstone'}}"); ++ register(2865, "{Name:'minecraft:chiseled_red_sandstone'}", "{Name:'minecraft:red_sandstone',Properties:{type:'chiseled_red_sandstone'}}"); ++ register(2866, "{Name:'minecraft:cut_red_sandstone'}", "{Name:'minecraft:red_sandstone',Properties:{type:'smooth_red_sandstone'}}"); ++ register(2880, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(2881, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(2882, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(2883, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(2884, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(2885, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(2886, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(2887, "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:red_sandstone_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(2896, "{Name:'minecraft:red_sandstone_slab',Properties:{type:'double'}}", "{Name:'minecraft:double_stone_slab2',Properties:{seamless:'false',variant:'red_sandstone'}}"); ++ register(2904, "{Name:'minecraft:smooth_red_sandstone'}", "{Name:'minecraft:double_stone_slab2',Properties:{seamless:'true',variant:'red_sandstone'}}"); ++ register(2912, "{Name:'minecraft:red_sandstone_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:stone_slab2',Properties:{half:'bottom',variant:'red_sandstone'}}"); ++ register(2920, "{Name:'minecraft:red_sandstone_slab',Properties:{type:'top'}}", "{Name:'minecraft:stone_slab2',Properties:{half:'top',variant:'red_sandstone'}}"); ++ register(2928, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2929, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2930, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2931, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2932, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2933, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2934, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2935, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2936, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2937, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2938, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2939, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2940, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2941, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2942, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2943, "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2944, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2945, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2946, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2947, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2948, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2949, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2950, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2951, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2952, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2953, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2954, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2955, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2956, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2957, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2958, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2959, "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:birch_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2960, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2961, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2962, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2963, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2964, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2965, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2966, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2967, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2968, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2969, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2970, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2971, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2972, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2973, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2974, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2975, "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2976, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2977, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2978, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2979, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2980, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2981, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2982, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2983, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2984, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2985, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2986, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2987, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(2988, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2989, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2990, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2991, "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(2992, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2993, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2994, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2995, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'false'}}"); ++ register(2996, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2997, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2998, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'false'}}"); ++ register(2999, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'false'}}"); ++ register(3000, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'true',open:'false',powered:'true'}}"); ++ register(3001, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'true',open:'false',powered:'true'}}"); ++ register(3002, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'true',open:'false',powered:'true'}}"); ++ register(3003, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'true',open:'false',powered:'true'}}"); ++ register(3004, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'south',in_wall:'true',open:'true',powered:'true'}}"); ++ register(3005, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'west',in_wall:'true',open:'true',powered:'true'}}"); ++ register(3006, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'north',in_wall:'true',open:'true',powered:'true'}}"); ++ register(3007, "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'false',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_fence_gate',Properties:{facing:'east',in_wall:'true',open:'true',powered:'true'}}"); ++ register(3008, "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:spruce_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(3024, "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:birch_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(3040, "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:jungle_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(3056, "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:dark_oak_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(3072, "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'false',north:'true',south:'true',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'false',south:'false',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'false',south:'false',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'false',south:'true',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'false',south:'true',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'true',south:'false',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'true',south:'false',west:'true'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'true',south:'true',west:'false'}}", "{Name:'minecraft:acacia_fence',Properties:{east:'true',north:'true',south:'true',west:'true'}}"); ++ register(3088, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3089, "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3090, "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3091, "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3092, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3093, "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3094, "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3095, "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3096, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(3097, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(3098, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(3099, "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:spruce_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(3104, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3105, "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3106, "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3107, "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3108, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3109, "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3110, "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3111, "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3112, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(3113, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(3114, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(3115, "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:birch_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(3120, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3121, "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3122, "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3123, "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3124, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3125, "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3126, "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3127, "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3128, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(3129, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(3130, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(3131, "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:jungle_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(3136, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3137, "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3138, "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3139, "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3140, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3141, "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3142, "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3143, "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3144, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(3145, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(3146, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(3147, "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:acacia_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(3152, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3153, "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3154, "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3155, "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'false',powered:'true'}}"); ++ register(3156, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3157, "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3158, "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3159, "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'lower',hinge:'right',open:'true',powered:'true'}}"); ++ register(3160, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'false'}}"); ++ register(3161, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'false'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'false'}}"); ++ register(3162, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'left',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'left',open:'true',powered:'true'}}"); ++ register(3163, "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'east',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'north',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'south',half:'upper',hinge:'right',open:'true',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'false',powered:'true'}}", "{Name:'minecraft:dark_oak_door',Properties:{facing:'west',half:'upper',hinge:'right',open:'true',powered:'true'}}"); ++ register(3168, "{Name:'minecraft:end_rod',Properties:{facing:'down'}}", "{Name:'minecraft:end_rod',Properties:{facing:'down'}}"); ++ register(3169, "{Name:'minecraft:end_rod',Properties:{facing:'up'}}", "{Name:'minecraft:end_rod',Properties:{facing:'up'}}"); ++ register(3170, "{Name:'minecraft:end_rod',Properties:{facing:'north'}}", "{Name:'minecraft:end_rod',Properties:{facing:'north'}}"); ++ register(3171, "{Name:'minecraft:end_rod',Properties:{facing:'south'}}", "{Name:'minecraft:end_rod',Properties:{facing:'south'}}"); ++ register(3172, "{Name:'minecraft:end_rod',Properties:{facing:'west'}}", "{Name:'minecraft:end_rod',Properties:{facing:'west'}}"); ++ register(3173, "{Name:'minecraft:end_rod',Properties:{facing:'east'}}", "{Name:'minecraft:end_rod',Properties:{facing:'east'}}"); ++ register(3184, "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'false',east:'true',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'false',north:'true',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'false',south:'true',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'false',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'false',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'false',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'false',up:'true',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'true',up:'false',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'true',up:'false',west:'true'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'true',up:'true',west:'false'}}", "{Name:'minecraft:chorus_plant',Properties:{down:'true',east:'true',north:'true',south:'true',up:'true',west:'true'}}"); ++ register(3200, "{Name:'minecraft:chorus_flower',Properties:{age:'0'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'0'}}"); ++ register(3201, "{Name:'minecraft:chorus_flower',Properties:{age:'1'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'1'}}"); ++ register(3202, "{Name:'minecraft:chorus_flower',Properties:{age:'2'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'2'}}"); ++ register(3203, "{Name:'minecraft:chorus_flower',Properties:{age:'3'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'3'}}"); ++ register(3204, "{Name:'minecraft:chorus_flower',Properties:{age:'4'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'4'}}"); ++ register(3205, "{Name:'minecraft:chorus_flower',Properties:{age:'5'}}", "{Name:'minecraft:chorus_flower',Properties:{age:'5'}}"); ++ register(3216, "{Name:'minecraft:purpur_block'}", "{Name:'minecraft:purpur_block'}"); ++ register(3232, "{Name:'minecraft:purpur_pillar',Properties:{axis:'y'}}", "{Name:'minecraft:purpur_pillar',Properties:{axis:'y'}}"); ++ register(3236, "{Name:'minecraft:purpur_pillar',Properties:{axis:'x'}}", "{Name:'minecraft:purpur_pillar',Properties:{axis:'x'}}"); ++ register(3240, "{Name:'minecraft:purpur_pillar',Properties:{axis:'z'}}", "{Name:'minecraft:purpur_pillar',Properties:{axis:'z'}}"); ++ register(3248, "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'bottom',shape:'straight'}}"); ++ register(3249, "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'bottom',shape:'straight'}}"); ++ register(3250, "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'bottom',shape:'straight'}}"); ++ register(3251, "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'bottom',shape:'straight'}}"); ++ register(3252, "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'east',half:'top',shape:'straight'}}"); ++ register(3253, "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'west',half:'top',shape:'straight'}}"); ++ register(3254, "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'south',half:'top',shape:'straight'}}"); ++ register(3255, "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'inner_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'inner_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'outer_left'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'outer_right'}}", "{Name:'minecraft:purpur_stairs',Properties:{facing:'north',half:'top',shape:'straight'}}"); ++ register(3264, "{Name:'minecraft:purpur_slab',Properties:{type:'double'}}", "{Name:'minecraft:purpur_double_slab',Properties:{variant:'default'}}"); ++ register(3280, "{Name:'minecraft:purpur_slab',Properties:{type:'bottom'}}", "{Name:'minecraft:purpur_slab',Properties:{half:'bottom',variant:'default'}}"); ++ register(3288, "{Name:'minecraft:purpur_slab',Properties:{type:'top'}}", "{Name:'minecraft:purpur_slab',Properties:{half:'top',variant:'default'}}"); ++ register(3296, "{Name:'minecraft:end_stone_bricks'}", "{Name:'minecraft:end_bricks'}"); ++ register(3312, "{Name:'minecraft:beetroots',Properties:{age:'0'}}", "{Name:'minecraft:beetroots',Properties:{age:'0'}}"); ++ register(3313, "{Name:'minecraft:beetroots',Properties:{age:'1'}}", "{Name:'minecraft:beetroots',Properties:{age:'1'}}"); ++ register(3314, "{Name:'minecraft:beetroots',Properties:{age:'2'}}", "{Name:'minecraft:beetroots',Properties:{age:'2'}}"); ++ register(3315, "{Name:'minecraft:beetroots',Properties:{age:'3'}}", "{Name:'minecraft:beetroots',Properties:{age:'3'}}"); ++ register(3328, "{Name:'minecraft:grass_path'}", "{Name:'minecraft:grass_path'}"); ++ register(3344, "{Name:'minecraft:end_gateway'}", "{Name:'minecraft:end_gateway'}"); ++ register(3360, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'down'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'down'}}"); ++ register(3361, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'up'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'up'}}"); ++ register(3362, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'north'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'north'}}"); ++ register(3363, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'south'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'south'}}"); ++ register(3364, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'west'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'west'}}"); ++ register(3365, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'east'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'false',facing:'east'}}"); ++ register(3368, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'down'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'down'}}"); ++ register(3369, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'up'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'up'}}"); ++ register(3370, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'north'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'north'}}"); ++ register(3371, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'south'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'south'}}"); ++ register(3372, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'west'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'west'}}"); ++ register(3373, "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'east'}}", "{Name:'minecraft:repeating_command_block',Properties:{conditional:'true',facing:'east'}}"); ++ register(3376, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'down'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'down'}}"); ++ register(3377, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'up'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'up'}}"); ++ register(3378, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'north'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'north'}}"); ++ register(3379, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'south'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'south'}}"); ++ register(3380, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'west'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'west'}}"); ++ register(3381, "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'east'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'false',facing:'east'}}"); ++ register(3384, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'down'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'down'}}"); ++ register(3385, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'up'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'up'}}"); ++ register(3386, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'north'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'north'}}"); ++ register(3387, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'south'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'south'}}"); ++ register(3388, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'west'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'west'}}"); ++ register(3389, "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'east'}}", "{Name:'minecraft:chain_command_block',Properties:{conditional:'true',facing:'east'}}"); ++ register(3392, "{Name:'minecraft:frosted_ice',Properties:{age:'0'}}", "{Name:'minecraft:frosted_ice',Properties:{age:'0'}}"); ++ register(3393, "{Name:'minecraft:frosted_ice',Properties:{age:'1'}}", "{Name:'minecraft:frosted_ice',Properties:{age:'1'}}"); ++ register(3394, "{Name:'minecraft:frosted_ice',Properties:{age:'2'}}", "{Name:'minecraft:frosted_ice',Properties:{age:'2'}}"); ++ register(3395, "{Name:'minecraft:frosted_ice',Properties:{age:'3'}}", "{Name:'minecraft:frosted_ice',Properties:{age:'3'}}"); ++ register(3408, "{Name:'minecraft:magma_block'}", "{Name:'minecraft:magma'}"); ++ register(3424, "{Name:'minecraft:nether_wart_block'}", "{Name:'minecraft:nether_wart_block'}"); ++ register(3440, "{Name:'minecraft:red_nether_bricks'}", "{Name:'minecraft:red_nether_brick'}"); ++ register(3456, "{Name:'minecraft:bone_block',Properties:{axis:'y'}}", "{Name:'minecraft:bone_block',Properties:{axis:'y'}}"); ++ register(3460, "{Name:'minecraft:bone_block',Properties:{axis:'x'}}", "{Name:'minecraft:bone_block',Properties:{axis:'x'}}"); ++ register(3464, "{Name:'minecraft:bone_block',Properties:{axis:'z'}}", "{Name:'minecraft:bone_block',Properties:{axis:'z'}}"); ++ register(3472, "{Name:'minecraft:structure_void'}", "{Name:'minecraft:structure_void'}"); ++ register(3488, "{Name:'minecraft:observer',Properties:{facing:'down',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'down',powered:'false'}}"); ++ register(3489, "{Name:'minecraft:observer',Properties:{facing:'up',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'up',powered:'false'}}"); ++ register(3490, "{Name:'minecraft:observer',Properties:{facing:'north',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'north',powered:'false'}}"); ++ register(3491, "{Name:'minecraft:observer',Properties:{facing:'south',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'south',powered:'false'}}"); ++ register(3492, "{Name:'minecraft:observer',Properties:{facing:'west',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'west',powered:'false'}}"); ++ register(3493, "{Name:'minecraft:observer',Properties:{facing:'east',powered:'false'}}", "{Name:'minecraft:observer',Properties:{facing:'east',powered:'false'}}"); ++ register(3496, "{Name:'minecraft:observer',Properties:{facing:'down',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'down',powered:'true'}}"); ++ register(3497, "{Name:'minecraft:observer',Properties:{facing:'up',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'up',powered:'true'}}"); ++ register(3498, "{Name:'minecraft:observer',Properties:{facing:'north',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'north',powered:'true'}}"); ++ register(3499, "{Name:'minecraft:observer',Properties:{facing:'south',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'south',powered:'true'}}"); ++ register(3500, "{Name:'minecraft:observer',Properties:{facing:'west',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'west',powered:'true'}}"); ++ register(3501, "{Name:'minecraft:observer',Properties:{facing:'east',powered:'true'}}", "{Name:'minecraft:observer',Properties:{facing:'east',powered:'true'}}"); ++ register(3504, "{Name:'minecraft:white_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'down'}}"); ++ register(3505, "{Name:'minecraft:white_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'up'}}"); ++ register(3506, "{Name:'minecraft:white_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'north'}}"); ++ register(3507, "{Name:'minecraft:white_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'south'}}"); ++ register(3508, "{Name:'minecraft:white_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'west'}}"); ++ register(3509, "{Name:'minecraft:white_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:white_shulker_box',Properties:{facing:'east'}}"); ++ register(3520, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'down'}}"); ++ register(3521, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'up'}}"); ++ register(3522, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'north'}}"); ++ register(3523, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'south'}}"); ++ register(3524, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'west'}}"); ++ register(3525, "{Name:'minecraft:orange_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:orange_shulker_box',Properties:{facing:'east'}}"); ++ register(3536, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'down'}}"); ++ register(3537, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'up'}}"); ++ register(3538, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'north'}}"); ++ register(3539, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'south'}}"); ++ register(3540, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'west'}}"); ++ register(3541, "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:magenta_shulker_box',Properties:{facing:'east'}}"); ++ register(3552, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'down'}}"); ++ register(3553, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'up'}}"); ++ register(3554, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'north'}}"); ++ register(3555, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'south'}}"); ++ register(3556, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'west'}}"); ++ register(3557, "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:light_blue_shulker_box',Properties:{facing:'east'}}"); ++ register(3568, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'down'}}"); ++ register(3569, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'up'}}"); ++ register(3570, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'north'}}"); ++ register(3571, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'south'}}"); ++ register(3572, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'west'}}"); ++ register(3573, "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:yellow_shulker_box',Properties:{facing:'east'}}"); ++ register(3584, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'down'}}"); ++ register(3585, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'up'}}"); ++ register(3586, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'north'}}"); ++ register(3587, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'south'}}"); ++ register(3588, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'west'}}"); ++ register(3589, "{Name:'minecraft:lime_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:lime_shulker_box',Properties:{facing:'east'}}"); ++ register(3600, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'down'}}"); ++ register(3601, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'up'}}"); ++ register(3602, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'north'}}"); ++ register(3603, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'south'}}"); ++ register(3604, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'west'}}"); ++ register(3605, "{Name:'minecraft:pink_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:pink_shulker_box',Properties:{facing:'east'}}"); ++ register(3616, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'down'}}"); ++ register(3617, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'up'}}"); ++ register(3618, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'north'}}"); ++ register(3619, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'south'}}"); ++ register(3620, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'west'}}"); ++ register(3621, "{Name:'minecraft:gray_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:gray_shulker_box',Properties:{facing:'east'}}"); ++ register(3632, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'down'}}"); ++ register(3633, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'up'}}"); ++ register(3634, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'north'}}"); ++ register(3635, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'south'}}"); ++ register(3636, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'west'}}"); ++ register(3637, "{Name:'minecraft:light_gray_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:silver_shulker_box',Properties:{facing:'east'}}"); ++ register(3648, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'down'}}"); ++ register(3649, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'up'}}"); ++ register(3650, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'north'}}"); ++ register(3651, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'south'}}"); ++ register(3652, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'west'}}"); ++ register(3653, "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:cyan_shulker_box',Properties:{facing:'east'}}"); ++ register(3664, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'down'}}"); ++ register(3665, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'up'}}"); ++ register(3666, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'north'}}"); ++ register(3667, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'south'}}"); ++ register(3668, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'west'}}"); ++ register(3669, "{Name:'minecraft:purple_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:purple_shulker_box',Properties:{facing:'east'}}"); ++ register(3680, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'down'}}"); ++ register(3681, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'up'}}"); ++ register(3682, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'north'}}"); ++ register(3683, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'south'}}"); ++ register(3684, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'west'}}"); ++ register(3685, "{Name:'minecraft:blue_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:blue_shulker_box',Properties:{facing:'east'}}"); ++ register(3696, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'down'}}"); ++ register(3697, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'up'}}"); ++ register(3698, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'north'}}"); ++ register(3699, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'south'}}"); ++ register(3700, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'west'}}"); ++ register(3701, "{Name:'minecraft:brown_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:brown_shulker_box',Properties:{facing:'east'}}"); ++ register(3712, "{Name:'minecraft:green_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'down'}}"); ++ register(3713, "{Name:'minecraft:green_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'up'}}"); ++ register(3714, "{Name:'minecraft:green_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'north'}}"); ++ register(3715, "{Name:'minecraft:green_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'south'}}"); ++ register(3716, "{Name:'minecraft:green_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'west'}}"); ++ register(3717, "{Name:'minecraft:green_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:green_shulker_box',Properties:{facing:'east'}}"); ++ register(3728, "{Name:'minecraft:red_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'down'}}"); ++ register(3729, "{Name:'minecraft:red_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'up'}}"); ++ register(3730, "{Name:'minecraft:red_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'north'}}"); ++ register(3731, "{Name:'minecraft:red_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'south'}}"); ++ register(3732, "{Name:'minecraft:red_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'west'}}"); ++ register(3733, "{Name:'minecraft:red_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:red_shulker_box',Properties:{facing:'east'}}"); ++ register(3744, "{Name:'minecraft:black_shulker_box',Properties:{facing:'down'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'down'}}"); ++ register(3745, "{Name:'minecraft:black_shulker_box',Properties:{facing:'up'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'up'}}"); ++ register(3746, "{Name:'minecraft:black_shulker_box',Properties:{facing:'north'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'north'}}"); ++ register(3747, "{Name:'minecraft:black_shulker_box',Properties:{facing:'south'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'south'}}"); ++ register(3748, "{Name:'minecraft:black_shulker_box',Properties:{facing:'west'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'west'}}"); ++ register(3749, "{Name:'minecraft:black_shulker_box',Properties:{facing:'east'}}", "{Name:'minecraft:black_shulker_box',Properties:{facing:'east'}}"); ++ register(3760, "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3761, "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3762, "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3763, "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:white_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3776, "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3777, "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3778, "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3779, "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:orange_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3792, "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3793, "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3794, "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3795, "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:magenta_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3808, "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3809, "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3810, "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3811, "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:light_blue_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3824, "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3825, "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3826, "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3827, "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:yellow_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3840, "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3841, "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3842, "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3843, "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:lime_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3856, "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3857, "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3858, "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3859, "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:pink_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3872, "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3873, "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3874, "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3875, "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:gray_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3888, "{Name:'minecraft:light_gray_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:silver_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3889, "{Name:'minecraft:light_gray_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:silver_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3890, "{Name:'minecraft:light_gray_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:silver_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3891, "{Name:'minecraft:light_gray_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:silver_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3904, "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3905, "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3906, "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3907, "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:cyan_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3920, "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3921, "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3922, "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3923, "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:purple_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3936, "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3937, "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3938, "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3939, "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:blue_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3952, "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3953, "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3954, "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3955, "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:brown_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3968, "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3969, "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3970, "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3971, "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:green_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(3984, "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(3985, "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(3986, "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(3987, "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:red_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(4000, "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'south'}}", "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'south'}}"); ++ register(4001, "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'west'}}", "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'west'}}"); ++ register(4002, "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'north'}}", "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'north'}}"); ++ register(4003, "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'east'}}", "{Name:'minecraft:black_glazed_terracotta',Properties:{facing:'east'}}"); ++ register(4016, "{Name:'minecraft:white_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'white'}}"); ++ register(4017, "{Name:'minecraft:orange_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'orange'}}"); ++ register(4018, "{Name:'minecraft:magenta_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'magenta'}}"); ++ register(4019, "{Name:'minecraft:light_blue_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'light_blue'}}"); ++ register(4020, "{Name:'minecraft:yellow_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'yellow'}}"); ++ register(4021, "{Name:'minecraft:lime_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'lime'}}"); ++ register(4022, "{Name:'minecraft:pink_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'pink'}}"); ++ register(4023, "{Name:'minecraft:gray_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'gray'}}"); ++ register(4024, "{Name:'minecraft:light_gray_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'silver'}}"); ++ register(4025, "{Name:'minecraft:cyan_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'cyan'}}"); ++ register(4026, "{Name:'minecraft:purple_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'purple'}}"); ++ register(4027, "{Name:'minecraft:blue_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'blue'}}"); ++ register(4028, "{Name:'minecraft:brown_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'brown'}}"); ++ register(4029, "{Name:'minecraft:green_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'green'}}"); ++ register(4030, "{Name:'minecraft:red_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'red'}}"); ++ register(4031, "{Name:'minecraft:black_concrete'}", "{Name:'minecraft:concrete',Properties:{color:'black'}}"); ++ register(4032, "{Name:'minecraft:white_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'white'}}"); ++ register(4033, "{Name:'minecraft:orange_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'orange'}}"); ++ register(4034, "{Name:'minecraft:magenta_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'magenta'}}"); ++ register(4035, "{Name:'minecraft:light_blue_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'light_blue'}}"); ++ register(4036, "{Name:'minecraft:yellow_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'yellow'}}"); ++ register(4037, "{Name:'minecraft:lime_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'lime'}}"); ++ register(4038, "{Name:'minecraft:pink_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'pink'}}"); ++ register(4039, "{Name:'minecraft:gray_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'gray'}}"); ++ register(4040, "{Name:'minecraft:light_gray_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'silver'}}"); ++ register(4041, "{Name:'minecraft:cyan_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'cyan'}}"); ++ register(4042, "{Name:'minecraft:purple_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'purple'}}"); ++ register(4043, "{Name:'minecraft:blue_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'blue'}}"); ++ register(4044, "{Name:'minecraft:brown_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'brown'}}"); ++ register(4045, "{Name:'minecraft:green_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'green'}}"); ++ register(4046, "{Name:'minecraft:red_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'red'}}"); ++ register(4047, "{Name:'minecraft:black_concrete_powder'}", "{Name:'minecraft:concrete_powder',Properties:{color:'black'}}"); ++ register(4080, "{Name:'minecraft:structure_block',Properties:{mode:'save'}}", "{Name:'minecraft:structure_block',Properties:{mode:'save'}}"); ++ register(4081, "{Name:'minecraft:structure_block',Properties:{mode:'load'}}", "{Name:'minecraft:structure_block',Properties:{mode:'load'}}"); ++ register(4082, "{Name:'minecraft:structure_block',Properties:{mode:'corner'}}", "{Name:'minecraft:structure_block',Properties:{mode:'corner'}}"); ++ register(4083, "{Name:'minecraft:structure_block',Properties:{mode:'data'}}", "{Name:'minecraft:structure_block',Properties:{mode:'data'}}"); ++ finalizeMaps(); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperItemNameV102.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperItemNameV102.java +new file mode 100644 +index 0000000000000000000000000000000000000000..86f6aa3e3fa886976809f350fc5eb16f6a026ed9 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperItemNameV102.java +@@ -0,0 +1,533 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++public final class HelperItemNameV102 { ++ ++ // This class is responsible for mapping the id -> string update in itemstacks and potions ++ ++ private static final Int2ObjectOpenHashMap ITEM_NAMES = new Int2ObjectOpenHashMap() { ++ @Override ++ public String put(final int k, final String o) { ++ final String ret = super.put(k, o); ++ ++ if (ret != null) { ++ throw new IllegalStateException("Mapping already exists for " + k + ": prev: " + ret + ", new: " + o); ++ } ++ ++ return ret; ++ } ++ }; ++ ++ static { ++ ITEM_NAMES.put(0, "minecraft:air"); ++ ITEM_NAMES.put(1, "minecraft:stone"); ++ ITEM_NAMES.put(2, "minecraft:grass"); ++ ITEM_NAMES.put(3, "minecraft:dirt"); ++ ITEM_NAMES.put(4, "minecraft:cobblestone"); ++ ITEM_NAMES.put(5, "minecraft:planks"); ++ ITEM_NAMES.put(6, "minecraft:sapling"); ++ ITEM_NAMES.put(7, "minecraft:bedrock"); ++ ITEM_NAMES.put(8, "minecraft:flowing_water"); ++ ITEM_NAMES.put(9, "minecraft:water"); ++ ITEM_NAMES.put(10, "minecraft:flowing_lava"); ++ ITEM_NAMES.put(11, "minecraft:lava"); ++ ITEM_NAMES.put(12, "minecraft:sand"); ++ ITEM_NAMES.put(13, "minecraft:gravel"); ++ ITEM_NAMES.put(14, "minecraft:gold_ore"); ++ ITEM_NAMES.put(15, "minecraft:iron_ore"); ++ ITEM_NAMES.put(16, "minecraft:coal_ore"); ++ ITEM_NAMES.put(17, "minecraft:log"); ++ ITEM_NAMES.put(18, "minecraft:leaves"); ++ ITEM_NAMES.put(19, "minecraft:sponge"); ++ ITEM_NAMES.put(20, "minecraft:glass"); ++ ITEM_NAMES.put(21, "minecraft:lapis_ore"); ++ ITEM_NAMES.put(22, "minecraft:lapis_block"); ++ ITEM_NAMES.put(23, "minecraft:dispenser"); ++ ITEM_NAMES.put(24, "minecraft:sandstone"); ++ ITEM_NAMES.put(25, "minecraft:noteblock"); ++ ITEM_NAMES.put(27, "minecraft:golden_rail"); ++ ITEM_NAMES.put(28, "minecraft:detector_rail"); ++ ITEM_NAMES.put(29, "minecraft:sticky_piston"); ++ ITEM_NAMES.put(30, "minecraft:web"); ++ ITEM_NAMES.put(31, "minecraft:tallgrass"); ++ ITEM_NAMES.put(32, "minecraft:deadbush"); ++ ITEM_NAMES.put(33, "minecraft:piston"); ++ ITEM_NAMES.put(35, "minecraft:wool"); ++ ITEM_NAMES.put(37, "minecraft:yellow_flower"); ++ ITEM_NAMES.put(38, "minecraft:red_flower"); ++ ITEM_NAMES.put(39, "minecraft:brown_mushroom"); ++ ITEM_NAMES.put(40, "minecraft:red_mushroom"); ++ ITEM_NAMES.put(41, "minecraft:gold_block"); ++ ITEM_NAMES.put(42, "minecraft:iron_block"); ++ ITEM_NAMES.put(43, "minecraft:double_stone_slab"); ++ ITEM_NAMES.put(44, "minecraft:stone_slab"); ++ ITEM_NAMES.put(45, "minecraft:brick_block"); ++ ITEM_NAMES.put(46, "minecraft:tnt"); ++ ITEM_NAMES.put(47, "minecraft:bookshelf"); ++ ITEM_NAMES.put(48, "minecraft:mossy_cobblestone"); ++ ITEM_NAMES.put(49, "minecraft:obsidian"); ++ ITEM_NAMES.put(50, "minecraft:torch"); ++ ITEM_NAMES.put(51, "minecraft:fire"); ++ ITEM_NAMES.put(52, "minecraft:mob_spawner"); ++ ITEM_NAMES.put(53, "minecraft:oak_stairs"); ++ ITEM_NAMES.put(54, "minecraft:chest"); ++ ITEM_NAMES.put(56, "minecraft:diamond_ore"); ++ ITEM_NAMES.put(57, "minecraft:diamond_block"); ++ ITEM_NAMES.put(58, "minecraft:crafting_table"); ++ ITEM_NAMES.put(60, "minecraft:farmland"); ++ ITEM_NAMES.put(61, "minecraft:furnace"); ++ ITEM_NAMES.put(62, "minecraft:lit_furnace"); ++ ITEM_NAMES.put(65, "minecraft:ladder"); ++ ITEM_NAMES.put(66, "minecraft:rail"); ++ ITEM_NAMES.put(67, "minecraft:stone_stairs"); ++ ITEM_NAMES.put(69, "minecraft:lever"); ++ ITEM_NAMES.put(70, "minecraft:stone_pressure_plate"); ++ ITEM_NAMES.put(72, "minecraft:wooden_pressure_plate"); ++ ITEM_NAMES.put(73, "minecraft:redstone_ore"); ++ ITEM_NAMES.put(76, "minecraft:redstone_torch"); ++ ITEM_NAMES.put(77, "minecraft:stone_button"); ++ ITEM_NAMES.put(78, "minecraft:snow_layer"); ++ ITEM_NAMES.put(79, "minecraft:ice"); ++ ITEM_NAMES.put(80, "minecraft:snow"); ++ ITEM_NAMES.put(81, "minecraft:cactus"); ++ ITEM_NAMES.put(82, "minecraft:clay"); ++ ITEM_NAMES.put(84, "minecraft:jukebox"); ++ ITEM_NAMES.put(85, "minecraft:fence"); ++ ITEM_NAMES.put(86, "minecraft:pumpkin"); ++ ITEM_NAMES.put(87, "minecraft:netherrack"); ++ ITEM_NAMES.put(88, "minecraft:soul_sand"); ++ ITEM_NAMES.put(89, "minecraft:glowstone"); ++ ITEM_NAMES.put(90, "minecraft:portal"); ++ ITEM_NAMES.put(91, "minecraft:lit_pumpkin"); ++ ITEM_NAMES.put(95, "minecraft:stained_glass"); ++ ITEM_NAMES.put(96, "minecraft:trapdoor"); ++ ITEM_NAMES.put(97, "minecraft:monster_egg"); ++ ITEM_NAMES.put(98, "minecraft:stonebrick"); ++ ITEM_NAMES.put(99, "minecraft:brown_mushroom_block"); ++ ITEM_NAMES.put(100, "minecraft:red_mushroom_block"); ++ ITEM_NAMES.put(101, "minecraft:iron_bars"); ++ ITEM_NAMES.put(102, "minecraft:glass_pane"); ++ ITEM_NAMES.put(103, "minecraft:melon_block"); ++ ITEM_NAMES.put(106, "minecraft:vine"); ++ ITEM_NAMES.put(107, "minecraft:fence_gate"); ++ ITEM_NAMES.put(108, "minecraft:brick_stairs"); ++ ITEM_NAMES.put(109, "minecraft:stone_brick_stairs"); ++ ITEM_NAMES.put(110, "minecraft:mycelium"); ++ ITEM_NAMES.put(111, "minecraft:waterlily"); ++ ITEM_NAMES.put(112, "minecraft:nether_brick"); ++ ITEM_NAMES.put(113, "minecraft:nether_brick_fence"); ++ ITEM_NAMES.put(114, "minecraft:nether_brick_stairs"); ++ ITEM_NAMES.put(116, "minecraft:enchanting_table"); ++ ITEM_NAMES.put(119, "minecraft:end_portal"); ++ ITEM_NAMES.put(120, "minecraft:end_portal_frame"); ++ ITEM_NAMES.put(121, "minecraft:end_stone"); ++ ITEM_NAMES.put(122, "minecraft:dragon_egg"); ++ ITEM_NAMES.put(123, "minecraft:redstone_lamp"); ++ ITEM_NAMES.put(125, "minecraft:double_wooden_slab"); ++ ITEM_NAMES.put(126, "minecraft:wooden_slab"); ++ ITEM_NAMES.put(127, "minecraft:cocoa"); ++ ITEM_NAMES.put(128, "minecraft:sandstone_stairs"); ++ ITEM_NAMES.put(129, "minecraft:emerald_ore"); ++ ITEM_NAMES.put(130, "minecraft:ender_chest"); ++ ITEM_NAMES.put(131, "minecraft:tripwire_hook"); ++ ITEM_NAMES.put(133, "minecraft:emerald_block"); ++ ITEM_NAMES.put(134, "minecraft:spruce_stairs"); ++ ITEM_NAMES.put(135, "minecraft:birch_stairs"); ++ ITEM_NAMES.put(136, "minecraft:jungle_stairs"); ++ ITEM_NAMES.put(137, "minecraft:command_block"); ++ ITEM_NAMES.put(138, "minecraft:beacon"); ++ ITEM_NAMES.put(139, "minecraft:cobblestone_wall"); ++ ITEM_NAMES.put(141, "minecraft:carrots"); ++ ITEM_NAMES.put(142, "minecraft:potatoes"); ++ ITEM_NAMES.put(143, "minecraft:wooden_button"); ++ ITEM_NAMES.put(145, "minecraft:anvil"); ++ ITEM_NAMES.put(146, "minecraft:trapped_chest"); ++ ITEM_NAMES.put(147, "minecraft:light_weighted_pressure_plate"); ++ ITEM_NAMES.put(148, "minecraft:heavy_weighted_pressure_plate"); ++ ITEM_NAMES.put(151, "minecraft:daylight_detector"); ++ ITEM_NAMES.put(152, "minecraft:redstone_block"); ++ ITEM_NAMES.put(153, "minecraft:quartz_ore"); ++ ITEM_NAMES.put(154, "minecraft:hopper"); ++ ITEM_NAMES.put(155, "minecraft:quartz_block"); ++ ITEM_NAMES.put(156, "minecraft:quartz_stairs"); ++ ITEM_NAMES.put(157, "minecraft:activator_rail"); ++ ITEM_NAMES.put(158, "minecraft:dropper"); ++ ITEM_NAMES.put(159, "minecraft:stained_hardened_clay"); ++ ITEM_NAMES.put(160, "minecraft:stained_glass_pane"); ++ ITEM_NAMES.put(161, "minecraft:leaves2"); ++ ITEM_NAMES.put(162, "minecraft:log2"); ++ ITEM_NAMES.put(163, "minecraft:acacia_stairs"); ++ ITEM_NAMES.put(164, "minecraft:dark_oak_stairs"); ++ ITEM_NAMES.put(170, "minecraft:hay_block"); ++ ITEM_NAMES.put(171, "minecraft:carpet"); ++ ITEM_NAMES.put(172, "minecraft:hardened_clay"); ++ ITEM_NAMES.put(173, "minecraft:coal_block"); ++ ITEM_NAMES.put(174, "minecraft:packed_ice"); ++ ITEM_NAMES.put(175, "minecraft:double_plant"); ++ ITEM_NAMES.put(256, "minecraft:iron_shovel"); ++ ITEM_NAMES.put(257, "minecraft:iron_pickaxe"); ++ ITEM_NAMES.put(258, "minecraft:iron_axe"); ++ ITEM_NAMES.put(259, "minecraft:flint_and_steel"); ++ ITEM_NAMES.put(260, "minecraft:apple"); ++ ITEM_NAMES.put(261, "minecraft:bow"); ++ ITEM_NAMES.put(262, "minecraft:arrow"); ++ ITEM_NAMES.put(263, "minecraft:coal"); ++ ITEM_NAMES.put(264, "minecraft:diamond"); ++ ITEM_NAMES.put(265, "minecraft:iron_ingot"); ++ ITEM_NAMES.put(266, "minecraft:gold_ingot"); ++ ITEM_NAMES.put(267, "minecraft:iron_sword"); ++ ITEM_NAMES.put(268, "minecraft:wooden_sword"); ++ ITEM_NAMES.put(269, "minecraft:wooden_shovel"); ++ ITEM_NAMES.put(270, "minecraft:wooden_pickaxe"); ++ ITEM_NAMES.put(271, "minecraft:wooden_axe"); ++ ITEM_NAMES.put(272, "minecraft:stone_sword"); ++ ITEM_NAMES.put(273, "minecraft:stone_shovel"); ++ ITEM_NAMES.put(274, "minecraft:stone_pickaxe"); ++ ITEM_NAMES.put(275, "minecraft:stone_axe"); ++ ITEM_NAMES.put(276, "minecraft:diamond_sword"); ++ ITEM_NAMES.put(277, "minecraft:diamond_shovel"); ++ ITEM_NAMES.put(278, "minecraft:diamond_pickaxe"); ++ ITEM_NAMES.put(279, "minecraft:diamond_axe"); ++ ITEM_NAMES.put(280, "minecraft:stick"); ++ ITEM_NAMES.put(281, "minecraft:bowl"); ++ ITEM_NAMES.put(282, "minecraft:mushroom_stew"); ++ ITEM_NAMES.put(283, "minecraft:golden_sword"); ++ ITEM_NAMES.put(284, "minecraft:golden_shovel"); ++ ITEM_NAMES.put(285, "minecraft:golden_pickaxe"); ++ ITEM_NAMES.put(286, "minecraft:golden_axe"); ++ ITEM_NAMES.put(287, "minecraft:string"); ++ ITEM_NAMES.put(288, "minecraft:feather"); ++ ITEM_NAMES.put(289, "minecraft:gunpowder"); ++ ITEM_NAMES.put(290, "minecraft:wooden_hoe"); ++ ITEM_NAMES.put(291, "minecraft:stone_hoe"); ++ ITEM_NAMES.put(292, "minecraft:iron_hoe"); ++ ITEM_NAMES.put(293, "minecraft:diamond_hoe"); ++ ITEM_NAMES.put(294, "minecraft:golden_hoe"); ++ ITEM_NAMES.put(295, "minecraft:wheat_seeds"); ++ ITEM_NAMES.put(296, "minecraft:wheat"); ++ ITEM_NAMES.put(297, "minecraft:bread"); ++ ITEM_NAMES.put(298, "minecraft:leather_helmet"); ++ ITEM_NAMES.put(299, "minecraft:leather_chestplate"); ++ ITEM_NAMES.put(300, "minecraft:leather_leggings"); ++ ITEM_NAMES.put(301, "minecraft:leather_boots"); ++ ITEM_NAMES.put(302, "minecraft:chainmail_helmet"); ++ ITEM_NAMES.put(303, "minecraft:chainmail_chestplate"); ++ ITEM_NAMES.put(304, "minecraft:chainmail_leggings"); ++ ITEM_NAMES.put(305, "minecraft:chainmail_boots"); ++ ITEM_NAMES.put(306, "minecraft:iron_helmet"); ++ ITEM_NAMES.put(307, "minecraft:iron_chestplate"); ++ ITEM_NAMES.put(308, "minecraft:iron_leggings"); ++ ITEM_NAMES.put(309, "minecraft:iron_boots"); ++ ITEM_NAMES.put(310, "minecraft:diamond_helmet"); ++ ITEM_NAMES.put(311, "minecraft:diamond_chestplate"); ++ ITEM_NAMES.put(312, "minecraft:diamond_leggings"); ++ ITEM_NAMES.put(313, "minecraft:diamond_boots"); ++ ITEM_NAMES.put(314, "minecraft:golden_helmet"); ++ ITEM_NAMES.put(315, "minecraft:golden_chestplate"); ++ ITEM_NAMES.put(316, "minecraft:golden_leggings"); ++ ITEM_NAMES.put(317, "minecraft:golden_boots"); ++ ITEM_NAMES.put(318, "minecraft:flint"); ++ ITEM_NAMES.put(319, "minecraft:porkchop"); ++ ITEM_NAMES.put(320, "minecraft:cooked_porkchop"); ++ ITEM_NAMES.put(321, "minecraft:painting"); ++ ITEM_NAMES.put(322, "minecraft:golden_apple"); ++ ITEM_NAMES.put(323, "minecraft:sign"); ++ ITEM_NAMES.put(324, "minecraft:wooden_door"); ++ ITEM_NAMES.put(325, "minecraft:bucket"); ++ ITEM_NAMES.put(326, "minecraft:water_bucket"); ++ ITEM_NAMES.put(327, "minecraft:lava_bucket"); ++ ITEM_NAMES.put(328, "minecraft:minecart"); ++ ITEM_NAMES.put(329, "minecraft:saddle"); ++ ITEM_NAMES.put(330, "minecraft:iron_door"); ++ ITEM_NAMES.put(331, "minecraft:redstone"); ++ ITEM_NAMES.put(332, "minecraft:snowball"); ++ ITEM_NAMES.put(333, "minecraft:boat"); ++ ITEM_NAMES.put(334, "minecraft:leather"); ++ ITEM_NAMES.put(335, "minecraft:milk_bucket"); ++ ITEM_NAMES.put(336, "minecraft:brick"); ++ ITEM_NAMES.put(337, "minecraft:clay_ball"); ++ ITEM_NAMES.put(338, "minecraft:reeds"); ++ ITEM_NAMES.put(339, "minecraft:paper"); ++ ITEM_NAMES.put(340, "minecraft:book"); ++ ITEM_NAMES.put(341, "minecraft:slime_ball"); ++ ITEM_NAMES.put(342, "minecraft:chest_minecart"); ++ ITEM_NAMES.put(343, "minecraft:furnace_minecart"); ++ ITEM_NAMES.put(344, "minecraft:egg"); ++ ITEM_NAMES.put(345, "minecraft:compass"); ++ ITEM_NAMES.put(346, "minecraft:fishing_rod"); ++ ITEM_NAMES.put(347, "minecraft:clock"); ++ ITEM_NAMES.put(348, "minecraft:glowstone_dust"); ++ ITEM_NAMES.put(349, "minecraft:fish"); ++ ITEM_NAMES.put(350, "minecraft:cooked_fish"); // Fix typo, the game never recognized cooked_fished ++ ITEM_NAMES.put(351, "minecraft:dye"); ++ ITEM_NAMES.put(352, "minecraft:bone"); ++ ITEM_NAMES.put(353, "minecraft:sugar"); ++ ITEM_NAMES.put(354, "minecraft:cake"); ++ ITEM_NAMES.put(355, "minecraft:bed"); ++ ITEM_NAMES.put(356, "minecraft:repeater"); ++ ITEM_NAMES.put(357, "minecraft:cookie"); ++ ITEM_NAMES.put(358, "minecraft:filled_map"); ++ ITEM_NAMES.put(359, "minecraft:shears"); ++ ITEM_NAMES.put(360, "minecraft:melon"); ++ ITEM_NAMES.put(361, "minecraft:pumpkin_seeds"); ++ ITEM_NAMES.put(362, "minecraft:melon_seeds"); ++ ITEM_NAMES.put(363, "minecraft:beef"); ++ ITEM_NAMES.put(364, "minecraft:cooked_beef"); ++ ITEM_NAMES.put(365, "minecraft:chicken"); ++ ITEM_NAMES.put(366, "minecraft:cooked_chicken"); ++ ITEM_NAMES.put(367, "minecraft:rotten_flesh"); ++ ITEM_NAMES.put(368, "minecraft:ender_pearl"); ++ ITEM_NAMES.put(369, "minecraft:blaze_rod"); ++ ITEM_NAMES.put(370, "minecraft:ghast_tear"); ++ ITEM_NAMES.put(371, "minecraft:gold_nugget"); ++ ITEM_NAMES.put(372, "minecraft:nether_wart"); ++ ITEM_NAMES.put(373, "minecraft:potion"); ++ ITEM_NAMES.put(374, "minecraft:glass_bottle"); ++ ITEM_NAMES.put(375, "minecraft:spider_eye"); ++ ITEM_NAMES.put(376, "minecraft:fermented_spider_eye"); ++ ITEM_NAMES.put(377, "minecraft:blaze_powder"); ++ ITEM_NAMES.put(378, "minecraft:magma_cream"); ++ ITEM_NAMES.put(379, "minecraft:brewing_stand"); ++ ITEM_NAMES.put(380, "minecraft:cauldron"); ++ ITEM_NAMES.put(381, "minecraft:ender_eye"); ++ ITEM_NAMES.put(382, "minecraft:speckled_melon"); ++ ITEM_NAMES.put(383, "minecraft:spawn_egg"); ++ ITEM_NAMES.put(384, "minecraft:experience_bottle"); ++ ITEM_NAMES.put(385, "minecraft:fire_charge"); ++ ITEM_NAMES.put(386, "minecraft:writable_book"); ++ ITEM_NAMES.put(387, "minecraft:written_book"); ++ ITEM_NAMES.put(388, "minecraft:emerald"); ++ ITEM_NAMES.put(389, "minecraft:item_frame"); ++ ITEM_NAMES.put(390, "minecraft:flower_pot"); ++ ITEM_NAMES.put(391, "minecraft:carrot"); ++ ITEM_NAMES.put(392, "minecraft:potato"); ++ ITEM_NAMES.put(393, "minecraft:baked_potato"); ++ ITEM_NAMES.put(394, "minecraft:poisonous_potato"); ++ ITEM_NAMES.put(395, "minecraft:map"); ++ ITEM_NAMES.put(396, "minecraft:golden_carrot"); ++ ITEM_NAMES.put(397, "minecraft:skull"); ++ ITEM_NAMES.put(398, "minecraft:carrot_on_a_stick"); ++ ITEM_NAMES.put(399, "minecraft:nether_star"); ++ ITEM_NAMES.put(400, "minecraft:pumpkin_pie"); ++ ITEM_NAMES.put(401, "minecraft:fireworks"); ++ ITEM_NAMES.put(402, "minecraft:firework_charge"); ++ ITEM_NAMES.put(403, "minecraft:enchanted_book"); ++ ITEM_NAMES.put(404, "minecraft:comparator"); ++ ITEM_NAMES.put(405, "minecraft:netherbrick"); ++ ITEM_NAMES.put(406, "minecraft:quartz"); ++ ITEM_NAMES.put(407, "minecraft:tnt_minecart"); ++ ITEM_NAMES.put(408, "minecraft:hopper_minecart"); ++ ITEM_NAMES.put(417, "minecraft:iron_horse_armor"); ++ ITEM_NAMES.put(418, "minecraft:golden_horse_armor"); ++ ITEM_NAMES.put(419, "minecraft:diamond_horse_armor"); ++ ITEM_NAMES.put(420, "minecraft:lead"); ++ ITEM_NAMES.put(421, "minecraft:name_tag"); ++ ITEM_NAMES.put(422, "minecraft:command_block_minecart"); ++ ITEM_NAMES.put(2256, "minecraft:record_13"); ++ ITEM_NAMES.put(2257, "minecraft:record_cat"); ++ ITEM_NAMES.put(2258, "minecraft:record_blocks"); ++ ITEM_NAMES.put(2259, "minecraft:record_chirp"); ++ ITEM_NAMES.put(2260, "minecraft:record_far"); ++ ITEM_NAMES.put(2261, "minecraft:record_mall"); ++ ITEM_NAMES.put(2262, "minecraft:record_mellohi"); ++ ITEM_NAMES.put(2263, "minecraft:record_stal"); ++ ITEM_NAMES.put(2264, "minecraft:record_strad"); ++ ITEM_NAMES.put(2265, "minecraft:record_ward"); ++ ITEM_NAMES.put(2266, "minecraft:record_11"); ++ ITEM_NAMES.put(2267, "minecraft:record_wait"); ++ // https://github.com/starlis/empirecraft/commit/2da59d1901407fc0c135ef0458c0fe9b016570b3 ++ // It's likely that this is a result of old CB/Spigot behavior still writing ids into items as ints. ++ // These ids do not appear to be used by regular MC anyways, so I do not see the harm of porting it here. ++ // Extras can be added if needed ++ String[] extra = new String[4_000]; ++ // EMC start ++ extra[409] = "minecraft:prismarine_shard"; ++ extra[410] = "minecraft:prismarine_crystals"; ++ extra[411] = "minecraft:rabbit"; ++ extra[412] = "minecraft:cooked_rabbit"; ++ extra[413] = "minecraft:rabbit_stew"; ++ extra[414] = "minecraft:rabbit_foot"; ++ extra[415] = "minecraft:rabbit_hide"; ++ extra[416] = "minecraft:armor_stand"; ++ extra[423] = "minecraft:mutton"; ++ extra[424] = "minecraft:cooked_mutton"; ++ extra[425] = "minecraft:banner"; ++ extra[426] = "minecraft:end_crystal"; ++ extra[427] = "minecraft:spruce_door"; ++ extra[428] = "minecraft:birch_door"; ++ extra[429] = "minecraft:jungle_door"; ++ extra[430] = "minecraft:acacia_door"; ++ extra[431] = "minecraft:dark_oak_door"; ++ extra[432] = "minecraft:chorus_fruit"; ++ extra[433] = "minecraft:chorus_fruit_popped"; ++ extra[434] = "minecraft:beetroot"; ++ extra[435] = "minecraft:beetroot_seeds"; ++ extra[436] = "minecraft:beetroot_soup"; ++ extra[437] = "minecraft:dragon_breath"; ++ extra[438] = "minecraft:splash_potion"; ++ extra[439] = "minecraft:spectral_arrow"; ++ extra[440] = "minecraft:tipped_arrow"; ++ extra[441] = "minecraft:lingering_potion"; ++ extra[442] = "minecraft:shield"; ++ extra[443] = "minecraft:elytra"; ++ extra[444] = "minecraft:spruce_boat"; ++ extra[445] = "minecraft:birch_boat"; ++ extra[446] = "minecraft:jungle_boat"; ++ extra[447] = "minecraft:acacia_boat"; ++ extra[448] = "minecraft:dark_oak_boat"; ++ extra[449] = "minecraft:totem_of_undying"; ++ extra[450] = "minecraft:shulker_shell"; ++ extra[452] = "minecraft:iron_nugget"; ++ extra[453] = "minecraft:knowledge_book"; ++ // EMC end ++ ++ // dump extra into map ++ for (int i = 0; i < extra.length; ++i) { ++ if (extra[i] != null) { ++ ITEM_NAMES.put(i, extra[i]); ++ } ++ } ++ } ++ ++ private static final String[] POTION_NAMES = new String[128]; ++ static { ++ POTION_NAMES[0] = "minecraft:water"; ++ POTION_NAMES[1] = "minecraft:regeneration"; ++ POTION_NAMES[2] = "minecraft:swiftness"; ++ POTION_NAMES[3] = "minecraft:fire_resistance"; ++ POTION_NAMES[4] = "minecraft:poison"; ++ POTION_NAMES[5] = "minecraft:healing"; ++ POTION_NAMES[6] = "minecraft:night_vision"; ++ POTION_NAMES[7] = null; ++ POTION_NAMES[8] = "minecraft:weakness"; ++ POTION_NAMES[9] = "minecraft:strength"; ++ POTION_NAMES[10] = "minecraft:slowness"; ++ POTION_NAMES[11] = "minecraft:leaping"; ++ POTION_NAMES[12] = "minecraft:harming"; ++ POTION_NAMES[13] = "minecraft:water_breathing"; ++ POTION_NAMES[14] = "minecraft:invisibility"; ++ POTION_NAMES[15] = null; ++ POTION_NAMES[16] = "minecraft:awkward"; ++ POTION_NAMES[17] = "minecraft:regeneration"; ++ POTION_NAMES[18] = "minecraft:swiftness"; ++ POTION_NAMES[19] = "minecraft:fire_resistance"; ++ POTION_NAMES[20] = "minecraft:poison"; ++ POTION_NAMES[21] = "minecraft:healing"; ++ POTION_NAMES[22] = "minecraft:night_vision"; ++ POTION_NAMES[23] = null; ++ POTION_NAMES[24] = "minecraft:weakness"; ++ POTION_NAMES[25] = "minecraft:strength"; ++ POTION_NAMES[26] = "minecraft:slowness"; ++ POTION_NAMES[27] = "minecraft:leaping"; ++ POTION_NAMES[28] = "minecraft:harming"; ++ POTION_NAMES[29] = "minecraft:water_breathing"; ++ POTION_NAMES[30] = "minecraft:invisibility"; ++ POTION_NAMES[31] = null; ++ POTION_NAMES[32] = "minecraft:thick"; ++ POTION_NAMES[33] = "minecraft:strong_regeneration"; ++ POTION_NAMES[34] = "minecraft:strong_swiftness"; ++ POTION_NAMES[35] = "minecraft:fire_resistance"; ++ POTION_NAMES[36] = "minecraft:strong_poison"; ++ POTION_NAMES[37] = "minecraft:strong_healing"; ++ POTION_NAMES[38] = "minecraft:night_vision"; ++ POTION_NAMES[39] = null; ++ POTION_NAMES[40] = "minecraft:weakness"; ++ POTION_NAMES[41] = "minecraft:strong_strength"; ++ POTION_NAMES[42] = "minecraft:slowness"; ++ POTION_NAMES[43] = "minecraft:strong_leaping"; ++ POTION_NAMES[44] = "minecraft:strong_harming"; ++ POTION_NAMES[45] = "minecraft:water_breathing"; ++ POTION_NAMES[46] = "minecraft:invisibility"; ++ POTION_NAMES[47] = null; ++ POTION_NAMES[48] = null; ++ POTION_NAMES[49] = "minecraft:strong_regeneration"; ++ POTION_NAMES[50] = "minecraft:strong_swiftness"; ++ POTION_NAMES[51] = "minecraft:fire_resistance"; ++ POTION_NAMES[52] = "minecraft:strong_poison"; ++ POTION_NAMES[53] = "minecraft:strong_healing"; ++ POTION_NAMES[54] = "minecraft:night_vision"; ++ POTION_NAMES[55] = null; ++ POTION_NAMES[56] = "minecraft:weakness"; ++ POTION_NAMES[57] = "minecraft:strong_strength"; ++ POTION_NAMES[58] = "minecraft:slowness"; ++ POTION_NAMES[59] = "minecraft:strong_leaping"; ++ POTION_NAMES[60] = "minecraft:strong_harming"; ++ POTION_NAMES[61] = "minecraft:water_breathing"; ++ POTION_NAMES[62] = "minecraft:invisibility"; ++ POTION_NAMES[63] = null; ++ POTION_NAMES[64] = "minecraft:mundane"; ++ POTION_NAMES[65] = "minecraft:long_regeneration"; ++ POTION_NAMES[66] = "minecraft:long_swiftness"; ++ POTION_NAMES[67] = "minecraft:long_fire_resistance"; ++ POTION_NAMES[68] = "minecraft:long_poison"; ++ POTION_NAMES[69] = "minecraft:healing"; ++ POTION_NAMES[70] = "minecraft:long_night_vision"; ++ POTION_NAMES[71] = null; ++ POTION_NAMES[72] = "minecraft:long_weakness"; ++ POTION_NAMES[73] = "minecraft:long_strength"; ++ POTION_NAMES[74] = "minecraft:long_slowness"; ++ POTION_NAMES[75] = "minecraft:long_leaping"; ++ POTION_NAMES[76] = "minecraft:harming"; ++ POTION_NAMES[77] = "minecraft:long_water_breathing"; ++ POTION_NAMES[78] = "minecraft:long_invisibility"; ++ POTION_NAMES[79] = null; ++ POTION_NAMES[80] = "minecraft:awkward"; ++ POTION_NAMES[81] = "minecraft:long_regeneration"; ++ POTION_NAMES[82] = "minecraft:long_swiftness"; ++ POTION_NAMES[83] = "minecraft:long_fire_resistance"; ++ POTION_NAMES[84] = "minecraft:long_poison"; ++ POTION_NAMES[85] = "minecraft:healing"; ++ POTION_NAMES[86] = "minecraft:long_night_vision"; ++ POTION_NAMES[87] = null; ++ POTION_NAMES[88] = "minecraft:long_weakness"; ++ POTION_NAMES[89] = "minecraft:long_strength"; ++ POTION_NAMES[90] = "minecraft:long_slowness"; ++ POTION_NAMES[91] = "minecraft:long_leaping"; ++ POTION_NAMES[92] = "minecraft:harming"; ++ POTION_NAMES[93] = "minecraft:long_water_breathing"; ++ POTION_NAMES[94] = "minecraft:long_invisibility"; ++ POTION_NAMES[95] = null; ++ POTION_NAMES[96] = "minecraft:thick"; ++ POTION_NAMES[97] = "minecraft:regeneration"; ++ POTION_NAMES[98] = "minecraft:swiftness"; ++ POTION_NAMES[99] = "minecraft:long_fire_resistance"; ++ POTION_NAMES[100] = "minecraft:poison"; ++ POTION_NAMES[101] = "minecraft:strong_healing"; ++ POTION_NAMES[102] = "minecraft:long_night_vision"; ++ POTION_NAMES[103] = null; ++ POTION_NAMES[104] = "minecraft:long_weakness"; ++ POTION_NAMES[105] = "minecraft:strength"; ++ POTION_NAMES[106] = "minecraft:long_slowness"; ++ POTION_NAMES[107] = "minecraft:leaping"; ++ POTION_NAMES[108] = "minecraft:strong_harming"; ++ POTION_NAMES[109] = "minecraft:long_water_breathing"; ++ POTION_NAMES[110] = "minecraft:long_invisibility"; ++ POTION_NAMES[111] = null; ++ POTION_NAMES[112] = null; ++ POTION_NAMES[113] = "minecraft:regeneration"; ++ POTION_NAMES[114] = "minecraft:swiftness"; ++ POTION_NAMES[115] = "minecraft:long_fire_resistance"; ++ POTION_NAMES[116] = "minecraft:poison"; ++ POTION_NAMES[117] = "minecraft:strong_healing"; ++ POTION_NAMES[118] = "minecraft:long_night_vision"; ++ POTION_NAMES[119] = null; ++ POTION_NAMES[120] = "minecraft:long_weakness"; ++ POTION_NAMES[121] = "minecraft:strength"; ++ POTION_NAMES[122] = "minecraft:long_slowness"; ++ POTION_NAMES[123] = "minecraft:leaping"; ++ POTION_NAMES[124] = "minecraft:strong_harming"; ++ POTION_NAMES[125] = "minecraft:long_water_breathing"; ++ POTION_NAMES[126] = "minecraft:long_invisibility"; ++ POTION_NAMES[127] = null; ++ } ++ ++ // ret is nullable, you are supposed to log when it does not exist, NOT HIDE IT! ++ public static String getNameFromId(final int id) { ++ return ITEM_NAMES.get(id); ++ } ++ ++ public static String getPotionNameFromId(final short id) { ++ return POTION_NAMES[id & 127]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperSpawnEggNameV105.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperSpawnEggNameV105.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bcc586cb68148fd960dd685eecce853169a92ed5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/HelperSpawnEggNameV105.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++public final class HelperSpawnEggNameV105 { ++ ++ private static final String[] ID_TO_STRING = new String[256]; ++ static { ++ ID_TO_STRING[1] = "Item"; ++ ID_TO_STRING[2] = "XPOrb"; ++ ID_TO_STRING[7] = "ThrownEgg"; ++ ID_TO_STRING[8] = "LeashKnot"; ++ ID_TO_STRING[9] = "Painting"; ++ ID_TO_STRING[10] = "Arrow"; ++ ID_TO_STRING[11] = "Snowball"; ++ ID_TO_STRING[12] = "Fireball"; ++ ID_TO_STRING[13] = "SmallFireball"; ++ ID_TO_STRING[14] = "ThrownEnderpearl"; ++ ID_TO_STRING[15] = "EyeOfEnderSignal"; ++ ID_TO_STRING[16] = "ThrownPotion"; ++ ID_TO_STRING[17] = "ThrownExpBottle"; ++ ID_TO_STRING[18] = "ItemFrame"; ++ ID_TO_STRING[19] = "WitherSkull"; ++ ID_TO_STRING[20] = "PrimedTnt"; ++ ID_TO_STRING[21] = "FallingSand"; ++ ID_TO_STRING[22] = "FireworksRocketEntity"; ++ ID_TO_STRING[23] = "TippedArrow"; ++ ID_TO_STRING[24] = "SpectralArrow"; ++ ID_TO_STRING[25] = "ShulkerBullet"; ++ ID_TO_STRING[26] = "DragonFireball"; ++ ID_TO_STRING[30] = "ArmorStand"; ++ ID_TO_STRING[41] = "Boat"; ++ ID_TO_STRING[42] = "MinecartRideable"; ++ ID_TO_STRING[43] = "MinecartChest"; ++ ID_TO_STRING[44] = "MinecartFurnace"; ++ ID_TO_STRING[45] = "MinecartTNT"; ++ ID_TO_STRING[46] = "MinecartHopper"; ++ ID_TO_STRING[47] = "MinecartSpawner"; ++ ID_TO_STRING[40] = "MinecartCommandBlock"; ++ ID_TO_STRING[50] = "Creeper"; ++ ID_TO_STRING[51] = "Skeleton"; ++ ID_TO_STRING[52] = "Spider"; ++ ID_TO_STRING[53] = "Giant"; ++ ID_TO_STRING[54] = "Zombie"; ++ ID_TO_STRING[55] = "Slime"; ++ ID_TO_STRING[56] = "Ghast"; ++ ID_TO_STRING[57] = "PigZombie"; ++ ID_TO_STRING[58] = "Enderman"; ++ ID_TO_STRING[59] = "CaveSpider"; ++ ID_TO_STRING[60] = "Silverfish"; ++ ID_TO_STRING[61] = "Blaze"; ++ ID_TO_STRING[62] = "LavaSlime"; ++ ID_TO_STRING[63] = "EnderDragon"; ++ ID_TO_STRING[64] = "WitherBoss"; ++ ID_TO_STRING[65] = "Bat"; ++ ID_TO_STRING[66] = "Witch"; ++ ID_TO_STRING[67] = "Endermite"; ++ ID_TO_STRING[68] = "Guardian"; ++ ID_TO_STRING[69] = "Shulker"; ++ ID_TO_STRING[90] = "Pig"; ++ ID_TO_STRING[91] = "Sheep"; ++ ID_TO_STRING[92] = "Cow"; ++ ID_TO_STRING[93] = "Chicken"; ++ ID_TO_STRING[94] = "Squid"; ++ ID_TO_STRING[95] = "Wolf"; ++ ID_TO_STRING[96] = "MushroomCow"; ++ ID_TO_STRING[97] = "SnowMan"; ++ ID_TO_STRING[98] = "Ozelot"; ++ ID_TO_STRING[99] = "VillagerGolem"; ++ ID_TO_STRING[100] = "EntityHorse"; ++ ID_TO_STRING[101] = "Rabbit"; ++ ID_TO_STRING[120] = "Villager"; ++ ID_TO_STRING[200] = "EnderCrystal"; ++ } ++ ++ public static String getSpawnNameFromId(final short id) { ++ return ID_TO_STRING[id & 255]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/helpers/RenameHelper.java b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/RenameHelper.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1c0483b72f45f8c98e19237579bfdf5915001768 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/helpers/RenameHelper.java +@@ -0,0 +1,108 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.helpers; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.ArrayList; ++import java.util.List; ++import java.util.function.Function; ++ ++public final class RenameHelper { ++ ++ // assumes no two or more entries are renamed to a single value, otherwise result will be only one of them will win ++ // and there is no defined winner in such a case ++ public static void renameKeys(final MapType data, final Function renamer) { ++ if (data == null) { ++ return; ++ } ++ ++ List newKeys = null; ++ List newValues = null; ++ boolean needsRename = false; ++ for (final String key : data.keys()) { ++ final String renamed = renamer.apply(key); ++ if (renamed != null) { ++ newKeys = new ArrayList<>(); ++ newValues = new ArrayList<>(); ++ newValues.add(data.getGeneric(key)); ++ newKeys.add(renamed); ++ data.remove(key); ++ needsRename = true; ++ break; ++ } ++ } ++ ++ if (!needsRename) { ++ return; ++ } ++ ++ for (final String key : new ArrayList<>(data.keys())) { ++ final String renamed = renamer.apply(key); ++ ++ if (renamed != null) { ++ newValues.add(data.getGeneric(key)); ++ newKeys.add(renamed); ++ data.remove(key); ++ } ++ } ++ ++ // insert new keys ++ for (int i = 0, len = newKeys.size(); i < len; ++i) { ++ final String key = newKeys.get(i); ++ final Object value = newValues.get(i); ++ ++ data.setGeneric(key, value); ++ } ++ } ++ ++ // Clobbers anything in toKey if fromKey exists ++ public static boolean renameSingle(final MapType data, final String fromKey, final String toKey) { ++ if (data == null) { ++ return false; ++ } ++ ++ final Object value = data.getGeneric(fromKey); ++ if (value != null) { ++ data.remove(fromKey); ++ data.setGeneric(toKey, value); ++ return true; ++ } ++ return false; ++ } ++ ++ public static void renameString(final MapType data, final String key, final Function renamer) { ++ if (data == null) { ++ return; ++ } ++ ++ final String value = data.getString(key); ++ if (value == null) { ++ return; ++ } ++ ++ final String renamed = renamer.apply(value); ++ if (renamed == null) { ++ return; ++ } ++ ++ data.setString(key, renamed); ++ } ++ ++ public static void renameListMapItems(final MapType data, final String listPath, final String mapPath, ++ final Function renamer) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(listPath); ++ if (list == null) { ++ return; ++ } ++ ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ RenameHelper.renameString(list.getMap(i, null), mapPath, renamer); ++ } ++ } ++ ++ private RenameHelper() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemname/ConverterAbstractItemRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemname/ConverterAbstractItemRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..94569f0ccff0d3a09eafd4ba73572d9db0a0ac5b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemname/ConverterAbstractItemRename.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.itemname; ++ ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.function.Function; ++ ++public final class ConverterAbstractItemRename { ++ ++ private ConverterAbstractItemRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ ConverterAbstractStringValueTypeRename.register(version, subVersion, MCTypeRegistry.ITEM_NAME, renamer); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0244aab4905fc2b88abff344c2b2ab753d4b335e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterEnchantmentsRename.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.itemstack; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import java.util.function.Function; ++ ++public final class ConverterEnchantmentsRename extends DataConverter { ++ ++ private final Function renamer; ++ ++ public ConverterEnchantmentsRename(final int toVersion, final Function renamer) { ++ this(toVersion, 0, renamer); ++ } ++ ++ public ConverterEnchantmentsRename(final int toVersion, final int versionStep, final Function renamer) { ++ super(toVersion, versionStep); ++ ++ this.renamer = (final String input) -> { ++ return renamer.apply(NamespaceUtil.correctNamespace(input)); ++ }; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ ++ if (tag == null) { ++ return null; ++ } ++ ++ RenameHelper.renameListMapItems(tag, "Enchantments", "id", this.renamer); ++ RenameHelper.renameListMapItems(tag, "StoredEnchantments", "id", this.renamer); ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenItemStack.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenItemStack.java +new file mode 100644 +index 0000000000000000000000000000000000000000..eca9a58f43ac80f2fd3c8179d2790dae737951f7 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenItemStack.java +@@ -0,0 +1,460 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.itemstack; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++import java.util.Arrays; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class ConverterFlattenItemStack extends DataConverter { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ // Map of "id.damage" -> "flattened id" ++ private static final Map FLATTEN_MAP = new HashMap<>(); ++ static { ++ FLATTEN_MAP.put("minecraft:stone.0", "minecraft:stone"); ++ FLATTEN_MAP.put("minecraft:stone.1", "minecraft:granite"); ++ FLATTEN_MAP.put("minecraft:stone.2", "minecraft:polished_granite"); ++ FLATTEN_MAP.put("minecraft:stone.3", "minecraft:diorite"); ++ FLATTEN_MAP.put("minecraft:stone.4", "minecraft:polished_diorite"); ++ FLATTEN_MAP.put("minecraft:stone.5", "minecraft:andesite"); ++ FLATTEN_MAP.put("minecraft:stone.6", "minecraft:polished_andesite"); ++ FLATTEN_MAP.put("minecraft:dirt.0", "minecraft:dirt"); ++ FLATTEN_MAP.put("minecraft:dirt.1", "minecraft:coarse_dirt"); ++ FLATTEN_MAP.put("minecraft:dirt.2", "minecraft:podzol"); ++ FLATTEN_MAP.put("minecraft:leaves.0", "minecraft:oak_leaves"); ++ FLATTEN_MAP.put("minecraft:leaves.1", "minecraft:spruce_leaves"); ++ FLATTEN_MAP.put("minecraft:leaves.2", "minecraft:birch_leaves"); ++ FLATTEN_MAP.put("minecraft:leaves.3", "minecraft:jungle_leaves"); ++ FLATTEN_MAP.put("minecraft:leaves2.0", "minecraft:acacia_leaves"); ++ FLATTEN_MAP.put("minecraft:leaves2.1", "minecraft:dark_oak_leaves"); ++ FLATTEN_MAP.put("minecraft:log.0", "minecraft:oak_log"); ++ FLATTEN_MAP.put("minecraft:log.1", "minecraft:spruce_log"); ++ FLATTEN_MAP.put("minecraft:log.2", "minecraft:birch_log"); ++ FLATTEN_MAP.put("minecraft:log.3", "minecraft:jungle_log"); ++ FLATTEN_MAP.put("minecraft:log2.0", "minecraft:acacia_log"); ++ FLATTEN_MAP.put("minecraft:log2.1", "minecraft:dark_oak_log"); ++ FLATTEN_MAP.put("minecraft:sapling.0", "minecraft:oak_sapling"); ++ FLATTEN_MAP.put("minecraft:sapling.1", "minecraft:spruce_sapling"); ++ FLATTEN_MAP.put("minecraft:sapling.2", "minecraft:birch_sapling"); ++ FLATTEN_MAP.put("minecraft:sapling.3", "minecraft:jungle_sapling"); ++ FLATTEN_MAP.put("minecraft:sapling.4", "minecraft:acacia_sapling"); ++ FLATTEN_MAP.put("minecraft:sapling.5", "minecraft:dark_oak_sapling"); ++ FLATTEN_MAP.put("minecraft:planks.0", "minecraft:oak_planks"); ++ FLATTEN_MAP.put("minecraft:planks.1", "minecraft:spruce_planks"); ++ FLATTEN_MAP.put("minecraft:planks.2", "minecraft:birch_planks"); ++ FLATTEN_MAP.put("minecraft:planks.3", "minecraft:jungle_planks"); ++ FLATTEN_MAP.put("minecraft:planks.4", "minecraft:acacia_planks"); ++ FLATTEN_MAP.put("minecraft:planks.5", "minecraft:dark_oak_planks"); ++ FLATTEN_MAP.put("minecraft:sand.0", "minecraft:sand"); ++ FLATTEN_MAP.put("minecraft:sand.1", "minecraft:red_sand"); ++ FLATTEN_MAP.put("minecraft:quartz_block.0", "minecraft:quartz_block"); ++ FLATTEN_MAP.put("minecraft:quartz_block.1", "minecraft:chiseled_quartz_block"); ++ FLATTEN_MAP.put("minecraft:quartz_block.2", "minecraft:quartz_pillar"); ++ FLATTEN_MAP.put("minecraft:anvil.0", "minecraft:anvil"); ++ FLATTEN_MAP.put("minecraft:anvil.1", "minecraft:chipped_anvil"); ++ FLATTEN_MAP.put("minecraft:anvil.2", "minecraft:damaged_anvil"); ++ FLATTEN_MAP.put("minecraft:wool.0", "minecraft:white_wool"); ++ FLATTEN_MAP.put("minecraft:wool.1", "minecraft:orange_wool"); ++ FLATTEN_MAP.put("minecraft:wool.2", "minecraft:magenta_wool"); ++ FLATTEN_MAP.put("minecraft:wool.3", "minecraft:light_blue_wool"); ++ FLATTEN_MAP.put("minecraft:wool.4", "minecraft:yellow_wool"); ++ FLATTEN_MAP.put("minecraft:wool.5", "minecraft:lime_wool"); ++ FLATTEN_MAP.put("minecraft:wool.6", "minecraft:pink_wool"); ++ FLATTEN_MAP.put("minecraft:wool.7", "minecraft:gray_wool"); ++ FLATTEN_MAP.put("minecraft:wool.8", "minecraft:light_gray_wool"); ++ FLATTEN_MAP.put("minecraft:wool.9", "minecraft:cyan_wool"); ++ FLATTEN_MAP.put("minecraft:wool.10", "minecraft:purple_wool"); ++ FLATTEN_MAP.put("minecraft:wool.11", "minecraft:blue_wool"); ++ FLATTEN_MAP.put("minecraft:wool.12", "minecraft:brown_wool"); ++ FLATTEN_MAP.put("minecraft:wool.13", "minecraft:green_wool"); ++ FLATTEN_MAP.put("minecraft:wool.14", "minecraft:red_wool"); ++ FLATTEN_MAP.put("minecraft:wool.15", "minecraft:black_wool"); ++ FLATTEN_MAP.put("minecraft:carpet.0", "minecraft:white_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.1", "minecraft:orange_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.2", "minecraft:magenta_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.3", "minecraft:light_blue_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.4", "minecraft:yellow_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.5", "minecraft:lime_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.6", "minecraft:pink_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.7", "minecraft:gray_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.8", "minecraft:light_gray_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.9", "minecraft:cyan_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.10", "minecraft:purple_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.11", "minecraft:blue_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.12", "minecraft:brown_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.13", "minecraft:green_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.14", "minecraft:red_carpet"); ++ FLATTEN_MAP.put("minecraft:carpet.15", "minecraft:black_carpet"); ++ FLATTEN_MAP.put("minecraft:hardened_clay.0", "minecraft:terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.0", "minecraft:white_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.1", "minecraft:orange_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.2", "minecraft:magenta_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.3", "minecraft:light_blue_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.4", "minecraft:yellow_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.5", "minecraft:lime_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.6", "minecraft:pink_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.7", "minecraft:gray_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.8", "minecraft:light_gray_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.9", "minecraft:cyan_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.10", "minecraft:purple_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.11", "minecraft:blue_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.12", "minecraft:brown_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.13", "minecraft:green_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.14", "minecraft:red_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_hardened_clay.15", "minecraft:black_terracotta"); ++ FLATTEN_MAP.put("minecraft:silver_glazed_terracotta.0", "minecraft:light_gray_glazed_terracotta"); ++ FLATTEN_MAP.put("minecraft:stained_glass.0", "minecraft:white_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.1", "minecraft:orange_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.2", "minecraft:magenta_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.3", "minecraft:light_blue_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.4", "minecraft:yellow_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.5", "minecraft:lime_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.6", "minecraft:pink_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.7", "minecraft:gray_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.8", "minecraft:light_gray_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.9", "minecraft:cyan_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.10", "minecraft:purple_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.11", "minecraft:blue_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.12", "minecraft:brown_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.13", "minecraft:green_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.14", "minecraft:red_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass.15", "minecraft:black_stained_glass"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.0", "minecraft:white_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.1", "minecraft:orange_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.2", "minecraft:magenta_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.3", "minecraft:light_blue_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.4", "minecraft:yellow_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.5", "minecraft:lime_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.6", "minecraft:pink_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.7", "minecraft:gray_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.8", "minecraft:light_gray_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.9", "minecraft:cyan_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.10", "minecraft:purple_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.11", "minecraft:blue_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.12", "minecraft:brown_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.13", "minecraft:green_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.14", "minecraft:red_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:stained_glass_pane.15", "minecraft:black_stained_glass_pane"); ++ FLATTEN_MAP.put("minecraft:prismarine.0", "minecraft:prismarine"); ++ FLATTEN_MAP.put("minecraft:prismarine.1", "minecraft:prismarine_bricks"); ++ FLATTEN_MAP.put("minecraft:prismarine.2", "minecraft:dark_prismarine"); ++ FLATTEN_MAP.put("minecraft:concrete.0", "minecraft:white_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.1", "minecraft:orange_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.2", "minecraft:magenta_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.3", "minecraft:light_blue_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.4", "minecraft:yellow_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.5", "minecraft:lime_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.6", "minecraft:pink_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.7", "minecraft:gray_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.8", "minecraft:light_gray_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.9", "minecraft:cyan_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.10", "minecraft:purple_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.11", "minecraft:blue_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.12", "minecraft:brown_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.13", "minecraft:green_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.14", "minecraft:red_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete.15", "minecraft:black_concrete"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.0", "minecraft:white_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.1", "minecraft:orange_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.2", "minecraft:magenta_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.3", "minecraft:light_blue_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.4", "minecraft:yellow_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.5", "minecraft:lime_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.6", "minecraft:pink_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.7", "minecraft:gray_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.8", "minecraft:light_gray_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.9", "minecraft:cyan_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.10", "minecraft:purple_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.11", "minecraft:blue_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.12", "minecraft:brown_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.13", "minecraft:green_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.14", "minecraft:red_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:concrete_powder.15", "minecraft:black_concrete_powder"); ++ FLATTEN_MAP.put("minecraft:cobblestone_wall.0", "minecraft:cobblestone_wall"); ++ FLATTEN_MAP.put("minecraft:cobblestone_wall.1", "minecraft:mossy_cobblestone_wall"); ++ FLATTEN_MAP.put("minecraft:sandstone.0", "minecraft:sandstone"); ++ FLATTEN_MAP.put("minecraft:sandstone.1", "minecraft:chiseled_sandstone"); ++ FLATTEN_MAP.put("minecraft:sandstone.2", "minecraft:cut_sandstone"); ++ FLATTEN_MAP.put("minecraft:red_sandstone.0", "minecraft:red_sandstone"); ++ FLATTEN_MAP.put("minecraft:red_sandstone.1", "minecraft:chiseled_red_sandstone"); ++ FLATTEN_MAP.put("minecraft:red_sandstone.2", "minecraft:cut_red_sandstone"); ++ FLATTEN_MAP.put("minecraft:stonebrick.0", "minecraft:stone_bricks"); ++ FLATTEN_MAP.put("minecraft:stonebrick.1", "minecraft:mossy_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:stonebrick.2", "minecraft:cracked_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:stonebrick.3", "minecraft:chiseled_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:monster_egg.0", "minecraft:infested_stone"); ++ FLATTEN_MAP.put("minecraft:monster_egg.1", "minecraft:infested_cobblestone"); ++ FLATTEN_MAP.put("minecraft:monster_egg.2", "minecraft:infested_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:monster_egg.3", "minecraft:infested_mossy_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:monster_egg.4", "minecraft:infested_cracked_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:monster_egg.5", "minecraft:infested_chiseled_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:yellow_flower.0", "minecraft:dandelion"); ++ FLATTEN_MAP.put("minecraft:red_flower.0", "minecraft:poppy"); ++ FLATTEN_MAP.put("minecraft:red_flower.1", "minecraft:blue_orchid"); ++ FLATTEN_MAP.put("minecraft:red_flower.2", "minecraft:allium"); ++ FLATTEN_MAP.put("minecraft:red_flower.3", "minecraft:azure_bluet"); ++ FLATTEN_MAP.put("minecraft:red_flower.4", "minecraft:red_tulip"); ++ FLATTEN_MAP.put("minecraft:red_flower.5", "minecraft:orange_tulip"); ++ FLATTEN_MAP.put("minecraft:red_flower.6", "minecraft:white_tulip"); ++ FLATTEN_MAP.put("minecraft:red_flower.7", "minecraft:pink_tulip"); ++ FLATTEN_MAP.put("minecraft:red_flower.8", "minecraft:oxeye_daisy"); ++ FLATTEN_MAP.put("minecraft:double_plant.0", "minecraft:sunflower"); ++ FLATTEN_MAP.put("minecraft:double_plant.1", "minecraft:lilac"); ++ FLATTEN_MAP.put("minecraft:double_plant.2", "minecraft:tall_grass"); ++ FLATTEN_MAP.put("minecraft:double_plant.3", "minecraft:large_fern"); ++ FLATTEN_MAP.put("minecraft:double_plant.4", "minecraft:rose_bush"); ++ FLATTEN_MAP.put("minecraft:double_plant.5", "minecraft:peony"); ++ FLATTEN_MAP.put("minecraft:deadbush.0", "minecraft:dead_bush"); ++ FLATTEN_MAP.put("minecraft:tallgrass.0", "minecraft:dead_bush"); ++ FLATTEN_MAP.put("minecraft:tallgrass.1", "minecraft:grass"); ++ FLATTEN_MAP.put("minecraft:tallgrass.2", "minecraft:fern"); ++ FLATTEN_MAP.put("minecraft:sponge.0", "minecraft:sponge"); ++ FLATTEN_MAP.put("minecraft:sponge.1", "minecraft:wet_sponge"); ++ FLATTEN_MAP.put("minecraft:purpur_slab.0", "minecraft:purpur_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.0", "minecraft:stone_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.1", "minecraft:sandstone_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.2", "minecraft:petrified_oak_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.3", "minecraft:cobblestone_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.4", "minecraft:brick_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.5", "minecraft:stone_brick_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.6", "minecraft:nether_brick_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab.7", "minecraft:quartz_slab"); ++ FLATTEN_MAP.put("minecraft:stone_slab2.0", "minecraft:red_sandstone_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.0", "minecraft:oak_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.1", "minecraft:spruce_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.2", "minecraft:birch_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.3", "minecraft:jungle_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.4", "minecraft:acacia_slab"); ++ FLATTEN_MAP.put("minecraft:wooden_slab.5", "minecraft:dark_oak_slab"); ++ FLATTEN_MAP.put("minecraft:coal.0", "minecraft:coal"); ++ FLATTEN_MAP.put("minecraft:coal.1", "minecraft:charcoal"); ++ FLATTEN_MAP.put("minecraft:fish.0", "minecraft:cod"); ++ FLATTEN_MAP.put("minecraft:fish.1", "minecraft:salmon"); ++ FLATTEN_MAP.put("minecraft:fish.2", "minecraft:clownfish"); ++ FLATTEN_MAP.put("minecraft:fish.3", "minecraft:pufferfish"); ++ FLATTEN_MAP.put("minecraft:cooked_fish.0", "minecraft:cooked_cod"); ++ FLATTEN_MAP.put("minecraft:cooked_fish.1", "minecraft:cooked_salmon"); ++ FLATTEN_MAP.put("minecraft:skull.0", "minecraft:skeleton_skull"); ++ FLATTEN_MAP.put("minecraft:skull.1", "minecraft:wither_skeleton_skull"); ++ FLATTEN_MAP.put("minecraft:skull.2", "minecraft:zombie_head"); ++ FLATTEN_MAP.put("minecraft:skull.3", "minecraft:player_head"); ++ FLATTEN_MAP.put("minecraft:skull.4", "minecraft:creeper_head"); ++ FLATTEN_MAP.put("minecraft:skull.5", "minecraft:dragon_head"); ++ FLATTEN_MAP.put("minecraft:golden_apple.0", "minecraft:golden_apple"); ++ FLATTEN_MAP.put("minecraft:golden_apple.1", "minecraft:enchanted_golden_apple"); ++ FLATTEN_MAP.put("minecraft:fireworks.0", "minecraft:firework_rocket"); ++ FLATTEN_MAP.put("minecraft:firework_charge.0", "minecraft:firework_star"); ++ FLATTEN_MAP.put("minecraft:dye.0", "minecraft:ink_sac"); ++ FLATTEN_MAP.put("minecraft:dye.1", "minecraft:rose_red"); ++ FLATTEN_MAP.put("minecraft:dye.2", "minecraft:cactus_green"); ++ FLATTEN_MAP.put("minecraft:dye.3", "minecraft:cocoa_beans"); ++ FLATTEN_MAP.put("minecraft:dye.4", "minecraft:lapis_lazuli"); ++ FLATTEN_MAP.put("minecraft:dye.5", "minecraft:purple_dye"); ++ FLATTEN_MAP.put("minecraft:dye.6", "minecraft:cyan_dye"); ++ FLATTEN_MAP.put("minecraft:dye.7", "minecraft:light_gray_dye"); ++ FLATTEN_MAP.put("minecraft:dye.8", "minecraft:gray_dye"); ++ FLATTEN_MAP.put("minecraft:dye.9", "minecraft:pink_dye"); ++ FLATTEN_MAP.put("minecraft:dye.10", "minecraft:lime_dye"); ++ FLATTEN_MAP.put("minecraft:dye.11", "minecraft:dandelion_yellow"); ++ FLATTEN_MAP.put("minecraft:dye.12", "minecraft:light_blue_dye"); ++ FLATTEN_MAP.put("minecraft:dye.13", "minecraft:magenta_dye"); ++ FLATTEN_MAP.put("minecraft:dye.14", "minecraft:orange_dye"); ++ FLATTEN_MAP.put("minecraft:dye.15", "minecraft:bone_meal"); ++ FLATTEN_MAP.put("minecraft:silver_shulker_box.0", "minecraft:light_gray_shulker_box"); ++ FLATTEN_MAP.put("minecraft:fence.0", "minecraft:oak_fence"); ++ FLATTEN_MAP.put("minecraft:fence_gate.0", "minecraft:oak_fence_gate"); ++ FLATTEN_MAP.put("minecraft:wooden_door.0", "minecraft:oak_door"); ++ FLATTEN_MAP.put("minecraft:boat.0", "minecraft:oak_boat"); ++ FLATTEN_MAP.put("minecraft:lit_pumpkin.0", "minecraft:jack_o_lantern"); ++ FLATTEN_MAP.put("minecraft:pumpkin.0", "minecraft:carved_pumpkin"); ++ FLATTEN_MAP.put("minecraft:trapdoor.0", "minecraft:oak_trapdoor"); ++ FLATTEN_MAP.put("minecraft:nether_brick.0", "minecraft:nether_bricks"); ++ FLATTEN_MAP.put("minecraft:red_nether_brick.0", "minecraft:red_nether_bricks"); ++ FLATTEN_MAP.put("minecraft:netherbrick.0", "minecraft:nether_brick"); ++ FLATTEN_MAP.put("minecraft:wooden_button.0", "minecraft:oak_button"); ++ FLATTEN_MAP.put("minecraft:wooden_pressure_plate.0", "minecraft:oak_pressure_plate"); ++ FLATTEN_MAP.put("minecraft:noteblock.0", "minecraft:note_block"); ++ FLATTEN_MAP.put("minecraft:bed.0", "minecraft:white_bed"); ++ FLATTEN_MAP.put("minecraft:bed.1", "minecraft:orange_bed"); ++ FLATTEN_MAP.put("minecraft:bed.2", "minecraft:magenta_bed"); ++ FLATTEN_MAP.put("minecraft:bed.3", "minecraft:light_blue_bed"); ++ FLATTEN_MAP.put("minecraft:bed.4", "minecraft:yellow_bed"); ++ FLATTEN_MAP.put("minecraft:bed.5", "minecraft:lime_bed"); ++ FLATTEN_MAP.put("minecraft:bed.6", "minecraft:pink_bed"); ++ FLATTEN_MAP.put("minecraft:bed.7", "minecraft:gray_bed"); ++ FLATTEN_MAP.put("minecraft:bed.8", "minecraft:light_gray_bed"); ++ FLATTEN_MAP.put("minecraft:bed.9", "minecraft:cyan_bed"); ++ FLATTEN_MAP.put("minecraft:bed.10", "minecraft:purple_bed"); ++ FLATTEN_MAP.put("minecraft:bed.11", "minecraft:blue_bed"); ++ FLATTEN_MAP.put("minecraft:bed.12", "minecraft:brown_bed"); ++ FLATTEN_MAP.put("minecraft:bed.13", "minecraft:green_bed"); ++ FLATTEN_MAP.put("minecraft:bed.14", "minecraft:red_bed"); ++ FLATTEN_MAP.put("minecraft:bed.15", "minecraft:black_bed"); ++ FLATTEN_MAP.put("minecraft:banner.15", "minecraft:white_banner"); ++ FLATTEN_MAP.put("minecraft:banner.14", "minecraft:orange_banner"); ++ FLATTEN_MAP.put("minecraft:banner.13", "minecraft:magenta_banner"); ++ FLATTEN_MAP.put("minecraft:banner.12", "minecraft:light_blue_banner"); ++ FLATTEN_MAP.put("minecraft:banner.11", "minecraft:yellow_banner"); ++ FLATTEN_MAP.put("minecraft:banner.10", "minecraft:lime_banner"); ++ FLATTEN_MAP.put("minecraft:banner.9", "minecraft:pink_banner"); ++ FLATTEN_MAP.put("minecraft:banner.8", "minecraft:gray_banner"); ++ FLATTEN_MAP.put("minecraft:banner.7", "minecraft:light_gray_banner"); ++ FLATTEN_MAP.put("minecraft:banner.6", "minecraft:cyan_banner"); ++ FLATTEN_MAP.put("minecraft:banner.5", "minecraft:purple_banner"); ++ FLATTEN_MAP.put("minecraft:banner.4", "minecraft:blue_banner"); ++ FLATTEN_MAP.put("minecraft:banner.3", "minecraft:brown_banner"); ++ FLATTEN_MAP.put("minecraft:banner.2", "minecraft:green_banner"); ++ FLATTEN_MAP.put("minecraft:banner.1", "minecraft:red_banner"); ++ FLATTEN_MAP.put("minecraft:banner.0", "minecraft:black_banner"); ++ FLATTEN_MAP.put("minecraft:grass.0", "minecraft:grass_block"); ++ FLATTEN_MAP.put("minecraft:brick_block.0", "minecraft:bricks"); ++ FLATTEN_MAP.put("minecraft:end_bricks.0", "minecraft:end_stone_bricks"); ++ FLATTEN_MAP.put("minecraft:golden_rail.0", "minecraft:powered_rail"); ++ FLATTEN_MAP.put("minecraft:magma.0", "minecraft:magma_block"); ++ FLATTEN_MAP.put("minecraft:quartz_ore.0", "minecraft:nether_quartz_ore"); ++ FLATTEN_MAP.put("minecraft:reeds.0", "minecraft:sugar_cane"); ++ FLATTEN_MAP.put("minecraft:slime.0", "minecraft:slime_block"); ++ FLATTEN_MAP.put("minecraft:stone_stairs.0", "minecraft:cobblestone_stairs"); ++ FLATTEN_MAP.put("minecraft:waterlily.0", "minecraft:lily_pad"); ++ FLATTEN_MAP.put("minecraft:web.0", "minecraft:cobweb"); ++ FLATTEN_MAP.put("minecraft:snow.0", "minecraft:snow_block"); ++ FLATTEN_MAP.put("minecraft:snow_layer.0", "minecraft:snow"); ++ FLATTEN_MAP.put("minecraft:record_11.0", "minecraft:music_disc_11"); ++ FLATTEN_MAP.put("minecraft:record_13.0", "minecraft:music_disc_13"); ++ FLATTEN_MAP.put("minecraft:record_blocks.0", "minecraft:music_disc_blocks"); ++ FLATTEN_MAP.put("minecraft:record_cat.0", "minecraft:music_disc_cat"); ++ FLATTEN_MAP.put("minecraft:record_chirp.0", "minecraft:music_disc_chirp"); ++ FLATTEN_MAP.put("minecraft:record_far.0", "minecraft:music_disc_far"); ++ FLATTEN_MAP.put("minecraft:record_mall.0", "minecraft:music_disc_mall"); ++ FLATTEN_MAP.put("minecraft:record_mellohi.0", "minecraft:music_disc_mellohi"); ++ FLATTEN_MAP.put("minecraft:record_stal.0", "minecraft:music_disc_stal"); ++ FLATTEN_MAP.put("minecraft:record_strad.0", "minecraft:music_disc_strad"); ++ FLATTEN_MAP.put("minecraft:record_wait.0", "minecraft:music_disc_wait"); ++ FLATTEN_MAP.put("minecraft:record_ward.0", "minecraft:music_disc_ward"); ++ } ++ ++ // maps out ids requiring flattening ++ private static final Set IDS_REQUIRING_FLATTENING = new HashSet<>(); ++ static { ++ for (final String key : FLATTEN_MAP.keySet()) { ++ IDS_REQUIRING_FLATTENING.add(key.substring(0, key.indexOf('.'))); ++ } ++ } ++ ++ // Damage tag is moved from the ItemStack base tag to the ItemStack tag, and we only want to migrate that ++ // for items that actually require it for damage purposes (Remember, old damage was used to differentiate item types) ++ // It should be noted that this ID set should not be included in the flattening map, because damage for these items ++ // is actual damage and not a subtype specifier ++ private static final Set ITEMS_WITH_DAMAGE = new HashSet<>(Arrays.asList( ++ "minecraft:bow", ++ "minecraft:carrot_on_a_stick", ++ "minecraft:chainmail_boots", ++ "minecraft:chainmail_chestplate", ++ "minecraft:chainmail_helmet", ++ "minecraft:chainmail_leggings", ++ "minecraft:diamond_axe", ++ "minecraft:diamond_boots", ++ "minecraft:diamond_chestplate", ++ "minecraft:diamond_helmet", ++ "minecraft:diamond_hoe", ++ "minecraft:diamond_leggings", ++ "minecraft:diamond_pickaxe", ++ "minecraft:diamond_shovel", ++ "minecraft:diamond_sword", ++ "minecraft:elytra", ++ "minecraft:fishing_rod", ++ "minecraft:flint_and_steel", ++ "minecraft:golden_axe", ++ "minecraft:golden_boots", ++ "minecraft:golden_chestplate", ++ "minecraft:golden_helmet", ++ "minecraft:golden_hoe", ++ "minecraft:golden_leggings", ++ "minecraft:golden_pickaxe", ++ "minecraft:golden_shovel", ++ "minecraft:golden_sword", ++ "minecraft:iron_axe", ++ "minecraft:iron_boots", ++ "minecraft:iron_chestplate", ++ "minecraft:iron_helmet", ++ "minecraft:iron_hoe", ++ "minecraft:iron_leggings", ++ "minecraft:iron_pickaxe", ++ "minecraft:iron_shovel", ++ "minecraft:iron_sword", ++ "minecraft:leather_boots", ++ "minecraft:leather_chestplate", ++ "minecraft:leather_helmet", ++ "minecraft:leather_leggings", ++ "minecraft:shears", ++ "minecraft:shield", ++ "minecraft:stone_axe", ++ "minecraft:stone_hoe", ++ "minecraft:stone_pickaxe", ++ "minecraft:stone_shovel", ++ "minecraft:stone_sword", ++ "minecraft:wooden_axe", ++ "minecraft:wooden_hoe", ++ "minecraft:wooden_pickaxe", ++ "minecraft:wooden_shovel", ++ "minecraft:wooden_sword" ++ )); ++ ++ public ConverterFlattenItemStack() { ++ super(MCVersions.V17W47A, 4); ++ } ++ ++ public static String flattenItem(final String oldName, final int data) { ++ if (IDS_REQUIRING_FLATTENING.contains(oldName)) { ++ final String flattened = FLATTEN_MAP.get(oldName + '.' + data); ++ return flattened == null ? FLATTEN_MAP.get(oldName.concat(".0")) : flattened; ++ } else { ++ return null; ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ ++ if (id == null) { ++ return null; ++ } ++ ++ final int damage = data.getInt("Damage"); ++ data.remove("Damage"); ++ ++ if (IDS_REQUIRING_FLATTENING.contains(id)) { ++ String remap = FLATTEN_MAP.get(id + '.' + damage); ++ if (remap == null) { ++ remap = FLATTEN_MAP.get(id.concat(".0")); ++ // this shouldn't be null ++ } ++ if (remap != null) { ++ data.setString("id", remap); ++ } else { ++ LOGGER.warn("Item '" + id + "' requires flattening but found no mapping for it! (ConverterFlattenItemStack)"); ++ } ++ } ++ ++ if (damage != 0 && ITEMS_WITH_DAMAGE.contains(id)) { ++ // migrate damage ++ MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ tag = Types.NBT.createEmptyMap(); ++ data.setMap("tag", tag); ++ } ++ tag.setInt("Damage", damage); ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenSpawnEgg.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenSpawnEgg.java +new file mode 100644 +index 0000000000000000000000000000000000000000..32d498fac143f40124dc69fa0cf566f1ac33545c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterFlattenSpawnEgg.java +@@ -0,0 +1,87 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.itemstack; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class ConverterFlattenSpawnEgg extends DataConverter { ++ ++ private static final Map ENTITY_ID_TO_NEW_EGG_ID = new HashMap<>(); ++ static { ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:bat", "minecraft:bat_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:blaze", "minecraft:blaze_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:cave_spider", "minecraft:cave_spider_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:chicken", "minecraft:chicken_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:cow", "minecraft:cow_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:creeper", "minecraft:creeper_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:donkey", "minecraft:donkey_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:elder_guardian", "minecraft:elder_guardian_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:ender_dragon", "minecraft:ender_dragon_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:enderman", "minecraft:enderman_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:endermite", "minecraft:endermite_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:evocation_illager", "minecraft:evocation_illager_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:ghast", "minecraft:ghast_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:guardian", "minecraft:guardian_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:horse", "minecraft:horse_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:husk", "minecraft:husk_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:iron_golem", "minecraft:iron_golem_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:llama", "minecraft:llama_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:magma_cube", "minecraft:magma_cube_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:mooshroom", "minecraft:mooshroom_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:mule", "minecraft:mule_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:ocelot", "minecraft:ocelot_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:pufferfish", "minecraft:pufferfish_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:parrot", "minecraft:parrot_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:pig", "minecraft:pig_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:polar_bear", "minecraft:polar_bear_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:rabbit", "minecraft:rabbit_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:sheep", "minecraft:sheep_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:shulker", "minecraft:shulker_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:silverfish", "minecraft:silverfish_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:skeleton", "minecraft:skeleton_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:skeleton_horse", "minecraft:skeleton_horse_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:slime", "minecraft:slime_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:snow_golem", "minecraft:snow_golem_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:spider", "minecraft:spider_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:squid", "minecraft:squid_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:stray", "minecraft:stray_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:turtle", "minecraft:turtle_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:vex", "minecraft:vex_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:villager", "minecraft:villager_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:vindication_illager", "minecraft:vindication_illager_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:witch", "minecraft:witch_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:wither", "minecraft:wither_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:wither_skeleton", "minecraft:wither_skeleton_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:wolf", "minecraft:wolf_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:zombie", "minecraft:zombie_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:zombie_horse", "minecraft:zombie_horse_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:zombie_pigman", "minecraft:zombie_pigman_spawn_egg"); ++ ENTITY_ID_TO_NEW_EGG_ID.put("minecraft:zombie_villager", "minecraft:zombie_villager_spawn_egg"); ++ } ++ ++ public ConverterFlattenSpawnEgg(final int version, final int versionStep) { ++ super(version, versionStep); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType entityTag = tag.getMap("EntityTag"); ++ if (entityTag == null) { ++ return null; ++ } ++ ++ final String id = entityTag.getString("id"); ++ if (id != null) { ++ data.setString("id", ENTITY_ID_TO_NEW_EGG_ID.getOrDefault(id, "minecraft:pig_spawn_egg")); ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d5c5b711406f63a3e35ae7e5bfbf1d306bee4f1c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/itemstack/ConverterItemStackToDataComponents.java +@@ -0,0 +1,1244 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.itemstack; ++ ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.minecraft.versions.V3818; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import net.minecraft.util.Mth; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class ConverterItemStackToDataComponents { ++ ++ private static final int TOOLTIP_FLAG_HIDE_ENCHANTMENTS = 1 << 0; ++ private static final int TOOLTIP_FLAG_HIDE_MODIFIERS = 1 << 1; ++ private static final int TOOLTIP_FLAG_HIDE_UNBREAKABLE = 1 << 2; ++ private static final int TOOLTIP_FLAG_HIDE_CAN_DESTROY = 1 << 3; ++ private static final int TOOLTIP_FLAG_HIDE_CAN_PLACE = 1 << 4; ++ private static final int TOOLTIP_FLAG_HIDE_ADDITIONAL = 1 << 5; ++ private static final int TOOLTIP_FLAG_HIDE_DYE = 1 << 6; ++ private static final int TOOLTIP_FLAG_HIDE_UPGRADES = 1 << 7; ++ ++ private static final int DEFAULT_LEATHER_COLOUR = (160 << 16) | (101 << 8) | (64 << 0); // r, g, b ++ ++ private static final String[] BUCKETED_MOB_TAGS = new String[] { ++ "NoAI", ++ "Silent", ++ "NoGravity", ++ "Glowing", ++ "Invulnerable", ++ "Health", ++ "Age", ++ "Variant", ++ "HuntingCooldown", ++ "BucketVariantTag" ++ }; ++ private static final Set BOOLEAN_BLOCK_STATE_PROPERTIES = new HashSet<>( ++ Arrays.asList( ++ "attached", ++ "bottom", ++ "conditional", ++ "disarmed", ++ "drag", ++ "enabled", ++ "extended", ++ "eye", ++ "falling", ++ "hanging", ++ "has_bottle_0", ++ "has_bottle_1", ++ "has_bottle_2", ++ "has_record", ++ "has_book", ++ "inverted", ++ "in_wall", ++ "lit", ++ "locked", ++ "occupied", ++ "open", ++ "persistent", ++ "powered", ++ "short", ++ "signal_fire", ++ "snowy", ++ "triggered", ++ "unstable", ++ "waterlogged", ++ "berries", ++ "bloom", ++ "shrieking", ++ "can_summon", ++ "up", ++ "down", ++ "north", ++ "east", ++ "south", ++ "west", ++ "slot_0_occupied", ++ "slot_1_occupied", ++ "slot_2_occupied", ++ "slot_3_occupied", ++ "slot_4_occupied", ++ "slot_5_occupied", ++ "cracked", ++ "crafting" ++ ) ++ ); ++ private static final String[] MAP_DECORATION_CONVERSION_TABLE = new String[34]; ++ static { ++ MAP_DECORATION_CONVERSION_TABLE[0] = "player"; ++ MAP_DECORATION_CONVERSION_TABLE[1] = "frame"; ++ MAP_DECORATION_CONVERSION_TABLE[2] = "red_marker"; ++ MAP_DECORATION_CONVERSION_TABLE[3] = "blue_marker"; ++ MAP_DECORATION_CONVERSION_TABLE[4] = "target_x"; ++ MAP_DECORATION_CONVERSION_TABLE[5] = "target_point"; ++ MAP_DECORATION_CONVERSION_TABLE[6] = "player_off_map"; ++ MAP_DECORATION_CONVERSION_TABLE[7] = "player_off_limits"; ++ MAP_DECORATION_CONVERSION_TABLE[8] = "mansion"; ++ MAP_DECORATION_CONVERSION_TABLE[9] = "monument"; ++ MAP_DECORATION_CONVERSION_TABLE[10] = "banner_white"; ++ MAP_DECORATION_CONVERSION_TABLE[11] = "banner_orange"; ++ MAP_DECORATION_CONVERSION_TABLE[12] = "banner_magenta"; ++ MAP_DECORATION_CONVERSION_TABLE[13] = "banner_light_blue"; ++ MAP_DECORATION_CONVERSION_TABLE[14] = "banner_yellow"; ++ MAP_DECORATION_CONVERSION_TABLE[15] = "banner_lime"; ++ MAP_DECORATION_CONVERSION_TABLE[16] = "banner_pink"; ++ MAP_DECORATION_CONVERSION_TABLE[17] = "banner_gray"; ++ MAP_DECORATION_CONVERSION_TABLE[18] = "banner_light_gray"; ++ MAP_DECORATION_CONVERSION_TABLE[19] = "banner_cyan"; ++ MAP_DECORATION_CONVERSION_TABLE[20] = "banner_purple"; ++ MAP_DECORATION_CONVERSION_TABLE[21] = "banner_blue"; ++ MAP_DECORATION_CONVERSION_TABLE[22] = "banner_brown"; ++ MAP_DECORATION_CONVERSION_TABLE[23] = "banner_green"; ++ MAP_DECORATION_CONVERSION_TABLE[24] = "banner_red"; ++ MAP_DECORATION_CONVERSION_TABLE[25] = "banner_black"; ++ MAP_DECORATION_CONVERSION_TABLE[26] = "red_x"; ++ MAP_DECORATION_CONVERSION_TABLE[27] = "village_desert"; ++ MAP_DECORATION_CONVERSION_TABLE[28] = "village_plains"; ++ MAP_DECORATION_CONVERSION_TABLE[29] = "village_savanna"; ++ MAP_DECORATION_CONVERSION_TABLE[30] = "village_snowy"; ++ MAP_DECORATION_CONVERSION_TABLE[31] = "village_taiga"; ++ MAP_DECORATION_CONVERSION_TABLE[32] = "jungle_temple"; ++ MAP_DECORATION_CONVERSION_TABLE[33] = "swamp_hut"; ++ } ++ ++ private static String convertMapDecorationId(final int type) { ++ return type >= 0 && type < MAP_DECORATION_CONVERSION_TABLE.length ? MAP_DECORATION_CONVERSION_TABLE[type] : MAP_DECORATION_CONVERSION_TABLE[0]; ++ } ++ ++ private static void convertBlockStateProperties(final MapType properties) { ++ // convert values stored as boolean/integer to string ++ for (final String key : properties.keys()) { ++ final Object value = properties.getGeneric(key); ++ if (value instanceof Number number) { ++ if (BOOLEAN_BLOCK_STATE_PROPERTIES.contains(key)) { ++ properties.setString(key, Boolean.toString(number.byteValue() != (byte)0)); ++ } else { ++ properties.setString(key, number.toString()); ++ } ++ } ++ } ++ } ++ ++ private static void convertTileEntity(final MapType tileEntity, final TransientItemStack transientItem) { ++ final Object lock = tileEntity.getGeneric("Lock"); ++ if (lock != null) { ++ tileEntity.remove("Lock"); ++ transientItem.componentSetGeneric("minecraft:lock", lock); ++ } ++ ++ final Object lootTable = tileEntity.getGeneric("LootTable"); ++ if (lootTable != null) { ++ final MapType containerLoot = tileEntity.getTypeUtil().createEmptyMap(); ++ transientItem.componentSetMap("minecraft:container_loot", containerLoot); ++ ++ containerLoot.setGeneric("loot_table", lootTable); ++ ++ final long seed = tileEntity.getLong("LootTableSeed", 0L); ++ if (seed != 0L) { ++ containerLoot.setLong("seed", seed); ++ } ++ ++ tileEntity.remove("LootTable"); ++ tileEntity.remove("LootTableSeed"); ++ } ++ ++ final String id = NamespaceUtil.correctNamespace(tileEntity.getString("id", "")); ++ ++ switch (id) { ++ case "minecraft:skull": { ++ final Object noteBlockSound = tileEntity.getGeneric("note_block_sound"); ++ if (noteBlockSound != null) { ++ tileEntity.remove("note_block_sound"); ++ transientItem.componentSetGeneric("minecraft:note_block_sound", noteBlockSound); ++ } ++ ++ break; ++ } ++ case "minecraft:decorated_pot": { ++ final Object sherds = tileEntity.getGeneric("sherds"); ++ if (sherds != null) { ++ tileEntity.remove("sherds"); ++ transientItem.componentSetGeneric("minecraft:pot_decorations", sherds); ++ } ++ ++ final Object item = tileEntity.getGeneric("item"); ++ if (item != null) { ++ tileEntity.remove("item"); ++ ++ final ListType container = tileEntity.getTypeUtil().createEmptyList(); ++ transientItem.componentSetList("minecraft:container", container); ++ ++ final MapType wrappedItem = tileEntity.getTypeUtil().createEmptyMap(); ++ container.addMap(wrappedItem); ++ ++ wrappedItem.setInt("slot", 0); ++ wrappedItem.setGeneric("item", item); ++ } ++ ++ break; ++ } ++ case "minecraft:banner": { ++ final Object patterns = tileEntity.getGeneric("patterns"); ++ if (patterns != null) { ++ tileEntity.remove("patterns"); ++ ++ transientItem.componentSetGeneric("minecraft:banner_patterns", patterns); ++ } ++ ++ final Number base = tileEntity.getNumber("Base"); ++ if (base != null) { ++ tileEntity.remove("Base"); ++ ++ transientItem.componentSetString("minecraft:base_color", V3818.getBannerColour(base.intValue())); ++ } ++ ++ break; ++ } ++ ++ case "minecraft:shulker_box": ++ case "minecraft:chest": ++ case "minecraft:trapped_chest": ++ case "minecraft:furnace": ++ case "minecraft:ender_chest": ++ case "minecraft:dispenser": ++ case "minecraft:dropper": ++ case "minecraft:brewing_stand": ++ case "minecraft:hopper": ++ case "minecraft:barrel": ++ case "minecraft:smoker": ++ case "minecraft:blast_furnace": ++ case "minecraft:campfire": ++ case "minecraft:chiseled_bookshelf": ++ case "minecraft:crafter": { ++ final ListType items = tileEntity.getList("Items", ObjectType.MAP); ++ tileEntity.remove("Items"); ++ if (items != null && items.size() > 0) { ++ transientItem.componentSetList("minecraft:container", items); ++ ++ for (int i = 0, len = items.size(); i < len; ++i) { ++ final MapType item = items.getMap(i); ++ final int slot = (int)item.getByte("Slot", (byte)0) & 0xFF; ++ item.remove("Slot"); ++ ++ final MapType wrappedItem = item.getTypeUtil().createEmptyMap(); ++ items.setMap(i, wrappedItem); ++ ++ wrappedItem.setInt("slot", slot); ++ wrappedItem.setMap("item", item); ++ } ++ } ++ ++ break; ++ } ++ ++ case "minecraft:beehive": { ++ final Object bees = tileEntity.getGeneric("bees"); ++ if (bees != null) { ++ tileEntity.remove("bees"); ++ ++ transientItem.componentSetGeneric("minecraft:bees", bees); ++ } ++ break; ++ } ++ } ++ } ++ ++ private static void convertEnchantments(final TransientItemStack transientItem, final TypeUtil type, ++ final String tagKey, final String componentKey, ++ final boolean hideToolTip) { ++ final ListType enchantments = transientItem.tagRemoveList(tagKey, ObjectType.MAP); ++ if (enchantments == null || enchantments.size() == 0) { ++ if (hideToolTip) { ++ final MapType newEnchants = type.createEmptyMap(); ++ transientItem.componentSetMap(componentKey, newEnchants); ++ ++ newEnchants.setMap("levels", type.createEmptyMap()); ++ newEnchants.setBoolean("show_in_tooltip", false); ++ } ++ } else { ++ final MapType newEnchantments = type.createEmptyMap(); ++ ++ for (int i = 0, len = enchantments.size(); i < len; ++i) { ++ final MapType enchantment = enchantments.getMap(i); ++ ++ final String id = enchantment.getString("id"); ++ final Number level = enchantment.getNumber("lvl"); ++ ++ if (id == null || level == null) { ++ continue; ++ } ++ ++ newEnchantments.setInt(id, Mth.clamp(level.intValue(), 0, 0xFF)); ++ } ++ ++ if (!newEnchantments.isEmpty() || hideToolTip) { ++ final MapType newEnchants = type.createEmptyMap(); ++ transientItem.componentSetMap(componentKey, newEnchants); ++ ++ newEnchants.setMap("levels", newEnchantments); ++ if (hideToolTip) { ++ newEnchants.setBoolean("show_in_tooltip", false); ++ } ++ } ++ } ++ ++ if (enchantments != null && enchantments.size() == 0) { ++ transientItem.componentSetBoolean("minecraft:enchantment_glint_override", true); ++ } ++ } ++ ++ private static void convertDisplay(final TransientItemStack transientItem, final TypeUtil type, final int flags) { ++ final MapType display = transientItem.tag.getMap("display"); ++ ++ if (display != null) { ++ final Object name = display.getGeneric("Name"); ++ if (name != null) { ++ display.remove("Name"); ++ ++ transientItem.componentSetGeneric("minecraft:custom_name", name); ++ } ++ ++ final Object lore = display.getGeneric("Lore"); ++ if (lore != null) { ++ display.remove("Lore"); ++ ++ transientItem.componentSetGeneric("minecraft:lore", lore); ++ } ++ } ++ ++ final Number color = display == null ? null : display.getNumber("color"); ++ final boolean hideDye = (flags & TOOLTIP_FLAG_HIDE_DYE) != 0; ++ ++ if (hideDye || color != null) { ++ if (color != null) { ++ display.remove("color"); ++ } ++ ++ final MapType dyedColor = type.createEmptyMap(); ++ transientItem.componentSetMap("minecraft:dyed_color", dyedColor); ++ ++ dyedColor.setInt("rgb", color == null ? DEFAULT_LEATHER_COLOUR : color.intValue()); ++ if (hideDye) { ++ dyedColor.setBoolean("show_in_tooltip", false); ++ } ++ } ++ ++ final Object locName = display == null ? null : display.getGeneric("LocName"); ++ if (locName != null) { ++ display.remove("LocName"); ++ ++ if (locName instanceof String locNameString) { ++ transientItem.componentSetString("minecraft:item_name", ComponentUtils.createTranslatableComponent(locNameString)); ++ } ++ } ++ ++ if (display != null && "minecraft:filled_map".equals(transientItem.id)) { ++ final Object mapColor = display.getGeneric("MapColor"); ++ if (mapColor != null) { ++ display.remove("MapColor"); ++ ++ transientItem.componentSetGeneric("minecraft:map_color", mapColor); ++ } ++ } ++ ++ // mirror behavior of fixSubTag ++ if (display != null && display.isEmpty()) { ++ transientItem.tagRemoveMap("display"); ++ } ++ } ++ ++ public static MapType convertBlockStatePredicate(final String value, final TypeUtil type) { ++ final int propertyStart = value.indexOf('['); ++ final int nbtStart = value.indexOf('{'); ++ int blockNameEnd = value.length(); ++ ++ if (propertyStart != -1) { ++ blockNameEnd = propertyStart; ++ } ++ if (nbtStart != -1) { ++ blockNameEnd = Math.min(blockNameEnd, nbtStart); ++ } ++ ++ final MapType ret = type.createEmptyMap(); ++ ++ final String blockName = value.substring(0, blockNameEnd); ++ ++ // string is fine here, the underlying type accepts string AND list under the same name... ++ ret.setString("blocks", blockName.trim()); ++ ++ if (propertyStart != -1) { ++ // unlike DFU, set the fromIndex so that on malformed data we do not IOOBE ++ final int propertyEnd = value.indexOf(']', propertyStart + 1); ++ if (propertyEnd != -1) { ++ final MapType state = type.createEmptyMap(); ++ ret.setMap("state", state); ++ ++ for (final String property : value.substring(propertyStart + 1, propertyEnd).split(",")) { ++ final int separatorIdx = property.indexOf('='); ++ if (separatorIdx == -1) { ++ continue; ++ } ++ ++ final String propertyKey = property.substring(0, separatorIdx).trim(); ++ final String propertyValue = property.substring(separatorIdx + 1); ++ ++ state.setString(propertyKey, propertyValue); ++ } ++ } ++ } ++ ++ if (nbtStart != -1) { ++ // unlike DFU, set the fromIndex so that on malformed data we do not IOOBE ++ final int nbtEnd = value.indexOf('}', nbtStart + 1); ++ if (nbtEnd != -1) { ++ // note: want to include { and } ++ ret.setString("nbt", value.substring(nbtStart, nbtEnd + 1)); ++ } ++ } ++ ++ return ret; ++ } ++ ++ private static void convertBlockStatePredicates(final TransientItemStack item, final TypeUtil type, ++ final String tagKey, final String componentKey, ++ final boolean hideInTooltip) { ++ final ListType blocks = item.tagRemoveListUnchecked(tagKey); ++ if (blocks == null) { ++ return; ++ } ++ ++ final MapType blockPredicates = type.createEmptyMap(); ++ item.componentSetMap(componentKey, blockPredicates); ++ ++ if (hideInTooltip) { ++ blockPredicates.setBoolean("show_in_tooltip", false); ++ } ++ ++ final ListType predicates = type.createEmptyList(); ++ blockPredicates.setList("predicates", predicates); ++ ++ for (int i = 0, len = blocks.size(); i < len; ++i) { ++ final Object block = blocks.getGeneric(i); ++ if (!(block instanceof String blockString)) { ++ // cannot type error here, if block is not a string then nothing in `blocks` is as they have the same type ++ predicates.addGeneric(block); ++ continue; ++ } ++ ++ final MapType predicate = convertBlockStatePredicate(blockString, type); ++ ++ predicates.addMap(predicate); ++ } ++ } ++ ++ private static void convertAdventureMode(final TransientItemStack item, final TypeUtil type, final int flags) { ++ convertBlockStatePredicates( ++ item, type, "CanDestroy", "minecraft:can_break", ++ (flags & TOOLTIP_FLAG_HIDE_CAN_DESTROY) != 0 ++ ); ++ convertBlockStatePredicates( ++ item, type, "CanPlaceOn", "minecraft:can_place_on", ++ (flags & TOOLTIP_FLAG_HIDE_CAN_PLACE) != 0 ++ ); ++ } ++ ++ private static void copy(final MapType src, final String srcKey, final MapType dst, final String dstKey) { ++ if (src == null || dst == null) { ++ return; ++ } ++ ++ final Object srcValue = src.getGeneric(srcKey); ++ if (srcValue != null) { ++ dst.setGeneric(dstKey, srcValue); ++ } ++ } ++ ++ private static MapType convertAttribute(final Object inputGeneric, final TypeUtil type) { ++ final MapType input = inputGeneric instanceof MapType casted ? (MapType)casted : null; ++ ++ final MapType ret = type.createEmptyMap(); ++ ret.setString("name", ""); ++ ret.setDouble("amount", 0.0); ++ ret.setString("operation", "add_value"); ++ ++ copy(input, "AttributeName", ret, "type"); ++ copy(input, "Slot", ret, "slot"); ++ copy(input, "UUID", ret, "uuid"); ++ copy(input, "Name", ret, "name"); ++ copy(input, "Amount", ret, "amount"); ++ ++ // note: no type check on hasKey ++ if (input != null && input.hasKey("Operation")) { ++ final String operation; ++ switch (input.getInt("Operation", 0)) { ++ case 1: { ++ operation = "add_multiplied_base"; ++ break; ++ } ++ case 2: { ++ operation = "add_multiplied_total"; ++ break; ++ } ++ default: { ++ operation = "add_value"; ++ break; ++ } ++ } ++ ret.setString("operation", operation); ++ } ++ ++ return ret; ++ } ++ ++ private static void convertAttributes(final TransientItemStack item, final TypeUtil type, final int flags) { ++ final ListType attributes = item.tagRemoveListUnchecked("AttributeModifiers"); ++ final ListType newAttributes = type.createEmptyList(); ++ ++ if (attributes != null) { ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ newAttributes.addMap(convertAttribute(attributes.getGeneric(i), type)); ++ } ++ } ++ ++ if (newAttributes.size() > 0) { ++ final MapType newModifiers = type.createEmptyMap(); ++ item.componentSetMap("minecraft:attribute_modifiers", newModifiers); ++ ++ newModifiers.setList("modifiers", newAttributes); ++ ++ final boolean hideModifiers = (flags & TOOLTIP_FLAG_HIDE_MODIFIERS) != 0; ++ if (hideModifiers) { ++ newModifiers.setBoolean("show_in_tooltip", false); ++ } ++ } ++ } ++ ++ private static void convertMap(final TransientItemStack item, final TypeUtil type) { ++ item.tagMigrateToComponent("map", "minecraft:map_id"); ++ ++ final ListType decorations = item.tagRemoveListUnchecked("Decorations"); ++ if (decorations != null) { ++ final MapType newDecorations = type.createEmptyMap(); ++ ++ for (int i = 0, len = decorations.size(); i < len; ++i) { ++ final Object decorationGeneric = decorations.getGeneric(i); ++ ++ final MapType decoration = decorationGeneric instanceof MapType casted ? (MapType)casted : null; ++ ++ final String id = decoration == null ? "" : decoration.getString("id", ""); ++ if (newDecorations.hasKey(id)) { ++ // note: never replace existing decorations by id ++ continue; ++ } ++ ++ final int typeId = decoration == null ? 0 : decoration.getInt("type", 0); ++ final double x = decoration == null ? 0.0 : decoration.getDouble("x", 0.0); ++ final double z = decoration == null ? 0.0 : decoration.getDouble("z", 0.0); ++ final float rot = decoration == null ? 0.0f : (float)decoration.getDouble("rot", 0.0); ++ ++ final MapType newDecoration = type.createEmptyMap(); ++ newDecorations.setMap(id, newDecoration); ++ ++ newDecoration.setString("type", convertMapDecorationId(typeId)); ++ newDecoration.setDouble("x", x); ++ newDecoration.setDouble("z", z); ++ newDecoration.setFloat("rotation", rot); ++ } ++ ++ if (!newDecorations.isEmpty()) { ++ item.componentSetMap("minecraft:map_decorations", newDecorations); ++ } ++ } ++ } ++ ++ private static void convertPotion(final TransientItemStack item, final TypeUtil type) { ++ final MapType potionContents = type.createEmptyMap(); ++ ++ final String potion = item.tagRemoveString("Potion"); ++ ++ if (potion != null && !"minecraft:empty".equals(potion)) { ++ potionContents.setString("potion", potion); ++ } ++ ++ item.migrateTagTo("CustomPotionColor", potionContents, "custom_color"); ++ item.migrateTagTo("custom_potion_effects", potionContents, "custom_effects"); ++ ++ if (!potionContents.isEmpty()) { ++ item.componentSetMap("minecraft:potion_contents", potionContents); ++ } ++ } ++ ++ private static MapType makeFilteredText(final String raw, final String filtered, final TypeUtil type) { ++ final MapType ret = type.createEmptyMap(); ++ ++ ret.setString("raw", raw); ++ if (filtered != null) { ++ ret.setString("filtered", filtered); ++ } ++ ++ return ret; ++ } ++ ++ private static ListType convertBookPages(final TransientItemStack item, final TypeUtil type) { ++ final ListType oldPages = item.tagRemoveListUnchecked("pages"); ++ ++ final MapType filteredPages = item.tagRemoveMap("filtered_pages"); ++ ++ if (oldPages == null || oldPages.size() == 0) { ++ return null; ++ } ++ ++ final ListType ret = type.createEmptyList(); ++ ++ for (int i = 0, len = oldPages.size(); i < len; ++i) { ++ final String page = oldPages.getGeneric(i) instanceof String str ? str : ""; ++ final String filtered = filteredPages == null ? null : filteredPages.getString(Integer.toString(i)); ++ ++ ret.addMap(makeFilteredText(page, filtered, type)); ++ } ++ ++ return ret; ++ } ++ ++ private static void convertWritableBook(final TransientItemStack item, final TypeUtil type) { ++ final ListType pages = convertBookPages(item, type); ++ if (pages != null) { ++ final MapType bookContent = type.createEmptyMap(); ++ item.componentSetMap("minecraft:writable_book_content", bookContent); ++ ++ bookContent.setList("pages", pages); ++ } ++ } ++ ++ private static void convertWrittenBook(final TransientItemStack item, final TypeUtil type) { ++ final ListType pages = convertBookPages(item, type); ++ ++ final MapType bookContent = type.createEmptyMap(); ++ item.componentSetMap("minecraft:written_book_content", bookContent); ++ if (pages != null) { ++ bookContent.setList("pages", pages); ++ } ++ ++ final String title = item.tagRemoveString("title", ""); ++ final String filteredTitle = item.tagRemoveString("filtered_title"); ++ ++ bookContent.setMap("title", makeFilteredText(title, filteredTitle, type)); ++ ++ bookContent.setString("author", item.tagRemoveString("author", "")); ++ item.migrateTagTo("resolved", bookContent, "resolved"); ++ item.migrateTagTo("generation", bookContent, "generation"); ++ } ++ ++ private static void convertMobBucket(final TransientItemStack item, final TypeUtil type) { ++ final MapType bucketEntityData = type.createEmptyMap(); ++ ++ for (final String oldKey : BUCKETED_MOB_TAGS) { ++ item.migrateTagTo(oldKey, bucketEntityData, oldKey); ++ } ++ ++ if (!bucketEntityData.isEmpty()) { ++ item.componentSetMap("minecraft:bucket_entity_data", bucketEntityData); ++ } ++ } ++ ++ private static void convertCompass(final TransientItemStack item, final TypeUtil type) { ++ final Object lodestonePos = item.tagRemoveGeneric("LodestonePos"); ++ final Object lodestoneDim = item.tagRemoveGeneric("LodestoneDimension"); ++ ++ if (lodestonePos == null && lodestoneDim == null) { ++ return; ++ } ++ ++ final MapType lodestoneTracker = type.createEmptyMap(); ++ item.componentSetMap("minecraft:lodestone_tracker", lodestoneTracker); ++ ++ if (lodestonePos != null && lodestoneDim != null) { ++ final MapType target = type.createEmptyMap(); ++ lodestoneTracker.setMap("target", target); ++ ++ target.setGeneric("pos", lodestonePos); ++ target.setGeneric("dimension", lodestoneDim); ++ } ++ ++ final boolean tracked = item.tagRemoveBoolean("LodestoneTracked", true); ++ if (!tracked) { ++ lodestoneTracker.setBoolean("tracked", false); ++ } ++ } ++ ++ private static void convertFireworkExplosion(final Object inputGeneric) { ++ if (!(inputGeneric instanceof MapType)) { ++ return; ++ } ++ ++ final MapType input = (MapType)inputGeneric; ++ ++ RenameHelper.renameSingle(input, "Colors", "colors"); ++ RenameHelper.renameSingle(input, "FadeColors", "fade_colors"); ++ RenameHelper.renameSingle(input, "Trail", "has_trail"); ++ RenameHelper.renameSingle(input, "Flicker", "has_twinkle"); ++ ++ final int type = input.getInt("Type", 0); ++ input.remove("Type"); ++ ++ final String newType; ++ switch (type) { ++ case 1: { ++ newType = "large_ball"; ++ break; ++ } ++ case 2: { ++ newType = "star"; ++ break; ++ } ++ case 3: { ++ newType = "creeper"; ++ break; ++ } ++ case 4: { ++ newType = "burst"; ++ break; ++ } ++ default: { ++ newType = "small_ball"; ++ break; ++ } ++ } ++ ++ input.setString("shape", newType); ++ } ++ ++ private static void convertFireworkRocket(final TransientItemStack item, final TypeUtil type) { ++ // adhere to fixSubTag(true) behavior ++ final Object fireworksGeneric = item.tag.getGeneric("Fireworks"); ++ if (fireworksGeneric == null) { ++ return; ++ } ++ ++ if (!(fireworksGeneric instanceof MapType)) { ++ final MapType newFireworks = type.createEmptyMap(); ++ item.componentSetMap("minecraft:fireworks", newFireworks); ++ ++ newFireworks.setList("explosions", type.createEmptyList()); ++ newFireworks.setByte("flight_duration", (byte)0); ++ ++ return; ++ } ++ ++ final MapType fireworks = (MapType)fireworksGeneric; ++ ++ final MapType newFireworks = type.createEmptyMap(); ++ item.componentSetMap("minecraft:fireworks", newFireworks); ++ ++ final int flight = fireworks.getInt("Flight", 0); ++ newFireworks.setByte("flight_duration", (byte)flight); ++ ++ final ListType explosions = fireworks.getListUnchecked("Explosions", type.createEmptyList()); ++ newFireworks.setList("explosions", explosions); ++ ++ for (int i = 0, len = explosions.size(); i < len; ++i) { ++ convertFireworkExplosion(explosions.getGeneric(i)); ++ } ++ ++ fireworks.remove("Explosions"); ++ fireworks.remove("Flight"); ++ if (fireworks.isEmpty()) { ++ item.tag.remove("Fireworks"); ++ } ++ } ++ ++ private static Object copyGeneric(final Object value, final TypeUtil type) { ++ if (value == null || value instanceof Number || value instanceof String) { ++ return value; ++ } ++ if (value instanceof MapType mapType) { ++ return mapType.copy(); ++ } ++ if (value instanceof ListType listType) { ++ return listType.copy(); ++ } ++ // rest of the cases can take the slow path ++ ++ final ListType dummy = type.createEmptyList(); ++ dummy.addGeneric(value); ++ ++ return dummy.copy().getGeneric(0); ++ } ++ ++ private static void convertFireworkStar(final TransientItemStack item, final TypeUtil type) { ++ // note: adhere to fixSubTag(true) behavior ++ final Object explosionGeneric = item.tag.getGeneric("Explosion"); ++ if (explosionGeneric == null) { ++ return; ++ } ++ ++ if (!(explosionGeneric instanceof MapType)) { ++ // important that we copy the generic value when not moving it ++ item.componentSetGeneric("minecraft:firework_explosion", copyGeneric(explosionGeneric, type)); ++ return; ++ } ++ ++ final MapType explosion = (MapType)explosionGeneric; ++ ++ final MapType explosionCopy = explosion.copy(); ++ item.componentSetGeneric("minecraft:firework_explosion", explosionCopy); ++ convertFireworkExplosion(explosionCopy); ++ ++ explosion.remove("Type"); ++ explosion.remove("Colors"); ++ explosion.remove("FadeColors"); ++ explosion.remove("Trail"); ++ explosion.remove("Flicker"); ++ ++ if (explosion.isEmpty()) { ++ item.tag.remove("Explosion"); ++ } ++ } ++ ++ private static boolean isValidPlayerName(final String name) { ++ if (name.length() > 16) { ++ return false; ++ } ++ ++ for (int i = 0, len = name.length(); i < len; ++i) { ++ final char character = name.charAt(i); ++ if (character <= 0x20 || character >= 0x7F) { // printable ascii ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ ++ private static ListType convertProperties(final MapType properties, final TypeUtil type) { ++ final ListType ret = type.createEmptyList(); ++ ++ for (final String propertyKey : properties.keys()) { ++ final ListType propertyValues = properties.getListUnchecked(propertyKey); ++ ++ if (propertyValues == null) { ++ continue; ++ } ++ ++ for (int i = 0, len = propertyValues.size(); i < len; ++i) { ++ final MapType property = propertyValues.getGeneric(i) instanceof MapType casted ? (MapType)casted : null; ++ ++ final String value = property == null ? "" : property.getString("Value", ""); ++ final String signature = property == null ? null : property.getString("Signature"); ++ ++ final MapType newProperty = type.createEmptyMap(); ++ ret.addMap(newProperty); ++ ++ newProperty.setString("name", propertyKey); ++ newProperty.setString("value", value); ++ if (signature != null) { ++ newProperty.setString("signature", signature); ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ public static MapType convertProfile(final Object inputGeneric, final TypeUtil type) { ++ final MapType ret = type.createEmptyMap(); ++ ++ if (inputGeneric instanceof String name) { ++ if (!isValidPlayerName(name)) { ++ return ret; ++ } ++ ++ ret.setString("name", name); ++ ++ return ret; ++ } ++ ++ final MapType input = inputGeneric instanceof MapType casted ? (MapType)casted : null; ++ ++ final String name = input == null ? "" : input.getString("Name", ""); ++ ++ if (isValidPlayerName(name)) { ++ ret.setString("name", name); ++ } ++ ++ final Object id = input == null ? null : input.getGeneric("Id"); ++ ++ if (id != null) { ++ ret.setGeneric("id", id); ++ } ++ ++ final MapType properties = input == null ? null : input.getMap("Properties"); ++ if (properties != null && !properties.isEmpty()) { ++ ret.setList("properties", convertProperties(properties, type)); ++ } ++ ++ return ret; ++ } ++ ++ private static void convertSukll(final TransientItemStack item, final TypeUtil type) { ++ final Object skullOwnerGeneric = item.tagRemoveGeneric("SkullOwner"); ++ if (skullOwnerGeneric == null) { ++ return; ++ } ++ ++ item.componentSetMap("minecraft:profile", convertProfile(skullOwnerGeneric, type)); ++ } ++ ++ // input is unmodified ++ public static MapType convertItem(final MapType input) { ++ if (!input.hasKey("id", ObjectType.STRING) || !input.hasKey("Count", ObjectType.NUMBER)) { ++ return input.copy(); ++ } ++ ++ final TypeUtil type = input.getTypeUtil(); ++ ++ final TransientItemStack item = new TransientItemStack(input); ++ ++ item.tagMigrateToComponent("Damage", "minecraft:damage", 0); ++ item.tagMigrateToComponent("RepairCost", "minecraft:repair_cost", 0); ++ item.tagMigrateToComponent("CustomModelData", "minecraft:custom_model_data"); ++ ++ final MapType blockStateProperties = item.tagRemoveMap("BlockStateTag"); ++ if (blockStateProperties != null) { ++ item.componentSetMap("minecraft:block_state", blockStateProperties); ++ convertBlockStateProperties(blockStateProperties); ++ } ++ ++ item.tagMigrateToComponent("EntityTag", "minecraft:entity_data"); ++ ++ final MapType tileEntityTag = item.tagRemoveMap("BlockEntityTag"); ++ if (tileEntityTag != null) { ++ convertTileEntity(tileEntityTag, item); ++ ++ if (tileEntityTag.size() > 1 || (tileEntityTag.size() == 1 && !tileEntityTag.hasKey("id"))) { ++ item.componentSetMap("minecraft:block_entity_data", tileEntityTag); ++ } ++ } ++ ++ final int flags = item.tagRemoveInt("HideFlags", 0); ++ ++ if (item.tagRemoveInt("Unbreakable", 0) != 0) { ++ final MapType unbreakable = type.createEmptyMap(); ++ item.componentSetMap("minecraft:unbreakable", unbreakable); ++ if ((flags & TOOLTIP_FLAG_HIDE_UNBREAKABLE) != 0) { ++ unbreakable.setBoolean("show_in_tooltip", false); ++ } ++ } ++ ++ convertEnchantments( ++ item, type, "Enchantments", "minecraft:enchantments", ++ (flags & TOOLTIP_FLAG_HIDE_ENCHANTMENTS) != 0 ++ ); ++ ++ convertDisplay(item, type, flags); ++ convertAdventureMode(item, type, flags); ++ convertAttributes(item, type, flags); ++ ++ final Object trim = item.tagRemoveGeneric("Trim"); ++ if (trim != null) { ++ // note: DFU set does nothing if not map ++ if ((flags & TOOLTIP_FLAG_HIDE_UPGRADES) != 0 && trim instanceof MapType) { ++ ((MapType)trim).setBoolean("show_in_tooltip", false); ++ } ++ ++ item.componentSetGeneric("minecraft:trim", trim); ++ } ++ ++ if ((flags & TOOLTIP_FLAG_HIDE_ADDITIONAL) != 0) { ++ item.componentSetMap("minecraft:hide_additional_tooltip", type.createEmptyMap()); ++ } ++ ++ switch (item.id) { ++ case "minecraft:enchanted_book": { ++ convertEnchantments( ++ item, type, "StoredEnchantments", "minecraft:stored_enchantments", ++ (flags & TOOLTIP_FLAG_HIDE_ADDITIONAL) != 0 ++ ); ++ break; ++ } ++ case "minecraft:crossbow": { ++ item.tagRemoveGeneric("Charged"); ++ item.tagMigrateNonEmptyListToComponent("ChargedProjectiles", "minecraft:charged_projectiles"); ++ break; ++ } ++ case "minecraft:bundle": { ++ item.tagMigrateNonEmptyListToComponent("Items", "minecraft:bundle_contents"); ++ break; ++ } ++ case "minecraft:filled_map": { ++ convertMap(item, type); ++ break; ++ } ++ case "minecraft:potion": ++ case "minecraft:splash_potion": ++ case "minecraft:lingering_potion": ++ case "minecraft:tipped_arrow": { ++ convertPotion(item, type); ++ break; ++ } ++ case "minecraft:writable_book": { ++ convertWritableBook(item, type); ++ break; ++ } ++ case "minecraft:written_book": { ++ convertWrittenBook(item, type); ++ break; ++ } ++ case "minecraft:suspicious_stew": { ++ item.tagMigrateToComponent("effects", "minecraft:suspicious_stew_effects"); ++ break; ++ } ++ case "minecraft:debug_stick": { ++ item.tagMigrateToComponent("DebugProperty", "minecraft:debug_stick_state"); ++ break; ++ } ++ case "minecraft:pufferfish_bucket": ++ case "minecraft:salmon_bucket": ++ case "minecraft:cod_bucket": ++ case "minecraft:tropical_fish_bucket": ++ case "minecraft:axolotl_bucket": ++ case "minecraft:tadpole_bucket": { ++ convertMobBucket(item, type); ++ break; ++ } ++ case "minecraft:goat_horn": { ++ item.tagMigrateToComponent("instrument", "minecraft:instrument"); ++ break; ++ } ++ case "minecraft:knowledge_book": { ++ item.tagMigrateToComponent("Recipes", "minecraft:recipes"); ++ break; ++ } ++ case "minecraft:compass": { ++ convertCompass(item, type); ++ break; ++ } ++ case "minecraft:firework_rocket": { ++ convertFireworkRocket(item, type); ++ break; ++ } ++ case "minecraft:firework_star": { ++ convertFireworkStar(item, type); ++ break; ++ } ++ case "minecraft:player_head": { ++ convertSukll(item, type); ++ break; ++ } ++ } ++ ++ return item.serialize(); ++ } ++ ++ private ConverterItemStackToDataComponents() {} ++ ++ private static final class TransientItemStack { ++ ++ private final String id; ++ private final int count; ++ ++ private final MapType components; ++ private final MapType tag; ++ private final MapType root; ++ ++ public TransientItemStack(final MapType root) { ++ this.id = root.getString("id"); ++ this.count = root.getInt("Count"); ++ ++ final TypeUtil type = root.getTypeUtil(); ++ ++ this.components = type.createEmptyMap(); ++ ++ final MapType rootCopy = root.copy(); ++ ++ final MapType tag = rootCopy.getMap("tag"); ++ ++ rootCopy.remove("id"); ++ rootCopy.remove("Count"); ++ rootCopy.remove("tag"); ++ ++ this.tag = tag == null ? type.createEmptyMap() : tag; ++ ++ this.root = rootCopy; ++ } ++ ++ public void migrateTagTo(final String tagKey, final MapType dst, final String dstKey) { ++ final Object value = this.tag.getGeneric(tagKey); ++ ++ if (value != null) { ++ this.tag.remove(tagKey); ++ ++ dst.setGeneric(dstKey, value); ++ } ++ } ++ ++ public String tagRemoveString(final String key) { ++ final String ret = this.tag.getString(key); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public String tagRemoveString(final String key, final String dfl) { ++ final String ret = this.tag.getString(key, dfl); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public ListType tagRemoveListUnchecked(final String key) { ++ final ListType ret = this.tag.getListUnchecked(key); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public ListType tagRemoveList(final String key, final ObjectType listType) { ++ final ListType ret = this.tag.getList(key, listType); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public MapType tagRemoveMap(final String key) { ++ final MapType ret = this.tag.getMap(key); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public boolean tagRemoveBoolean(final String key, final boolean dfl) { ++ final boolean ret = this.tag.getBoolean(key, dfl); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public int tagRemoveInt(final String key, final int dfl) { ++ final int ret = this.tag.getInt(key, dfl); ++ ++ this.tag.remove(key); ++ ++ return ret; ++ } ++ ++ public Object tagRemoveGeneric(final String key) { ++ final Object ret = this.tag.getGeneric(key); ++ ++ if (ret != null) { ++ this.tag.remove(key); ++ return ret; ++ } ++ ++ return ret; ++ } ++ ++ public void tagMigrateToComponent(final String tagKey, final String componentKey) { ++ final Object value = this.tag.getGeneric(tagKey); ++ if (value != null) { ++ this.tag.remove(tagKey); ++ ++ this.components.setGeneric(componentKey, value); ++ } ++ } ++ ++ public void tagMigrateNonEmptyListToComponent(final String tagKey, final String componentKey) { ++ final Object value = this.tag.getGeneric(tagKey); ++ if (value != null) { ++ this.tag.remove(tagKey); ++ ++ if (!(value instanceof ListType list) || list.size() > 0) { ++ this.components.setGeneric(componentKey, value); ++ } ++ } ++ } ++ ++ public void tagMigrateToComponent(final String tagKey, final String componentKey, final int defaultComponent) { ++ final int value = this.tag.getInt(tagKey, defaultComponent); ++ this.tag.remove(tagKey); ++ ++ if (value != defaultComponent) { ++ this.components.setGeneric(componentKey, value); ++ } ++ } ++ ++ public void componentSetBoolean(final String key, final boolean value) { ++ this.components.setBoolean(key, value); ++ } ++ ++ public void componentSetString(final String key, final String value) { ++ this.components.setString(key, value); ++ } ++ ++ public void componentSetList(final String key, final ListType value) { ++ this.components.setList(key, value); ++ } ++ ++ public void componentSetMap(final String key, final MapType value) { ++ this.components.setMap(key, value); ++ } ++ ++ public void componentSetGeneric(final String key, final Object value) { ++ this.components.setGeneric(key, value); ++ } ++ ++ public MapType serialize() { ++ final MapType ret = this.components.getTypeUtil().createEmptyMap(); ++ ++ ret.setString("id", this.id); ++ ret.setInt("count", this.count); ++ if (!this.tag.isEmpty()) { ++ this.components.setMap("minecraft:custom_data", this.tag); ++ } ++ ++ if (!this.components.isEmpty()) { ++ ret.setMap("components", this.components); ++ } ++ ++ // merge root to ret, with entries in ret taking priority ++ if (!this.root.isEmpty()) { ++ for (final String key : this.root.keys()) { ++ if (ret.hasKey(key)) { ++ continue; ++ } ++ ++ ret.setGeneric(key, this.root.getGeneric(key)); ++ } ++ } ++ ++ return ret; ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/leveldat/ConverterRemoveFeatureFlag.java b/ca/spottedleaf/dataconverter/minecraft/converters/leveldat/ConverterRemoveFeatureFlag.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d47f922b2dd1a92be1d128df16a81983eddc2ac2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/leveldat/ConverterRemoveFeatureFlag.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.leveldat; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.Set; ++ ++public final class ConverterRemoveFeatureFlag extends DataConverter { ++ ++ private final Set flags; ++ ++ public ConverterRemoveFeatureFlag(final int toVersion, final Set flags) { ++ this(toVersion, 0, flags); ++ } ++ ++ public ConverterRemoveFeatureFlag(final int toVersion, final int versionStep, final Set flags) { ++ super(toVersion, versionStep); ++ this.flags = flags; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType enabledFeatures = data.getList("enabled_features", ObjectType.STRING); ++ if (enabledFeatures == null) { ++ return null; ++ } ++ ++ ListType removedFeatures = null; ++ ++ for (int i = 0; i < enabledFeatures.size(); ++i) { ++ final String flag = enabledFeatures.getString(i); ++ if (!this.flags.contains(flag)) { ++ continue; ++ } ++ enabledFeatures.remove(i--); ++ ++ if (removedFeatures == null) { ++ removedFeatures = data.getOrCreateList("removed_features", ObjectType.STRING); ++ } ++ removedFeatures.addString(flag); ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/options/ConverterAbstractOptionsRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/options/ConverterAbstractOptionsRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3b6341eb7cd843749f377684c14cbb81043660bc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/options/ConverterAbstractOptionsRename.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.options; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.ArrayList; ++import java.util.function.Function; ++ ++public final class ConverterAbstractOptionsRename { ++ ++ private ConverterAbstractOptionsRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameKeys(data, renamer); ++ return null; ++ } ++ }); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/particle/ConverterParticleToNBT.java b/ca/spottedleaf/dataconverter/minecraft/converters/particle/ConverterParticleToNBT.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e02fac460178e5aef15f330de88253c019e492b6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/particle/ConverterParticleToNBT.java +@@ -0,0 +1,270 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.particle; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import com.mojang.brigadier.StringReader; ++import com.mojang.brigadier.exceptions.CommandSyntaxException; ++import com.mojang.logging.LogUtils; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.TagParser; ++import net.minecraft.util.Mth; ++import org.slf4j.Logger; ++ ++public final class ConverterParticleToNBT { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static CompoundTag parseNBT(final String flat) { ++ try { ++ return TagParser.parseCompoundFully(flat); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse nbt: " + flat, ex); ++ return null; ++ } ++ } ++ ++ private static void convertItem(final MapType nbt, final String data) { ++ final MapType itemNBT = nbt.getTypeUtil().createEmptyMap(); ++ nbt.setMap("item", itemNBT); ++ itemNBT.setInt("Count", 1); ++ ++ final int nbtStart = data.indexOf('{'); ++ if (nbtStart == -1) { ++ // assume data is item name ++ itemNBT.setString("id", NamespaceUtil.correctNamespace(data)); ++ return; ++ } ++ // itemname{tagNBT} ++ itemNBT.setString("id", NamespaceUtil.correctNamespace(data.substring(0, nbtStart))); ++ ++ final CompoundTag tag = parseNBT(data.substring(nbtStart)); ++ if (tag != null) { ++ // do we need to worry about type conversion? ++ itemNBT.setMap("tag", new NBTMapType(tag)); ++ } ++ } ++ ++ private static MapType parseProperties(final String input, final TypeUtil type) { ++ final MapType ret = type.createEmptyMap(); ++ try { ++ // format: [p1=v1, p2=v2, p3=v3, ...] ++ final StringReader reader = new StringReader(input); ++ ++ reader.expect('['); ++ reader.skipWhitespace(); ++ ++ if (reader.canRead() && reader.peek() != ']') { ++ while (reader.canRead()) { ++ final String property = reader.readString(); ++ ++ reader.skipWhitespace(); ++ reader.expect('='); ++ reader.skipWhitespace(); ++ ++ final String value = reader.readString(); ++ ret.setString(property, value); ++ ++ reader.skipWhitespace(); ++ if (reader.canRead()) { ++ if (reader.peek() != ',') { ++ // invalid character or ']' ++ break; ++ } ++ ++ // skip ',' and move onto next entry ++ reader.skip(); ++ } ++ ++ reader.skipWhitespace(); ++ } ++ } ++ ++ reader.expect(']'); ++ return ret; ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse block properties: " + input, ex); ++ return null; ++ } ++ } ++ ++ private static void convertBlock(final MapType nbt, final String data) { ++ final MapType blockNBT = nbt.getTypeUtil().createEmptyMap(); ++ nbt.setMap("block_state", blockNBT); ++ ++ final int propertiesStart = data.indexOf('['); ++ if (propertiesStart == -1) { ++ // assume data is id ++ blockNBT.setString("Name", NamespaceUtil.correctNamespace(data)); ++ return; ++ } ++ blockNBT.setString("Name", NamespaceUtil.correctNamespace(data.substring(0, propertiesStart))); ++ ++ // blockname{properties} ++ final MapType properties = parseProperties(data.substring(propertiesStart), nbt.getTypeUtil()); ++ if (properties != null && !properties.isEmpty()) { ++ blockNBT.setMap("Properties", properties); ++ } ++ } ++ ++ private static ListType parseFloatVector(final StringReader reader, final TypeUtil type) throws CommandSyntaxException { ++ final float x = reader.readFloat(); ++ ++ reader.expect(' '); ++ final float y = reader.readFloat(); ++ ++ reader.expect(' '); ++ final float z = reader.readFloat(); ++ ++ final ListType ret = type.createEmptyList(); ++ ret.addFloat(x); ++ ret.addFloat(y); ++ ret.addFloat(z); ++ ++ return ret; ++ } ++ ++ private static void convertDust(final MapType nbt, final String data) { ++ try { ++ final StringReader reader = new StringReader(data); ++ ++ final ListType color = parseFloatVector(reader, nbt.getTypeUtil()); ++ ++ reader.expect(' '); ++ final float scale = reader.readFloat(); ++ ++ nbt.setList("color", color); ++ nbt.setFloat("scale", scale); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse dust particle: " + data, ex); ++ } ++ } ++ ++ private static void convertColorDust(final MapType nbt, final String data) { ++ try { ++ final StringReader reader = new StringReader(data); ++ ++ final ListType fromColor = parseFloatVector(reader, nbt.getTypeUtil()); ++ ++ reader.expect(' '); ++ final float scale = reader.readFloat(); ++ ++ reader.expect(' '); ++ final ListType toColor = parseFloatVector(reader, nbt.getTypeUtil()); ++ ++ nbt.setList("from_color", fromColor); ++ nbt.setFloat("scale", scale); ++ nbt.setList("to_color", toColor); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse color transition dust particle: " + data, ex); ++ } ++ } ++ ++ private static void convertSculk(final MapType nbt, final String data) { ++ try { ++ final StringReader reader = new StringReader(data); ++ ++ final float roll = reader.readFloat(); ++ ++ nbt.setFloat("roll", roll); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse sculk particle: " + data, ex); ++ } ++ } ++ ++ private static void convertVibration(final MapType nbt, final String data) { ++ try { ++ final StringReader reader = new StringReader(data); ++ ++ final double posX = reader.readDouble(); ++ ++ reader.expect(' '); ++ final double posY = reader.readDouble(); ++ ++ reader.expect(' '); ++ final double posZ = reader.readDouble(); ++ ++ reader.expect(' '); ++ final int arrival = reader.readInt(); ++ ++ nbt.setInt("arrival_in_ticks", arrival); ++ ++ final MapType destination = nbt.getTypeUtil().createEmptyMap(); ++ nbt.setMap("destination", destination); ++ ++ destination.setString("type", "minecraft:block"); ++ ++ final ListType pos = nbt.getTypeUtil().createEmptyList(); ++ destination.setList("pos", pos); ++ ++ pos.addInt(Mth.floor(posX)); ++ pos.addInt(Mth.floor(posY)); ++ pos.addInt(Mth.floor(posZ)); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse vibration particle: " + data, ex); ++ } ++ } ++ ++ private static void convertShriek(final MapType nbt, final String data) { ++ try { ++ final StringReader reader = new StringReader(data); ++ ++ final int delay = reader.readInt(); ++ ++ nbt.setInt("delay", delay); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse shriek particle: " + data, ex); ++ } ++ } ++ ++ public static MapType convert(final String flat, final TypeUtil type) { ++ final String[] split = flat.split(" ", 2); ++ final String name = NamespaceUtil.correctNamespace(split[0]); ++ ++ final MapType ret = type.createEmptyMap(); ++ ret.setString("type", name); ++ ++ if (split.length > 1) { ++ final String data = split[1]; ++ switch (name) { ++ case "minecraft:item": { ++ convertItem(ret, data); ++ break; ++ } ++ case "minecraft:block": ++ case "minecraft:block_marker": ++ case "minecraft:falling_dust": ++ case "minecraft:dust_pillar": { ++ convertBlock(ret, data); ++ break; ++ } ++ case "minecraft:dust": { ++ convertDust(ret, data); ++ break; ++ } ++ case "minecraft:dust_color_transition": { ++ convertColorDust(ret, data); ++ break; ++ } ++ case "minecraft:sculk_charge": { ++ convertSculk(ret, data); ++ break; ++ } ++ case "minecraft:vibration": { ++ convertVibration(ret, data); ++ break; ++ } ++ case "minecraft:shriek": { ++ convertShriek(ret, data); ++ break; ++ } ++ } ++ } ++ ++ return ret; ++ } ++ ++ private ConverterParticleToNBT() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterAbstractPOIRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterAbstractPOIRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cdd60c91796691b79e4848a5565616351474f453 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterAbstractPOIRename.java +@@ -0,0 +1,53 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.poi; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractPOIRename { ++ ++ private ConverterAbstractPOIRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.POI_CHUNK.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType sections = data.getMap("Sections"); ++ if (sections == null) { ++ return null; ++ } ++ ++ for (final String key : sections.keys()) { ++ final MapType section = sections.getMap(key); ++ ++ final ListType records = section.getList("Records", ObjectType.MAP); ++ ++ if (records == null) { ++ continue; ++ } ++ ++ for (int i = 0, len = records.size(); i < len; ++i) { ++ final MapType record = records.getMap(i); ++ ++ final String type = record.getString("type"); ++ if (type != null) { ++ final String converted = renamer.apply(type); ++ if (converted != null) { ++ record.setString("type", converted); ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterPoiDelete.java b/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterPoiDelete.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c61537e7ebef1c48d65a302ab174ef41847560a8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/poi/ConverterPoiDelete.java +@@ -0,0 +1,53 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.poi; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.function.Predicate; ++ ++public final class ConverterPoiDelete extends DataConverter { ++ ++ private final Predicate delete; ++ ++ public ConverterPoiDelete(final int toVersion, final Predicate delete) { ++ super(toVersion); ++ this.delete = delete; ++ } ++ ++ public ConverterPoiDelete(final int toVersion, final int versionStep, final Predicate delete) { ++ super(toVersion, versionStep); ++ this.delete = delete; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType sections = data.getMap("Sections"); ++ if (sections == null) { ++ return null; ++ } ++ ++ for (final String key : sections.keys()) { ++ final MapType section = sections.getMap(key); ++ ++ final ListType records = section.getList("Records", ObjectType.MAP); ++ ++ if (records == null) { ++ continue; ++ } ++ ++ for (int i = 0; i < records.size();) { ++ final MapType record = records.getMap(i); ++ ++ final String type = record.getString("type"); ++ if (type != null && this.delete.test(type)) { ++ records.remove(i); ++ continue; ++ } ++ ++i; ++ } ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/recipe/ConverterAbstractRecipeRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/recipe/ConverterAbstractRecipeRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8f35cbbd78a629712f9ae3cd5d180269f015a11d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/recipe/ConverterAbstractRecipeRename.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.recipe; ++ ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.function.Function; ++ ++public final class ConverterAbstractRecipeRename { ++ ++ private ConverterAbstractRecipeRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ ConverterAbstractStringValueTypeRename.register(version, subVersion, MCTypeRegistry.RECIPE, renamer); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterAbstractStatsRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterAbstractStatsRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2468ebedfabfb93f9b8d398d77e70d019b9a3dfa +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterAbstractStatsRename.java +@@ -0,0 +1,66 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.stats; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.ArrayList; ++import java.util.function.Function; ++ ++public final class ConverterAbstractStatsRename { ++ ++ private ConverterAbstractStatsRename() {} ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.OBJECTIVE.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType criteriaType = data.getMap("CriteriaType"); ++ if (criteriaType == null) { ++ return null; ++ } ++ ++ final String type = criteriaType.getString("type"); ++ if (!"minecraft:custom".equals(type)) { ++ return null; ++ } ++ ++ final String id = criteriaType.getString("id"); ++ if (id == null) { ++ return null; ++ } ++ ++ final String rename = renamer.apply(id); ++ if (rename != null) { ++ criteriaType.setString("id", rename); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.STATS.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType stats = data.getMap("stats"); ++ ++ if (stats == null) { ++ return null; ++ } ++ ++ final MapType custom = stats.getMap("minecraft:custom"); ++ if (custom == null) { ++ return null; ++ } ++ ++ RenameHelper.renameKeys(custom, renamer); ++ ++ return null; ++ } ++ }); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterFlattenStats.java b/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterFlattenStats.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f8a5d9e4d8fb0f1b3c2fed900fa1d52e2d25f5ec +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/stats/ConverterFlattenStats.java +@@ -0,0 +1,321 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.stats; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperBlockFlatteningV1450; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterFlattenItemStack; ++import ca.spottedleaf.dataconverter.minecraft.versions.V1451; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.collect.ImmutableMap; ++import com.google.common.collect.ImmutableSet; ++import org.apache.commons.lang3.StringUtils; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class ConverterFlattenStats { ++ ++ private static final int VERSION = MCVersions.V17W47A; ++ private static final int VERSION_STEP = 6; ++ ++ private static final Set SPECIAL_OBJECTIVE_CRITERIA = new HashSet<>( ++ Set.of( ++ "dummy", ++ "trigger", ++ "deathCount", ++ "playerKillCount", ++ "totalKillCount", ++ "health", ++ "food", ++ "air", ++ "armor", ++ "xp", ++ "level", ++ "killedByTeam.aqua", ++ "killedByTeam.black", ++ "killedByTeam.blue", ++ "killedByTeam.dark_aqua", ++ "killedByTeam.dark_blue", ++ "killedByTeam.dark_gray", ++ "killedByTeam.dark_green", ++ "killedByTeam.dark_purple", ++ "killedByTeam.dark_red", ++ "killedByTeam.gold", ++ "killedByTeam.gray", ++ "killedByTeam.green", ++ "killedByTeam.light_purple", ++ "killedByTeam.red", ++ "killedByTeam.white", ++ "killedByTeam.yellow", ++ "teamkill.aqua", ++ "teamkill.black", ++ "teamkill.blue", ++ "teamkill.dark_aqua", ++ "teamkill.dark_blue", ++ "teamkill.dark_gray", ++ "teamkill.dark_green", ++ "teamkill.dark_purple", ++ "teamkill.dark_red", ++ "teamkill.gold", ++ "teamkill.gray", ++ "teamkill.green", ++ "teamkill.light_purple", ++ "teamkill.red", ++ "teamkill.white", ++ "teamkill.yellow" ++ ) ++ ); ++ ++ private static final Set SKIP = new HashSet<>( ++ ImmutableSet.builder() ++ .add("stat.craftItem.minecraft.spawn_egg") ++ .add("stat.useItem.minecraft.spawn_egg") ++ .add("stat.breakItem.minecraft.spawn_egg") ++ .add("stat.pickup.minecraft.spawn_egg") ++ .add("stat.drop.minecraft.spawn_egg") ++ .build() ++ ); ++ ++ private static final Map CUSTOM_MAP = new HashMap<>( ++ ImmutableMap.builder() ++ .put("stat.leaveGame", "minecraft:leave_game") ++ .put("stat.playOneMinute", "minecraft:play_one_minute") ++ .put("stat.timeSinceDeath", "minecraft:time_since_death") ++ .put("stat.sneakTime", "minecraft:sneak_time") ++ .put("stat.walkOneCm", "minecraft:walk_one_cm") ++ .put("stat.crouchOneCm", "minecraft:crouch_one_cm") ++ .put("stat.sprintOneCm", "minecraft:sprint_one_cm") ++ .put("stat.swimOneCm", "minecraft:swim_one_cm") ++ .put("stat.fallOneCm", "minecraft:fall_one_cm") ++ .put("stat.climbOneCm", "minecraft:climb_one_cm") ++ .put("stat.flyOneCm", "minecraft:fly_one_cm") ++ .put("stat.diveOneCm", "minecraft:dive_one_cm") ++ .put("stat.minecartOneCm", "minecraft:minecart_one_cm") ++ .put("stat.boatOneCm", "minecraft:boat_one_cm") ++ .put("stat.pigOneCm", "minecraft:pig_one_cm") ++ .put("stat.horseOneCm", "minecraft:horse_one_cm") ++ .put("stat.aviateOneCm", "minecraft:aviate_one_cm") ++ .put("stat.jump", "minecraft:jump") ++ .put("stat.drop", "minecraft:drop") ++ .put("stat.damageDealt", "minecraft:damage_dealt") ++ .put("stat.damageTaken", "minecraft:damage_taken") ++ .put("stat.deaths", "minecraft:deaths") ++ .put("stat.mobKills", "minecraft:mob_kills") ++ .put("stat.animalsBred", "minecraft:animals_bred") ++ .put("stat.playerKills", "minecraft:player_kills") ++ .put("stat.fishCaught", "minecraft:fish_caught") ++ .put("stat.talkedToVillager", "minecraft:talked_to_villager") ++ .put("stat.tradedWithVillager", "minecraft:traded_with_villager") ++ .put("stat.cakeSlicesEaten", "minecraft:eat_cake_slice") ++ .put("stat.cauldronFilled", "minecraft:fill_cauldron") ++ .put("stat.cauldronUsed", "minecraft:use_cauldron") ++ .put("stat.armorCleaned", "minecraft:clean_armor") ++ .put("stat.bannerCleaned", "minecraft:clean_banner") ++ .put("stat.brewingstandInteraction", "minecraft:interact_with_brewingstand") ++ .put("stat.beaconInteraction", "minecraft:interact_with_beacon") ++ .put("stat.dropperInspected", "minecraft:inspect_dropper") ++ .put("stat.hopperInspected", "minecraft:inspect_hopper") ++ .put("stat.dispenserInspected", "minecraft:inspect_dispenser") ++ .put("stat.noteblockPlayed", "minecraft:play_noteblock") ++ .put("stat.noteblockTuned", "minecraft:tune_noteblock") ++ .put("stat.flowerPotted", "minecraft:pot_flower") ++ .put("stat.trappedChestTriggered", "minecraft:trigger_trapped_chest") ++ .put("stat.enderchestOpened", "minecraft:open_enderchest") ++ .put("stat.itemEnchanted", "minecraft:enchant_item") ++ .put("stat.recordPlayed", "minecraft:play_record") ++ .put("stat.furnaceInteraction", "minecraft:interact_with_furnace") ++ .put("stat.craftingTableInteraction", "minecraft:interact_with_crafting_table") ++ .put("stat.chestOpened", "minecraft:open_chest") ++ .put("stat.sleepInBed", "minecraft:sleep_in_bed") ++ .put("stat.shulkerBoxOpened", "minecraft:open_shulker_box") ++ .build() ++ ); ++ ++ private static final String BLOCK_KEY = "stat.mineBlock"; ++ private static final String NEW_BLOCK_KEY = "minecraft:mined"; ++ ++ private static final Map ITEM_KEYS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("stat.craftItem", "minecraft:crafted") ++ .put("stat.useItem", "minecraft:used") ++ .put("stat.breakItem", "minecraft:broken") ++ .put("stat.pickup", "minecraft:picked_up") ++ .put("stat.drop", "minecraft:dropped") ++ .build() ++ ); ++ ++ private static final Map ENTITY_KEYS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("stat.entityKilledBy", "minecraft:killed_by") ++ .put("stat.killEntity", "minecraft:killed") ++ .build() ++ ); ++ ++ private static final Map ENTITIES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("Bat", "minecraft:bat") ++ .put("Blaze", "minecraft:blaze") ++ .put("CaveSpider", "minecraft:cave_spider") ++ .put("Chicken", "minecraft:chicken") ++ .put("Cow", "minecraft:cow") ++ .put("Creeper", "minecraft:creeper") ++ .put("Donkey", "minecraft:donkey") ++ .put("ElderGuardian", "minecraft:elder_guardian") ++ .put("Enderman", "minecraft:enderman") ++ .put("Endermite", "minecraft:endermite") ++ .put("EvocationIllager", "minecraft:evocation_illager") ++ .put("Ghast", "minecraft:ghast") ++ .put("Guardian", "minecraft:guardian") ++ .put("Horse", "minecraft:horse") ++ .put("Husk", "minecraft:husk") ++ .put("Llama", "minecraft:llama") ++ .put("LavaSlime", "minecraft:magma_cube") ++ .put("MushroomCow", "minecraft:mooshroom") ++ .put("Mule", "minecraft:mule") ++ .put("Ozelot", "minecraft:ocelot") ++ .put("Parrot", "minecraft:parrot") ++ .put("Pig", "minecraft:pig") ++ .put("PolarBear", "minecraft:polar_bear") ++ .put("Rabbit", "minecraft:rabbit") ++ .put("Sheep", "minecraft:sheep") ++ .put("Shulker", "minecraft:shulker") ++ .put("Silverfish", "minecraft:silverfish") ++ .put("SkeletonHorse", "minecraft:skeleton_horse") ++ .put("Skeleton", "minecraft:skeleton") ++ .put("Slime", "minecraft:slime") ++ .put("Spider", "minecraft:spider") ++ .put("Squid", "minecraft:squid") ++ .put("Stray", "minecraft:stray") ++ .put("Vex", "minecraft:vex") ++ .put("Villager", "minecraft:villager") ++ .put("VindicationIllager", "minecraft:vindication_illager") ++ .put("Witch", "minecraft:witch") ++ .put("WitherSkeleton", "minecraft:wither_skeleton") ++ .put("Wolf", "minecraft:wolf") ++ .put("ZombieHorse", "minecraft:zombie_horse") ++ .put("PigZombie", "minecraft:zombie_pigman") ++ .put("ZombieVillager", "minecraft:zombie_villager") ++ .put("Zombie", "minecraft:zombie") ++ .build() ++ ); ++ ++ private static final String NEW_CUSTOM_KEY = "minecraft:custom"; ++ ++ private ConverterFlattenStats() {} ++ ++ private static String upgradeItem(final String itemName) { ++ return ConverterFlattenItemStack.flattenItem(itemName, 0); ++ } ++ ++ private static String upgradeBlock(final String block) { ++ return HelperBlockFlatteningV1450.getNewBlockName(block); ++ } ++ ++ private static record StatType(String category, String key) {} ++ ++ private static StatType convertLegacyKey(final String key) { ++ if (SKIP.contains(key)) { ++ return null; ++ } ++ ++ final String custom = CUSTOM_MAP.get(key); ++ if (custom != null) { ++ return new StatType(NEW_CUSTOM_KEY, custom); ++ } ++ ++ final int i = StringUtils.ordinalIndexOf(key, ".", 2); ++ if (i < 0) { ++ return null; ++ } ++ ++ final String stat = key.substring(0, i); ++ ++ if (BLOCK_KEY.equals(stat)) { ++ return new StatType(NEW_BLOCK_KEY, upgradeBlock(key.substring(i + 1).replace('.', ':'))); ++ } ++ ++ final String itemStat = ITEM_KEYS.get(stat); ++ ++ if (itemStat != null) { ++ final String itemId = key.substring(i + 1).replace('.', ':'); ++ final String flattenedItem = upgradeItem(itemId); ++ ++ return new StatType(itemStat, flattenedItem == null ? itemId : flattenedItem); ++ } ++ ++ final String entityStat = ENTITY_KEYS.get(stat); ++ if (entityStat != null) { ++ final String entityId = key.substring(i + 1).replace('.', ':'); ++ ++ return new StatType(entityStat, ENTITIES.getOrDefault(entityId, entityId)); ++ } ++ ++ return null; ++ } ++ ++ public static DataConverter makeStatsConverter() { ++ return new DataConverter<>(VERSION, VERSION_STEP) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType stats = Types.NBT.createEmptyMap(); ++ ++ for (final String statKey : data.keys()) { ++ final Number value = data.getNumber(statKey); ++ if (value == null) { ++ continue; ++ } ++ ++ final StatType converted = convertLegacyKey(statKey); ++ ++ if (converted == null) { ++ continue; ++ } ++ ++ stats.getOrCreateMap(converted.category()).setGeneric(converted.key(), value); ++ } ++ ++ data.clear(); ++ data.setMap("stats", stats); ++ ++ return null; ++ } ++ }; ++ } ++ ++ public static DataConverter makeObjectiveConverter() { ++ return new DataConverter<>(VERSION, VERSION_STEP) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertCriteriaName(data, "CriteriaName"); ++ ++ // We also need to update CriteriaType that is created by the data hook in V1451, ++ // otherwise that data hook will overwrite our CriteriaName ++ final MapType criteriaType = data.getMap("CriteriaType"); ++ if (criteriaType != null) { ++ if ("_special".equals(criteriaType.getString("type"))) { ++ convertCriteriaName(criteriaType, "id"); ++ } ++ } ++ ++ return null; ++ } ++ ++ private void convertCriteriaName(final MapType data, final String key) { ++ final String criteriaName = data.getString(key); ++ ++ if (criteriaName == null) { ++ return; ++ } ++ ++ if (SPECIAL_OBJECTIVE_CRITERIA.contains(criteriaName)) { ++ return; ++ } ++ ++ final StatType converted = convertLegacyKey(criteriaName); ++ data.setString(key, converted == null ? "dummy" : V1451.packWithDot(converted.category()) + ":" + V1451.packWithDot(converted.key())); ++ } ++ }; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/converters/tileentity/ConverterAbstractTileEntityRename.java b/ca/spottedleaf/dataconverter/minecraft/converters/tileentity/ConverterAbstractTileEntityRename.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9b82500851430bbe55669d83602931edbc2fa973 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/converters/tileentity/ConverterAbstractTileEntityRename.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.converters.tileentity; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.function.Function; ++ ++public final class ConverterAbstractTileEntityRename { ++ ++ public static void register(final int version, final Function renamer) { ++ register(version, 0, renamer); ++ } ++ ++ public static void register(final int version, final int subVersion, final Function renamer) { ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(version, subVersion) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (id == null) { ++ return null; ++ } ++ ++ final String converted = renamer.apply(id); ++ ++ if (converted != null) { ++ data.setString("id", converted); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/datatypes/DynamicDataType.java b/ca/spottedleaf/dataconverter/minecraft/datatypes/DynamicDataType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..48f5e7950a27995f16787d4eaaa7dc10182a10c8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/datatypes/DynamicDataType.java +@@ -0,0 +1,132 @@ ++package ca.spottedleaf.dataconverter.minecraft.datatypes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersionRegistry; ++import ca.spottedleaf.dataconverter.util.Long2ObjectArraySortedMap; ++import java.util.ArrayList; ++import java.util.List; ++ ++public class DynamicDataType extends DataType { ++ ++ public final String name; ++ ++ protected final ArrayList> structureConverters = new ArrayList<>(); ++ protected final Long2ObjectArraySortedMap>> structureWalkers = new Long2ObjectArraySortedMap<>(); ++ protected final Long2ObjectArraySortedMap>> structureHooks = new Long2ObjectArraySortedMap<>(); ++ ++ public DynamicDataType(final String name) { ++ this.name = name; ++ } ++ ++ public void addStructureConverter(final DataConverter converter) { ++ MCVersionRegistry.checkVersion(converter.getEncodedVersion()); ++ final boolean sort = !this.structureConverters.isEmpty() ++ && DataConverter.LOWEST_VERSION_COMPARATOR.compare(this.structureConverters.getLast(), converter) > 0; ++ this.structureConverters.add(converter); ++ if (sort) { ++ this.structureConverters.sort(DataConverter.LOWEST_VERSION_COMPARATOR); ++ } ++ } ++ ++ public void addStructureWalker(final int minVersion, final DataWalker walker) { ++ this.addStructureWalker(minVersion, 0, walker); ++ } ++ ++ public void addStructureWalker(final int minVersion, final int versionStep, final DataWalker walker) { ++ this.structureWalkers.computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(walker); ++ } ++ ++ public void addStructureHook(final int minVersion, final DataHook hook) { ++ this.addStructureHook(minVersion, 0, hook); ++ } ++ ++ public void addStructureHook(final int minVersion, final int versionStep, final DataHook hook) { ++ this.structureHooks.computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(hook); ++ } ++ ++ @Override ++ public Object convert(Object data, final long fromVersion, final long toVersion) { ++ Object ret = null; ++ ++ final List> converters = this.structureConverters; ++ for (int i = 0, len = converters.size(); i < len; ++i) { ++ final DataConverter converter = converters.get(i); ++ final long converterVersion = converter.getEncodedVersion(); ++ ++ if (converterVersion <= fromVersion) { ++ continue; ++ } ++ ++ if (converterVersion > toVersion) { ++ break; ++ } ++ ++ List> hooks = this.structureHooks.getFloor(converterVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final Object replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final Object replace = converter.convert(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ ++ // possibly new data format, update hooks ++ hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final Object postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ } ++ ++ final List> hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final Object replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final List> walkers = this.structureWalkers.getFloor(toVersion); ++ if (walkers != null) { ++ for (int i = 0, len = walkers.size(); i < len; ++i) { ++ final Object replace = walkers.get(i).walk(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final Object postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ ++ return ret; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/datatypes/IDDataType.java b/ca/spottedleaf/dataconverter/minecraft/datatypes/IDDataType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..35ae849cb57e2e6b54f5607e8bacdc43448ae6a1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/datatypes/IDDataType.java +@@ -0,0 +1,170 @@ ++package ca.spottedleaf.dataconverter.minecraft.datatypes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersionRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.Long2ObjectArraySortedMap; ++ ++import java.util.ArrayList; ++import java.util.HashMap; ++import java.util.List; ++import java.util.Map; ++ ++public class IDDataType extends MCDataType { ++ ++ protected final Map>>> walkersById = new HashMap<>(); ++ ++ public IDDataType(final String name) { ++ super(name); ++ } ++ ++ public void addConverterForId(final String id, final DataConverter converter) { ++ this.addStructureConverter(new DataConverter<>(converter.getToVersion(), converter.getVersionStep()) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!id.equals(data.getString("id"))) { ++ return null; ++ } ++ return converter.convert(data, sourceVersion, toVersion); ++ } ++ }); ++ } ++ ++ public boolean hasWalkers(final String id) { ++ return this.walkersById.containsKey(id); ++ } ++ ++ public void addWalker(final int minVersion, final String id, final DataWalker walker) { ++ this.addWalker(minVersion, 0, id, walker); ++ } ++ ++ public void addWalker(final int minVersion, final int versionStep, final String id, final DataWalker walker) { ++ this.walkersById.computeIfAbsent(id, (final String keyInMap) -> { ++ return new Long2ObjectArraySortedMap<>(); ++ }).computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(walker); ++ } ++ ++ public void copyWalkers(final int minVersion, final String fromId, final String toId) { ++ this.copyWalkers(minVersion, 0, fromId, toId); ++ } ++ ++ public void copyWalkers(final int minVersion, final int versionStep, final String fromId, final String toId) { ++ final long version = DataConverter.encodeVersions(minVersion, versionStep); ++ final Long2ObjectArraySortedMap>> walkersForId = this.walkersById.get(fromId); ++ if (walkersForId == null) { ++ return; ++ } ++ ++ final List> nearest = walkersForId.getFloor(version); ++ ++ if (nearest == null) { ++ return; ++ } ++ ++ for (final DataWalker walker : nearest) { ++ this.addWalker(minVersion, versionStep, toId, walker); ++ } ++ } ++ ++ @Override ++ public MapType convert(MapType data, final long fromVersion, final long toVersion) { ++ MapType ret = null; ++ ++ final List> converters = this.structureConverters; ++ for (int i = 0, len = converters.size(); i < len; ++i) { ++ final DataConverter converter = converters.get(i); ++ final long converterVersion = converter.getEncodedVersion(); ++ ++ if (converterVersion <= fromVersion) { ++ continue; ++ } ++ ++ if (converterVersion > toVersion) { ++ break; ++ } ++ ++ List> hooks = this.structureHooks.getFloor(converterVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final MapType replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final MapType replace = converter.convert(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ ++ // possibly new data format, update hooks ++ hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final MapType postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ } ++ ++ final List> hooks = this.structureHooks.getFloor(toVersion); ++ ++ // run pre hooks ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final MapType replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ // run all walkers ++ ++ final List> walkers = this.structureWalkers.getFloor(toVersion); ++ if (walkers != null) { ++ for (int i = 0, len = walkers.size(); i < len; ++i) { ++ final MapType replace = walkers.get(i).walk(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final Long2ObjectArraySortedMap>> walkersByVersion = this.walkersById.get(data.getString("id")); ++ if (walkersByVersion != null) { ++ final List> walkersForId = walkersByVersion.getFloor(toVersion); ++ if (walkersForId != null) { ++ for (int i = 0, len = walkersForId.size(); i < len; ++i) { ++ final MapType replace = walkersForId.get(i).walk(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ } ++ ++ // run post hooks ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final MapType postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ ++ return ret; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/datatypes/MCDataType.java b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCDataType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e1f7c0d7fd80556941bbba8018aa85e7c896b630 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCDataType.java +@@ -0,0 +1,133 @@ ++package ca.spottedleaf.dataconverter.minecraft.datatypes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersionRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.Long2ObjectArraySortedMap; ++import java.util.ArrayList; ++import java.util.List; ++ ++public class MCDataType extends DataType { ++ ++ public final String name; ++ ++ protected final ArrayList> structureConverters = new ArrayList<>(); ++ protected final Long2ObjectArraySortedMap>> structureWalkers = new Long2ObjectArraySortedMap<>(); ++ protected final Long2ObjectArraySortedMap>> structureHooks = new Long2ObjectArraySortedMap<>(); ++ ++ public MCDataType(final String name) { ++ this.name = name; ++ } ++ ++ public void addStructureConverter(final DataConverter converter) { ++ MCVersionRegistry.checkVersion(converter.getEncodedVersion()); ++ final boolean sort = !this.structureConverters.isEmpty() ++ && DataConverter.LOWEST_VERSION_COMPARATOR.compare(this.structureConverters.getLast(), converter) > 0; ++ this.structureConverters.add(converter); ++ if (sort) { ++ this.structureConverters.sort(DataConverter.LOWEST_VERSION_COMPARATOR); ++ } ++ } ++ ++ public void addStructureWalker(final int minVersion, final DataWalker walker) { ++ this.addStructureWalker(minVersion, 0, walker); ++ } ++ ++ public void addStructureWalker(final int minVersion, final int versionStep, final DataWalker walker) { ++ this.structureWalkers.computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(walker); ++ } ++ ++ public void addStructureHook(final int minVersion, final DataHook hook) { ++ this.addStructureHook(minVersion, 0, hook); ++ } ++ ++ public void addStructureHook(final int minVersion, final int versionStep, final DataHook hook) { ++ this.structureHooks.computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(hook); ++ } ++ ++ @Override ++ public MapType convert(MapType data, final long fromVersion, final long toVersion) { ++ MapType ret = null; ++ ++ final List> converters = this.structureConverters; ++ for (int i = 0, len = converters.size(); i < len; ++i) { ++ final DataConverter converter = converters.get(i); ++ final long converterVersion = converter.getEncodedVersion(); ++ ++ if (converterVersion <= fromVersion) { ++ continue; ++ } ++ ++ if (converterVersion > toVersion) { ++ break; ++ } ++ ++ List> hooks = this.structureHooks.getFloor(converterVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final MapType replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final MapType replace = converter.convert(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ ++ // possibly new data format, update hooks ++ hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final MapType postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ } ++ ++ final List> hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final MapType replace = hooks.get(k).preHook(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ final List> walkers = this.structureWalkers.getFloor(toVersion); ++ if (walkers != null) { ++ for (int i = 0, len = walkers.size(); i < len; ++i) { ++ final MapType replace = walkers.get(i).walk(data, fromVersion, toVersion); ++ if (replace != null) { ++ ret = data = replace; ++ } ++ } ++ } ++ ++ if (hooks != null) { ++ for (int klen = hooks.size(), k = klen - 1; k >= 0; --k) { ++ final MapType postReplace = hooks.get(k).postHook(data, fromVersion, toVersion); ++ if (postReplace != null) { ++ ret = data = postReplace; ++ } ++ } ++ } ++ ++ return ret; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4888b386d0e7f0237c2fe416e9034658cba0f1b0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCTypeRegistry.java +@@ -0,0 +1,367 @@ ++package ca.spottedleaf.dataconverter.minecraft.datatypes; ++ ++import ca.spottedleaf.dataconverter.minecraft.versions.*; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++import java.text.DecimalFormat; ++ ++public final class MCTypeRegistry { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ public static final MCDataType LEVEL = new MCDataType("Level"); ++ public static final MCDataType LIGHTWEIGHT_LEVEL = new MCDataType("LightweightLevel"); ++ public static final MCDataType PLAYER = new MCDataType("Player"); ++ public static final MCDataType CHUNK = new MCDataType("Chunk"); ++ public static final MCDataType HOTBAR = new MCDataType("CreativeHotbar"); ++ public static final MCDataType OPTIONS = new MCDataType("Options"); ++ public static final MCDataType STRUCTURE = new MCDataType("Structure"); ++ public static final MCDataType STATS = new MCDataType("Stats"); ++ public static final MCDataType ADVANCEMENTS = new MCDataType("Advancements"); ++ public static final MCDataType POI_CHUNK = new MCDataType("PoiChunk"); ++ public static final MCDataType ENTITY_CHUNK = new MCDataType("EntityChunk"); ++ public static final IDDataType TILE_ENTITY = new IDDataType("TileEntity"); ++ public static final IDDataType ITEM_STACK = new IDDataType("ItemStack"); ++ public static final MCDataType BLOCK_STATE = new MCDataType("BlockState"); ++ public static final MCValueType FLAT_BLOCK_STATE = new MCValueType("FlatBlockState"); ++ public static final MCDataType DATA_COMPONENTS = new MCDataType("DataComponents"); ++ public static final MCDataType VILLAGER_TRADE = new MCDataType("VillagerTrade"); ++ public static final DynamicDataType PARTICLE = new DynamicDataType("Particle"); ++ public static final MCValueType ENTITY_NAME = new MCValueType("EntityName"); ++ public static final IDDataType ENTITY = new IDDataType("Entity"); ++ public static final MCValueType BLOCK_NAME = new MCValueType("BlockName"); ++ public static final MCValueType ITEM_NAME = new MCValueType("ItemName"); ++ public static final MCDataType UNTAGGED_SPAWNER = new MCDataType("Spawner"); ++ public static final MCDataType STRUCTURE_FEATURE = new MCDataType("StructureFeature"); ++ public static final MCDataType OBJECTIVE = new MCDataType("Objective"); ++ public static final MCDataType TEAM = new MCDataType("Team"); ++ public static final MCValueType RECIPE = new MCValueType("RecipeName"); ++ public static final MCValueType BIOME = new MCValueType("Biome"); ++ public static final MCDataType WORLD_GEN_SETTINGS = new MCDataType("WorldGenSettings"); ++ public static final MCValueType GAME_EVENT_NAME = new MCValueType("GameEventName"); ++ // NOTE: Prior to V165, TEXT_COMPONENT _also_ mark plain strings (not components!) to be converted to json format. ++ // So, great care should be taken to ensure that when dealing with versions up to and including V165 that BOTH formats ++ // of JSON and plain text are parsed properly. ++ // As a result, we differ from Vanilla's schemas to ensure that legacy data converts correctly. ++ public static final DynamicDataType TEXT_COMPONENT = new DynamicDataType("TextComponent"); ++ public static final MCDataType ENTITY_EQUIPMENT = new MCDataType("EntityEquipment"); ++ ++ public static final MCValueType MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST = new MCValueType("MultiNoiseBiomeSourceParameterList"); ++ ++ public static final MCDataType SAVED_DATA_RANDOM_SEQUENCES = new MCDataType("SavedData/RandomSequences"); ++ public static final MCDataType SAVED_DATA_SCOREBOARD = new MCDataType("SavedData/Scoreboard"); ++ public static final MCDataType SAVED_DATA_STRUCTURE_FEATURE_INDICES = new MCDataType("SavedData/StructureFeatureIndices"); ++ public static final MCDataType SAVED_DATA_MAP_DATA = new MCDataType("SavedData/MapData"); ++ public static final MCDataType SAVED_DATA_RAIDS = new MCDataType("SavedData/Raids"); ++ public static final MCDataType SAVED_DATA_COMMAND_STORAGE = new MCDataType("SavedData/CommandStorage"); ++ public static final MCDataType SAVED_DATA_MAP_INDEX = new MCDataType("SavedData/IdCounts"); ++ public static final MCDataType SAVED_DATA_TICKETS = new MCDataType("SavedData/Tickets"); ++ ++ public static final DynamicDataType DATACONVERTER_CUSTOM_TYPE_COMMAND = new DynamicDataType("DC_Custom/Command"); ++ ++ static { ++ LOGGER.info("Initialising converters for DataConverter..."); ++ ++ final long start = System.nanoTime(); ++ try { ++ registerAll(); ++ } catch (final Throwable thr) { ++ LOGGER.error(LogUtils.FATAL_MARKER, "Failed to register data converters", thr); ++ throw new RuntimeException(thr); ++ } ++ final long end = System.nanoTime(); ++ ++ final DecimalFormat oneDecimalFormat = new DecimalFormat("#,##0.0"); ++ ++ LOGGER.info("Finished initialising converters for DataConverter in " + oneDecimalFormat.format((double)(end - start) / 1.0E6) + "ms"); ++ } ++ ++ public static void init() {} ++ ++ private static void registerAll() { ++ // General notes: ++ // - Structure converters run before everything. ++ // - ID specific converters run after structure converters. ++ // - Structure walkers run after id specific converters. ++ // - ID specific walkers run after structure walkers. ++ ++ V99.register(); // all legacy data before converters existed ++ V100.register(); // first version with version id ++ V101.register(); ++ V102.register(); ++ V105.register(); ++ V106.register(); ++ V107.register(); ++ V108.register(); ++ V109.register(); ++ V110.register(); ++ V111.register(); ++ V113.register(); ++ V135.register(); ++ V143.register(); ++ V147.register(); ++ V165.register(); ++ V501.register(); ++ V502.register(); ++ V505.register(); ++ V700.register(); ++ V701.register(); ++ V702.register(); ++ V703.register(); ++ V704.register(); ++ V705.register(); ++ V804.register(); ++ V806.register(); ++ V808.register(); ++ V813.register(); ++ V816.register(); ++ V820.register(); ++ V1022.register(); ++ V1125.register(); ++ // END OF LEGACY DATA CONVERTERS ++ ++ // V1.13 ++ V1344.register(); ++ V1446.register(); ++ // START THE FLATTENING ++ V1450.register(); ++ V1451.register(); ++ // END THE FLATTENING ++ ++ V1456.register(); ++ V1458.register(); ++ V1460.register(); ++ V1466.register(); ++ V1470.register(); ++ V1474.register(); ++ V1475.register(); ++ V1480.register(); ++ // V1481 is adding simple block entity ++ V1483.register(); ++ V1484.register(); ++ V1486.register(); ++ V1487.register(); ++ V1488.register(); ++ V1490.register(); ++ V1492.register(); ++ V1494.register(); ++ V1496.register(); ++ V1500.register(); ++ V1501.register(); ++ V1502.register(); ++ V1506.register(); ++ V1510.register(); ++ V1514.register(); ++ V1515.register(); ++ V1624.register(); ++ // V1.14 ++ V1800.register(); ++ V1801.register(); ++ V1802.register(); ++ V1803.register(); ++ V1904.register(); ++ V1905.register(); ++ V1906.register(); ++ V1909.register(); ++ V1911.register(); ++ V1914.register(); ++ V1917.register(); ++ V1918.register(); ++ V1920.register(); ++ V1925.register(); ++ V1928.register(); ++ V1929.register(); ++ V1931.register(); ++ V1936.register(); ++ V1946.register(); ++ V1948.register(); ++ V1953.register(); ++ V1955.register(); ++ V1961.register(); ++ V1963.register(); ++ // V1.15 ++ V2100.register(); ++ V2202.register(); ++ V2209.register(); ++ V2211.register(); ++ V2218.register(); ++ // V1.16 ++ V2501.register(); ++ V2502.register(); ++ V2503.register(); ++ V2505.register(); ++ V2508.register(); ++ V2509.register(); ++ V2511.register(); ++ V2514.register(); ++ V2516.register(); ++ V2518.register(); ++ V2519.register(); ++ V2522.register(); ++ V2523.register(); ++ V2527.register(); ++ V2528.register(); ++ V2529.register(); ++ V2531.register(); ++ V2533.register(); ++ V2535.register(); ++ V2537.register(); ++ V2538.register(); ++ V2550.register(); ++ V2551.register(); ++ V2552.register(); ++ V2553.register(); ++ V2558.register(); ++ V2568.register(); ++ // V1.17 ++ // WARN: Mojang registers V2671 under 2571, but that version predates 1.16.5? So it looks like a typo... ++ // I changed it to 2671, just so that it's after 1.16.5, but even then this looks misplaced... Thankfully this is ++ // the first datafixer, and all it does is add a walker, so I think even if the version here is just wrong it will ++ // work. ++ V2671.register(); ++ V2679.register(); ++ V2680.register(); ++ V2684.register(); ++ V2686.register(); ++ V2688.register(); ++ V2690.register(); ++ V2691.register(); ++ V2693.register(); ++ V2696.register(); ++ V2700.register(); ++ V2701.register(); ++ V2702.register(); ++ // In reference to V2671, why the fuck is goat being registered again? For this obvious reason, V2704 is absent. ++ V2707.register(); ++ V2710.register(); ++ V2717.register(); ++ // V1.18 ++ V2825.register(); ++ V2831.register(); ++ V2832.register(); ++ V2833.register(); ++ V2838.register(); ++ V2841.register(); ++ V2842.register(); ++ V2843.register(); ++ V2846.register(); ++ V2852.register(); ++ V2967.register(); ++ V2970.register(); ++ // V1.19 ++ // V3076 is registering a simple tile entity (sculk_catalyst) ++ V3077.register(); ++ V3078.register(); ++ V3081.register(); ++ V3082.register(); ++ V3083.register(); ++ V3084.register(); ++ V3086.register(); ++ V3087.register(); ++ V3088.register(); ++ V3090.register(); ++ V3093.register(); ++ V3094.register(); ++ V3097.register(); ++ V3108.register(); ++ V3201.register(); ++ V3202.register(); ++ V3203.register(); ++ V3204.register(); ++ V3209.register(); ++ V3214.register(); ++ V3319.register(); ++ V3322.register(); ++ V3325.register(); ++ V3326.register(); ++ V3327.register(); ++ V3328.register(); ++ // V1.20 ++ V3438.register(); ++ V3439.register(); ++ V3440.register(); ++ V3441.register(); ++ V3447.register(); ++ V3448.register(); ++ V3450.register(); ++ V3451.register(); ++ V3459.register(); ++ V3564.register(); ++ V3565.register(); ++ V3566.register(); ++ V3568.register(); ++ V3682.register(); ++ V3683.register(); ++ V3685.register(); ++ V3689.register(); ++ V3692.register(); ++ // V1.20.5 ++ V3799.register(); ++ V3800.register(); ++ V3803.register(); ++ V3807.register(); ++ V3808.register(); ++ V3809.register(); ++ V3812.register(); ++ V3813.register(); ++ V3814.register(); ++ V3816.register(); ++ V3818.register(); ++ V3820.register(); ++ V3825.register(); ++ V3828.register(); ++ V3833.register(); ++ // V1.21 ++ V3938.register(); ++ V3939.register(); ++ V3943.register(); ++ V3945.register(); ++ // V1.21.2 ++ V4054.register(); ++ V4055.register(); ++ V4057.register(); ++ V4059.register(); ++ V4061.register(); ++ V4064.register(); ++ V4067.register(); ++ V4068.register(); ++ V4070.register(); ++ V4071.register(); ++ // V1.21.3 ++ V4081.register(); ++ // V1.21.4 ++ V4173.register(); ++ V4175.register(); ++ V4176.register(); ++ V4180.register(); ++ V4181.register(); ++ V4185.register(); ++ V4187.register(); ++ // V1.21.5 ++ V4290.register(); ++ V4291.register(); ++ V4292.register(); ++ V4293.register(); ++ V4294.register(); ++ V4295.register(); ++ V4296.register(); ++ V4297.register(); ++ V4299.register(); ++ V4300.register(); ++ V4301.register(); ++ V4302.register(); ++ V4303.register(); ++ V4305.register(); ++ V4306.register(); ++ V4307.register(); ++ V4309.register(); ++ V4311.register(); ++ V4312.register(); ++ V4314.register(); ++ V4420.register(); ++ V4421.register(); ++ V4424.register(); ++ } ++ ++ private MCTypeRegistry() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/datatypes/MCValueType.java b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCValueType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c2598db6f73019e2730622e8156b71196bfe0ee5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/datatypes/MCValueType.java +@@ -0,0 +1,90 @@ ++package ca.spottedleaf.dataconverter.minecraft.datatypes; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.minecraft.MCVersionRegistry; ++import ca.spottedleaf.dataconverter.util.Long2ObjectArraySortedMap; ++import java.util.ArrayList; ++import java.util.List; ++ ++public class MCValueType extends DataType { ++ ++ public final String name; ++ ++ protected final ArrayList> converters = new ArrayList<>(); ++ protected final Long2ObjectArraySortedMap>> structureHooks = new Long2ObjectArraySortedMap<>(); ++ ++ public MCValueType(final String name) { ++ this.name = name; ++ } ++ ++ public void addStructureHook(final int minVersion, final DataHook hook) { ++ this.addStructureHook(minVersion, 0, hook); ++ } ++ ++ public void addStructureHook(final int minVersion, final int versionStep, final DataHook hook) { ++ this.structureHooks.computeIfAbsent(DataConverter.encodeVersions(minVersion, versionStep), (final long keyInMap) -> { ++ return new ArrayList<>(); ++ }).add(hook); ++ } ++ ++ public void addConverter(final DataConverter converter) { ++ MCVersionRegistry.checkVersion(converter.getEncodedVersion()); ++ final boolean sort = !this.converters.isEmpty() ++ && DataConverter.LOWEST_VERSION_COMPARATOR.compare(this.converters.getLast(), converter) > 0; ++ this.converters.add(converter); ++ if (sort) { ++ this.converters.sort(DataConverter.LOWEST_VERSION_COMPARATOR); ++ } ++ } ++ ++ @Override ++ public Object convert(final Object data, final long fromVersion, final long toVersion) { ++ Object ret = null; ++ final List> converters = this.converters; ++ ++ for (int i = 0, len = converters.size(); i < len; ++i) { ++ final DataConverter converter = converters.get(i); ++ final long converterVersion = converter.getEncodedVersion(); ++ ++ if (converterVersion <= fromVersion) { ++ continue; ++ } ++ ++ if (converterVersion > toVersion) { ++ break; ++ } ++ ++ List> hooks = this.structureHooks.getFloor(converterVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final Object replace = hooks.get(k).preHook(ret == null ? data : ret, fromVersion, toVersion); ++ if (replace != null) { ++ ret = replace; ++ } ++ } ++ } ++ ++ final Object converted = converter.convert(ret == null ? data : ret, fromVersion, toVersion); ++ if (converted != null) { ++ ret = converted; ++ } ++ ++ // possibly new data format, update hooks ++ hooks = this.structureHooks.getFloor(toVersion); ++ ++ if (hooks != null) { ++ for (int k = 0, klen = hooks.size(); k < klen; ++k) { ++ final Object replace = hooks.get(k).postHook(ret == null ? data : ret, fromVersion, toVersion); ++ if (replace != null) { ++ ret = replace; ++ } ++ } ++ } ++ } ++ ++ return ret; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookEnforceNamespacedID.java b/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookEnforceNamespacedID.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a0d5bdfce1e7f433ee3bb984814315a157fa3c15 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookEnforceNamespacedID.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.hooks; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public class DataHookEnforceNamespacedID implements DataHook { ++ ++ private final String path; ++ ++ public DataHookEnforceNamespacedID() { ++ this("id"); ++ } ++ ++ public DataHookEnforceNamespacedID(final String path) { ++ this.path = path; ++ } ++ ++ @Override ++ public MapType preHook(final MapType data, final long fromVersion, final long toVersion) { ++ NamespaceUtil.enforceForPath(data, this.path); ++ return null; ++ } ++ ++ @Override ++ public MapType postHook(final MapType data, final long fromVersion, final long toVersion) { ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookValueTypeEnforceNamespaced.java b/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookValueTypeEnforceNamespaced.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8467d4849f9988da3d79620337be8e12815fa4ff +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/hooks/DataHookValueTypeEnforceNamespaced.java +@@ -0,0 +1,20 @@ ++package ca.spottedleaf.dataconverter.minecraft.hooks; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public class DataHookValueTypeEnforceNamespaced implements DataHook { ++ ++ @Override ++ public Object preHook(final Object data, final long fromVersion, final long toVersion) { ++ if (data instanceof String string) { ++ return NamespaceUtil.correctNamespaceOrNull(string); ++ } ++ return null; ++ } ++ ++ @Override ++ public Object postHook(final Object data, final long fromVersion, final long toVersion) { ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java b/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java +new file mode 100644 +index 0000000000000000000000000000000000000000..17ded002b5546de8be4a5238c20ccfda460a98bb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/util/ComponentUtils.java +@@ -0,0 +1,82 @@ ++package ca.spottedleaf.dataconverter.minecraft.util; ++ ++import com.google.gson.JsonElement; ++import com.google.gson.JsonObject; ++import com.google.gson.JsonParseException; ++import com.google.gson.JsonParser; ++import com.google.gson.JsonPrimitive; ++import net.minecraft.util.GsonHelper; ++ ++public final class ComponentUtils { ++ ++ public static final String EMPTY = createPlainTextComponent(""); ++ ++ public static String createPlainTextComponent(final String text) { ++ final JsonObject ret = new JsonObject(); ++ ++ ret.addProperty("text", text); ++ ++ return GsonHelper.toStableString(ret); ++ } ++ ++ public static String createTranslatableComponent(final String key) { ++ final JsonObject ret = new JsonObject(); ++ ++ ret.addProperty("translate", key); ++ ++ return GsonHelper.toStableString(ret); ++ } ++ ++ public static String retrieveTranslationString(final String possibleJson) { ++ if (possibleJson == null) { ++ return null; ++ } ++ ++ try { ++ final JsonElement element = JsonParser.parseString(possibleJson); ++ ++ if (element instanceof JsonObject object) { ++ final JsonElement translation = object.get("translate"); ++ if (translation instanceof JsonPrimitive primitive) { ++ return primitive.getAsString(); ++ } ++ } ++ ++ return null; ++ } catch (final Exception ex) { ++ return null; ++ } ++ } ++ ++ public static String convertFromLenient(final String input) { ++ if (input == null) { ++ return input; ++ } ++ ++ if (input.isEmpty() || input.equals("null")) { ++ return EMPTY; ++ } ++ ++ final char firstCharacter = input.charAt(0); ++ final char lastCharacter = input.charAt(input.length() - 1); ++ if ((firstCharacter == '"' && lastCharacter == '"') ++ || (firstCharacter == '{' && lastCharacter == '}') ++ || (firstCharacter == '[' && lastCharacter == ']')) { ++ try { ++ final JsonElement json = JsonParser.parseString(input); ++ ++ if (json.isJsonPrimitive()) { ++ return createPlainTextComponent(json.getAsString()); ++ } ++ ++ return GsonHelper.toStableString(json); ++ } catch (final JsonParseException ignored) { ++ // fall through to plain text ++ } ++ } ++ ++ return createPlainTextComponent(input); ++ } ++ ++ private ComponentUtils() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/util/Version.java b/ca/spottedleaf/dataconverter/minecraft/util/Version.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c289ec6b7f6d199182ffdfb1cd95a1746bfd6e76 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/util/Version.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.dataconverter.minecraft.util; ++ ++import net.minecraft.SharedConstants; ++ ++public final class Version { ++ ++ public static int getCurrentVersion() { ++ return SharedConstants.getCurrentVersion().dataVersion().version(); ++ } ++ ++ private Version() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V100.java b/ca/spottedleaf/dataconverter/minecraft/versions/V100.java +new file mode 100644 +index 0000000000000000000000000000000000000000..166953878ce7df4317a40ad274f56ecd3f7214cc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V100.java +@@ -0,0 +1,124 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.block_name.DataWalkerBlockNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V100 { ++ ++ private static final int VERSION = MCVersions.V15W32A; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType equipment = data.getList("Equipment", ObjectType.MAP); ++ data.remove("Equipment"); ++ ++ if (equipment != null) { ++ if (equipment.size() > 0 && data.getListUnchecked("HandItems") == null) { ++ final ListType handItems = Types.NBT.createEmptyList(); ++ data.setList("HandItems", handItems); ++ handItems.addMap(equipment.getMap(0)); ++ handItems.addMap(Types.NBT.createEmptyMap()); ++ } ++ ++ if (equipment.size() > 1 && data.getListUnchecked("ArmorItems") == null) { ++ final ListType armorItems = Types.NBT.createEmptyList(); ++ data.setList("ArmorItems", armorItems); ++ for (int i = 1; i < Math.min(equipment.size(), 5); ++i) { ++ armorItems.addMap(equipment.getMap(i)); ++ } ++ } ++ } ++ ++ final ListType dropChances = data.getList("DropChances", ObjectType.FLOAT); ++ data.remove("DropChances"); ++ ++ if (dropChances != null) { ++ if (data.getListUnchecked("HandDropChances") == null) { ++ final ListType handDropChances = Types.NBT.createEmptyList(); ++ data.setList("HandDropChances", handDropChances); ++ if (0 < dropChances.size()) { ++ handDropChances.addFloat(dropChances.getFloat(0)); ++ } else { ++ handDropChances.addFloat(0.0F); ++ } ++ handDropChances.addFloat(0.0F); ++ } ++ ++ if (data.getListUnchecked("ArmorDropChances") == null) { ++ final ListType armorDropChances = Types.NBT.createEmptyList(); ++ data.setList("ArmorDropChances", armorDropChances); ++ for (int i = 1; i < 5; ++i) { ++ if (i < dropChances.size()) { ++ armorDropChances.addFloat(dropChances.getFloat(i)); ++ } else { ++ armorDropChances.addFloat(0.0F); ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY_EQUIPMENT.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "ArmorItems", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "HandItems", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, data, "body_armor_item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, data, "saddle", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ //registerMob("ArmorStand"); // changed to simple in 1.21.5 ++ //registerMob("Creeper"); // changed to simple in 1.21.5 ++ //registerMob("Skeleton"); // changed to simple in 1.21.5 ++ //registerMob("Spider"); // changed to simple in 1.21.5 ++ //registerMob("Giant"); // changed to simple in 1.21.5 ++ //registerMob("Zombie"); // changed to simple in 1.21.5 ++ //registerMob("Slime"); // changed to simple in 1.21.5 ++ //registerMob("Ghast"); // changed to simple in 1.21.5 ++ //registerMob("PigZombie"); // changed to simple in 1.21.5 ++ // Enderman is now identical to V99 due to moving equipment to base in 1.21.5 ++ //registerMob("CaveSpider"); // changed to simple in 1.21.5 ++ //registerMob("Silverfish"); // changed to simple in 1.21.5 ++ //registerMob("Blaze"); // changed to simple in 1.21.5 ++ //registerMob("LavaSlime"); // changed to simple in 1.21.5 ++ //registerMob("EnderDragon"); // changed to simple in 1.21.5 ++ //registerMob("WitherBoss"); // changed to simple in 1.21.5 ++ //registerMob("Bat"); // changed to simple in 1.21.5 ++ //registerMob("Witch"); // changed to simple in 1.21.5 ++ //registerMob("Endermite"); // changed to simple in 1.21.5 ++ //registerMob("Guardian"); // changed to simple in 1.21.5 ++ //registerMob("Pig"); // changed to simple in 1.21.5 ++ //registerMob("Sheep"); // changed to simple in 1.21.5 ++ //registerMob("Cow"); // changed to simple in 1.21.5 ++ //registerMob("Chicken"); // changed to simple in 1.21.5 ++ //registerMob("Squid"); // changed to simple in 1.21.5 ++ //registerMob("Wolf"); // changed to simple in 1.21.5 ++ //registerMob("MushroomCow"); // changed to simple in 1.21.5 ++ //registerMob("SnowMan"); // changed to simple in 1.21.5 ++ //registerMob("Ozelot"); // changed to simple in 1.21.5 ++ //registerMob("VillagerGolem"); // changed to simple in 1.21.5 ++ // EntityHorse is now identical to V99 due to moving equipment to base in 1.21.5 ++ //registerMob("Rabbit"); // changed to simple in 1.21.5 ++ // Villager is now identical to V99 due to moving equipment to base in 1.21.5 ++ //registerMob("Shulker"); // changed to simple in 1.21.5 ++ // AreaEffectCloud is now identical to V99 due to moving equipment to base in 1.21.5 ++ ++ // Moved to V99 in 1.21.5 ++ } ++ ++ private V100() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V101.java b/ca/spottedleaf/dataconverter/minecraft/versions/V101.java +new file mode 100644 +index 0000000000000000000000000000000000000000..787f09af1338483fdb820806f94680c7e5db7d7c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V101.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V101 { ++ ++ private static final int VERSION = MCVersions.V15W32A + 1; ++ ++ private static void updateLine(final MapType data, final String path) { ++ final String textString = data.getString(path); ++ ++ if (textString == null) { ++ return; ++ } ++ ++ data.setString(path, ComponentUtils.convertFromLenient(textString)); ++ } ++ ++ public static void register() { ++ // Mojang Removed in 1.21.5, replaced in V165 - although we should not be modifying old converters unless ++ // we need to (the conversion is the same) ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("Sign", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateLine(data, "Text1"); ++ updateLine(data, "Text2"); ++ updateLine(data, "Text3"); ++ updateLine(data, "Text4"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("Villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setBoolean("CanPickUpLoot", true); ++ return null; ++ } ++ }); ++ } ++ ++ private V101() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V102.java b/ca/spottedleaf/dataconverter/minecraft/versions/V102.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b9f23288d9cc912eccd07418e38cd6ffcdf65360 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V102.java +@@ -0,0 +1,86 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperItemNameV102; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++ ++public final class V102 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V15W32A + 2; ++ ++ public static void register() { ++ // V102 -> V15W32A + 2 ++ // V102 schema only modifies ITEM_STACK to have only a string ID, but our ITEM_NAME is generic (int or String) so we don't ++ // actually need to update the walker ++ ++ MCTypeRegistry.ITEM_NAME.addConverter(new DataConverter<>(VERSION) { ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (!(data instanceof Number)) { ++ return null; ++ } ++ final int id = ((Number)data).intValue(); ++ final String remap = HelperItemNameV102.getNameFromId(id); ++ if (remap == null) { ++ LOGGER.warn("Unknown legacy integer id (V102) " + id); ++ } ++ return remap == null ? HelperItemNameV102.getNameFromId(0) : remap; ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.hasKey("id", ObjectType.NUMBER)) { ++ return null; ++ } ++ ++ final int id = data.getInt("id"); ++ ++ String remap = HelperItemNameV102.getNameFromId(id); ++ if (remap == null) { ++ LOGGER.warn("Unknown legacy integer id (V102) " + id); ++ remap = HelperItemNameV102.getNameFromId(0); ++ } ++ ++ data.setString("id", remap); ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:potion", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final short damage = data.getShort("Damage"); ++ if (damage != 0) { ++ data.setShort("Damage", (short)0); ++ } ++ MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ tag = Types.NBT.createEmptyMap(); ++ data.setMap("tag", tag); ++ } ++ ++ if (!tag.hasKey("Potion", ObjectType.STRING)) { ++ final String converted = HelperItemNameV102.getPotionNameFromId(damage); ++ tag.setString("Potion", converted == null ? "minecraft:water" : converted); ++ if ((damage & 16384) == 16384) { ++ data.setString("id", "minecraft:splash_potion"); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V102() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dab97581780d0d3156335fe0fbb84ea0823c5585 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1022.java +@@ -0,0 +1,43 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1022 { ++ ++ private static final int VERSION = MCVersions.V17W06A; ++ ++ public static void register() { ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("RootVehicle"), "Entity", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "EnderItems", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityLeft", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityRight", fromVersion, toVersion); ++ ++ final MapType recipeBook = data.getMap("recipeBook"); ++ if (recipeBook != null) { ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "recipes", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "toBeDisplayed", fromVersion, toVersion); ++ } ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.HOTBAR.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ for (final String key : data.keys()) { ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, key, fromVersion, toVersion); ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V1022() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V105.java b/ca/spottedleaf/dataconverter/minecraft/versions/V105.java +new file mode 100644 +index 0000000000000000000000000000000000000000..072c64eda648496ceee300abaff62c8b64a84219 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V105.java +@@ -0,0 +1,49 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperSpawnEggNameV105; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V105 { ++ ++ private static final int VERSION = MCVersions.V15W32C + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:spawn_egg", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ tag = Types.NBT.createEmptyMap(); ++ } ++ ++ final short damage = data.getShort("Damage"); ++ if (damage != 0) { ++ data.setShort("Damage", (short)0); ++ } ++ ++ MapType entityTag = tag.getMap("EntityTag"); ++ if (entityTag == null) { ++ entityTag = Types.NBT.createEmptyMap(); ++ } ++ ++ if (!entityTag.hasKey("id", ObjectType.STRING)) { ++ final String converted = HelperSpawnEggNameV105.getSpawnNameFromId(damage); ++ if (converted != null) { ++ entityTag.setString("id", converted); ++ tag.setMap("EntityTag", entityTag); ++ data.setMap("tag", tag); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V105() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V106.java b/ca/spottedleaf/dataconverter/minecraft/versions/V106.java +new file mode 100644 +index 0000000000000000000000000000000000000000..025488260309ea2816b6513338a0aba21fd6f9e3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V106.java +@@ -0,0 +1,83 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V106 { ++ ++ private static final int VERSION = MCVersions.V15W32C + 2; ++ ++ public static void register() { ++ // V106 -> V15W32C + 2 ++ ++ MCTypeRegistry.UNTAGGED_SPAWNER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // While all converters for spawners check the id for this version, we don't because spawners exist in minecarts. ooops! Loading a chunk ++ // with a minecart spawner from 1.7.10 in 1.16.5 vanilla will fail to convert! Clearly there was a mistake in how they ++ // used and applied spawner converters. In anycase, do not check the id - we are not guaranteed to be a tile ++ // entity. We can be a regular old minecart spawner. And we know we are a spawner because this is only called from data walkers. ++ ++ final String entityId = data.getString("EntityId"); ++ if (entityId != null) { ++ data.remove("EntityId"); ++ MapType spawnData = data.getMap("SpawnData"); ++ if (spawnData == null) { ++ spawnData = Types.NBT.createEmptyMap(); ++ data.setMap("SpawnData", spawnData); ++ } ++ spawnData.setString("id", entityId.isEmpty() ? "Pig" : entityId); ++ } ++ ++ final ListType spawnPotentials = data.getList("SpawnPotentials", ObjectType.MAP); ++ if (spawnPotentials != null) { ++ for (int i = 0, len = spawnPotentials.size(); i < len; ++i) { ++ // convert to standard entity format (it's not a coincidence a walker for spawners is only added ++ // in this version) ++ final MapType spawn = spawnPotentials.getMap(i); ++ final String spawnType = spawn.getString("Type"); ++ if (spawnType == null) { ++ continue; ++ } ++ spawn.remove("Type"); ++ ++ MapType properties = spawn.getMap("Properties"); ++ if (properties == null) { ++ properties = Types.NBT.createEmptyMap(); ++ } else { ++ spawn.remove("Properties"); ++ } ++ ++ properties.setString("id", spawnType); ++ ++ spawn.setMap("Entity", properties); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.UNTAGGED_SPAWNER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final ListType spawnPotentials = data.getList("SpawnPotentials", ObjectType.MAP); ++ if (spawnPotentials != null) { ++ for (int i = 0, len = spawnPotentials.size(); i < len; ++i) { ++ final MapType spawnPotential = spawnPotentials.getMap(i); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, spawnPotential, "Entity", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "SpawnData", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private V106() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V107.java b/ca/spottedleaf/dataconverter/minecraft/versions/V107.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1b845e6df83694de203181382094c6c30684c0cc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V107.java +@@ -0,0 +1,43 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V107 { ++ ++ private static final int VERSION = MCVersions.V15W32C + 3; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Minecart", new DataConverter<>(VERSION) { ++ protected final String[] MINECART_IDS = new String[] { ++ "MinecartRideable", // 0 ++ "MinecartChest", // 1 ++ "MinecartFurnace", // 2 ++ "MinecartTNT", // 3 ++ "MinecartSpawner", // 4 ++ "MinecartHopper", // 5 ++ "MinecartCommandBlock" // 6 ++ }; ++ // Vanilla does not use all of the IDs here. The legacy (pre DFU) code does, so I'm going to use them. ++ // No harm in catching more cases here. ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ String newId = "MinecartRideable"; // dfl ++ final int type = data.getInt("Type"); ++ data.remove("Type"); ++ ++ if (type >= 0 && type < MINECART_IDS.length) { ++ newId = MINECART_IDS[type]; ++ } ++ data.setString("id", newId); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V107() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V108.java b/ca/spottedleaf/dataconverter/minecraft/versions/V108.java +new file mode 100644 +index 0000000000000000000000000000000000000000..19246f5219896f018b2e6a6adfcadce95a795f59 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V108.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++import java.util.UUID; ++ ++public final class V108 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V15W32C + 4; ++ ++ public static void register() { ++ // Convert String UUID into UUIDMost and UUIDLeast ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String uuidString = data.getString("UUID"); ++ ++ if (uuidString == null) { ++ return null; ++ } ++ data.remove("UUID"); ++ ++ final UUID uuid; ++ try { ++ uuid = UUID.fromString(uuidString); ++ } catch (final Exception ex) { ++ LOGGER.warn("Failed to parse UUID for legacy entity (V108): " + uuidString, ex); ++ return null; ++ } ++ ++ data.setLong("UUIDMost", uuid.getMostSignificantBits()); ++ data.setLong("UUIDLeast", uuid.getLeastSignificantBits()); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V108() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V109.java b/ca/spottedleaf/dataconverter/minecraft/versions/V109.java +new file mode 100644 +index 0000000000000000000000000000000000000000..05e54a7f716899060aae56be20e8b3764bc97081 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V109.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V109 { ++ ++ private static final int VERSION = MCVersions.V15W32C + 5; ++ ++ public static void register() { ++ // Converts health to be in float, and cleans up whatever the hell was going on with HealF and Health... ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Number healF = data.getNumber("HealF"); ++ final Number heal = data.getNumber("Health"); ++ ++ final float newHealth; ++ ++ if (healF != null) { ++ data.remove("HealF"); ++ newHealth = healF.floatValue(); ++ } else { ++ if (heal == null) { ++ return null; ++ } ++ ++ newHealth = heal.floatValue(); ++ } ++ ++ data.setFloat("Health", newHealth); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V109() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V110.java b/ca/spottedleaf/dataconverter/minecraft/versions/V110.java +new file mode 100644 +index 0000000000000000000000000000000000000000..11db20648cf877eacaa2a39e62fa66daad3a79bb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V110.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V110 { ++ ++ private static final int VERSION = MCVersions.V15W32C + 6; ++ ++ public static void register() { ++ // Moves the Saddle boolean to be an actual saddle item. Note: The data walker for the SaddleItem exists ++ // in V99, it doesn't need to be added here. ++ MCTypeRegistry.ENTITY.addConverterForId("EntityHorse", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.getBoolean("Saddle") || data.hasKey("SaddleItem", ObjectType.MAP)) { ++ return null; ++ } ++ ++ final MapType saddleItem = Types.NBT.createEmptyMap(); ++ data.remove("Saddle"); ++ data.setMap("SaddleItem", saddleItem); ++ ++ saddleItem.setString("id", "minecraft:saddle"); ++ saddleItem.setByte("Count", (byte)1); ++ saddleItem.setShort("Damage", (short)0); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V110() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V111.java b/ca/spottedleaf/dataconverter/minecraft/versions/V111.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9eaf34660e1b42ab99d06d43d86cda13a69448ae +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V111.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V111 { ++ ++ private static final int VERSION = MCVersions.V15W33B; ++ ++ public static void register() { ++ final EntityRotationFix rotationFix = new EntityRotationFix(VERSION); ++ MCTypeRegistry.ENTITY.addConverterForId("Painting", rotationFix); ++ MCTypeRegistry.ENTITY.addConverterForId("ItemFrame", rotationFix); ++ } ++ ++ private V111() {} ++ ++ protected static final class EntityRotationFix extends DataConverter { ++ ++ private static final int[][] DIRECTIONS = new int[][] { ++ {0, 0, 1}, ++ {-1, 0, 0}, ++ {0, 0, -1}, ++ {1, 0, 0} ++ }; ++ ++ public EntityRotationFix(final int version) { ++ super(version); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getNumber("Facing") != null) { ++ return null; ++ } ++ ++ final Number direction = data.getNumber("Direction"); ++ final int facing; ++ if (direction != null) { ++ data.remove("Direction"); ++ facing = direction.intValue() % DIRECTIONS.length; ++ final int[] offsets = DIRECTIONS[facing]; ++ data.setInt("TileX", data.getInt("TileX") + offsets[0]); ++ data.setInt("TileY", data.getInt("TileY") + offsets[1]); ++ data.setInt("TileZ", data.getInt("TileZ") + offsets[2]); ++ if ("ItemFrame".equals(data.getString("id"))) { ++ final Number rotation = data.getNumber("ItemRotation"); ++ if (rotation != null) { ++ data.setByte("ItemRotation", (byte)(rotation.byteValue() * 2)); ++ } ++ } ++ } else { ++ facing = data.getByte("Dir") % DIRECTIONS.length; ++ data.remove("Dir"); ++ } ++ ++ data.setByte("Facing", (byte)facing); ++ ++ return null; ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1125.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1125.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ff99e8e263d6fd234bce01c0c02fdb3eb0ff7eaa +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1125.java +@@ -0,0 +1,101 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookValueTypeEnforceNamespaced; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V1125 { ++ ++ private static final int VERSION = MCVersions.V17W15A; ++ private static final int BED_BLOCK_ID = 416; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ final int chunkX = level.getInt("xPos"); ++ final int chunkZ = level.getInt("zPos"); ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ ListType tileEntities = level.getList("TileEntities", ObjectType.MAP); ++ if (tileEntities == null) { ++ tileEntities = Types.NBT.createEmptyList(); ++ level.setList("TileEntities", tileEntities); ++ } ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final byte sectionY = section.getByte("Y"); ++ final byte[] blocks = section.getBytes("Blocks"); ++ ++ if (blocks == null) { ++ continue; ++ } ++ ++ for (int blockIndex = 0; blockIndex < blocks.length; ++blockIndex) { ++ if (BED_BLOCK_ID != ((blocks[blockIndex] & 255) << 4)) { ++ continue; ++ } ++ ++ final int localX = blockIndex & 15; ++ final int localZ = (blockIndex >> 4) & 15; ++ final int localY = (blockIndex >> 8) & 15; ++ ++ final MapType newTile = Types.NBT.createEmptyMap(); ++ newTile.setString("id", "minecraft:bed"); ++ newTile.setInt("x", localX + (chunkX << 4)); ++ newTile.setInt("y", localY + (sectionY << 4)); ++ newTile.setInt("z", localZ + (chunkZ << 4)); ++ newTile.setShort("color", (short)14); // Red ++ ++ tileEntities.addMap(newTile); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:bed", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getShort("Damage") == 0) { ++ data.setShort("Damage", (short)14); // Red ++ } ++ ++ return null; ++ } ++ }); ++ ++ ++ MCTypeRegistry.ADVANCEMENTS.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertKeys(MCTypeRegistry.BIOME, data.getMap("minecraft:adventure/adventuring_time"), "criteria", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ENTITY_NAME, data.getMap("minecraft:adventure/kill_a_mob"), "criteria", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ENTITY_NAME, data.getMap("minecraft:adventure/kill_all_mobs"), "criteria", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ENTITY_NAME, data.getMap("minecraft:adventure/bred_all_animals"), "criteria", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Enforce namespacing for ids ++ MCTypeRegistry.BIOME.addStructureHook(VERSION, new DataHookValueTypeEnforceNamespaced()); ++ } ++ ++ private V1125() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V113.java b/ca/spottedleaf/dataconverter/minecraft/versions/V113.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3470afede273da32d98571524817dc1979b3044d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V113.java +@@ -0,0 +1,40 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V113 { ++ ++ private static final int VERSION = MCVersions.V15W33C + 1; ++ ++ private static void checkList(final MapType data, final String id, final int requiredLength) { ++ final ListType list = data.getList(id, ObjectType.FLOAT); ++ if (list != null && list.size() == requiredLength) { ++ for (int i = 0; i < requiredLength; ++i) { ++ if (list.getFloat(i) != 0.0F) { ++ return; ++ } ++ } ++ } ++ ++ data.remove(id); ++ } ++ ++ public static void register() { ++ // Removes "HandDropChances" and "ArmorDropChances" if they're empty. ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ checkList(data, "HandDropChances", 2); ++ checkList(data, "ArmorDropChances", 4); ++ return null; ++ } ++ }); ++ } ++ ++ private V113() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1344.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1344.java +new file mode 100644 +index 0000000000000000000000000000000000000000..18d5a0f47066b8c92dc13e5b7c441f8c8258c85d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1344.java +@@ -0,0 +1,176 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++public final class V1344 { ++ ++ private static final int VERSION = MCVersions.V1_12_2 + 1; ++ ++ private static final Int2ObjectOpenHashMap BUTTON_ID_TO_NAME = new Int2ObjectOpenHashMap<>(); ++ static { ++ BUTTON_ID_TO_NAME.put(0, "key.unknown"); ++ BUTTON_ID_TO_NAME.put(11, "key.0"); ++ BUTTON_ID_TO_NAME.put(2, "key.1"); ++ BUTTON_ID_TO_NAME.put(3, "key.2"); ++ BUTTON_ID_TO_NAME.put(4, "key.3"); ++ BUTTON_ID_TO_NAME.put(5, "key.4"); ++ BUTTON_ID_TO_NAME.put(6, "key.5"); ++ BUTTON_ID_TO_NAME.put(7, "key.6"); ++ BUTTON_ID_TO_NAME.put(8, "key.7"); ++ BUTTON_ID_TO_NAME.put(9, "key.8"); ++ BUTTON_ID_TO_NAME.put(10, "key.9"); ++ BUTTON_ID_TO_NAME.put(30, "key.a"); ++ BUTTON_ID_TO_NAME.put(40, "key.apostrophe"); ++ BUTTON_ID_TO_NAME.put(48, "key.b"); ++ BUTTON_ID_TO_NAME.put(43, "key.backslash"); ++ BUTTON_ID_TO_NAME.put(14, "key.backspace"); ++ BUTTON_ID_TO_NAME.put(46, "key.c"); ++ BUTTON_ID_TO_NAME.put(58, "key.caps.lock"); ++ BUTTON_ID_TO_NAME.put(51, "key.comma"); ++ BUTTON_ID_TO_NAME.put(32, "key.d"); ++ BUTTON_ID_TO_NAME.put(211, "key.delete"); ++ BUTTON_ID_TO_NAME.put(208, "key.down"); ++ BUTTON_ID_TO_NAME.put(18, "key.e"); ++ BUTTON_ID_TO_NAME.put(207, "key.end"); ++ BUTTON_ID_TO_NAME.put(28, "key.enter"); ++ BUTTON_ID_TO_NAME.put(13, "key.equal"); ++ BUTTON_ID_TO_NAME.put(1, "key.escape"); ++ BUTTON_ID_TO_NAME.put(33, "key.f"); ++ BUTTON_ID_TO_NAME.put(59, "key.f1"); ++ BUTTON_ID_TO_NAME.put(68, "key.f10"); ++ BUTTON_ID_TO_NAME.put(87, "key.f11"); ++ BUTTON_ID_TO_NAME.put(88, "key.f12"); ++ BUTTON_ID_TO_NAME.put(100, "key.f13"); ++ BUTTON_ID_TO_NAME.put(101, "key.f14"); ++ BUTTON_ID_TO_NAME.put(102, "key.f15"); ++ BUTTON_ID_TO_NAME.put(103, "key.f16"); ++ BUTTON_ID_TO_NAME.put(104, "key.f17"); ++ BUTTON_ID_TO_NAME.put(105, "key.f18"); ++ BUTTON_ID_TO_NAME.put(113, "key.f19"); ++ BUTTON_ID_TO_NAME.put(60, "key.f2"); ++ BUTTON_ID_TO_NAME.put(61, "key.f3"); ++ BUTTON_ID_TO_NAME.put(62, "key.f4"); ++ BUTTON_ID_TO_NAME.put(63, "key.f5"); ++ BUTTON_ID_TO_NAME.put(64, "key.f6"); ++ BUTTON_ID_TO_NAME.put(65, "key.f7"); ++ BUTTON_ID_TO_NAME.put(66, "key.f8"); ++ BUTTON_ID_TO_NAME.put(67, "key.f9"); ++ BUTTON_ID_TO_NAME.put(34, "key.g"); ++ BUTTON_ID_TO_NAME.put(41, "key.grave.accent"); ++ BUTTON_ID_TO_NAME.put(35, "key.h"); ++ BUTTON_ID_TO_NAME.put(199, "key.home"); ++ BUTTON_ID_TO_NAME.put(23, "key.i"); ++ BUTTON_ID_TO_NAME.put(210, "key.insert"); ++ BUTTON_ID_TO_NAME.put(36, "key.j"); ++ BUTTON_ID_TO_NAME.put(37, "key.k"); ++ BUTTON_ID_TO_NAME.put(82, "key.keypad.0"); ++ BUTTON_ID_TO_NAME.put(79, "key.keypad.1"); ++ BUTTON_ID_TO_NAME.put(80, "key.keypad.2"); ++ BUTTON_ID_TO_NAME.put(81, "key.keypad.3"); ++ BUTTON_ID_TO_NAME.put(75, "key.keypad.4"); ++ BUTTON_ID_TO_NAME.put(76, "key.keypad.5"); ++ BUTTON_ID_TO_NAME.put(77, "key.keypad.6"); ++ BUTTON_ID_TO_NAME.put(71, "key.keypad.7"); ++ BUTTON_ID_TO_NAME.put(72, "key.keypad.8"); ++ BUTTON_ID_TO_NAME.put(73, "key.keypad.9"); ++ BUTTON_ID_TO_NAME.put(78, "key.keypad.add"); ++ BUTTON_ID_TO_NAME.put(83, "key.keypad.decimal"); ++ BUTTON_ID_TO_NAME.put(181, "key.keypad.divide"); ++ BUTTON_ID_TO_NAME.put(156, "key.keypad.enter"); ++ BUTTON_ID_TO_NAME.put(141, "key.keypad.equal"); ++ BUTTON_ID_TO_NAME.put(55, "key.keypad.multiply"); ++ BUTTON_ID_TO_NAME.put(74, "key.keypad.subtract"); ++ BUTTON_ID_TO_NAME.put(38, "key.l"); ++ BUTTON_ID_TO_NAME.put(203, "key.left"); ++ BUTTON_ID_TO_NAME.put(56, "key.left.alt"); ++ BUTTON_ID_TO_NAME.put(26, "key.left.bracket"); ++ BUTTON_ID_TO_NAME.put(29, "key.left.control"); ++ BUTTON_ID_TO_NAME.put(42, "key.left.shift"); ++ BUTTON_ID_TO_NAME.put(219, "key.left.win"); ++ BUTTON_ID_TO_NAME.put(50, "key.m"); ++ BUTTON_ID_TO_NAME.put(12, "key.minus"); ++ BUTTON_ID_TO_NAME.put(49, "key.n"); ++ BUTTON_ID_TO_NAME.put(69, "key.num.lock"); ++ BUTTON_ID_TO_NAME.put(24, "key.o"); ++ BUTTON_ID_TO_NAME.put(25, "key.p"); ++ BUTTON_ID_TO_NAME.put(209, "key.page.down"); ++ BUTTON_ID_TO_NAME.put(201, "key.page.up"); ++ BUTTON_ID_TO_NAME.put(197, "key.pause"); ++ BUTTON_ID_TO_NAME.put(52, "key.period"); ++ BUTTON_ID_TO_NAME.put(183, "key.print.screen"); ++ BUTTON_ID_TO_NAME.put(16, "key.q"); ++ BUTTON_ID_TO_NAME.put(19, "key.r"); ++ BUTTON_ID_TO_NAME.put(205, "key.right"); ++ BUTTON_ID_TO_NAME.put(184, "key.right.alt"); ++ BUTTON_ID_TO_NAME.put(27, "key.right.bracket"); ++ BUTTON_ID_TO_NAME.put(157, "key.right.control"); ++ BUTTON_ID_TO_NAME.put(54, "key.right.shift"); ++ BUTTON_ID_TO_NAME.put(220, "key.right.win"); ++ BUTTON_ID_TO_NAME.put(31, "key.s"); ++ BUTTON_ID_TO_NAME.put(70, "key.scroll.lock"); ++ BUTTON_ID_TO_NAME.put(39, "key.semicolon"); ++ BUTTON_ID_TO_NAME.put(53, "key.slash"); ++ BUTTON_ID_TO_NAME.put(57, "key.space"); ++ BUTTON_ID_TO_NAME.put(20, "key.t"); ++ BUTTON_ID_TO_NAME.put(15, "key.tab"); ++ BUTTON_ID_TO_NAME.put(22, "key.u"); ++ BUTTON_ID_TO_NAME.put(200, "key.up"); ++ BUTTON_ID_TO_NAME.put(47, "key.v"); ++ BUTTON_ID_TO_NAME.put(17, "key.w"); ++ BUTTON_ID_TO_NAME.put(45, "key.x"); ++ BUTTON_ID_TO_NAME.put(21, "key.y"); ++ BUTTON_ID_TO_NAME.put(44, "key.z"); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ for (final String key : data.keys()) { ++ if (!key.startsWith("key_")) { ++ continue; ++ } ++ final String value = data.getString(key); ++ final int code; ++ try { ++ code = Integer.parseInt(value); ++ } catch (final NumberFormatException ex) { ++ continue; ++ } ++ ++ final String newEntry; ++ ++ if (code < 0) { ++ final int mouseCode = code + 100; ++ switch (mouseCode) { ++ case 0: ++ newEntry = "key.mouse.left"; ++ break; ++ case 1: ++ newEntry = "key.mouse.right"; ++ break; ++ case 2: ++ newEntry = "key.mouse.middle"; ++ break; ++ default: ++ newEntry = "key.mouse." + (mouseCode + 1); ++ break; ++ } ++ } else { ++ newEntry = BUTTON_ID_TO_NAME.getOrDefault(code, "key.unknown"); ++ } ++ ++ // No CMEs occur for existing entries in maps. ++ data.setString(key, newEntry); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V1344() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V135.java b/ca/spottedleaf/dataconverter/minecraft/versions/V135.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9b6d09980bd1479ca9a4dc275f2abb4cfbecd545 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V135.java +@@ -0,0 +1,62 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V135 { ++ ++ private static final int VERSION = MCVersions.V15W40B + 1; ++ ++ public static void register() { ++ // In this update they changed the "Riding" value to be "Passengers", which is now a list. So it added ++ // support for multiple entities riding. Of course, Riding and Passenger are opposites - so it also will ++ // switch the data layout to be from highest rider to lowest rider, in terms of depth. ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(MapType data, final long sourceVersion, final long toVersion) { ++ MapType ret = null; ++ while (data.hasKey("Riding", ObjectType.MAP)) { ++ final MapType riding = data.getMap("Riding"); ++ data.remove("Riding"); ++ ++ final ListType passengers = Types.NBT.createEmptyList(); ++ riding.setList("Passengers", passengers); ++ passengers.addMap(data); ++ ++ ret = data = riding; ++ } ++ ++ return ret; ++ } ++ }); ++ ++ ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, new DataWalkerItemLists("Inventory", "EnderItems")); ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType rootVehicle = data.getMap("RootVehicle"); ++ if (rootVehicle != null) { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, rootVehicle, "Entity", fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "Passengers", fromVersion, toVersion); ++ ++ return MCTypeRegistry.ENTITY_EQUIPMENT.convert(data, fromVersion, toVersion); ++ }); ++ ++ } ++ ++ private V135() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V143.java b/ca/spottedleaf/dataconverter/minecraft/versions/V143.java +new file mode 100644 +index 0000000000000000000000000000000000000000..90889dddd8a510fe69c47413f5fe3ed4a756fedb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V143.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++ ++public final class V143 { ++ ++ private static final int VERSION = MCVersions.V15W44B; ++ ++ public static void register() { ++ ConverterAbstractEntityRename.register(VERSION, (final String input) -> { ++ return "TippedArrow".equals(input) ? "Arrow" : null; ++ }); ++ } ++ ++ private V143() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1446.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1446.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8d1d3a5898e87754510e63ce7444286418a077ef +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1446.java +@@ -0,0 +1,35 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1446 { ++ ++ private static final int VERSION = MCVersions.V17W43B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ for (final String key : data.keys()) { ++ if (!key.startsWith("key_")) { ++ continue; ++ } ++ ++ final String value = data.getString(key); ++ ++ if (value.startsWith("key.mouse") || value.startsWith("scancode.")) { ++ continue; ++ } ++ ++ data.setString(key, "key.keyboard." + value.substring("key.".length())); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V1446() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1450.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1450.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7f2e0b6c1f75c61230d138a2fa4328dd9cc99eab +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1450.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperBlockFlatteningV1450; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1450 { ++ ++ private static final int VERSION = MCVersions.V17W46A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType ret = HelperBlockFlatteningV1450.flattenNBT(data); ++ return ret == data ? null : ret.copy(); // copy to avoid problems with later state datafixers ++ } ++ }); ++ } ++ ++ private V1450() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1856060ba8124c36fd64c816921a4b908fec2bfd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1451.java +@@ -0,0 +1,518 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterFlattenChunk; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperBlockFlatteningV1450; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperItemNameV102; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterFlattenItemStack; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterFlattenSpawnEgg; ++import ca.spottedleaf.dataconverter.minecraft.converters.stats.ConverterFlattenStats; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterFlattenEntity; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.minecraft.walkers.tile_entity.DataWalkerTileEntities; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.base.Splitter; ++import net.minecraft.resources.ResourceLocation; ++import net.minecraft.util.datafix.fixes.BlockStateData; ++import net.minecraft.util.datafix.fixes.EntityBlockStateFix; ++import org.apache.commons.lang3.math.NumberUtils; ++import java.util.Iterator; ++import java.util.List; ++import java.util.stream.Collectors; ++import java.util.stream.StreamSupport; ++ ++public final class V1451 { ++ ++ private static final int VERSION = MCVersions.V17W47A; ++ ++ public static String packWithDot(final String string) { ++ final ResourceLocation resourceLocation = ResourceLocation.tryParse(string); ++ return resourceLocation != null ? resourceLocation.getNamespace() + "." + resourceLocation.getPath() : string; ++ } ++ ++ public static void register() { ++ // V0 ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, 0, "minecraft:trapped_chest", new DataWalkerItemLists("Items")); ++ ++ // V1 ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterFlattenChunk()); ++ ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, 1, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, level, "Entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, level, "TileEntities", fromVersion, toVersion); ++ ++ final ListType tileTicks = level.getList("TileTicks", ObjectType.MAP); ++ if (tileTicks != null) { ++ for (int i = 0, len = tileTicks.size(); i < len; ++i) { ++ final MapType tileTick = tileTicks.getMap(i); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, tileTick, "i", fromVersion, toVersion); ++ } ++ } ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section, "Palette", fromVersion, toVersion); ++ } ++ } ++ ++ return null; ++ }); ++ ++ // V2 ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:piston", new DataConverter<>(VERSION, 2) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int blockId = data.getInt("blockId"); ++ final int blockData = data.getInt("blockData") & 15; ++ ++ data.remove("blockId"); ++ data.remove("blockData"); ++ ++ data.setMap("blockState", HelperBlockFlatteningV1450.getNBTForId((blockId << 4) | blockData).copy()); // copy to avoid problems with later state datafixers ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, 2, "minecraft:piston", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "blockState")); ++ ++ // V3 ++ ConverterFlattenEntity.register(); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:filled_map", new DataConverter<>(VERSION, 3) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ tag = Types.NBT.createEmptyMap(); ++ data.setMap("tag", tag); ++ } ++ ++ if (!tag.hasKey("map", ObjectType.NUMBER)) { // This if is from CB. as usual, no documentation from CB. I'm guessing it just wants to avoid possibly overwriting it. seems fine. ++ tag.setInt("map", data.getInt("Damage")); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:potion", new DataWalkerItems("Potion")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:arrow", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:enderman", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "carriedBlockState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:falling_block", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "BlockState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:falling_block", new DataWalkerTileEntities("TileEntityData")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:spectral_arrow", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:chest_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:chest_minecart", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:commandblock_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:commandblock_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "LastOutput")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:furnace_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:hopper_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:hopper_minecart", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:spawner_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:spawner_minecart", (final MapType data, final long fromVersion, final long toVersion) -> { ++ return MCTypeRegistry.UNTAGGED_SPAWNER.convert(data, fromVersion, toVersion); ++ }); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 3, "minecraft:tnt_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "DisplayState")); ++ ++ // V4 ++ MCTypeRegistry.BLOCK_NAME.addConverter(new DataConverter<>(VERSION, 4) { ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (data instanceof Number) { ++ return HelperBlockFlatteningV1450.getNameForId(((Number)data).intValue()); ++ } else if (data instanceof String) { ++ return HelperBlockFlatteningV1450.getNewBlockName((String)data); // structure hook ensured data is namespaced ++ } ++ return null; ++ } ++ }); ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new ConverterFlattenItemStack()); ++ ++ // V5 ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:spawn_egg", new ConverterFlattenSpawnEgg(VERSION, 5)); ++ /* This datafixer has been disabled because the collar colour handler did not change from 1.12 -> 1.13 at all. ++ // So clearly somebody fucked up. This fixes wolf colours incorrectly converting between versions ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:wolf", new DataConverter<>(VERSION, 5) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Number colour = data.getNumber("CollarColor"); ++ ++ if (colour != null) { ++ data.setByte("CollarColor", (byte)(15 - colour.intValue())); ++ } ++ ++ return null; ++ } ++ }); ++ */ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION, 5) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Number base = data.getNumber("Base"); ++ if (base != null) { ++ data.setInt("Base", 15 - base.intValue()); ++ } ++ ++ final ListType patterns = data.getList("Patterns", ObjectType.MAP); ++ if (patterns != null) { ++ for (int i = 0, len = patterns.size(); i < len; ++i) { ++ final MapType pattern = patterns.getMap(i); ++ final Number colour = pattern.getNumber("Color"); ++ if (colour != null) { ++ pattern.setInt("Color", 15 - colour.intValue()); ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.LEVEL.addStructureConverter(new DataConverter<>(VERSION, 5) { ++ private final Splitter SPLITTER = Splitter.on(';').limit(5); ++ private final Splitter LAYER_SPLITTER = Splitter.on(','); ++ private final Splitter OLD_AMOUNT_SPLITTER = Splitter.on('x').limit(2); ++ private final Splitter AMOUNT_SPLITTER = Splitter.on('*').limit(2); ++ private final Splitter BLOCK_SPLITTER = Splitter.on(':').limit(3); ++ ++ // idk man i just copy and pasted this one ++ private String fixGeneratorSettings(final String generatorSettings) { ++ if (generatorSettings.isEmpty()) { ++ return "minecraft:bedrock,2*minecraft:dirt,minecraft:grass_block;1;village"; ++ } else { ++ Iterator iterator = SPLITTER.split(generatorSettings).iterator(); ++ String string2 = (String)iterator.next(); ++ int j; ++ String string4; ++ if (iterator.hasNext()) { ++ j = NumberUtils.toInt(string2, 0); ++ string4 = (String)iterator.next(); ++ } else { ++ j = 0; ++ string4 = string2; ++ } ++ ++ if (j >= 0 && j <= 3) { ++ StringBuilder stringBuilder = new StringBuilder(); ++ Splitter splitter = j < 3 ? OLD_AMOUNT_SPLITTER : AMOUNT_SPLITTER; ++ stringBuilder.append((String) StreamSupport.stream(LAYER_SPLITTER.split(string4).spliterator(), false).map((stringx) -> { ++ List list = splitter.splitToList(stringx); ++ int k; ++ String string3; ++ if (list.size() == 2) { ++ k = NumberUtils.toInt((String)list.get(0)); ++ string3 = (String)list.get(1); ++ } else { ++ k = 1; ++ string3 = (String)list.get(0); ++ } ++ ++ List list2 = BLOCK_SPLITTER.splitToList(string3); ++ int l = ((String)list2.get(0)).equals("minecraft") ? 1 : 0; ++ String string5 = (String)list2.get(l); ++ int m = j == 3 ? EntityBlockStateFix.getBlockId("minecraft:" + string5) : NumberUtils.toInt(string5, 0); ++ int n = l + 1; ++ int o = list2.size() > n ? NumberUtils.toInt((String)list2.get(n), 0) : 0; ++ return (k == 1 ? "" : k + "*") + BlockStateData.getTag(m << 4 | o).get("Name").asString(""); ++ }).collect(Collectors.joining(","))); ++ ++ while(iterator.hasNext()) { ++ stringBuilder.append(';').append((String)iterator.next()); ++ } ++ ++ return stringBuilder.toString(); ++ } else { ++ return "minecraft:bedrock,2*minecraft:dirt,minecraft:grass_block;1;village"; ++ } ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"flat".equalsIgnoreCase(data.getString("generatorName"))) { ++ return null; ++ } ++ ++ final String generatorOptions = data.getString("generatorOptions"); ++ if (generatorOptions == null) { ++ return null; ++ } ++ ++ data.setString("generatorOptions", this.fixGeneratorSettings(generatorOptions)); ++ ++ return null; ++ } ++ }); ++ ++ // V6 ++ MCTypeRegistry.STATS.addStructureConverter(ConverterFlattenStats.makeStatsConverter()); ++ MCTypeRegistry.OBJECTIVE.addStructureConverter(ConverterFlattenStats.makeObjectiveConverter()); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:jukebox", new DataConverter<>(VERSION, 6) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int record = data.getInt("Record"); ++ if (record <= 0) { ++ return null; ++ } ++ ++ data.remove("Record"); ++ ++ final String newItemId = ConverterFlattenItemStack.flattenItem(HelperItemNameV102.getNameFromId(record), 0); ++ if (newItemId == null) { ++ return null; ++ } ++ ++ final MapType recordItem = Types.NBT.createEmptyMap(); ++ data.setMap("RecordItem", recordItem); ++ ++ recordItem.setString("id", newItemId); ++ recordItem.setByte("Count", (byte)1); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.STATS.addStructureWalker(VERSION, 6, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType stats = data.getMap("stats"); ++ if (stats == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertKeys(MCTypeRegistry.BLOCK_NAME, stats, "minecraft:mined", fromVersion, toVersion); ++ ++ WalkerUtils.convertKeys(MCTypeRegistry.ITEM_NAME, stats, "minecraft:crafted", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ITEM_NAME, stats, "minecraft:used", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ITEM_NAME, stats, "minecraft:broken", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ITEM_NAME, stats, "minecraft:picked_up", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ITEM_NAME, stats, "minecraft:dropped", fromVersion, toVersion); ++ ++ WalkerUtils.convertKeys(MCTypeRegistry.ENTITY_NAME, stats, "minecraft:killed", fromVersion, toVersion); ++ WalkerUtils.convertKeys(MCTypeRegistry.ENTITY_NAME, stats, "minecraft:killed_by", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.OBJECTIVE.addStructureHook(VERSION, 6, new DataHook<>() { ++ @Override ++ public MapType preHook(final MapType data, final long fromVersion, final long toVersion) { ++ // unpack ++ final String criteriaName = data.getString("CriteriaName"); ++ String type; ++ String id; ++ ++ if (criteriaName != null) { ++ final int index = criteriaName.indexOf(':'); ++ if (index < 0) { ++ type = "_special"; ++ id = criteriaName; ++ } else { ++ try { ++ type = ResourceLocation.bySeparator(criteriaName.substring(0, index), '.').toString(); ++ id = ResourceLocation.bySeparator(criteriaName.substring(index + 1), '.').toString(); ++ } catch (final Exception ex) { ++ type = "_special"; ++ id = criteriaName; ++ } ++ } ++ } else { ++ type = null; ++ id = null; ++ } ++ ++ if (type != null && id != null) { ++ final MapType criteriaType = Types.NBT.createEmptyMap(); ++ data.setMap("CriteriaType", criteriaType); ++ ++ criteriaType.setString("type", type); ++ criteriaType.setString("id", id); ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public MapType postHook(final MapType data, final long fromVersion, final long toVersion) { ++ // repack ++ final MapType criteriaType = data.getMap("CriteriaType"); ++ ++ final String newName; ++ if (criteriaType == null) { ++ newName = null; ++ } else { ++ final String type = criteriaType.getString("type"); ++ final String id = criteriaType.getString("id"); ++ if (type != null && id != null) { ++ if ("_special".equals(type)) { ++ newName = id; ++ } else { ++ newName = packWithDot(type) + ":" + packWithDot(id); ++ } ++ } else { ++ newName = null; ++ } ++ } ++ ++ if (newName != null) { ++ data.remove("CriteriaType"); ++ data.setString("CriteriaName", newName); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.OBJECTIVE.addStructureWalker(VERSION, 6, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "DisplayName", fromVersion, toVersion); ++ ++ final MapType criteriaType = data.getMap("CriteriaType"); ++ if (criteriaType == null) { ++ return null; ++ } ++ ++ final String type = criteriaType.getString("type"); ++ ++ if (type == null) { ++ return null; ++ } ++ ++ switch (type) { ++ case "minecraft:mined": { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, criteriaType, "id", fromVersion, toVersion); ++ break; ++ } ++ ++ case "minecraft:crafted": ++ case "minecraft:used": ++ case "minecraft:broken": ++ case "minecraft:picked_up": ++ case "minecraft:dropped": { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_NAME, criteriaType, "id", fromVersion, toVersion); ++ break; ++ } ++ ++ case "minecraft:killed": ++ case "minecraft:killed_by": { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, criteriaType, "id", fromVersion, toVersion); ++ break; ++ } ++ } ++ ++ return null; ++ }); ++ ++ ++ // V7 ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION, 7) { ++ private static void convertToBlockState(final MapType data, final String path) { ++ final Number number = data.getNumber(path); ++ if (number == null) { ++ return; ++ } ++ ++ data.setMap(path, HelperBlockFlatteningV1450.getNBTForId(number.intValue() << 4).copy()); // copy to avoid problems with later state datafixers ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType children = data.getList("Children", ObjectType.MAP); ++ if (children == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = children.size(); i < len; ++i) { ++ final MapType child = children.getMap(i); ++ ++ final String id = child.getString("id"); ++ ++ switch (id) { ++ case "ViF": ++ convertToBlockState(child, "CA"); ++ convertToBlockState(child, "CB"); ++ break; ++ case "ViDF": ++ convertToBlockState(child, "CA"); ++ convertToBlockState(child, "CB"); ++ convertToBlockState(child, "CC"); ++ convertToBlockState(child, "CD"); ++ break; ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ // convert villagers to trade with pumpkins and not the carved pumpkin ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", new DataConverter<>(VERSION, 7) { ++ private static void convertPumpkin(final MapType data, final String path) { ++ final MapType item = data.getMap(path); ++ if (item == null) { ++ return; ++ } ++ ++ final String id = item.getString("id"); ++ ++ if (id.equals("minecraft:carved_pumpkin")) { ++ item.setString("id", "minecraft:pumpkin"); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType offers = data.getMap("Offers"); ++ if (offers != null) { ++ final ListType recipes = offers.getList("Recipes", ObjectType.MAP); ++ if (recipes != null) { ++ for (int i = 0, len = recipes.size(); i < len; ++i) { ++ final MapType recipe = recipes.getMap(i); ++ ++ convertPumpkin(recipe, "buy"); ++ convertPumpkin(recipe, "buyB"); ++ convertPumpkin(recipe, "sell"); ++ } ++ } ++ } ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureWalker(VERSION, 7, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final ListType list = data.getListUnchecked("Children"); ++ if (list == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType child = list.getMap(i, null); ++ if (child == null) { ++ continue; ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CA", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CB", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CC", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CD", fromVersion, toVersion); ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V1451() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1456.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1456.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1ea9da33a49891da1e12fd1e870118c6e74c7464 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1456.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1456 { ++ ++ private static final int VERSION = MCVersions.V17W49B + 1; ++ ++ private static byte direction2dTo3d(final byte old) { ++ switch (old) { ++ case 0: ++ return 3; ++ case 1: ++ return 4; ++ case 2: ++ default: ++ return 2; ++ case 3: ++ return 5; ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:item_frame", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setByte("Facing", direction2dTo3d(data.getByte("Facing"))); ++ return null; ++ } ++ }); ++ } ++ ++ private V1456() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1458.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1458.java +new file mode 100644 +index 0000000000000000000000000000000000000000..84104a80ee0c0b408dda258a84cdca8c03997093 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1458.java +@@ -0,0 +1,142 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1458 { ++ ++ public static final int VERSION = MCVersions.V17W50A + 1; ++ ++ public static MapType updateCustomName(final MapType data) { ++ final String customName = data.getString("CustomName", ""); ++ ++ if (customName.isEmpty()) { ++ data.remove("CustomName"); ++ } else { ++ data.setString("CustomName", ComponentUtils.createPlainTextComponent(customName)); ++ } ++ ++ return null; ++ } ++ ++ static void named(final int version, final String id) { ++ MCTypeRegistry.TILE_ENTITY.addWalker(version, id, new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "CustomName")); ++ } ++ ++ static void namedInventory(final int version, final String id) { ++ named(version, id); ++ MCTypeRegistry.TILE_ENTITY.addWalker(version, id, new DataWalkerItemLists("Items")); ++ } ++ ++ public static void register() { ++ // From CB ++ MCTypeRegistry.PLAYER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ return updateCustomName(data); ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if ("minecraft:commandblock_minecart".equals(data.getString("id"))) { ++ return null; ++ } ++ ++ return updateCustomName(data); ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType display = tag.getMap("display"); ++ if (display == null) { ++ return null; ++ } ++ ++ final String name = display.getString("Name"); ++ if (name != null) { ++ display.setString("Name", ComponentUtils.createPlainTextComponent(name)); ++ } /* In 1.20.5, Mojang removed this branch (ItemCustomNameToComponentFix) */ /*else { ++ final String localisedName = display.getString("LocName"); ++ if (localisedName != null) { ++ display.setString("Name", ComponentUtils.createTranslatableComponent(localisedName)); ++ display.remove("LocName"); ++ } ++ }*/ ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if ("minecraft:command_block".equals(data.getString("id"))) { ++ return null; ++ } ++ ++ return updateCustomName(data); ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "Passengers", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "CustomName", fromVersion, toVersion); ++ ++ return MCTypeRegistry.ENTITY_EQUIPMENT.convert(data, fromVersion, toVersion); ++ }); ++ ++ // Note: This is not present in Vanilla, but since we have the converter from CB it makes sense that we ++ // would walk the CustomName field for Player if we are converting it ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("RootVehicle"), "Entity", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "EnderItems", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityLeft", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityRight", fromVersion, toVersion); ++ ++ final MapType recipeBook = data.getMap("recipeBook"); ++ if (recipeBook != null) { ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "recipes", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "toBeDisplayed", fromVersion, toVersion); ++ } ++ ++ // "From CB" ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "CustomName", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ named(VERSION, "minecraft:beacon"); ++ named(VERSION, "minecraft:banner"); ++ namedInventory(VERSION, "minecraft:brewing_stand"); ++ namedInventory(VERSION, "minecraft:chest"); ++ namedInventory(VERSION, "minecraft:trapped_chest"); ++ namedInventory(VERSION, "minecraft:dispenser"); ++ namedInventory(VERSION, "minecraft:dropper"); ++ named(VERSION, "minecraft:enchanting_table"); ++ namedInventory(VERSION, "minecraft:furnace"); ++ namedInventory(VERSION, "minecraft:hopper"); ++ namedInventory(VERSION, "minecraft:shulker_box"); ++ } ++ ++ private V1458() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dca03108730af672445463326aabc156e6ae16ca +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1460.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.block_name.DataWalkerBlockNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import net.minecraft.resources.ResourceLocation; ++import java.util.HashMap; ++import java.util.Locale; ++import java.util.Map; ++ ++public final class V1460 { ++ ++ private static final Map MOTIVE_REMAP = new HashMap<>(); ++ ++ static { ++ MOTIVE_REMAP.put("donkeykong", "donkey_kong"); ++ MOTIVE_REMAP.put("burningskull", "burning_skull"); ++ MOTIVE_REMAP.put("skullandroses", "skull_and_roses"); ++ } ++ ++ private static final int VERSION = MCVersions.V18W01A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:painting", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ String motive = data.getString("Motive"); ++ if (motive != null) { ++ motive = motive.toLowerCase(Locale.ROOT); ++ data.setString("Motive", NamespaceUtil.correctNamespace(MOTIVE_REMAP.getOrDefault(motive, motive))); ++ } ++ return null; ++ } ++ }); ++ ++ // No idea why so many type redefines exist here in Vanilla. nothing about the data structure changed, it's literally a copy of ++ // the existing types. ++ } ++ ++ private V1460() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1466.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1466.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b4d308812e8b86cca7a0fde5db133b5357895959 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1466.java +@@ -0,0 +1,142 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V1466 { ++ ++ private static final int VERSION = MCVersions.V18W06A; ++ ++ private static short packOffsetCoordinates(final int x, final int y, final int z) { ++ return (short)((x & 15) | ((y & 15) << 4) | ((z & 15) << 8)); ++ } ++ ++ public static void register() { ++ // There is a rather critical change I've made to this converter: changing the chunk status determination. ++ // In Vanilla, this is determined by whether the terrain has been populated and whether the chunk is lit. ++ // For reference, here is the full status progression (at the time of 18w06a): ++ // empty -> base -> carved -> decorated -> lighted -> mobs_spawned -> finalized -> fullchunk -> postprocessed ++ // So one of those must be picked. ++ // If the chunk is lit and terrain is populated, the Vanilla converter will set the status to "mobs_spawned." ++ // If it is anything else, it will be "empty" ++ // I've changed it to the following: if terrain is populated, it is set to at least decorated. If it is populated ++ // and lit, it is set to "mobs_spawned" ++ // But what if it is not populated? If it is not populated, ignore the lit field - obviously that's just broken. ++ // It can't be lit and not populated. ++ // Let's take a look at chunk generation logic for a chunk that is not populated, or even near a populated chunk. ++ // It actually will generate a chunk up to the "carved" stage. It generates the base terrain, (i.e using noise ++ // to figure out where stone is, dirt, grass) and it will generate caves. Nothing else though. No populators. ++ // So "carved" is the correct stage to use, not empty. Setting it to empty would clobber chunk data, when we don't ++ // need to. If it is populated, at least set it to decorated. If it is lit and populated, set it to mobs_spawned. Else, ++ // it is carved. ++ // This change also fixes the random light check "bug" (really this is Mojang's fault for fucking up the status conversion here) ++ // caused by spigot, which would not set the lit value for some chunks. Now those chunks will not be regenerated. ++ ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ final boolean terrainPopulated = level.getBoolean("TerrainPopulated"); ++ final boolean lightPopulated = level.getBoolean("LightPopulated") || level.getNumber("LightPopulated") == null; ++ final String newStatus = !terrainPopulated ? "carved" : (lightPopulated ? "mobs_spawned" : "decorated"); ++ ++ level.setString("Status", newStatus); ++ level.setBoolean("hasLegacyStructureData", true); ++ ++ // convert biome byte[] into int[] ++ final byte[] biomes = level.getBytes("Biomes"); ++ if (biomes != null) { ++ final int[] newBiomes = new int[256]; ++ for (int i = 0, len = Math.min(newBiomes.length, biomes.length); i < len; ++i) { ++ newBiomes[i] = biomes[i] & 255; ++ } ++ level.setInts("Biomes", newBiomes); ++ } ++ ++ // ProtoChunks have their own dedicated tick list, so we must convert the TileTicks to that. ++ final ListType ticks = level.getList("TileTicks", ObjectType.MAP); ++ if (ticks != null) { ++ final ListType sections = Types.NBT.createEmptyList(); ++ final ListType[] sectionAccess = new ListType[16]; ++ for (int i = 0; i < sectionAccess.length; ++i) { ++ sections.addList(sectionAccess[i] = Types.NBT.createEmptyList()); ++ } ++ level.setList("ToBeTicked", sections); ++ ++ for (int i = 0, len = ticks.size(); i < len; ++i) { ++ final MapType tick = ticks.getMap(i); ++ ++ final int x = tick.getInt("x"); ++ final int y = tick.getInt("y"); ++ final int z = tick.getInt("z"); ++ final short coordinate = packOffsetCoordinates(x, y, z); ++ ++ sectionAccess[y >> 4].addShort(coordinate); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, level, "Entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, level, "TileEntities", fromVersion, toVersion); ++ ++ final ListType tileTicks = level.getList("TileTicks", ObjectType.MAP); ++ if (tileTicks != null) { ++ for (int i = 0, len = tileTicks.size(); i < len; ++i) { ++ final MapType tileTick = tileTicks.getMap(i); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, tileTick, "i", fromVersion, toVersion); ++ } ++ } ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section, "Palette", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, level.getMap("Structures"), "Starts", fromVersion, toVersion); ++ ++ return null; ++ }); ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final ListType list = data.getList("Children", ObjectType.MAP); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType child = list.getMap(i); ++ ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CA", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CB", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CC", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, child, "CD", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.BIOME, data, "biome", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private V1466() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V147.java b/ca/spottedleaf/dataconverter/minecraft/versions/V147.java +new file mode 100644 +index 0000000000000000000000000000000000000000..02df67a0bb6d7dc3f7e6b7de5c0978295661c72f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V147.java +@@ -0,0 +1,26 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V147 { ++ ++ private static final int VERSION = MCVersions.V15W46A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("ArmorStand", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getBoolean("Silent") && !data.getBoolean("Marker")) { ++ data.remove("Silent"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V147() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1470.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1470.java +new file mode 100644 +index 0000000000000000000000000000000000000000..42cf72340be7e1ef84f794a569f2f00e5e56429e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1470.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V1470 { ++ ++ private static final int VERSION = MCVersions.V18W08A; ++ ++ public static void register() { ++ //registerMob("minecraft:turtle"); // is now simple in 1.21.5 ++ //registerMob("minecraft:cod_mob"); // is now simple in 1.21.5 ++ //registerMob("minecraft:tropical_fish"); // is now simple in 1.21.5 ++ //registerMob("minecraft:salmon_mob"); // is now simple in 1.21.5 ++ //registerMob("minecraft:puffer_fish"); // is now simple in 1.21.5 ++ //registerMob("minecraft:phantom"); // is now simple in 1.21.5 ++ //registerMob("minecraft:dolphin"); // is now simple in 1.21.5 ++ //registerMob("minecraft:drowned"); // is now simple in 1.21.5 ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:trident", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:trident", new DataWalkerItems("Trident")); ++ } ++ ++ private V1470() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1474.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1474.java +new file mode 100644 +index 0000000000000000000000000000000000000000..244baa4f38102ecbfdb7fe0b14bf0be1816a59a2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1474.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1474 { ++ ++ private static final int VERSION = MCVersions.V18W10B; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:shulker", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getInt("Color") == 10) { ++ data.setByte("Color", (byte)16); ++ } ++ return null; ++ } ++ }); ++ // data hooks ensure the inputs are namespaced ++ ConverterAbstractBlockRename.register(VERSION, (final String old) -> { ++ return "minecraft:purple_shulker_box".equals(old) ? "minecraft:shulker_box" : null; ++ }); ++ ConverterAbstractItemRename.register(VERSION, (final String old) -> { ++ return "minecraft:purple_shulker_box".equals(old) ? "minecraft:shulker_box" : null; ++ }); ++ } ++ ++ private V1474() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1475.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1475.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2ae50eea847671f3995688901c79caf520440d7a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1475.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V1475 { ++ ++ private static final int VERSION = MCVersions.V18W10B + 1; ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:flowing_water", "minecraft:water", ++ "minecraft:flowing_lava", "minecraft:lava" ++ ) ++ )::get); ++ } ++ ++ private V1475() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1480.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1480.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7180c1168bffb9fe70d18fe7414a5372518413a8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1480.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1480 { ++ ++ private static final int VERSION = MCVersions.V18W14A + 1; ++ ++ public static final Map RENAMED_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:blue_coral", "minecraft:tube_coral_block") ++ .put("minecraft:pink_coral", "minecraft:brain_coral_block") ++ .put("minecraft:purple_coral", "minecraft:bubble_coral_block") ++ .put("minecraft:red_coral", "minecraft:fire_coral_block") ++ .put("minecraft:yellow_coral", "minecraft:horn_coral_block") ++ .put("minecraft:blue_coral_plant", "minecraft:tube_coral") ++ .put("minecraft:pink_coral_plant", "minecraft:brain_coral") ++ .put("minecraft:purple_coral_plant", "minecraft:bubble_coral") ++ .put("minecraft:red_coral_plant", "minecraft:fire_coral") ++ .put("minecraft:yellow_coral_plant", "minecraft:horn_coral") ++ .put("minecraft:blue_coral_fan", "minecraft:tube_coral_fan") ++ .put("minecraft:pink_coral_fan", "minecraft:brain_coral_fan") ++ .put("minecraft:purple_coral_fan", "minecraft:bubble_coral_fan") ++ .put("minecraft:red_coral_fan", "minecraft:fire_coral_fan") ++ .put("minecraft:yellow_coral_fan", "minecraft:horn_coral_fan") ++ .put("minecraft:blue_dead_coral", "minecraft:dead_tube_coral") ++ .put("minecraft:pink_dead_coral", "minecraft:dead_brain_coral") ++ .put("minecraft:purple_dead_coral", "minecraft:dead_bubble_coral") ++ .put("minecraft:red_dead_coral", "minecraft:dead_fire_coral") ++ .put("minecraft:yellow_dead_coral", "minecraft:dead_horn_coral") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, RENAMED_IDS::get); ++ ConverterAbstractItemRename.register(VERSION, RENAMED_IDS::get); ++ } ++ ++ private V1480() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1483.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1483.java +new file mode 100644 +index 0000000000000000000000000000000000000000..56d9babebba8b8ba6be07ea413e9c04ffea84023 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1483.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V1483 { ++ ++ private static final int VERSION = MCVersions.V18W16A; ++ ++ public static void register() { ++ ConverterAbstractEntityRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:puffer_fish", "minecraft:pufferfish" ++ ) ++ )::get); ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:puffer_fish_spawn_egg", "minecraft:pufferfish_spawn_egg" ++ ) ++ )::get); ++ ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:puffer_fish", "minecraft:pufferfish"); ++ } ++ ++ private V1483() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1484.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1484.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cdc8ab8b0e1fc88cba8fd1d3000180288fe8d5fd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1484.java +@@ -0,0 +1,75 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1484 { ++ ++ private static final int VERSION = MCVersions.V18W19A; ++ ++ public static void register() { ++ final Map renamed = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:sea_grass", "minecraft:seagrass", ++ "minecraft:tall_sea_grass", "minecraft:tall_seagrass" ++ ) ++ ); ++ ++ ConverterAbstractItemRename.register(VERSION, renamed::get); ++ ConverterAbstractBlockRename.register(VERSION, renamed::get); ++ ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final MapType heightmaps = level.getMap("Heightmaps"); ++ ++ if (heightmaps == null) { ++ return null; ++ } ++ ++ final Object liquid = heightmaps.getGeneric("LIQUID"); ++ if (liquid != null) { ++ heightmaps.remove("LIQUID"); ++ heightmaps.setGeneric("WORLD_SURFACE_WG", liquid); ++ } ++ ++ final Object solid = heightmaps.getGeneric("SOLID"); ++ if (solid != null) { ++ heightmaps.remove("SOLID"); ++ heightmaps.setGeneric("OCEAN_FLOOR_WG", solid); ++ heightmaps.setGeneric("OCEAN_FLOOR", solid); ++ } ++ ++ final Object light = heightmaps.getGeneric("LIGHT"); ++ if (light != null) { ++ heightmaps.remove("LIGHT"); ++ heightmaps.setGeneric("LIGHT_BLOCKING", light); ++ } ++ ++ final Object rain = heightmaps.getGeneric("RAIN"); ++ if (rain != null) { ++ heightmaps.remove("RAIN"); ++ heightmaps.setGeneric("MOTION_BLOCKING", rain); ++ heightmaps.setGeneric("MOTION_BLOCKING_NO_LEAVES", rain); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1484() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1486.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1486.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a9e42da41064ea293a71dbf2d681a857b2e1812e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1486.java +@@ -0,0 +1,39 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1486 { ++ ++ private static final int VERSION = MCVersions.V18W19B + 1; ++ ++ public static final Map RENAMED_ENTITY_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:salmon_mob", "minecraft:salmon") ++ .put("minecraft:cod_mob", "minecraft:cod") ++ .build() ++ ); ++ public static final Map RENAMED_ITEM_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:salmon_mob_spawn_egg", "minecraft:salmon_spawn_egg") ++ .put("minecraft:cod_mob_spawn_egg", "minecraft:cod_spawn_egg") ++ .build() ++ ); ++ ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:cod_mob", "minecraft:cod"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:salmon_mob", "minecraft:salmon"); ++ ++ ConverterAbstractEntityRename.register(VERSION, RENAMED_ENTITY_IDS::get); ++ ConverterAbstractItemRename.register(VERSION, RENAMED_ITEM_IDS::get); ++ } ++ ++ private V1486() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1487.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1487.java +new file mode 100644 +index 0000000000000000000000000000000000000000..884049818efdf273443fb3d1c2d7250564fbdbf7 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1487.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1487 { ++ ++ private static final int VERSION = MCVersions.V18W19B + 2; ++ ++ public static void register() { ++ final Map remap = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:prismarine_bricks_slab", "minecraft:prismarine_brick_slab", ++ "minecraft:prismarine_bricks_stairs", "minecraft:prismarine_brick_stairs" ++ ) ++ ); ++ ++ ConverterAbstractItemRename.register(VERSION, remap::get); ++ ConverterAbstractBlockRename.register(VERSION, remap::get); ++ } ++ ++ private V1487() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1488.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1488.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a291dc5b9dbc4362038fcfb6fbb0de405b693c11 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1488.java +@@ -0,0 +1,99 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.ImmutableMap; ++ ++import java.util.HashMap; ++ ++public final class V1488 { ++ ++ private static final int VERSION = MCVersions.V18W19B + 3; ++ ++ private static boolean isIglooPiece(final MapType piece) { ++ return "Iglu".equals(piece.getString("id")); ++ } ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:kelp_top", "minecraft:kelp", ++ "minecraft:kelp", "minecraft:kelp_plant" ++ ) ++ )::get); ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:kelp_top", "minecraft:kelp" ++ ) ++ )::get); ++ ++ // Don't ask me why in V1458 they wrote the converter to NOT do command blocks and THEN in THIS version ++ // to ONLY do command blocks. I don't know. ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:command_block", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ return V1458.updateCustomName(data); ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:commandblock_minecart", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ return V1458.updateCustomName(data); ++ } ++ }); ++ ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType children = data.getList("Children", ObjectType.MAP); ++ boolean isIgloo; ++ if (children != null) { ++ isIgloo = true; ++ for (int i = 0, len = children.size(); i < len; ++i) { ++ if (!isIglooPiece(children.getMap(i))) { ++ isIgloo = false; ++ break; ++ } ++ } ++ } else { ++ isIgloo = false; ++ } ++ ++ if (isIgloo) { ++ data.remove("Children"); ++ data.setString("id", "Igloo"); ++ return null; ++ } ++ ++ if (children != null) { ++ for (int i = 0; i < children.size();) { ++ final MapType child = children.getMap(i); ++ if (isIglooPiece(child)) { ++ children.remove(i); ++ continue; ++ } ++ ++i; ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:command_block", ++ new DataWalkerTypePaths<>(MCTypeRegistry.DATACONVERTER_CUSTOM_TYPE_COMMAND, "Command") ++ ); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:command_block", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "CustomName", "LastOutput")); ++ } ++ ++ private V1488() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1490.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1490.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1e99de15732bdd283835a9531f76e29ddab91f46 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1490.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++ ++import java.util.HashMap; ++ ++public final class V1490 { ++ ++ private static final int VERSION = MCVersions.V18W20A + 1; ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:melon_block", "minecraft:melon" ++ ) ++ )::get); ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:melon_block", "minecraft:melon", ++ "minecraft:melon", "minecraft:melon_slice", ++ "minecraft:speckled_melon", "minecraft:glistering_melon_slice" ++ ) ++ )::get); ++ } ++ ++ private V1490() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1492.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1492.java +new file mode 100644 +index 0000000000000000000000000000000000000000..aa18e481f2d54d20784fe6af27846ec0d297f9c1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1492.java +@@ -0,0 +1,151 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.ImmutableMap; ++import com.mojang.datafixers.util.Pair; ++ ++public final class V1492 { ++ ++ private static final ImmutableMap>> RENAMES = ImmutableMap.>>builder() ++ .put("EndCity", Pair.of( ++ "ECP", ++ ImmutableMap.builder() ++ .put("second_floor", "second_floor_1") ++ .put("third_floor", "third_floor_1") ++ .put("third_floor_c", "third_floor_2") ++ .build() ++ ) ++ ) ++ ++ .put("Mansion", Pair.of( ++ "WMP", ++ ImmutableMap.builder() ++ .put("carpet_south", "carpet_south_1") ++ .put("carpet_west", "carpet_west_1") ++ .put("indoors_door", "indoors_door_1") ++ .put("indoors_wall", "indoors_wall_1") ++ .build() ++ ) ++ ) ++ ++ .put("Igloo", Pair.of( ++ "Iglu", ++ ImmutableMap.builder() ++ .put("minecraft:igloo/igloo_bottom", "minecraft:igloo/bottom") ++ .put("minecraft:igloo/igloo_middle", "minecraft:igloo/middle") ++ .put("minecraft:igloo/igloo_top", "minecraft:igloo/top") ++ .build() ++ ) ++ ) ++ .put("Ocean_Ruin", Pair.of( ++ "ORP", ++ ImmutableMap.builder() ++ .put("minecraft:ruin/big_ruin1_brick", "minecraft:underwater_ruin/big_brick_1") ++ .put("minecraft:ruin/big_ruin2_brick", "minecraft:underwater_ruin/big_brick_2") ++ .put("minecraft:ruin/big_ruin3_brick", "minecraft:underwater_ruin/big_brick_3") ++ .put("minecraft:ruin/big_ruin8_brick", "minecraft:underwater_ruin/big_brick_8") ++ .put("minecraft:ruin/big_ruin1_cracked", "minecraft:underwater_ruin/big_cracked_1") ++ .put("minecraft:ruin/big_ruin2_cracked", "minecraft:underwater_ruin/big_cracked_2") ++ .put("minecraft:ruin/big_ruin3_cracked", "minecraft:underwater_ruin/big_cracked_3") ++ .put("minecraft:ruin/big_ruin8_cracked", "minecraft:underwater_ruin/big_cracked_8") ++ .put("minecraft:ruin/big_ruin1_mossy", "minecraft:underwater_ruin/big_mossy_1") ++ .put("minecraft:ruin/big_ruin2_mossy", "minecraft:underwater_ruin/big_mossy_2") ++ .put("minecraft:ruin/big_ruin3_mossy", "minecraft:underwater_ruin/big_mossy_3") ++ .put("minecraft:ruin/big_ruin8_mossy", "minecraft:underwater_ruin/big_mossy_8") ++ .put("minecraft:ruin/big_ruin_warm4", "minecraft:underwater_ruin/big_warm_4") ++ .put("minecraft:ruin/big_ruin_warm5", "minecraft:underwater_ruin/big_warm_5") ++ .put("minecraft:ruin/big_ruin_warm6", "minecraft:underwater_ruin/big_warm_6") ++ .put("minecraft:ruin/big_ruin_warm7", "minecraft:underwater_ruin/big_warm_7") ++ .put("minecraft:ruin/ruin1_brick", "minecraft:underwater_ruin/brick_1") ++ .put("minecraft:ruin/ruin2_brick", "minecraft:underwater_ruin/brick_2") ++ .put("minecraft:ruin/ruin3_brick", "minecraft:underwater_ruin/brick_3") ++ .put("minecraft:ruin/ruin4_brick", "minecraft:underwater_ruin/brick_4") ++ .put("minecraft:ruin/ruin5_brick", "minecraft:underwater_ruin/brick_5") ++ .put("minecraft:ruin/ruin6_brick", "minecraft:underwater_ruin/brick_6") ++ .put("minecraft:ruin/ruin7_brick", "minecraft:underwater_ruin/brick_7") ++ .put("minecraft:ruin/ruin8_brick", "minecraft:underwater_ruin/brick_8") ++ .put("minecraft:ruin/ruin1_cracked", "minecraft:underwater_ruin/cracked_1") ++ .put("minecraft:ruin/ruin2_cracked", "minecraft:underwater_ruin/cracked_2") ++ .put("minecraft:ruin/ruin3_cracked", "minecraft:underwater_ruin/cracked_3") ++ .put("minecraft:ruin/ruin4_cracked", "minecraft:underwater_ruin/cracked_4") ++ .put("minecraft:ruin/ruin5_cracked", "minecraft:underwater_ruin/cracked_5") ++ .put("minecraft:ruin/ruin6_cracked", "minecraft:underwater_ruin/cracked_6") ++ .put("minecraft:ruin/ruin7_cracked", "minecraft:underwater_ruin/cracked_7") ++ .put("minecraft:ruin/ruin8_cracked", "minecraft:underwater_ruin/cracked_8") ++ .put("minecraft:ruin/ruin1_mossy", "minecraft:underwater_ruin/mossy_1") ++ .put("minecraft:ruin/ruin2_mossy", "minecraft:underwater_ruin/mossy_2") ++ .put("minecraft:ruin/ruin3_mossy", "minecraft:underwater_ruin/mossy_3") ++ .put("minecraft:ruin/ruin4_mossy", "minecraft:underwater_ruin/mossy_4") ++ .put("minecraft:ruin/ruin5_mossy", "minecraft:underwater_ruin/mossy_5") ++ .put("minecraft:ruin/ruin6_mossy", "minecraft:underwater_ruin/mossy_6") ++ .put("minecraft:ruin/ruin7_mossy", "minecraft:underwater_ruin/mossy_7") ++ .put("minecraft:ruin/ruin8_mossy", "minecraft:underwater_ruin/mossy_8") ++ .put("minecraft:ruin/ruin_warm1", "minecraft:underwater_ruin/warm_1") ++ .put("minecraft:ruin/ruin_warm2", "minecraft:underwater_ruin/warm_2") ++ .put("minecraft:ruin/ruin_warm3", "minecraft:underwater_ruin/warm_3") ++ .put("minecraft:ruin/ruin_warm4", "minecraft:underwater_ruin/warm_4") ++ .put("minecraft:ruin/ruin_warm5", "minecraft:underwater_ruin/warm_5") ++ .put("minecraft:ruin/ruin_warm6", "minecraft:underwater_ruin/warm_6") ++ .put("minecraft:ruin/ruin_warm7", "minecraft:underwater_ruin/warm_7") ++ .put("minecraft:ruin/ruin_warm8", "minecraft:underwater_ruin/warm_8") ++ .put("minecraft:ruin/big_brick_1", "minecraft:underwater_ruin/big_brick_1") ++ .put("minecraft:ruin/big_brick_2", "minecraft:underwater_ruin/big_brick_2") ++ .put("minecraft:ruin/big_brick_3", "minecraft:underwater_ruin/big_brick_3") ++ .put("minecraft:ruin/big_brick_8", "minecraft:underwater_ruin/big_brick_8") ++ .put("minecraft:ruin/big_mossy_1", "minecraft:underwater_ruin/big_mossy_1") ++ .put("minecraft:ruin/big_mossy_2", "minecraft:underwater_ruin/big_mossy_2") ++ .put("minecraft:ruin/big_mossy_3", "minecraft:underwater_ruin/big_mossy_3") ++ .put("minecraft:ruin/big_mossy_8", "minecraft:underwater_ruin/big_mossy_8") ++ .put("minecraft:ruin/big_cracked_1", "minecraft:underwater_ruin/big_cracked_1") ++ .put("minecraft:ruin/big_cracked_2", "minecraft:underwater_ruin/big_cracked_2") ++ .put("minecraft:ruin/big_cracked_3", "minecraft:underwater_ruin/big_cracked_3") ++ .put("minecraft:ruin/big_cracked_8", "minecraft:underwater_ruin/big_cracked_8") ++ .put("minecraft:ruin/big_warm_4", "minecraft:underwater_ruin/big_warm_4") ++ .put("minecraft:ruin/big_warm_5", "minecraft:underwater_ruin/big_warm_5") ++ .put("minecraft:ruin/big_warm_6", "minecraft:underwater_ruin/big_warm_6") ++ .put("minecraft:ruin/big_warm_7", "minecraft:underwater_ruin/big_warm_7") ++ .build() ++ ) ++ ) ++ ++ .build(); ++ ++ private static final int VERSION = MCVersions.V18W20B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType children = data.getList("Children", ObjectType.MAP); ++ if (children == null) { ++ return null; ++ } ++ ++ final String id = data.getString("id"); ++ ++ final Pair> renames = RENAMES.get(id); ++ if (renames == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = children.size(); i < len; ++i) { ++ final MapType child = children.getMap(i); ++ ++ if (renames.getFirst().equals(child.getString("id"))) { ++ final String template = child.getString("Template", ""); ++ child.setString("Template", renames.getSecond().getOrDefault(template, template)); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1492() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1494.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1494.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ef35ea5c1e471794721bd26834db14ea63ddd17f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1494.java +@@ -0,0 +1,88 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++public final class V1494 { ++ ++ private static final int VERSION = MCVersions.V18W20C + 1; ++ ++ private static final Int2ObjectOpenHashMap ENCH_ID_TO_NAME = new Int2ObjectOpenHashMap<>(); ++ static { ++ ENCH_ID_TO_NAME.put(0, "minecraft:protection"); ++ ENCH_ID_TO_NAME.put(1, "minecraft:fire_protection"); ++ ENCH_ID_TO_NAME.put(2, "minecraft:feather_falling"); ++ ENCH_ID_TO_NAME.put(3, "minecraft:blast_protection"); ++ ENCH_ID_TO_NAME.put(4, "minecraft:projectile_protection"); ++ ENCH_ID_TO_NAME.put(5, "minecraft:respiration"); ++ ENCH_ID_TO_NAME.put(6, "minecraft:aqua_affinity"); ++ ENCH_ID_TO_NAME.put(7, "minecraft:thorns"); ++ ENCH_ID_TO_NAME.put(8, "minecraft:depth_strider"); ++ ENCH_ID_TO_NAME.put(9, "minecraft:frost_walker"); ++ ENCH_ID_TO_NAME.put(10, "minecraft:binding_curse"); ++ ENCH_ID_TO_NAME.put(16, "minecraft:sharpness"); ++ ENCH_ID_TO_NAME.put(17, "minecraft:smite"); ++ ENCH_ID_TO_NAME.put(18, "minecraft:bane_of_arthropods"); ++ ENCH_ID_TO_NAME.put(19, "minecraft:knockback"); ++ ENCH_ID_TO_NAME.put(20, "minecraft:fire_aspect"); ++ ENCH_ID_TO_NAME.put(21, "minecraft:looting"); ++ ENCH_ID_TO_NAME.put(22, "minecraft:sweeping"); ++ ENCH_ID_TO_NAME.put(32, "minecraft:efficiency"); ++ ENCH_ID_TO_NAME.put(33, "minecraft:silk_touch"); ++ ENCH_ID_TO_NAME.put(34, "minecraft:unbreaking"); ++ ENCH_ID_TO_NAME.put(35, "minecraft:fortune"); ++ ENCH_ID_TO_NAME.put(48, "minecraft:power"); ++ ENCH_ID_TO_NAME.put(49, "minecraft:punch"); ++ ENCH_ID_TO_NAME.put(50, "minecraft:flame"); ++ ENCH_ID_TO_NAME.put(51, "minecraft:infinity"); ++ ENCH_ID_TO_NAME.put(61, "minecraft:luck_of_the_sea"); ++ ENCH_ID_TO_NAME.put(62, "minecraft:lure"); ++ ENCH_ID_TO_NAME.put(65, "minecraft:loyalty"); ++ ENCH_ID_TO_NAME.put(66, "minecraft:impaling"); ++ ENCH_ID_TO_NAME.put(67, "minecraft:riptide"); ++ ENCH_ID_TO_NAME.put(68, "minecraft:channeling"); ++ ENCH_ID_TO_NAME.put(70, "minecraft:mending"); ++ ENCH_ID_TO_NAME.put(71, "minecraft:vanishing_curse"); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final ListType enchants = tag.getList("ench", ObjectType.MAP); ++ if (enchants != null) { ++ tag.remove("ench"); ++ tag.setList("Enchantments", enchants); ++ ++ for (int i = 0, len = enchants.size(); i < len; ++i) { ++ final MapType enchant = enchants.getMap(i); ++ enchant.setString("id", ENCH_ID_TO_NAME.getOrDefault(enchant.getInt("id"), "null")); ++ } ++ } ++ ++ final ListType storedEnchants = tag.getList("StoredEnchantments", ObjectType.MAP); ++ if (storedEnchants != null) { ++ for (int i = 0, len = storedEnchants.size(); i < len; ++i) { ++ final MapType enchant = storedEnchants.getMap(i); ++ enchant.setString("id", ENCH_ID_TO_NAME.getOrDefault(enchant.getInt("id"), "null")); ++ } ++ } ++ ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1494() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1496.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1496.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4b34a890a96b67cd14fc576a051f6f69f1697e93 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1496.java +@@ -0,0 +1,370 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.datafixers.DataFixUtils; ++import it.unimi.dsi.fastutil.ints.Int2IntOpenHashMap; ++import it.unimi.dsi.fastutil.ints.IntIterator; ++import it.unimi.dsi.fastutil.ints.IntOpenHashSet; ++import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; ++import net.minecraft.util.datafix.PackedBitStorage; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V1496 { ++ ++ private static final int VERSION = MCVersions.V18W21B; ++ ++ private static final int[][] DIRECTIONS = new int[][] { ++ new int[] {-1, 0, 0}, ++ new int[] {1, 0, 0}, ++ new int[] {0, -1, 0}, ++ new int[] {0, 1, 0}, ++ new int[] {0, 0, -1}, ++ new int[] {0, 0, 1} ++ }; ++ ++ private static final Object2IntOpenHashMap LEAVES_TO_ID = new Object2IntOpenHashMap<>(); ++ static { ++ LEAVES_TO_ID.put("minecraft:acacia_leaves", 0); ++ LEAVES_TO_ID.put("minecraft:birch_leaves", 1); ++ LEAVES_TO_ID.put("minecraft:dark_oak_leaves", 2); ++ LEAVES_TO_ID.put("minecraft:jungle_leaves", 3); ++ LEAVES_TO_ID.put("minecraft:oak_leaves", 4); ++ LEAVES_TO_ID.put("minecraft:spruce_leaves", 5); ++ } ++ ++ private static final Set LOGS = new HashSet<>( ++ Arrays.asList( ++ "minecraft:acacia_bark", ++ "minecraft:birch_bark", ++ "minecraft:dark_oak_bark", ++ "minecraft:jungle_bark", ++ "minecraft:oak_bark", ++ "minecraft:spruce_bark", ++ "minecraft:acacia_log", ++ "minecraft:birch_log", ++ "minecraft:dark_oak_log", ++ "minecraft:jungle_log", ++ "minecraft:oak_log", ++ "minecraft:spruce_log", ++ "minecraft:stripped_acacia_log", ++ "minecraft:stripped_birch_log", ++ "minecraft:stripped_dark_oak_log", ++ "minecraft:stripped_jungle_log", ++ "minecraft:stripped_oak_log", ++ "minecraft:stripped_spruce_log" ++ ) ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ final ListType sectionsNBT = level.getList("Sections", ObjectType.MAP); ++ if (sectionsNBT == null) { ++ return null; ++ } ++ ++ int newSides = 0; ++ ++ final LeavesSection[] sections = new LeavesSection[16]; ++ boolean skippable = true; ++ for (int i = 0, len = sectionsNBT.size(); i < len; ++i) { ++ final LeavesSection section = new LeavesSection(sectionsNBT.getMap(i)); ++ sections[section.sectionY] = section; ++ ++ skippable &= section.isSkippable(); ++ } ++ ++ if (skippable) { ++ return null; ++ } ++ ++ final IntOpenHashSet[] positionsByDistance = new IntOpenHashSet[7]; ++ for (int i = 0; i < positionsByDistance.length; ++i) { ++ positionsByDistance[i] = new IntOpenHashSet(); ++ } ++ ++ for (final LeavesSection section : sections) { ++ if (section == null || section.isSkippable()) { ++ continue; ++ } ++ ++ for (int index = 0; index < 4096; ++index) { ++ final int block = section.getBlock(index); ++ if (section.isLog(block)) { ++ positionsByDistance[0].add(section.getSectionY() << 12 | index); ++ } else if (section.isLeaf(block)) { ++ int x = getX(index); ++ int z = getZ(index); ++ newSides |= getSideMask(x == 0, x == 15, z == 0, z == 15); ++ } ++ } ++ } ++ ++ // this is basically supposed to recalculate the distances, because a higher cap was added ++ for (int distance = 1; distance < 7; ++distance) { ++ final IntOpenHashSet positionsLess = positionsByDistance[distance - 1]; ++ final IntOpenHashSet positionsEqual = positionsByDistance[distance]; ++ ++ for (final IntIterator iterator = positionsLess.iterator(); iterator.hasNext();) { ++ final int position = iterator.nextInt(); ++ final int fromX = getX(position); ++ final int fromY = getY(position); ++ final int fromZ = getZ(position); ++ ++ for (final int[] direction : DIRECTIONS) { ++ final int toX = fromX + direction[0]; ++ final int toY = fromY + direction[1]; ++ final int toZ = fromZ + direction[2]; ++ ++ if (!(toX >= 0 && toX <= 15 && toZ >= 0 && toZ <= 15 && toY >= 0 && toY <= 255)) { ++ continue; ++ } ++ ++ final LeavesSection toSection = sections[toY >> 4]; ++ if (toSection == null || toSection.isSkippable()) { ++ continue; ++ } ++ ++ final int sectionLocalIndex = getIndex(toX, toY & 15, toZ); ++ final int toBlock = toSection.getBlock(sectionLocalIndex); ++ ++ if (toSection.isLeaf(toBlock)) { ++ final int newDistance = toSection.getDistance(toBlock); ++ if (newDistance > distance) { ++ toSection.setDistance(sectionLocalIndex, toBlock, distance); ++ positionsEqual.add(getIndex(toX, toY, toZ)); ++ } ++ } ++ } ++ } ++ } ++ ++ // done updating blocks, now just update the blockstates and palette ++ for (int i = 0, len = sectionsNBT.size(); i < len; ++i) { ++ final MapType sectionNBT = sectionsNBT.getMap(i); ++ final int y = sectionNBT.getInt("Y"); ++ final LeavesSection section = sections[y]; ++ ++ section.writeInto(sectionNBT); ++ } ++ ++ // if sides changed during process, update it now ++ if (newSides != 0) { ++ MapType upgradeData = level.getMap("UpgradeData"); ++ if (upgradeData == null) { ++ level.setMap("UpgradeData", upgradeData = Types.NBT.createEmptyMap()); ++ } ++ ++ upgradeData.setByte("Sides", (byte)(upgradeData.getByte("Sides") | newSides)); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ public static int getIndex(final int x, final int y, final int z) { ++ return y << 8 | z << 4 | x; ++ } ++ ++ public static int getX(final int index) { ++ return index & 15; ++ } ++ ++ public static int getY(final int index) { ++ return index >> 8 & 255; ++ } ++ ++ public static int getZ(final int index) { ++ return index >> 4 & 15; ++ } ++ ++ public static int getSideMask(final boolean noLeft, final boolean noRight, final boolean noBack, final boolean noForward) { ++ final int ret; ++ ++ if (noBack) { ++ if (noRight) { ++ ret = 2; ++ } else if (noLeft) { ++ ret = 128; ++ } else { ++ ret = 1; ++ } ++ } else if (noForward) { ++ if (noLeft) { ++ ret = 32; ++ } else if (noRight) { ++ ret = 8; ++ } else { ++ ret = 16; ++ } ++ } else if (noRight) { ++ ret = 4; ++ } else if (noLeft) { ++ ret = 64; ++ } else { ++ ret = 0; ++ } ++ ++ return ret; ++ } ++ ++ private V1496() {} ++ ++ public abstract static class Section { ++ protected final ListType palette; ++ protected final int sectionY; ++ protected PackedBitStorage storage; ++ ++ public Section(final MapType section) { ++ this.palette = section.getList("Palette", ObjectType.MAP); ++ this.sectionY = section.getInt("Y"); ++ this.readStorage(section); ++ } ++ ++ protected void readStorage(final MapType section) { ++ if (this.initSkippable()) { ++ this.storage = null; ++ } else { ++ final long[] states = section.getLongs("BlockStates"); ++ final int bits = Math.max(4, DataFixUtils.ceillog2(this.palette.size())); ++ this.storage = new PackedBitStorage(bits, 4096, states); ++ } ++ } ++ ++ public void writeInto(final MapType section) { ++ if (this.isSkippable()) { ++ return; ++ } ++ ++ section.setList("Palette", this.palette); ++ section.setLongs("BlockStates", this.storage.getRaw()); ++ } ++ ++ public boolean isSkippable() { ++ return this.storage == null; ++ } ++ ++ public int getBlock(final int index) { ++ return this.storage.get(index); ++ } ++ ++ protected int getStateId(final String name, final boolean persistent, final int distance) { ++ return LEAVES_TO_ID.getInt(name) << 5 | (persistent ? 16 : 0) | distance; ++ } ++ ++ protected int getSectionY() { ++ return this.sectionY; ++ } ++ ++ protected abstract boolean initSkippable(); ++ } ++ ++ public static final class LeavesSection extends Section { ++ private IntOpenHashSet leaveIds; ++ private IntOpenHashSet logIds; ++ private Int2IntOpenHashMap stateToIdMap; ++ ++ public LeavesSection(final MapType section) { ++ super(section); ++ } ++ ++ @Override ++ protected boolean initSkippable() { ++ this.leaveIds = new IntOpenHashSet(); ++ this.logIds = new IntOpenHashSet(); ++ this.stateToIdMap = new Int2IntOpenHashMap(); ++ this.stateToIdMap.defaultReturnValue(-1); ++ ++ for(int i = 0; i < this.palette.size(); ++i) { ++ final MapType blockState = this.palette.getMap(i); ++ final String name = blockState.getString("Name", ""); ++ if (LEAVES_TO_ID.containsKey(name)) { ++ final MapType properties = blockState.getMap("Properties"); ++ final boolean notDecayable = properties != null && "false".equals(properties.getString("decayable")); ++ ++ this.leaveIds.add(i); ++ this.stateToIdMap.put(this.getStateId(name, notDecayable, 7), i); ++ this.palette.setMap(i, this.makeNewLeafTag(name, notDecayable, 7)); ++ } ++ ++ if (LOGS.contains(name)) { ++ this.logIds.add(i); ++ } ++ } ++ ++ return this.leaveIds.isEmpty() && this.logIds.isEmpty(); ++ } ++ ++ private MapType makeNewLeafTag(final String name, final boolean notDecayable, final int distance) { ++ final MapType properties = Types.NBT.createEmptyMap(); ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setString("Name", name); ++ ret.setMap("Properties", properties); ++ ++ properties.setString("persistent", Boolean.toString(notDecayable)); ++ properties.setString("distance", Integer.toString(distance)); ++ ++ return ret; ++ } ++ ++ public boolean isLog(final int id) { ++ return this.logIds.contains(id); ++ } ++ ++ public boolean isLeaf(final int id) { ++ return this.leaveIds.contains(id); ++ } ++ ++ // only call for logs or leaves, will throw otherwise! ++ private int getDistance(final int id) { ++ if (this.isLog(id)) { ++ return 0; ++ } ++ ++ return Integer.parseInt(this.palette.getMap(id).getMap("Properties").getString("distance")); ++ } ++ ++ private void setDistance(final int index, final int id, final int distance) { ++ final MapType state = this.palette.getMap(id); ++ final String name = state.getString("Name"); ++ final boolean persistent = "true".equals(state.getMap("Properties").getString("persistent")); ++ final int newState = this.getStateId(name, persistent, distance); ++ int newStateId; ++ if ((newStateId = this.stateToIdMap.get(newState)) == -1) { ++ newStateId = this.palette.size(); ++ this.leaveIds.add(newStateId); ++ this.stateToIdMap.put(newState, newStateId); ++ this.palette.addMap(this.makeNewLeafTag(name, persistent, distance)); ++ } ++ ++ if (1 << this.storage.getBits() <= newStateId) { ++ // need to widen storage ++ final PackedBitStorage newStorage = new PackedBitStorage(this.storage.getBits() + 1, 4096); ++ ++ for(int i = 0; i < 4096; ++i) { ++ newStorage.set(i, this.storage.get(i)); ++ } ++ ++ this.storage = newStorage; ++ } ++ ++ this.storage.set(index, newStateId); ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1500.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1500.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3ee4c5cab7e8020b3432ef9f614f92c1dda5606e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1500.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1500 { ++ ++ private static final int VERSION = MCVersions.V18W22C + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("DUMMY", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setBoolean("keepPacked", true); ++ return null; ++ } ++ }); ++ } ++ ++ private V1500() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1501.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1501.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dbfb51b74c54a9a479de49ecb295854fc69aef64 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1501.java +@@ -0,0 +1,78 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterAbstractAdvancementsRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1501 { ++ ++ private static final int VERSION = MCVersions.V1_13_PRE1; ++ ++ private static final Map RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:recipes/brewing/speckled_melon", "minecraft:recipes/brewing/glistering_melon_slice") ++ .put("minecraft:recipes/building_blocks/black_stained_hardened_clay", "minecraft:recipes/building_blocks/black_terracotta") ++ .put("minecraft:recipes/building_blocks/blue_stained_hardened_clay", "minecraft:recipes/building_blocks/blue_terracotta") ++ .put("minecraft:recipes/building_blocks/brown_stained_hardened_clay", "minecraft:recipes/building_blocks/brown_terracotta") ++ .put("minecraft:recipes/building_blocks/cyan_stained_hardened_clay", "minecraft:recipes/building_blocks/cyan_terracotta") ++ .put("minecraft:recipes/building_blocks/gray_stained_hardened_clay", "minecraft:recipes/building_blocks/gray_terracotta") ++ .put("minecraft:recipes/building_blocks/green_stained_hardened_clay", "minecraft:recipes/building_blocks/green_terracotta") ++ .put("minecraft:recipes/building_blocks/light_blue_stained_hardened_clay", "minecraft:recipes/building_blocks/light_blue_terracotta") ++ .put("minecraft:recipes/building_blocks/light_gray_stained_hardened_clay", "minecraft:recipes/building_blocks/light_gray_terracotta") ++ .put("minecraft:recipes/building_blocks/lime_stained_hardened_clay", "minecraft:recipes/building_blocks/lime_terracotta") ++ .put("minecraft:recipes/building_blocks/magenta_stained_hardened_clay", "minecraft:recipes/building_blocks/magenta_terracotta") ++ .put("minecraft:recipes/building_blocks/orange_stained_hardened_clay", "minecraft:recipes/building_blocks/orange_terracotta") ++ .put("minecraft:recipes/building_blocks/pink_stained_hardened_clay", "minecraft:recipes/building_blocks/pink_terracotta") ++ .put("minecraft:recipes/building_blocks/purple_stained_hardened_clay", "minecraft:recipes/building_blocks/purple_terracotta") ++ .put("minecraft:recipes/building_blocks/red_stained_hardened_clay", "minecraft:recipes/building_blocks/red_terracotta") ++ .put("minecraft:recipes/building_blocks/white_stained_hardened_clay", "minecraft:recipes/building_blocks/white_terracotta") ++ .put("minecraft:recipes/building_blocks/yellow_stained_hardened_clay", "minecraft:recipes/building_blocks/yellow_terracotta") ++ .put("minecraft:recipes/building_blocks/acacia_wooden_slab", "minecraft:recipes/building_blocks/acacia_slab") ++ .put("minecraft:recipes/building_blocks/birch_wooden_slab", "minecraft:recipes/building_blocks/birch_slab") ++ .put("minecraft:recipes/building_blocks/dark_oak_wooden_slab", "minecraft:recipes/building_blocks/dark_oak_slab") ++ .put("minecraft:recipes/building_blocks/jungle_wooden_slab", "minecraft:recipes/building_blocks/jungle_slab") ++ .put("minecraft:recipes/building_blocks/oak_wooden_slab", "minecraft:recipes/building_blocks/oak_slab") ++ .put("minecraft:recipes/building_blocks/spruce_wooden_slab", "minecraft:recipes/building_blocks/spruce_slab") ++ .put("minecraft:recipes/building_blocks/brick_block", "minecraft:recipes/building_blocks/bricks") ++ .put("minecraft:recipes/building_blocks/chiseled_stonebrick", "minecraft:recipes/building_blocks/chiseled_stone_bricks") ++ .put("minecraft:recipes/building_blocks/end_bricks", "minecraft:recipes/building_blocks/end_stone_bricks") ++ .put("minecraft:recipes/building_blocks/lit_pumpkin", "minecraft:recipes/building_blocks/jack_o_lantern") ++ .put("minecraft:recipes/building_blocks/magma", "minecraft:recipes/building_blocks/magma_block") ++ .put("minecraft:recipes/building_blocks/melon_block", "minecraft:recipes/building_blocks/melon") ++ .put("minecraft:recipes/building_blocks/mossy_stonebrick", "minecraft:recipes/building_blocks/mossy_stone_bricks") ++ .put("minecraft:recipes/building_blocks/nether_brick", "minecraft:recipes/building_blocks/nether_bricks") ++ .put("minecraft:recipes/building_blocks/pillar_quartz_block", "minecraft:recipes/building_blocks/quartz_pillar") ++ .put("minecraft:recipes/building_blocks/red_nether_brick", "minecraft:recipes/building_blocks/red_nether_bricks") ++ .put("minecraft:recipes/building_blocks/snow", "minecraft:recipes/building_blocks/snow_block") ++ .put("minecraft:recipes/building_blocks/smooth_red_sandstone", "minecraft:recipes/building_blocks/cut_red_sandstone") ++ .put("minecraft:recipes/building_blocks/smooth_sandstone", "minecraft:recipes/building_blocks/cut_sandstone") ++ .put("minecraft:recipes/building_blocks/stonebrick", "minecraft:recipes/building_blocks/stone_bricks") ++ .put("minecraft:recipes/building_blocks/stone_stairs", "minecraft:recipes/building_blocks/cobblestone_stairs") ++ .put("minecraft:recipes/building_blocks/string_to_wool", "minecraft:recipes/building_blocks/white_wool_from_string") ++ .put("minecraft:recipes/decorations/fence", "minecraft:recipes/decorations/oak_fence") ++ .put("minecraft:recipes/decorations/purple_shulker_box", "minecraft:recipes/decorations/shulker_box") ++ .put("minecraft:recipes/decorations/slime", "minecraft:recipes/decorations/slime_block") ++ .put("minecraft:recipes/decorations/snow_layer", "minecraft:recipes/decorations/snow") ++ .put("minecraft:recipes/misc/bone_meal_from_block", "minecraft:recipes/misc/bone_meal_from_bone_block") ++ .put("minecraft:recipes/misc/bone_meal_from_bone", "minecraft:recipes/misc/bone_meal") ++ .put("minecraft:recipes/misc/gold_ingot_from_block", "minecraft:recipes/misc/gold_ingot_from_gold_block") ++ .put("minecraft:recipes/misc/iron_ingot_from_block", "minecraft:recipes/misc/iron_ingot_from_iron_block") ++ .put("minecraft:recipes/redstone/fence_gate", "minecraft:recipes/redstone/oak_fence_gate") ++ .put("minecraft:recipes/redstone/noteblock", "minecraft:recipes/redstone/note_block") ++ .put("minecraft:recipes/redstone/trapdoor", "minecraft:recipes/redstone/oak_trapdoor") ++ .put("minecraft:recipes/redstone/wooden_button", "minecraft:recipes/redstone/oak_button") ++ .put("minecraft:recipes/redstone/wooden_door", "minecraft:recipes/redstone/oak_door") ++ .put("minecraft:recipes/redstone/wooden_pressure_plate", "minecraft:recipes/redstone/oak_pressure_plate") ++ .put("minecraft:recipes/transportation/boat", "minecraft:recipes/transportation/oak_boat") ++ .put("minecraft:recipes/transportation/golden_rail", "minecraft:recipes/transportation/powered_rail") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractAdvancementsRename.register(VERSION, RENAMES::get); ++ } ++ ++ private V1501() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1502.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1502.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cd07718649f0e2ca66f1ec3b0aba81611333ba09 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1502.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.recipe.ConverterAbstractRecipeRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1502 { ++ ++ private static final int VERSION = MCVersions.V1_13_PRE2; ++ ++ private static final Map RECIPES_UPDATES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:acacia_wooden_slab", "minecraft:acacia_slab") ++ .put("minecraft:birch_wooden_slab", "minecraft:birch_slab") ++ .put("minecraft:black_stained_hardened_clay", "minecraft:black_terracotta") ++ .put("minecraft:blue_stained_hardened_clay", "minecraft:blue_terracotta") ++ .put("minecraft:boat", "minecraft:oak_boat") ++ .put("minecraft:bone_meal_from_block", "minecraft:bone_meal_from_bone_block") ++ .put("minecraft:bone_meal_from_bone", "minecraft:bone_meal") ++ .put("minecraft:brick_block", "minecraft:bricks") ++ .put("minecraft:brown_stained_hardened_clay", "minecraft:brown_terracotta") ++ .put("minecraft:chiseled_stonebrick", "minecraft:chiseled_stone_bricks") ++ .put("minecraft:cyan_stained_hardened_clay", "minecraft:cyan_terracotta") ++ .put("minecraft:dark_oak_wooden_slab", "minecraft:dark_oak_slab") ++ .put("minecraft:end_bricks", "minecraft:end_stone_bricks") ++ .put("minecraft:fence_gate", "minecraft:oak_fence_gate") ++ .put("minecraft:fence", "minecraft:oak_fence") ++ .put("minecraft:golden_rail", "minecraft:powered_rail") ++ .put("minecraft:gold_ingot_from_block", "minecraft:gold_ingot_from_gold_block") ++ .put("minecraft:gray_stained_hardened_clay", "minecraft:gray_terracotta") ++ .put("minecraft:green_stained_hardened_clay", "minecraft:green_terracotta") ++ .put("minecraft:iron_ingot_from_block", "minecraft:iron_ingot_from_iron_block") ++ .put("minecraft:jungle_wooden_slab", "minecraft:jungle_slab") ++ .put("minecraft:light_blue_stained_hardened_clay", "minecraft:light_blue_terracotta") ++ .put("minecraft:light_gray_stained_hardened_clay", "minecraft:light_gray_terracotta") ++ .put("minecraft:lime_stained_hardened_clay", "minecraft:lime_terracotta") ++ .put("minecraft:lit_pumpkin", "minecraft:jack_o_lantern") ++ .put("minecraft:magenta_stained_hardened_clay", "minecraft:magenta_terracotta") ++ .put("minecraft:magma", "minecraft:magma_block") ++ .put("minecraft:melon_block", "minecraft:melon") ++ .put("minecraft:mossy_stonebrick", "minecraft:mossy_stone_bricks") ++ .put("minecraft:noteblock", "minecraft:note_block") ++ .put("minecraft:oak_wooden_slab", "minecraft:oak_slab") ++ .put("minecraft:orange_stained_hardened_clay", "minecraft:orange_terracotta") ++ .put("minecraft:pillar_quartz_block", "minecraft:quartz_pillar") ++ .put("minecraft:pink_stained_hardened_clay", "minecraft:pink_terracotta") ++ .put("minecraft:purple_shulker_box", "minecraft:shulker_box") ++ .put("minecraft:purple_stained_hardened_clay", "minecraft:purple_terracotta") ++ .put("minecraft:red_nether_brick", "minecraft:red_nether_bricks") ++ .put("minecraft:red_stained_hardened_clay", "minecraft:red_terracotta") ++ .put("minecraft:slime", "minecraft:slime_block") ++ .put("minecraft:smooth_red_sandstone", "minecraft:cut_red_sandstone") ++ .put("minecraft:smooth_sandstone", "minecraft:cut_sandstone") ++ .put("minecraft:snow_layer", "minecraft:snow") ++ .put("minecraft:snow", "minecraft:snow_block") ++ .put("minecraft:speckled_melon", "minecraft:glistering_melon_slice") ++ .put("minecraft:spruce_wooden_slab", "minecraft:spruce_slab") ++ .put("minecraft:stonebrick", "minecraft:stone_bricks") ++ .put("minecraft:stone_stairs", "minecraft:cobblestone_stairs") ++ .put("minecraft:string_to_wool", "minecraft:white_wool_from_string") ++ .put("minecraft:trapdoor", "minecraft:oak_trapdoor") ++ .put("minecraft:white_stained_hardened_clay", "minecraft:white_terracotta") ++ .put("minecraft:wooden_button", "minecraft:oak_button") ++ .put("minecraft:wooden_door", "minecraft:oak_door") ++ .put("minecraft:wooden_pressure_plate", "minecraft:oak_pressure_plate") ++ .put("minecraft:yellow_stained_hardened_clay", "minecraft:yellow_terracotta") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractRecipeRename.register(VERSION, RECIPES_UPDATES::get); ++ } ++ ++ private V1502() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1506.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1506.java +new file mode 100644 +index 0000000000000000000000000000000000000000..36e32a8ff987e4006784c5cba369c736903fa222 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1506.java +@@ -0,0 +1,221 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import ca.spottedleaf.dataconverter.types.json.JsonMapType; ++import ca.spottedleaf.dataconverter.types.json.JsonTypeUtil; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import com.google.common.base.Splitter; ++import com.google.common.collect.ImmutableMap; ++import com.google.common.collect.Lists; ++import com.google.common.collect.Maps; ++import com.google.gson.JsonParser; ++import com.mojang.datafixers.util.Pair; ++import com.mojang.serialization.Dynamic; ++import com.mojang.serialization.DynamicOps; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.NbtOps; ++import net.minecraft.nbt.Tag; ++import net.minecraft.util.GsonHelper; ++import java.util.ArrayList; ++import java.util.Collections; ++import java.util.HashMap; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Locale; ++import java.util.Map; ++import java.util.stream.Collectors; ++ ++public final class V1506 { ++ ++ private static final int VERSION = MCVersions.V1_13_PRE4 + 2; ++ ++ static final Map MAP = new HashMap<>(); ++ static { ++ MAP.put("0", "minecraft:ocean"); ++ MAP.put("1", "minecraft:plains"); ++ MAP.put("2", "minecraft:desert"); ++ MAP.put("3", "minecraft:mountains"); ++ MAP.put("4", "minecraft:forest"); ++ MAP.put("5", "minecraft:taiga"); ++ MAP.put("6", "minecraft:swamp"); ++ MAP.put("7", "minecraft:river"); ++ MAP.put("8", "minecraft:nether"); ++ MAP.put("9", "minecraft:the_end"); ++ MAP.put("10", "minecraft:frozen_ocean"); ++ MAP.put("11", "minecraft:frozen_river"); ++ MAP.put("12", "minecraft:snowy_tundra"); ++ MAP.put("13", "minecraft:snowy_mountains"); ++ MAP.put("14", "minecraft:mushroom_fields"); ++ MAP.put("15", "minecraft:mushroom_field_shore"); ++ MAP.put("16", "minecraft:beach"); ++ MAP.put("17", "minecraft:desert_hills"); ++ MAP.put("18", "minecraft:wooded_hills"); ++ MAP.put("19", "minecraft:taiga_hills"); ++ MAP.put("20", "minecraft:mountain_edge"); ++ MAP.put("21", "minecraft:jungle"); ++ MAP.put("22", "minecraft:jungle_hills"); ++ MAP.put("23", "minecraft:jungle_edge"); ++ MAP.put("24", "minecraft:deep_ocean"); ++ MAP.put("25", "minecraft:stone_shore"); ++ MAP.put("26", "minecraft:snowy_beach"); ++ MAP.put("27", "minecraft:birch_forest"); ++ MAP.put("28", "minecraft:birch_forest_hills"); ++ MAP.put("29", "minecraft:dark_forest"); ++ MAP.put("30", "minecraft:snowy_taiga"); ++ MAP.put("31", "minecraft:snowy_taiga_hills"); ++ MAP.put("32", "minecraft:giant_tree_taiga"); ++ MAP.put("33", "minecraft:giant_tree_taiga_hills"); ++ MAP.put("34", "minecraft:wooded_mountains"); ++ MAP.put("35", "minecraft:savanna"); ++ MAP.put("36", "minecraft:savanna_plateau"); ++ MAP.put("37", "minecraft:badlands"); ++ MAP.put("38", "minecraft:wooded_badlands_plateau"); ++ MAP.put("39", "minecraft:badlands_plateau"); ++ MAP.put("40", "minecraft:small_end_islands"); ++ MAP.put("41", "minecraft:end_midlands"); ++ MAP.put("42", "minecraft:end_highlands"); ++ MAP.put("43", "minecraft:end_barrens"); ++ MAP.put("44", "minecraft:warm_ocean"); ++ MAP.put("45", "minecraft:lukewarm_ocean"); ++ MAP.put("46", "minecraft:cold_ocean"); ++ MAP.put("47", "minecraft:deep_warm_ocean"); ++ MAP.put("48", "minecraft:deep_lukewarm_ocean"); ++ MAP.put("49", "minecraft:deep_cold_ocean"); ++ MAP.put("50", "minecraft:deep_frozen_ocean"); ++ MAP.put("127", "minecraft:the_void"); ++ MAP.put("129", "minecraft:sunflower_plains"); ++ MAP.put("130", "minecraft:desert_lakes"); ++ MAP.put("131", "minecraft:gravelly_mountains"); ++ MAP.put("132", "minecraft:flower_forest"); ++ MAP.put("133", "minecraft:taiga_mountains"); ++ MAP.put("134", "minecraft:swamp_hills"); ++ MAP.put("140", "minecraft:ice_spikes"); ++ MAP.put("149", "minecraft:modified_jungle"); ++ MAP.put("151", "minecraft:modified_jungle_edge"); ++ MAP.put("155", "minecraft:tall_birch_forest"); ++ MAP.put("156", "minecraft:tall_birch_hills"); ++ MAP.put("157", "minecraft:dark_forest_hills"); ++ MAP.put("158", "minecraft:snowy_taiga_mountains"); ++ MAP.put("160", "minecraft:giant_spruce_taiga"); ++ MAP.put("161", "minecraft:giant_spruce_taiga_hills"); ++ MAP.put("162", "minecraft:modified_gravelly_mountains"); ++ MAP.put("163", "minecraft:shattered_savanna"); ++ MAP.put("164", "minecraft:shattered_savanna_plateau"); ++ MAP.put("165", "minecraft:eroded_badlands"); ++ MAP.put("166", "minecraft:modified_wooded_badlands_plateau"); ++ MAP.put("167", "minecraft:modified_badlands_plateau"); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.LEVEL.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String generatorOptions = data.getString("generatorOptions"); ++ final String generatorName = data.getString("generatorName"); ++ if ("flat".equalsIgnoreCase(generatorName)) { ++ data.setMap("generatorOptions", V1506.convert(generatorOptions == null ? "" : generatorOptions)); ++ } else if ("buffet".equalsIgnoreCase(generatorName) && generatorOptions != null) { ++ data.setGeneric("generatorOptions", Types.JSON.convertFromBaseToGeneric(JsonParser.parseString(generatorOptions), data.getTypeUtil())); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private static MapType convert(final String param0) { ++ final Dynamic dynamic = convert(param0, NbtOps.INSTANCE); ++ ++ return new NBTMapType((CompoundTag)dynamic.getValue()); ++ } ++ ++ // Yeah I ain't touching that. This is basically magic value hell. ++ private static Dynamic convert(final String generatorSettings, final DynamicOps ops) { ++ final Iterator splitSettings = Splitter.on(';').split(generatorSettings).iterator(); ++ String biome = "minecraft:plains"; ++ final Map> structures = Maps.newHashMap(); ++ final List> layers; ++ if (!generatorSettings.isEmpty() && splitSettings.hasNext()) { ++ layers = getLayersInfoFromString(splitSettings.next()); ++ if (!layers.isEmpty()) { ++ // biome is next ++ if (splitSettings.hasNext()) { ++ biome = MAP.getOrDefault(splitSettings.next(), "minecraft:plains"); ++ } ++ ++ // structures is next ++ if (splitSettings.hasNext()) { ++ final String[] structuresSplit = splitSettings.next().toLowerCase(Locale.ROOT).split(","); ++ ++ for (final String structureString : structuresSplit) { ++ final String[] structureInfo = structureString.split("\\(", 2); ++ if (!structureInfo[0].isEmpty()) { ++ structures.put(structureInfo[0], Maps.newHashMap()); ++ if (structureInfo.length > 1 && structureInfo[1].endsWith(")") && structureInfo[1].length() > 1) { ++ // I can't even guess the mappings for these. Not worth my time, it will work regardless of the mappings ++ final String[] var7 = structureInfo[1].substring(0, structureInfo[1].length() - 1).split(" "); ++ ++ for (final String var8 : var7) { ++ String[] var9 = var8.split("=", 2); ++ if (var9.length == 2) { ++ structures.get(structureInfo[0]).put(var9[0], var9[1]); ++ } ++ } ++ } ++ } ++ } ++ } else { ++ structures.put("village", Maps.newHashMap()); ++ } ++ } ++ } else { ++ layers = Lists.newArrayList(); ++ layers.add(Pair.of(1, "minecraft:bedrock")); ++ layers.add(Pair.of(2, "minecraft:dirt")); ++ layers.add(Pair.of(1, "minecraft:grass_block")); ++ structures.put("village", Maps.newHashMap()); ++ } ++ ++ final T layerTag = ops.createList(layers.stream().map((param1x) -> ops.createMap(ImmutableMap.of(ops.createString("height"), ops.createInt(param1x.getFirst()), ops.createString("block"), ops.createString(param1x.getSecond()))))); ++ final T structuresTag = ops.createMap(structures.entrySet().stream().map((param1x) -> Pair.of(ops.createString(param1x.getKey().toLowerCase(Locale.ROOT)), ops.createMap(param1x.getValue().entrySet().stream().map((param1xx) -> Pair.of(ops.createString(param1xx.getKey()), ops.createString(param1xx.getValue()))).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))))).collect(Collectors.toMap(Pair::getFirst, Pair::getSecond))); ++ return new Dynamic<>(ops, ops.createMap(ImmutableMap.of(ops.createString("layers"), layerTag, ops.createString("biome"), ops.createString(biome), ops.createString("structures"), structuresTag))); ++ } ++ ++ private static Pair getLayerInfoFromString(final String layerString) { ++ final String[] split = layerString.split("\\*", 2); ++ int layerCount; ++ if (split.length == 2) { ++ try { ++ layerCount = Integer.parseInt(split[0]); ++ } catch (final NumberFormatException ex) { ++ return null; ++ } ++ } else { ++ layerCount = 1; ++ } ++ ++ final String blockName = split[split.length - 1]; ++ return Pair.of(layerCount, blockName); ++ } ++ ++ private static List> getLayersInfoFromString(final String layersString) { ++ final List> ret = new ArrayList<>(); ++ final String[] layers = layersString.split(","); ++ ++ for (final String layerString : layers) { ++ final Pair layer = getLayerInfoFromString(layerString); ++ if (layer == null) { ++ return Collections.emptyList(); ++ } ++ ++ ret.add(layer); ++ } ++ ++ return ret; ++ } ++ ++ private V1506() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1510.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1510.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dfc9d1e89983c73e06ce3c8a22c29f49af4a935c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1510.java +@@ -0,0 +1,111 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.recipe.ConverterAbstractRecipeRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.stats.ConverterAbstractStatsRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1510 { ++ ++ public static final Map RENAMED_ENTITY_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:commandblock_minecart", "minecraft:command_block_minecart") ++ .put("minecraft:ender_crystal", "minecraft:end_crystal") ++ .put("minecraft:snowman", "minecraft:snow_golem") ++ .put("minecraft:evocation_illager", "minecraft:evoker") ++ .put("minecraft:evocation_fangs", "minecraft:evoker_fangs") ++ .put("minecraft:illusion_illager", "minecraft:illusioner") ++ .put("minecraft:vindication_illager", "minecraft:vindicator") ++ .put("minecraft:villager_golem", "minecraft:iron_golem") ++ .put("minecraft:xp_orb", "minecraft:experience_orb") ++ .put("minecraft:xp_bottle", "minecraft:experience_bottle") ++ .put("minecraft:eye_of_ender_signal", "minecraft:eye_of_ender") ++ .put("minecraft:fireworks_rocket", "minecraft:firework_rocket") ++ .build() ++ ); ++ ++ public static final Map RENAMED_BLOCKS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:portal", "minecraft:nether_portal") ++ .put("minecraft:oak_bark", "minecraft:oak_wood") ++ .put("minecraft:spruce_bark", "minecraft:spruce_wood") ++ .put("minecraft:birch_bark", "minecraft:birch_wood") ++ .put("minecraft:jungle_bark", "minecraft:jungle_wood") ++ .put("minecraft:acacia_bark", "minecraft:acacia_wood") ++ .put("minecraft:dark_oak_bark", "minecraft:dark_oak_wood") ++ .put("minecraft:stripped_oak_bark", "minecraft:stripped_oak_wood") ++ .put("minecraft:stripped_spruce_bark", "minecraft:stripped_spruce_wood") ++ .put("minecraft:stripped_birch_bark", "minecraft:stripped_birch_wood") ++ .put("minecraft:stripped_jungle_bark", "minecraft:stripped_jungle_wood") ++ .put("minecraft:stripped_acacia_bark", "minecraft:stripped_acacia_wood") ++ .put("minecraft:stripped_dark_oak_bark", "minecraft:stripped_dark_oak_wood") ++ .put("minecraft:mob_spawner", "minecraft:spawner") ++ .build() ++ ); ++ ++ public static final Map RENAMED_ITEMS = new HashMap<>( ++ ImmutableMap.builder() ++ .putAll(RENAMED_BLOCKS) ++ .put("minecraft:clownfish", "minecraft:tropical_fish") ++ .put("minecraft:chorus_fruit_popped", "minecraft:popped_chorus_fruit") ++ .put("minecraft:evocation_illager_spawn_egg", "minecraft:evoker_spawn_egg") ++ .put("minecraft:vindication_illager_spawn_egg", "minecraft:vindicator_spawn_egg") ++ .build() ++ ); ++ ++ private static final Map RECIPES_UPDATES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:acacia_bark", "minecraft:acacia_wood") ++ .put("minecraft:birch_bark", "minecraft:birch_wood") ++ .put("minecraft:dark_oak_bark", "minecraft:dark_oak_wood") ++ .put("minecraft:jungle_bark", "minecraft:jungle_wood") ++ .put("minecraft:oak_bark", "minecraft:oak_wood") ++ .put("minecraft:spruce_bark", "minecraft:spruce_wood") ++ .build() ++ ); ++ ++ private static final int VERSION = MCVersions.V1_13_PRE4 + 6; ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, RENAMED_BLOCKS::get); ++ ConverterAbstractItemRename.register(VERSION, RENAMED_ITEMS::get); ++ ConverterAbstractRecipeRename.register(VERSION, RECIPES_UPDATES::get); ++ ++ ConverterAbstractEntityRename.register(VERSION, (String input) -> { ++ if (input.startsWith("minecraft:bred_")) { ++ input = "minecraft:".concat(input.substring("minecraft:bred_".length())); ++ } ++ ++ return RENAMED_ENTITY_IDS.get(input); ++ }); ++ ++ ConverterAbstractStatsRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:swim_one_cm", "minecraft:walk_on_water_one_cm", ++ "minecraft:dive_one_cm", "minecraft:walk_under_water_one_cm" ++ ) ++ )::get); ++ ++ ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:commandblock_minecart", "minecraft:command_block_minecart"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:ender_crystal", "minecraft:end_crystal"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:snowman", "minecraft:snow_golem"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:evocation_illager", "minecraft:evoker"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:evocation_fangs", "minecraft:evoker_fangs"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:illusion_illager", "minecraft:illusioner"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:vindication_illager", "minecraft:vindicator"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:villager_golem", "minecraft:iron_golem"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:xp_orb", "minecraft:experience_orb"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:xp_bottle", "minecraft:experience_bottle"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:eye_of_ender_signal", "minecraft:eye_of_ender"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:fireworks_rocket", "minecraft:firework_rocket"); ++ } ++ ++ private V1510() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1514.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1514.java +new file mode 100644 +index 0000000000000000000000000000000000000000..308c29fece597117694b759b72b5161a43d160cf +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1514.java +@@ -0,0 +1,68 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1514 { ++ ++ private static final int VERSION = MCVersions.V1_13_PRE7 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OBJECTIVE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String displayName = data.getString("DisplayName"); ++ if (displayName == null) { ++ return null; ++ } ++ ++ final String update = ComponentUtils.createPlainTextComponent(displayName); ++ ++ data.setString("DisplayName", update); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TEAM.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String displayName = data.getString("DisplayName"); ++ if (displayName == null) { ++ return null; ++ } ++ ++ final String update = ComponentUtils.createPlainTextComponent(displayName); ++ ++ data.setString("DisplayName", update); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.OBJECTIVE.addStructureConverter(new DataConverter<>(VERSION) { ++ private static String getRenderType(String string) { ++ return string.equals("health") ? "hearts" : "integer"; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String renderType = data.getString("RenderType"); ++ if (renderType != null) { ++ return null; ++ } ++ ++ final String criteriaName = data.getString("CriteriaName", ""); ++ ++ data.setString("RenderType", getRenderType(criteriaName)); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1514() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1515.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1515.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d2093732e06ddccdd8a34bbfcaee6ede3aae96d0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1515.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1515 { ++ ++ private static final int VERSION = MCVersions.V1_13_PRE7 + 2; ++ ++ public static final Map RENAMED_BLOCK_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:tube_coral_fan", "minecraft:tube_coral_wall_fan") ++ .put("minecraft:brain_coral_fan", "minecraft:brain_coral_wall_fan") ++ .put("minecraft:bubble_coral_fan", "minecraft:bubble_coral_wall_fan") ++ .put("minecraft:fire_coral_fan", "minecraft:fire_coral_wall_fan") ++ .put("minecraft:horn_coral_fan", "minecraft:horn_coral_wall_fan") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, RENAMED_BLOCK_IDS::get); ++ } ++ ++ private V1515() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1624.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1624.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d1df382e095032950a1dc4c256b62b39b9fe96a4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1624.java +@@ -0,0 +1,110 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.mojang.logging.LogUtils; ++import it.unimi.dsi.fastutil.ints.IntOpenHashSet; ++import org.slf4j.Logger; ++ ++public final class V1624 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V18W32A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ final IntOpenHashSet positionsToLook = new IntOpenHashSet(); ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final TrappedChestSection section = new TrappedChestSection(sections.getMap(i)); ++ if (section.isSkippable()) { ++ continue; ++ } ++ ++ for (int index = 0; index < 4096; ++index) { ++ if (section.isTrappedChest(section.getBlock(index))) { ++ positionsToLook.add(section.getSectionY() << 12 | index); ++ } ++ } ++ } ++ ++ final int chunkX = level.getInt("xPos"); ++ final int chunkZ = level.getInt("zPos"); ++ ++ final ListType tileEntities = level.getList("TileEntities", ObjectType.MAP); ++ ++ if (tileEntities != null) { ++ for (int i = 0, len = tileEntities.size(); i < len; ++i) { ++ final MapType tile = tileEntities.getMap(i); ++ ++ final int x = tile.getInt("x"); ++ final int y = tile.getInt("y"); ++ final int z = tile.getInt("z"); ++ ++ final int index = V1496.getIndex(x - (chunkX << 4), y, z - (chunkZ << 4)); ++ if (!positionsToLook.contains(index)) { ++ continue; ++ } ++ ++ final String id = tile.getString("id"); ++ if (!"minecraft:chest".equals(id)) { ++ LOGGER.warn("Block Entity ({},{},{}) was expected to be a chest (V1624)", x, y, z); ++ } ++ ++ tile.setString("id", "minecraft:trapped_chest"); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1624() {} ++ ++ public static final class TrappedChestSection extends V1496.Section { ++ ++ private IntOpenHashSet chestIds; ++ ++ public TrappedChestSection(final MapType section) { ++ super(section); ++ } ++ ++ @Override ++ protected boolean initSkippable() { ++ this.chestIds = new IntOpenHashSet(); ++ ++ for (int i = 0; i < this.palette.size(); ++i) { ++ final MapType blockState = this.palette.getMap(i); ++ final String name = blockState.getString("Name"); ++ if ("minecraft:trapped_chest".equals(name)) { ++ this.chestIds.add(i); ++ } ++ } ++ ++ return this.chestIds.isEmpty(); ++ } ++ ++ public boolean isTrappedChest(final int id) { ++ return this.chestIds.contains(id); ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V165.java b/ca/spottedleaf/dataconverter/minecraft/versions/V165.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c4476d08e1c0103a1f0beeb5144061aab01f5077 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V165.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V165 { ++ ++ private static final int VERSION = MCVersions.V1_9_PRE2; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:written_book".equals(data.getString("id"))) { ++ return null; ++ } ++ ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final ListType pages = tag.getList("pages", ObjectType.STRING); ++ if (pages == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = pages.size(); i < len; ++i) { ++ final String page = pages.getString(i); ++ ++ pages.setString(i, ComponentUtils.convertFromLenient(page)); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V165() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1800.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1800.java +new file mode 100644 +index 0000000000000000000000000000000000000000..90967b33222ba7052d036c19cf08ca84a7dc7ef4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1800.java +@@ -0,0 +1,31 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1800 { ++ ++ private static final int VERSION = MCVersions.V1_13_2 + 169; ++ ++ public static final Map RENAMED_ITEM_IDS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:cactus_green", "minecraft:green_dye") ++ .put("minecraft:rose_red", "minecraft:red_dye") ++ .put("minecraft:dandelion_yellow", "minecraft:yellow_dye") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, RENAMED_ITEM_IDS::get); ++ ++ //registerMob("minecraft:panda"); // simple as of 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:pillager", new DataWalkerItemLists("Inventory")); ++ } ++ ++ private V1800() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1801.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1801.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e47ebb269f6e579274e2f1172c9180172e1064f7 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1801.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V1801 { ++ ++ private static final int VERSION = MCVersions.V1_13_2 + 170; ++ ++ public static void register() { ++ //registerMob("minecraft:illager_beast"); // changed to simple in 1.21.5 ++ } ++ ++ private V1801() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1802.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1802.java +new file mode 100644 +index 0000000000000000000000000000000000000000..aeae0c62efa1e189fe4b0da585c8a2a101bb5ede +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1802.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V1802 { ++ ++ private static final int VERSION = MCVersions.V1_13_2 + 171; ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:stone_slab", "minecraft:smooth_stone_slab", ++ "minecraft:sign", "minecraft:oak_sign", "minecraft:wall_sign", "minecraft:oak_wall_sign" ++ ) ++ )::get); ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>(ImmutableMap.of( ++ "minecraft:stone_slab", "minecraft:smooth_stone_slab", ++ "minecraft:sign", "minecraft:oak_sign" ++ ) ++ )::get); ++ } ++ ++ private V1802() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1803.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1803.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e12ae00288dcfc955d205b225dd8c5cf53d7afcb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1803.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V1803 { ++ ++ public static final int VERSION = MCVersions.V1_13_2 + 172; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType display = tag.getMap("display"); ++ ++ if (display == null) { ++ return null; ++ } ++ ++ final ListType lore = display.getList("Lore", ObjectType.STRING); ++ if (lore == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = lore.size(); i < len; ++i) { ++ lore.setString(i, ComponentUtils.createPlainTextComponent(lore.getString(i))); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1803() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1904.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1904.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b4b1bdaddb5a9ee6fc6e1bb6a1df09cbcd6fdf86 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1904.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1904 { ++ ++ private static final int VERSION = MCVersions.V18W43C + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:ocelot", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int catType = data.getInt("CatType"); ++ ++ if (catType == 0) { ++ final String owner = data.getString("Owner"); ++ final String ownerUUID = data.getString("OwnerUUID"); ++ if ((owner != null && owner.length() > 0) || (ownerUUID != null && ownerUUID.length() > 0)) { ++ data.setBoolean("Trusting", true); ++ } ++ } else if (catType > 0 && catType < 4) { ++ data.setString("id", "minecraft:cat"); ++ data.setString("OwnerUUID", data.getString("OwnerUUID", "")); ++ } ++ ++ return null; ++ } ++ }); ++ ++ //registerMob("minecraft:cat"); // changed to simple in 1.21.5 ++ } ++ ++ private V1904() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1905.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1905.java +new file mode 100644 +index 0000000000000000000000000000000000000000..feba11bb1c4c3aeee4dcfbe51f4ca15d35c2d542 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1905.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1905 { ++ ++ private static final int VERSION = MCVersions.V18W43C + 2; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final String status = level.getString("Status"); ++ ++ if ("postprocessed".equals(status)) { ++ level.setString("Status", "fullchunk"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1905() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1906.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1906.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fd60eb21ae8ced56a28b2515bd33a59f1eea44fd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1906.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V1906 { ++ ++ private static final int VERSION = MCVersions.V18W43C + 3; ++ ++ public static void register() { ++ V1458.namedInventory(VERSION, "minecraft:barrel"); ++ V1458.namedInventory(VERSION, "minecraft:smoker"); ++ V1458.namedInventory(VERSION, "minecraft:blast_furnace"); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:lectern", new DataWalkerItems("Book")); ++ } ++ ++ private V1906() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1909.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1909.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ede4d0bfc0fe0e4a3a6fb906037a4c964baac6e6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1909.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++ ++public final class V1909 { ++ ++ private static final int VERSION = MCVersions.V18W45A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:jigsaw", new DataWalkerTypePaths<>(MCTypeRegistry.FLAT_BLOCK_STATE, "final_state")); ++ } ++ ++ private V1909() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1911.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1911.java +new file mode 100644 +index 0000000000000000000000000000000000000000..db9981030c0d4d826ba595d8465825023acfce20 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1911.java +@@ -0,0 +1,49 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V1911 { ++ ++ private static final int VERSION = MCVersions.V18W46A + 1; ++ ++ private static final Map CHUNK_STATUS_REMAP = new HashMap<>( ++ ImmutableMap.builder() ++ .put("structure_references", "empty") ++ .put("biomes", "empty") ++ .put("base", "surface") ++ .put("carved", "carvers") ++ .put("liquid_carved", "liquid_carvers") ++ .put("decorated", "features") ++ .put("lighted", "light") ++ .put("mobs_spawned", "spawn") ++ .put("finalized", "heightmaps") ++ .put("fullchunk", "full") ++ .build() ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final String status = level.getString("Status", "empty"); ++ level.setString("Status", CHUNK_STATUS_REMAP.getOrDefault(status, "empty")); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1911() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fad451b5dd46774fe086f2459ff88077a900a15a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1914.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1914 { ++ ++ private static final int VERSION = MCVersions.V18W48A; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:chest", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String lootTable = data.getString("LootTable"); ++ ++ if ("minecraft:chests/village_blacksmith".equals(lootTable)) { ++ data.setString("LootTable", "minecraft:chests/village/village_weaponsmith"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1914() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1917.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1917.java +new file mode 100644 +index 0000000000000000000000000000000000000000..51c0dee566eb1220c1544591655f30d0f4fd49b8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1917.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1917 { ++ ++ private static final int VERSION = MCVersions.V18W49A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:cat", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getInt("CatType") == 9) { ++ data.setInt("CatType", 10); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V1917() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1918.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1918.java +new file mode 100644 +index 0000000000000000000000000000000000000000..74fab9ff2379fae494f48a19804b154c3162519c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1918.java +@@ -0,0 +1,65 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V1918 { ++ ++ private static final int VERSION = MCVersions.V18W49A + 2; ++ ++ private static String getProfessionString(final int professionId, final int careerId) { ++ if (professionId == 0) { ++ if (careerId == 2) { ++ return "minecraft:fisherman"; ++ } else if (careerId == 3) { ++ return "minecraft:shepherd"; ++ } else { ++ return careerId == 4 ? "minecraft:fletcher" : "minecraft:farmer"; ++ } ++ } else if (professionId == 1) { ++ return careerId == 2 ? "minecraft:cartographer" : "minecraft:librarian"; ++ } else if (professionId == 2) { ++ return "minecraft:cleric"; ++ } else if (professionId == 3) { ++ if (careerId == 2) { ++ return "minecraft:weaponsmith"; ++ } else { ++ return careerId == 3 ? "minecraft:toolsmith" : "minecraft:armorer"; ++ } ++ } else if (professionId == 4) { ++ return careerId == 2 ? "minecraft:leatherworker" : "minecraft:butcher"; ++ } else { ++ return professionId == 5 ? "minecraft:nitwit" : "minecraft:none"; ++ } ++ } ++ ++ public static void register() { ++ final DataConverter converter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int profession = data.getInt("Profession"); ++ final int career = data.getInt("Career"); ++ final int careerLevel = data.getInt("CareerLevel", 1); ++ data.remove("Profession"); ++ data.remove("Career"); ++ data.remove("CareerLevel"); ++ ++ final MapType villagerData = Types.NBT.createEmptyMap(); ++ data.setMap("VillagerData", villagerData); ++ villagerData.setString("type", "minecraft:plains"); ++ villagerData.setString("profession", getProfessionString(profession, career)); ++ villagerData.setInt("level", careerLevel); ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", converter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:zombie_villager", converter); ++ } ++ ++ private V1918() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1920.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1920.java +new file mode 100644 +index 0000000000000000000000000000000000000000..74f06a170cad432383a314b06833f9334a9cbd6c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1920.java +@@ -0,0 +1,75 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public final class V1920 { ++ ++ private static final int VERSION = MCVersions.V18W50A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ final MapType structures = level.getMap("Structures"); ++ if (structures == null) { ++ return null; ++ } ++ ++ final MapType starts = structures.getMap("Starts"); ++ if (starts != null) { ++ final MapType village = starts.getMap("New_Village"); ++ if (village != null) { ++ starts.remove("New_Village"); ++ starts.setMap("Village", village); ++ } else { ++ starts.remove("Village"); ++ } ++ } ++ ++ final MapType references = structures.getMap("References"); ++ if (references != null) { ++ final MapType newVillage = references.getMap("New_Village"); ++ // I believe Mojang had a typo here, removing Village from references only made sense ++ // if the new village didn't exist. DFU removes it whether or not it exists, but still relocates ++ // New_Village to Village first. It doesn't make sense to me to relocate it just to remove it, so it ++ // must be a typo. ++ if (newVillage == null) { ++ references.remove("Village"); ++ } else { ++ references.remove("New_Village"); ++ references.setMap("Village", newVillage); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ ++ if ("minecraft:new_village".equals(NamespaceUtil.correctNamespace(id))) { ++ data.setString("id", "minecraft:village"); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:campfire", new DataWalkerItemLists("Items")); ++ } ++ ++ private V1920() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1925.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1925.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8bc7155c186fdf52cc6c3ff45f04f9374bb9c87e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1925.java +@@ -0,0 +1,35 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V1925 { ++ ++ private static final int VERSION = MCVersions.V19W03C + 1; ++ ++ public static void register() { ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ret.setMap("data", root); ++ ++ return ret; ++ } ++ return null; ++ } ++ }); ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, root.getMap("data"), "banners", "Name", fromVersion, toVersion); ++ return null; ++ }); ++ } ++ ++ private V1925() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1928.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1928.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e43f828bb527e449e5c46c6da8ac980106e4940c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1928.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V1928 { ++ ++ private static final int VERSION = MCVersions.V19W04B + 1; ++ ++ public static void register() { ++ ConverterAbstractEntityRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:illager_beast", "minecraft:ravager" ++ ) ++ )::get); ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:illager_beast_spawn_egg", "minecraft:ravager_spawn_egg" ++ ) ++ )::get); ++ ++ //registerMob("minecraft:ravager"); // changed to simple in 1.21.5 ++ } ++ ++ private V1928() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1929.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1929.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cf63fd07bdb1736f5367d4fd217159d3aa383e6e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1929.java +@@ -0,0 +1,32 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1929 { ++ ++ private static final int VERSION = MCVersions.V19W04B + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:wandering_trader", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.VILLAGER_TRADE, data.getMap("Offers"), "Recipes", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:trader_llama", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, data, "SaddleItem", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, data, "DecorItem", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Items", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private V1929() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1931.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1931.java +new file mode 100644 +index 0000000000000000000000000000000000000000..06f467533d4139886510b61fd8aa6a190d4eb59c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1931.java +@@ -0,0 +1,15 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V1931 { ++ ++ private static final int VERSION = MCVersions.V19W06A; ++ ++ public static void register() { ++ //registerMob("minecraft:fox"); // changed to simple in 1.21.5 ++ } ++ ++ private V1931() {} ++ ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1936.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1936.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c6f99547735f0056609de2fd7c9e69c439c8a271 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1936.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1936 { ++ ++ private static final int VERSION = MCVersions.V19W09A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String chatOpacity = data.getString("chatOpacity"); ++ if (chatOpacity != null) { ++ // Vanilla uses createDouble here, but options is always string -> string. I presume they made ++ // a mistake with this converter. ++ data.setString("textBackgroundOpacity", Double.toString(calculateBackground(chatOpacity))); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private static double calculateBackground(final String opacity) { ++ try { ++ final double d = 0.9D * Double.parseDouble(opacity) + 0.1D; ++ return d / 2.0D; ++ } catch (final NumberFormatException ex) { ++ return 0.5D; ++ } ++ } ++ ++ private V1936() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1946.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1946.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2039be46ea37229b07bbfacb16506db7307cc576 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1946.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V1946 { ++ ++ private static final int VERSION = MCVersions.V19W14B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.POI_CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType sections = Types.NBT.createEmptyMap(); ++ data.setMap("Sections", sections); ++ ++ for (int y = 0; y < 16; ++y) { ++ final String key = Integer.toString(y); ++ final Object records = data.getGeneric(key); ++ ++ if (records == null) { ++ continue; ++ } ++ ++ data.remove(key); ++ ++ final MapType section = Types.NBT.createEmptyMap(); ++ section.setGeneric("Records", records); ++ sections.setMap(key, section); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1946() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1948.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1948.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b879d83bf8fa3b99ecdda552a71b4936ca93e7ce +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1948.java +@@ -0,0 +1,39 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1948 { ++ ++ private static final int VERSION = MCVersions.V1_14_PRE2; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:white_banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType display = tag.getMap("display"); ++ if (display == null) { ++ return null; ++ } ++ ++ final String name = display.getString("Name"); ++ if (name == null) { ++ return null; ++ } ++ ++ display.setString("Name", name.replace("\"translate\":\"block.minecraft.illager_banner\"", "\"translate\":\"block.minecraft.ominous_banner\"")); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1948() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1953.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1953.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3178487686defc7d30afe4f5bc3043da569bafae +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1953.java +@@ -0,0 +1,26 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1953 { ++ ++ private static final int VERSION = MCVersions.V1_14 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String name = data.getString("CustomName"); ++ if (name != null) { ++ data.setString("CustomName", name.replace("\"translate\":\"block.minecraft.illager_banner\"", "\"translate\":\"block.minecraft.ominous_banner\"")); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V1953() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1955.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1955.java +new file mode 100644 +index 0000000000000000000000000000000000000000..701c426b4aa3b35a490ebab734c3d4bd50ea10af +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1955.java +@@ -0,0 +1,93 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import net.minecraft.util.Mth; ++ ++public final class V1955 { ++ ++ private static final int VERSION = MCVersions.V1_14_1_PRE1; ++ ++ private static final int[] LEVEL_XP_THRESHOLDS = new int[] { ++ 0, ++ 10, ++ 50, ++ 100, ++ 150 ++ }; ++ ++ private static int getMinXpPerLevel(final int level) { ++ return LEVEL_XP_THRESHOLDS[Mth.clamp(level - 1, 0, LEVEL_XP_THRESHOLDS.length - 1)]; ++ } ++ ++ private static void addLevel(final MapType data, final int level) { ++ MapType villagerData = data.getMap("VillagerData"); ++ if (villagerData == null) { ++ villagerData = Types.NBT.createEmptyMap(); ++ data.setMap("VillagerData", villagerData); ++ } ++ villagerData.setInt("level", level); ++ } ++ ++ private static void addXpFromLevel(final MapType data, final int level) { ++ data.setInt("Xp", getMinXpPerLevel(level)); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType villagerData = data.getMap("VillagerData"); ++ int level = villagerData == null ? 0 : villagerData.getInt("level"); ++ if (level == 0 || level == 1) { ++ // count recipes ++ final MapType offers = data.getMap("Offers"); ++ final ListType recipes = offers == null ? null : offers.getList("Recipes", ObjectType.MAP); ++ final int recipeCount; ++ if (recipes != null) { ++ recipeCount = recipes.size(); ++ } else { ++ recipeCount = 0; ++ } ++ ++ level = Mth.clamp(recipeCount / 2, 1, 5); ++ if (level > 1) { ++ addLevel(data, level); ++ } ++ } ++ ++ if (!data.hasKey("Xp", ObjectType.NUMBER)) { ++ addXpFromLevel(data, level); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:zombie_villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Number xp = data.getNumber("Xp"); ++ if (xp == null) { ++ final int level; ++ final MapType villagerData = data.getMap("VillagerData"); ++ if (villagerData == null) { ++ level = 1; ++ } else { ++ level = villagerData.getInt("level", 1); ++ } ++ ++ data.setInt("Xp", getMinXpPerLevel(level)); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V1955() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1961.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1961.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e49e4c902c6fa6d5794ac0c22508c96d82c6ff7a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1961.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V1961 { ++ ++ private static final int VERSION = MCVersions.V1_14_2_PRE3 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ level.remove("isLightOn"); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1961() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V1963.java b/ca/spottedleaf/dataconverter/minecraft/versions/V1963.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e13c694cd9a992c0129fdec3a3c90ef3dad1ff17 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V1963.java +@@ -0,0 +1,39 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V1963 { ++ ++ private static final int VERSION = MCVersions.V1_14_2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType gossips = data.getList("Gossips", ObjectType.MAP); ++ if (gossips == null) { ++ return null; ++ } ++ ++ for (int i = 0; i < gossips.size();) { ++ final MapType gossip = gossips.getMap(i); ++ if ("golem".equals(gossip.getString("Type"))) { ++ gossips.remove(i); ++ continue; ++ } ++ ++ ++i; ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V1963() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2100.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2100.java +new file mode 100644 +index 0000000000000000000000000000000000000000..90d2fcf77e746081043a32503049df7b127e00a7 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2100.java +@@ -0,0 +1,47 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterAbstractAdvancementsRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.recipe.ConverterAbstractRecipeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2100 { ++ ++ private static final int VERSION = MCVersions.V1_14_4 + 124; ++ private static final Map RECIPE_RENAMES = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:sugar", "minecraft:sugar_from_sugar_cane" ++ ) ++ ); ++ private static final Map ADVANCEMENT_RENAMES = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:recipes/misc/sugar", "minecraft:recipes/misc/sugar_from_sugar_cane" ++ ) ++ ); ++ ++ public static void register() { ++ ConverterAbstractRecipeRename.register(VERSION, RECIPE_RENAMES::get); ++ ConverterAbstractAdvancementsRename.register(VERSION, ADVANCEMENT_RENAMES::get); ++ ++ //registerMob("minecraft:bee"); // changed in 1.21.5 to simple ++ //registerMob("minecraft:bee_stinger"); // changed in 1.21.5 to simple ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:beehive", (data, fromVersion, toVersion) -> { ++ final ListType bees = data.getList("Bees", ObjectType.MAP); ++ if (bees != null) { ++ for (int i = 0, len = bees.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, bees.getMap(i), "EntityData", fromVersion, toVersion); ++ } ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V2100() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2202.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2202.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ce20aaa8ef06c69ec85ddf0e5bdf17f57fa5ce70 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2202.java +@@ -0,0 +1,49 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2202 { ++ ++ private static final int VERSION = MCVersions.V19W35A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ final int[] oldBiomes = level.getInts("Biomes"); ++ ++ if (oldBiomes == null || oldBiomes.length != 256) { ++ return null; ++ } ++ ++ final int[] newBiomes = new int[1024]; ++ level.setInts("Biomes", newBiomes); ++ ++ for (int i = 0; i < 4; ++i) { ++ for (int j = 0; j < 4; ++j) { ++ int k = (j << 2) + 2; ++ int l = (i << 2) + 2; ++ int m = l << 4 | k; ++ newBiomes[i << 2 | j] = oldBiomes[m]; ++ } ++ } ++ ++ for (int i = 1; i < 64; ++i) { ++ System.arraycopy(newBiomes, 0, newBiomes, i * 16, 16); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2202() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2209.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2209.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7439d0e948f144d93a1fa7b57c2b478a54835d6d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2209.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.poi.ConverterAbstractPOIRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2209 { ++ ++ private static final int VERSION = MCVersions.V19W40A + 1; ++ ++ public static void register() { ++ final Map renamedIds = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:bee_hive", "minecraft:beehive" ++ ) ++ ); ++ ++ ConverterAbstractBlockRename.register(VERSION, renamedIds::get); ++ ConverterAbstractItemRename.register(VERSION, renamedIds::get); ++ ConverterAbstractPOIRename.register(VERSION, renamedIds::get); ++ } ++ ++ private V2209() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2211.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2211.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3b888aadf7f4abfd9feff25aa785d84782d14ba0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2211.java +@@ -0,0 +1,31 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2211 { ++ ++ private static final int VERSION = MCVersions.V19W41A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.hasKey("references", ObjectType.NUMBER)) { ++ return null; ++ } ++ ++ final int references = data.getInt("references"); ++ if (references <= 0) { ++ data.setInt("references", 1); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V2211() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2218.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2218.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3fc4c20e117edd06056145d58d822eb5c2c16e61 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2218.java +@@ -0,0 +1,33 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2218 { ++ ++ private static final int VERSION = MCVersions.V1_15_PRE1; ++ ++ public static void register() { ++ MCTypeRegistry.POI_CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType sections = data.getMap("Sections"); ++ if (sections == null) { ++ return null; ++ } ++ ++ for (final String key : sections.keys()) { ++ final MapType section = sections.getMap(key); ++ ++ section.remove("Valid"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2218() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2501.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2501.java +new file mode 100644 +index 0000000000000000000000000000000000000000..02dec41330c7e463f8b9869752ddae1601ac3763 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2501.java +@@ -0,0 +1,67 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V2501 { ++ ++ private static final int VERSION = MCVersions.V1_15_2 + 271; ++ ++ private static void registerFurnace(final String id) { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, id, (data, fromVersion, toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Items", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "CustomName", fromVersion, toVersion); ++ ++ WalkerUtils.convertKeys(MCTypeRegistry.RECIPE, data, "RecipesUsed", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ public static void register() { ++ final DataConverter converter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int recipesUsedSize = data.getInt("RecipesUsedSize"); ++ data.remove("RecipesUsedSize"); ++ ++ if (recipesUsedSize <= 0) { ++ return null; ++ } ++ ++ final MapType newRecipes = Types.NBT.createEmptyMap(); ++ data.setMap("RecipesUsed", newRecipes); ++ ++ for (int i = 0; i < recipesUsedSize; ++i) { ++ final String recipeKey = data.getString("RecipeLocation" + i); ++ data.remove("RecipeLocation" + i); ++ final int recipeAmount = data.getInt("RecipeAmount" + i); ++ data.remove("RecipeAmount" + i); ++ ++ if (i <= 0 || recipeKey == null) { ++ continue; ++ } ++ ++ newRecipes.setInt(recipeKey, recipeAmount); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:furnace", converter); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:blast_furnace", converter); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:smoker", converter); ++ ++ registerFurnace("minecraft:furnace"); ++ registerFurnace("minecraft:smoker"); ++ registerFurnace("minecraft:blast_furnace"); ++ } ++ ++ private V2501() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2502.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2502.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a2f0495c05e670d100cb90d526c1785ab172b5a2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2502.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2502 { ++ ++ private static final int VERSION = MCVersions.V1_15_2 + 272; ++ ++ public static void register() { ++ //registerMob("minecraft:hoglin"); changed to simple in 1.21.5 ++ } ++ ++ private V2502() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2503.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2503.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a1fca94f01bc9c18de17e4b40a98c57a4f965f7c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2503.java +@@ -0,0 +1,73 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterAbstractAdvancementsRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.google.common.collect.ImmutableMap; ++import com.google.common.collect.ImmutableSet; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V2503 { ++ ++ private static final int VERSION = MCVersions.V1_15_2 + 273; ++ ++ private static final Set WALL_BLOCKS = new HashSet<>( ++ ImmutableSet.of( ++ "minecraft:andesite_wall", ++ "minecraft:brick_wall", ++ "minecraft:cobblestone_wall", ++ "minecraft:diorite_wall", ++ "minecraft:end_stone_brick_wall", ++ "minecraft:granite_wall", ++ "minecraft:mossy_cobblestone_wall", ++ "minecraft:mossy_stone_brick_wall", ++ "minecraft:nether_brick_wall", ++ "minecraft:prismarine_wall", ++ "minecraft:red_nether_brick_wall", ++ "minecraft:red_sandstone_wall", ++ "minecraft:sandstone_wall", ++ "minecraft:stone_brick_wall" ++ ) ++ ); ++ ++ private static void changeWallProperty(final MapType properties, final String path) { ++ final String property = properties.getString(path); ++ if (property != null) { ++ properties.setString(path, "true".equals(property) ? "low" : "none"); ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!WALL_BLOCKS.contains(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ if (properties == null) { ++ return null; ++ } ++ ++ changeWallProperty(properties, "east"); ++ changeWallProperty(properties, "west"); ++ changeWallProperty(properties, "north"); ++ changeWallProperty(properties, "south"); ++ ++ return null; ++ } ++ }); ++ ConverterAbstractAdvancementsRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:recipes/misc/composter", "minecraft:recipes/decorations/composter" ++ ) ++ )::get); ++ } ++ ++ private V2503() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2505.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2505.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c7c4ddf11e841b23c17fc95fdcb878dffecb07d8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2505.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V2505 { ++ ++ private static final int VERSION = MCVersions.V20W06A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType brain = data.getMap("Brain"); ++ if (brain == null) { ++ return null; ++ } ++ ++ final MapType memories = brain.getMap("memories"); ++ if (memories == null) { ++ return null; ++ } ++ ++ for (final String key : memories.keys()) { ++ final Object value = memories.getGeneric(key); ++ ++ final MapType wrapped = Types.NBT.createEmptyMap(); ++ wrapped.setGeneric("value", value); ++ ++ memories.setMap(key, wrapped); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:piglin", new DataWalkerItemLists("Inventory")); ++ } ++ ++ private V2505() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2508.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2508.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f9e9d88e4cca15d2d4fdcbc0dbcae4c35c02284a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2508.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2508 { ++ ++ private static final int VERSION = MCVersions.V20W08A + 1; ++ ++ public static void register() { ++ final Map remap = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:warped_fungi", "minecraft:warped_fungus", ++ "minecraft:crimson_fungi", "minecraft:crimson_fungus" ++ ) ++ ); ++ ++ ConverterAbstractBlockRename.register(VERSION, remap::get); ++ ConverterAbstractItemRename.register(VERSION, remap::get); ++ } ++ ++ private V2508() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2509.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2509.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3c8780f626b10918851a222afd8406d82e3754c0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2509.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2509 { ++ ++ private static final int VERSION = MCVersions.V20W08A + 2; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:zombie_pigman_spawn_egg", "minecraft:zombified_piglin_spawn_egg" ++ ) ++ )::get); ++ ConverterAbstractEntityRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:zombie_pigman", "minecraft:zombified_piglin" ++ ) ++ )::get); ++ ++ //registerMob("minecraft:zombified_piglin"); // changed to simple in 1.21.5 ++ } ++ ++ private V2509() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2511.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2511.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0fe1e7b2c8c6e197c89643da0f2cda9fcf779dff +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2511.java +@@ -0,0 +1,99 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V2511 { ++ ++ private static final int VERSION = MCVersions.V20W09A + 1; ++ ++ private static int[] createUUIDArray(final long most, final long least) { ++ return new int[] { ++ (int)(most >>> 32), ++ (int)most, ++ (int)(least >>> 32), ++ (int)least ++ }; ++ } ++ ++ private static void setUUID(final MapType data, final long most, final long least) { ++ if (most != 0L && least != 0L) { ++ data.setInts("OwnerUUID", createUUIDArray(most, least)); ++ } ++ } ++ ++ public static void register() { ++ final DataConverter throwableConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType owner = data.getMap("owner"); ++ data.remove("owner"); ++ if (owner == null) { ++ return null; ++ } ++ ++ setUUID(data, owner.getLong("M"), owner.getLong("L")); ++ ++ return null; ++ } ++ }; ++ final DataConverter potionConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType potion = data.getMap("Potion"); ++ data.remove("Potion"); ++ ++ data.setMap("Item", potion == null ? Types.NBT.createEmptyMap() : potion); ++ ++ return null; ++ } ++ }; ++ final DataConverter llamaSpitConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType owner = data.getMap("Owner"); ++ data.remove("Owner"); ++ if (owner == null) { ++ return null; ++ } ++ ++ setUUID(data, owner.getLong("OwnerUUIDMost"), owner.getLong("OwnerUUIDLeast")); ++ ++ return null; ++ } ++ }; ++ final DataConverter arrowConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ setUUID(data, data.getLong("OwnerUUIDMost"), data.getLong("OwnerUUIDLeast")); ++ ++ data.remove("OwnerUUIDMost"); ++ data.remove("OwnerUUIDLeast"); ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:egg", throwableConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:ender_pearl", throwableConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:experience_bottle", throwableConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:snowball", throwableConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:potion", throwableConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:potion", potionConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:llama_spit", llamaSpitConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:arrow", arrowConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:spectral_arrow", arrowConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:trident", arrowConverter); ++ ++ // Vanilla uses version step 1, but there's no need to add a step here. ++ // Note: Originally we have had this walker on step 0, as Vanilla accidentally left this walker out ++ // until 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:potion", new DataWalkerItems("Item")); ++ } ++ ++ private V2511() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2514.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2514.java +new file mode 100644 +index 0000000000000000000000000000000000000000..167109fb53b45901e944ae3eb4a690956fe18e8f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2514.java +@@ -0,0 +1,590 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.collect.Sets; ++import java.util.Set; ++import java.util.UUID; ++ ++public final class V2514 { ++ ++ private static final int VERSION = MCVersions.V20W11A + 1; ++ ++ private static final Set ABSTRACT_HORSES = Sets.newHashSet(); ++ private static final Set TAMEABLE_ANIMALS = Sets.newHashSet(); ++ private static final Set ANIMALS = Sets.newHashSet(); ++ private static final Set MOBS = Sets.newHashSet(); ++ private static final Set LIVING_ENTITIES = Sets.newHashSet(); ++ private static final Set PROJECTILES = Sets.newHashSet(); ++ static { ++ ABSTRACT_HORSES.add("minecraft:donkey"); ++ ABSTRACT_HORSES.add("minecraft:horse"); ++ ABSTRACT_HORSES.add("minecraft:llama"); ++ ABSTRACT_HORSES.add("minecraft:mule"); ++ ABSTRACT_HORSES.add("minecraft:skeleton_horse"); ++ ABSTRACT_HORSES.add("minecraft:trader_llama"); ++ ABSTRACT_HORSES.add("minecraft:zombie_horse"); ++ ++ TAMEABLE_ANIMALS.add("minecraft:cat"); ++ TAMEABLE_ANIMALS.add("minecraft:parrot"); ++ TAMEABLE_ANIMALS.add("minecraft:wolf"); ++ ++ ANIMALS.add("minecraft:bee"); ++ ANIMALS.add("minecraft:chicken"); ++ ANIMALS.add("minecraft:cow"); ++ ANIMALS.add("minecraft:fox"); ++ ANIMALS.add("minecraft:mooshroom"); ++ ANIMALS.add("minecraft:ocelot"); ++ ANIMALS.add("minecraft:panda"); ++ ANIMALS.add("minecraft:pig"); ++ ANIMALS.add("minecraft:polar_bear"); ++ ANIMALS.add("minecraft:rabbit"); ++ ANIMALS.add("minecraft:sheep"); ++ ANIMALS.add("minecraft:turtle"); ++ ANIMALS.add("minecraft:hoglin"); ++ ++ MOBS.add("minecraft:bat"); ++ MOBS.add("minecraft:blaze"); ++ MOBS.add("minecraft:cave_spider"); ++ MOBS.add("minecraft:cod"); ++ MOBS.add("minecraft:creeper"); ++ MOBS.add("minecraft:dolphin"); ++ MOBS.add("minecraft:drowned"); ++ MOBS.add("minecraft:elder_guardian"); ++ MOBS.add("minecraft:ender_dragon"); ++ MOBS.add("minecraft:enderman"); ++ MOBS.add("minecraft:endermite"); ++ MOBS.add("minecraft:evoker"); ++ MOBS.add("minecraft:ghast"); ++ MOBS.add("minecraft:giant"); ++ MOBS.add("minecraft:guardian"); ++ MOBS.add("minecraft:husk"); ++ MOBS.add("minecraft:illusioner"); ++ MOBS.add("minecraft:magma_cube"); ++ MOBS.add("minecraft:pufferfish"); ++ MOBS.add("minecraft:zombified_piglin"); ++ MOBS.add("minecraft:salmon"); ++ MOBS.add("minecraft:shulker"); ++ MOBS.add("minecraft:silverfish"); ++ MOBS.add("minecraft:skeleton"); ++ MOBS.add("minecraft:slime"); ++ MOBS.add("minecraft:snow_golem"); ++ MOBS.add("minecraft:spider"); ++ MOBS.add("minecraft:squid"); ++ MOBS.add("minecraft:stray"); ++ MOBS.add("minecraft:tropical_fish"); ++ MOBS.add("minecraft:vex"); ++ MOBS.add("minecraft:villager"); ++ MOBS.add("minecraft:iron_golem"); ++ MOBS.add("minecraft:vindicator"); ++ MOBS.add("minecraft:pillager"); ++ MOBS.add("minecraft:wandering_trader"); ++ MOBS.add("minecraft:witch"); ++ MOBS.add("minecraft:wither"); ++ MOBS.add("minecraft:wither_skeleton"); ++ MOBS.add("minecraft:zombie"); ++ MOBS.add("minecraft:zombie_villager"); ++ MOBS.add("minecraft:phantom"); ++ MOBS.add("minecraft:ravager"); ++ MOBS.add("minecraft:piglin"); ++ ++ LIVING_ENTITIES.add("minecraft:armor_stand"); ++ ++ PROJECTILES.add("minecraft:arrow"); ++ PROJECTILES.add("minecraft:dragon_fireball"); ++ PROJECTILES.add("minecraft:firework_rocket"); ++ PROJECTILES.add("minecraft:fireball"); ++ PROJECTILES.add("minecraft:llama_spit"); ++ PROJECTILES.add("minecraft:small_fireball"); ++ PROJECTILES.add("minecraft:snowball"); ++ PROJECTILES.add("minecraft:spectral_arrow"); ++ PROJECTILES.add("minecraft:egg"); ++ PROJECTILES.add("minecraft:ender_pearl"); ++ PROJECTILES.add("minecraft:experience_bottle"); ++ PROJECTILES.add("minecraft:potion"); ++ PROJECTILES.add("minecraft:trident"); ++ PROJECTILES.add("minecraft:wither_skull"); ++ } ++ ++ static int[] createUUIDArray(final long most, final long least) { ++ return new int[] { ++ (int)(most >>> 32), ++ (int)most, ++ (int)(least >>> 32), ++ (int)least ++ }; ++ } ++ ++ static int[] createUUIDFromString(final MapType data, final String path) { ++ if (data == null) { ++ return null; ++ } ++ ++ final String uuidString = data.getString(path); ++ if (uuidString == null) { ++ return null; ++ } ++ ++ try { ++ final UUID uuid = UUID.fromString(uuidString); ++ return createUUIDArray(uuid.getMostSignificantBits(), uuid.getLeastSignificantBits()); ++ } catch (final IllegalArgumentException ignore) { ++ return null; ++ } ++ } ++ ++ static int[] createUUIDFromLongs(final MapType data, final String most, final String least) { ++ if (data == null) { ++ return null; ++ } ++ ++ final long mostBits = data.getLong(most); ++ final long leastBits = data.getLong(least); ++ ++ return (mostBits != 0 || leastBits != 0) ? createUUIDArray(mostBits, leastBits) : null; ++ } ++ ++ static void replaceUUIDString(final MapType data, final String oldPath, final String newPath) { ++ final int[] newUUID = createUUIDFromString(data, oldPath); ++ if (newUUID != null) { ++ data.remove(oldPath); ++ data.setInts(newPath, newUUID); ++ } ++ } ++ ++ static void replaceUUIDMLTag(final MapType data, final String oldPath, final String newPath) { ++ final int[] uuid = createUUIDFromLongs(data.getMap(oldPath), "M", "L"); ++ if (uuid != null) { ++ data.remove(oldPath); ++ data.setInts(newPath, uuid); ++ } ++ } ++ ++ static void replaceUUIDLeastMost(final MapType data, final String prefix, final String newPath) { ++ final String mostPath = prefix.concat("Most"); ++ final String leastPath = prefix.concat("Least"); ++ ++ final int[] uuid = createUUIDFromLongs(data, mostPath, leastPath); ++ if (uuid != null) { ++ data.remove(mostPath); ++ data.remove(leastPath); ++ data.setInts(newPath, uuid); ++ } ++ } ++ ++ private static void updatePiglin(final MapType data) { ++ final MapType brain = data.getMap("Brain"); ++ if (brain == null) { ++ return; ++ } ++ ++ final MapType memories = brain.getMap("memories"); ++ if (memories == null) { ++ return; ++ } ++ ++ final MapType angryAt = memories.getMap("minecraft:angry_at"); ++ ++ replaceUUIDString(angryAt, "value", "value"); ++ } ++ ++ private static void updateEvokerFangs(final MapType data) { ++ replaceUUIDLeastMost(data, "OwnerUUID", "Owner"); ++ } ++ ++ private static void updateZombieVillager(final MapType data) { ++ replaceUUIDLeastMost(data, "ConversionPlayer", "ConversionPlayer"); ++ } ++ ++ private static void updateAreaEffectCloud(final MapType data) { ++ replaceUUIDLeastMost(data, "OwnerUUID", "Owner"); ++ } ++ ++ private static void updateShulkerBullet(final MapType data) { ++ replaceUUIDMLTag(data, "Owner", "Owner"); ++ replaceUUIDMLTag(data, "Target", "Target"); ++ } ++ ++ private static void updateItem(final MapType data) { ++ replaceUUIDMLTag(data, "Owner", "Owner"); ++ replaceUUIDMLTag(data, "Thrower", "Thrower"); ++ } ++ ++ private static void updateFox(final MapType data) { ++ final ListType trustedUUIDS = data.getList("TrustedUUIDs", ObjectType.MAP); ++ if (trustedUUIDS == null) { ++ return; ++ } ++ ++ final ListType newUUIDs = Types.NBT.createEmptyList(); ++ data.remove("TrustedUUIDs"); ++ data.setList("Trusted", newUUIDs); ++ ++ for (int i = 0, len = trustedUUIDS.size(); i < len; ++i) { ++ final MapType uuid = trustedUUIDS.getMap(i); ++ final int[] newUUID = createUUIDFromLongs(uuid, "M", "L"); ++ if (newUUID != null) { ++ newUUIDs.addIntArray(newUUID); ++ } ++ } ++ } ++ ++ private static void updateHurtBy(final MapType data) { ++ replaceUUIDString(data, "HurtBy", "HurtBy"); ++ } ++ ++ private static void updateAnimalOwner(final MapType data) { ++ updateAnimal(data); ++ ++ replaceUUIDString(data, "OwnerUUID", "Owner"); ++ } ++ ++ private static void updateAnimal(final MapType data) { ++ updateMob(data); ++ ++ replaceUUIDLeastMost(data, "LoveCause", "LoveCause"); ++ } ++ ++ private static void updateMob(final MapType data) { ++ updateLivingEntity(data); ++ ++ final MapType leash = data.getMap("Leash"); ++ if (leash == null) { ++ return; ++ } ++ ++ replaceUUIDLeastMost(leash, "UUID", "UUID"); ++ } ++ ++ private static void updateLivingEntity(final MapType data) { ++ final ListType attributes = data.getList("Attributes", ObjectType.MAP); ++ if (attributes == null) { ++ return; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ final MapType attribute = attributes.getMap(i); ++ ++ final ListType modifiers = attribute.getList("Modifiers", ObjectType.MAP); ++ if (modifiers == null) { ++ continue; ++ } ++ ++ for (int k = 0; k < modifiers.size(); ++k) { ++ replaceUUIDLeastMost(modifiers.getMap(k), "UUID", "UUID"); ++ } ++ } ++ } ++ ++ private static void updateProjectile(final MapType data) { ++ final Object ownerUUID = data.getGeneric("OwnerUUID"); ++ if (ownerUUID != null) { ++ data.remove("OwnerUUID"); ++ data.setGeneric("Owner", ownerUUID); ++ } ++ } ++ ++ private static void updateEntityUUID(final MapType data) { ++ replaceUUIDLeastMost(data, "UUID", "UUID"); ++ } ++ ++ public static void register() { ++ // Entity UUID fixes ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateEntityUUID(data); ++ return null; ++ } ++ }); ++ ++ final DataConverter animalOwnerConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateAnimalOwner(data); ++ return null; ++ } ++ }; ++ final DataConverter animalConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateAnimal(data); ++ return null; ++ } ++ }; ++ final DataConverter mobConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateMob(data); ++ return null; ++ } ++ }; ++ final DataConverter livingEntityConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateLivingEntity(data); ++ return null; ++ } ++ }; ++ final DataConverter projectileConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateProjectile(data); ++ return null; ++ } ++ }; ++ for (final String id : ABSTRACT_HORSES) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, animalOwnerConverter); ++ } ++ for (final String id : TAMEABLE_ANIMALS) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, animalOwnerConverter); ++ } ++ for (final String id : ANIMALS) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, animalConverter); ++ } ++ for (final String id : MOBS) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, mobConverter); ++ } ++ for (final String id : LIVING_ENTITIES) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, livingEntityConverter); ++ } ++ for (final String id : PROJECTILES) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, projectileConverter); ++ } ++ ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:bee", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateHurtBy(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:zombified_piglin", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateHurtBy(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:fox", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateFox(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:item", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateItem(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:shulker_bullet", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateShulkerBullet(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:area_effect_cloud", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateAreaEffectCloud(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:zombie_villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateZombieVillager(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:evoker_fangs", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateEvokerFangs(data); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:piglin", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updatePiglin(data); ++ return null; ++ } ++ }); ++ ++ ++ // Update TE ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:conduit", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ replaceUUIDMLTag(data, "target_uuid", "Target"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:skull", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType owner = data.getMap("Owner"); ++ if (owner == null) { ++ return null; ++ } ++ ++ data.remove("Owner"); ++ ++ replaceUUIDString(owner, "Id", "Id"); ++ ++ data.setMap("SkullOwner", owner); ++ ++ return null; ++ } ++ }); ++ ++ // Player UUID ++ MCTypeRegistry.PLAYER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateLivingEntity(data); ++ updateEntityUUID(data); ++ ++ final MapType rootVehicle = data.getMap("RootVehicle"); ++ if (rootVehicle == null) { ++ return null; ++ } ++ ++ replaceUUIDLeastMost(rootVehicle, "Attach", "Attach"); ++ ++ return null; ++ } ++ }); ++ ++ // Level.dat ++ MCTypeRegistry.LEVEL.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ replaceUUIDString(data, "WanderingTraderId", "WanderingTraderId"); ++ ++ final MapType dimensionData = data.getMap("DimensionData"); ++ if (dimensionData != null) { ++ for (final String key : dimensionData.keys()) { ++ final MapType dimension = dimensionData.getMap(key); ++ ++ final MapType dragonFight = dimension.getMap("DragonFight"); ++ if (dragonFight == null) { ++ continue; ++ } ++ ++ replaceUUIDLeastMost(dragonFight, "DragonUUID", "Dragon"); ++ } ++ } ++ ++ final MapType customBossEvents = data.getMap("CustomBossEvents"); ++ if (customBossEvents != null) { ++ for (final String key : customBossEvents.keys()) { ++ final MapType customBossEvent = customBossEvents.getMap(key); ++ ++ final ListType players = customBossEvent.getList("Players", ObjectType.MAP); ++ if (players == null) { ++ continue; ++ } ++ ++ final ListType newPlayers = Types.NBT.createEmptyList(); ++ customBossEvent.setList("Players", newPlayers); ++ ++ for (int i = 0, len = players.size(); i < len; ++i) { ++ final int[] newUUID = createUUIDFromLongs(players.getMap(i), "M", "L"); ++ if (newUUID != null) { ++ newPlayers.addIntArray(newUUID); ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.SAVED_DATA_RAIDS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ final ListType raids = data.getList("Raids", ObjectType.MAP); ++ if (raids == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = raids.size(); i < len; ++i) { ++ final MapType raid = raids.getMap(i); ++ ++ final ListType heros = raid.getList("HeroesOfTheVillage", ObjectType.MAP); ++ ++ if (heros == null) { ++ continue; ++ } ++ ++ final ListType newHeros = Types.NBT.createEmptyList(); ++ raid.setList("HeroesOfTheVillage", newHeros); ++ ++ for (int k = 0, klen = heros.size(); k < klen; ++k) { ++ final MapType uuidOld = heros.getMap(i); ++ final int[] uuidNew = createUUIDFromLongs(uuidOld, "UUIDMost", "UUIDLeast"); ++ if (uuidNew != null) { ++ newHeros.addIntArray(uuidNew); ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ updateAttributeModifiers(tag); ++ ++ if ("minecraft:player_head".equals(data.getString("id"))) { ++ updateSkullOwner(tag); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private static void updateAttributeModifiers(final MapType tag) { ++ final ListType attributes = tag.getList("AttributeModifiers", ObjectType.MAP); ++ if (attributes == null) { ++ return; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ replaceUUIDLeastMost(attributes.getMap(i), "UUID", "UUID"); ++ } ++ } ++ ++ private static void updateSkullOwner(final MapType tag) { ++ replaceUUIDString(tag.getMap("SkullOwner"), "Id", "Id"); ++ } ++ ++ private V2514() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2516.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2516.java +new file mode 100644 +index 0000000000000000000000000000000000000000..50f8e258ecc71e2c7e88ae8ccd83494da9ca9dfd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2516.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2516 { ++ ++ private static final int VERSION = MCVersions.V20W12A + 1; ++ ++ public static void register() { ++ final DataConverter gossipUUIDConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType gossips = data.getList("Gossips", ObjectType.MAP); ++ ++ if (gossips == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = gossips.size(); i < len; ++i) { ++ V2514.replaceUUIDLeastMost(gossips.getMap(i), "Target", "Target"); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", gossipUUIDConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:zombie_villager", gossipUUIDConverter); ++ } ++ ++ private V2516() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2518.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2518.java +new file mode 100644 +index 0000000000000000000000000000000000000000..df2c6cd50b2b0bfc062210a48d7e4b25a6cf0cb0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2518.java +@@ -0,0 +1,65 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2518 { ++ ++ private static final int VERSION = MCVersions.V20W12A + 3; ++ ++ private static final Map FACING_RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("down", "down_south") ++ .put("up", "up_north") ++ .put("north", "north_up") ++ .put("south", "south_up") ++ .put("west", "west_up") ++ .put("east", "east_up") ++ .build() ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:jigsaw", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String type = data.getString("attachement_type", "minecraft:empty"); ++ final String pool = data.getString("target_pool", "minecraft:empty"); ++ data.remove("attachement_type"); ++ data.remove("target_pool"); ++ ++ data.setString("name", type); ++ data.setString("target", type); ++ data.setString("pool", pool); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:jigsaw".equals(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ if (properties == null) { ++ return null; ++ } ++ ++ final String facing = properties.getString("facing", "north"); ++ properties.remove("facing"); ++ properties.setString("orientation", FACING_RENAMES.getOrDefault(facing, facing)); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2518() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2519.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2519.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e270ccada1c13a4c71b227cf0096dc3094ceff6f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2519.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2519 { ++ ++ private static final int VERSION = MCVersions.V20W12A + 4; ++ ++ public static void register() { ++ //registerMob("minecraft:strider"); // changed to simple in 1.21.5 ++ } ++ ++ private V2519() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2522.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2522.java +new file mode 100644 +index 0000000000000000000000000000000000000000..89258da61bccb3668730adad70c0383de001a5a3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2522.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2522 { ++ ++ private static final int VERSION = MCVersions.V20W13B + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:zoglin"); // changed to simple in 1.21.5 ++ } ++ ++ private V2522() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7777d83d63dc177f0bac72290ed2e5c3cbd028be +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2523.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractOldAttributesRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2523 { ++ ++ private static final int VERSION = MCVersions.V20W13B + 2; ++ ++ private static final Map RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("generic.maxHealth", "minecraft:generic.max_health") ++ .put("Max Health", "minecraft:generic.max_health") ++ .put("zombie.spawnReinforcements", "minecraft:zombie.spawn_reinforcements") ++ .put("Spawn Reinforcements Chance", "minecraft:zombie.spawn_reinforcements") ++ .put("horse.jumpStrength", "minecraft:horse.jump_strength") ++ .put("Jump Strength", "minecraft:horse.jump_strength") ++ .put("generic.followRange", "minecraft:generic.follow_range") ++ .put("Follow Range", "minecraft:generic.follow_range") ++ .put("generic.knockbackResistance", "minecraft:generic.knockback_resistance") ++ .put("Knockback Resistance", "minecraft:generic.knockback_resistance") ++ .put("generic.movementSpeed", "minecraft:generic.movement_speed") ++ .put("Movement Speed", "minecraft:generic.movement_speed") ++ .put("generic.flyingSpeed", "minecraft:generic.flying_speed") ++ .put("Flying Speed", "minecraft:generic.flying_speed") ++ .put("generic.attackDamage", "minecraft:generic.attack_damage") ++ .put("generic.attackKnockback", "minecraft:generic.attack_knockback") ++ .put("generic.attackSpeed", "minecraft:generic.attack_speed") ++ .put("generic.armorToughness", "minecraft:generic.armor_toughness") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractOldAttributesRename.register(VERSION, RENAMES::get); ++ } ++ ++ private V2523() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2527.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2527.java +new file mode 100644 +index 0000000000000000000000000000000000000000..00268930307bc539e81ba364d66824f4b0a858b1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2527.java +@@ -0,0 +1,123 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.mojang.datafixers.DataFixUtils; ++import net.minecraft.util.Mth; ++ ++public final class V2527 { ++ ++ private static final int VERSION = MCVersions.V20W16A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final ListType palette = section.getList("Palette", ObjectType.MAP); ++ ++ if (palette == null) { ++ continue; ++ } ++ ++ final int bits = Math.max(4, DataFixUtils.ceillog2(palette.size())); ++ ++ if (Mth.isPowerOfTwo(bits)) { ++ // fits perfectly ++ continue; ++ } ++ ++ final long[] states = section.getLongs("BlockStates"); ++ if (states == null) { ++ // wat ++ continue; ++ } ++ ++ section.setLongs("BlockStates", addPadding(4096, bits, states)); ++ } ++ } ++ ++ final MapType heightMaps = level.getMap("Heightmaps"); ++ if (heightMaps != null) { ++ for (final String key : heightMaps.keys()) { ++ final long[] old = heightMaps.getLongs(key); ++ heightMaps.setLongs(key, addPadding(256, 9, old)); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ public static long[] addPadding(final int indices, final int bits, final long[] old) { ++ int k = old.length; ++ if (k == 0) { ++ return old; ++ } else { ++ long l = (1L << bits) - 1L; ++ int m = 64 / bits; ++ int n = (indices + m - 1) / m; ++ long[] padded = new long[n]; ++ int o = 0; ++ int p = 0; ++ long q = 0L; ++ int r = 0; ++ long s = old[0]; ++ long t = k > 1 ? old[1] : 0L; ++ ++ for(int u = 0; u < indices; ++u) { ++ int v = u * bits; ++ int w = v >> 6; ++ int x = (u + 1) * bits - 1 >> 6; ++ int y = v ^ w << 6; ++ if (w != r) { ++ s = t; ++ t = w + 1 < k ? old[w + 1] : 0L; ++ r = w; ++ } ++ ++ long ab; ++ int ac; ++ if (w == x) { ++ ab = s >>> y & l; ++ } else { ++ ac = 64 - y; ++ ab = (s >>> y | t << ac) & l; ++ } ++ ++ ac = p + bits; ++ if (ac >= 64) { ++ padded[o++] = q; ++ q = ab; ++ p = bits; ++ } else { ++ q |= ab << p; ++ p = ac; ++ } ++ } ++ ++ if (q != 0L) { ++ padded[o] = q; ++ } ++ ++ return padded; ++ } ++ } ++ ++ private V2527() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2528.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2528.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e7197d098b3d6269d3a4fd9be0432d85f0504dfd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2528.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2528 { ++ ++ private static final int VERSION = MCVersions.V20W16A + 2; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:soul_fire_torch", "minecraft:soul_torch", ++ "minecraft:soul_fire_lantern", "minecraft:soul_lantern" ++ ) ++ )::get); ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:soul_fire_torch", "minecraft:soul_torch", ++ "minecraft:soul_fire_wall_torch", "minecraft:soul_wall_torch", ++ "minecraft:soul_fire_lantern", "minecraft:soul_lantern" ++ ) ++ )::get); ++ } ++ ++ private V2528() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2529.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2529.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5ea1926080fe5cbf976c3c5886b0e2a2451b252d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2529.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2529 { ++ ++ private static final int VERSION = MCVersions.V20W17A; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:strider", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getBoolean("NoGravity")) { ++ data.setBoolean("NoGravity", false); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V2529() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2531.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2531.java +new file mode 100644 +index 0000000000000000000000000000000000000000..57ceb6e6a67f7fbc94e90c0327da9e353c612877 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2531.java +@@ -0,0 +1,63 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2531 { ++ ++ private static final int VERSION = MCVersions.V20W17A + 2; ++ ++ private static boolean isConnected(final String facing) { ++ return !"none".equals(facing); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:redstone_wire".equals(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ ++ if (properties == null) { ++ return null; ++ } ++ ++ ++ final String east = properties.getString("east", "none"); ++ final String west = properties.getString("west", "none"); ++ final String north = properties.getString("north", "none"); ++ final String south = properties.getString("south", "none"); ++ ++ final boolean connectedX = isConnected(east) || isConnected(west); ++ final boolean connectedZ = isConnected(north) || isConnected(south); ++ ++ final String newEast = !isConnected(east) && !connectedZ ? "side" : east; ++ final String newWest = !isConnected(west) && !connectedZ ? "side" : west; ++ final String newNorth = !isConnected(north) && !connectedX ? "side" : north; ++ final String newSouth = !isConnected(south) && !connectedX ? "side" : south; ++ ++ if (properties.hasKey("east")) { ++ properties.setString("east", newEast); ++ } ++ if (properties.hasKey("west")) { ++ properties.setString("west", newWest); ++ } ++ if (properties.hasKey("north")) { ++ properties.setString("north", newNorth); ++ } ++ if (properties.hasKey("south")) { ++ properties.setString("south", newSouth); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2531() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2533.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2533.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c89985ccfb271f84888dbe7975a0918d7ef7f38a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2533.java +@@ -0,0 +1,42 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2533 { ++ ++ private static final int VERSION = MCVersions.V20W18A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:villager", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType attributes = data.getList("Attributes", ObjectType.MAP); ++ ++ if (attributes == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ final MapType attribute = attributes.getMap(i); ++ ++ if (!"generic.follow_range".equals(attribute.getString("Name"))) { ++ continue; ++ } ++ ++ if (attribute.getDouble("Base") == 16.0) { ++ attribute.setDouble("Base", 48.0); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2533() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2535.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2535.java +new file mode 100644 +index 0000000000000000000000000000000000000000..21d79dfdfc0062bf66a904c66fd1445e953127d6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2535.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2535 { ++ ++ private static final int VERSION = MCVersions.V20W19A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:shulker", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // Mojang uses doubles for whatever reason... rotation is in FLOAT. by using double here ++ // the entity load will just ignore rotation and set it to 0... ++ final ListType rotation = data.getList("Rotation", ObjectType.FLOAT); ++ ++ if (rotation == null || rotation.size() == 0) { ++ return null; ++ } ++ ++ rotation.setFloat(0, rotation.getFloat(0) - 180.0F); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2535() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2537.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2537.java +new file mode 100644 +index 0000000000000000000000000000000000000000..28709ea1eb0e8966321a4a959350778bb2ea5fed +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2537.java +@@ -0,0 +1,61 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2537 { ++ ++ private static final int VERSION = MCVersions.V20W20B; ++ ++ private static void convertDimension(final MapType data, final String path) { ++ if (data == null) { ++ return; ++ } ++ ++ final Number dimension = data.getNumber(path); ++ if (dimension == null) { ++ return; ++ } ++ ++ final String newDimension; ++ switch (dimension.intValue()) { ++ case -1: { ++ newDimension = "minecraft:the_nether"; ++ break; ++ } ++ case 1: { ++ newDimension = "minecraft:the_end"; ++ break; ++ } ++ default: { ++ newDimension = "minecraft:overworld"; ++ break; ++ } ++ } ++ ++ data.setString(path, newDimension); ++ return; ++ } ++ ++ public static void register() { ++ MCTypeRegistry.PLAYER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertDimension(data, "Dimension"); ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ convertDimension(root.getMap("data"), "dimension"); ++ return null; ++ } ++ }); ++ } ++ ++ private V2537() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2538.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2538.java +new file mode 100644 +index 0000000000000000000000000000000000000000..69097398c3d2b8c04d9adefa2268803bcbaffa32 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2538.java +@@ -0,0 +1,43 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2538 { ++ ++ private static final int VERSION = MCVersions.V20W20B + 1; ++ private static final String[] MERGE_KEYS = new String[] { ++ "RandomSeed", ++ "generatorName", ++ "generatorOptions", ++ "generatorVersion", ++ "legacy_custom_options", ++ "MapFeatures", ++ "BonusChest" ++ }; ++ ++ public static void register() { ++ MCTypeRegistry.LEVEL.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType worldGenSettings = data.getOrCreateMap("WorldGenSettings"); ++ ++ for (final String key : MERGE_KEYS) { ++ final Object value = data.getGeneric(key); ++ if (value == null) { ++ continue; ++ } ++ ++ data.remove(key); ++ worldGenSettings.setGeneric(key, value); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2538() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2550.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2550.java +new file mode 100644 +index 0000000000000000000000000000000000000000..704ffd7fb6fa965d573040cb4fa2b32d31921aa3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2550.java +@@ -0,0 +1,346 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.collect.ImmutableMap; ++import org.apache.commons.lang3.math.NumberUtils; ++import java.util.HashMap; ++import java.util.Locale; ++import java.util.Map; ++ ++public final class V2550 { ++ ++ private static final int VERSION = MCVersions.V20W20B + 13; ++ ++ private static final Map DEFAULTS = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:village", new StructureFeatureConfiguration(32, 8, 10387312)) ++ .put("minecraft:desert_pyramid", new StructureFeatureConfiguration(32, 8, 14357617)) ++ .put("minecraft:igloo", new StructureFeatureConfiguration(32, 8, 14357618)) ++ .put("minecraft:jungle_pyramid", new StructureFeatureConfiguration(32, 8, 14357619)) ++ .put("minecraft:swamp_hut", new StructureFeatureConfiguration(32, 8, 14357620)) ++ .put("minecraft:pillager_outpost", new StructureFeatureConfiguration(32, 8, 165745296)) ++ .put("minecraft:monument", new StructureFeatureConfiguration(32, 5, 10387313)) ++ .put("minecraft:endcity", new StructureFeatureConfiguration(20, 11, 10387313)) ++ .put("minecraft:mansion", new StructureFeatureConfiguration(80, 20, 10387319)) ++ .build() ++ ); ++ ++ private static record StructureFeatureConfiguration(int spacing, int separation, int salt) { ++ ++ public MapType serialize() { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setInt("spacing", this.spacing); ++ ret.setInt("separation", this.separation); ++ ret.setInt("salt", this.salt); ++ ++ return ret; ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final long seed = data.getLong("RandomSeed"); ++ String generatorName = data.getString("generatorName"); ++ if (generatorName != null) { ++ generatorName = generatorName.toLowerCase(Locale.ROOT); ++ } ++ String legacyCustomOptions = data.getString("legacy_custom_options"); ++ if (legacyCustomOptions == null) { ++ legacyCustomOptions = "customized".equals(generatorName) ? data.getString("generatorOptions") : null; ++ } ++ ++ final MapType generator; ++ boolean caves = false; ++ ++ if ("customized".equals(generatorName) || generatorName == null) { ++ generator = defaultOverworld(seed); ++ } else { ++ switch (generatorName) { ++ case "flat": { ++ final MapType generatorOptions = data.getMap("generatorOptions"); ++ ++ final MapType structures = fixFlatStructures(generatorOptions); ++ final MapType settings = Types.NBT.createEmptyMap(); ++ generator = Types.NBT.createEmptyMap(); ++ generator.setString("type", "minecraft:flat"); ++ generator.setMap("settings", settings); ++ ++ settings.setMap("structures", structures); ++ ++ ListType layers = generatorOptions.getList("layers", ObjectType.MAP); ++ if (layers == null) { ++ layers = Types.NBT.createEmptyList(); ++ ++ final int[] heights = new int[] { 1, 2, 1 }; ++ final String[] blocks = new String[] { "minecraft:bedrock", "minecraft:dirt", "minecraft:grass_block" }; ++ for (int i = 0; i < 3; ++i) { ++ final MapType layer = Types.NBT.createEmptyMap(); ++ layer.setInt("height", heights[i]); ++ layer.setString("block", blocks[i]); ++ layers.addMap(layer); ++ } ++ } ++ ++ settings.setList("layers", layers); ++ settings.setString("biome", generatorOptions.getString("biome", "minecraft:plains")); ++ ++ break; ++ } ++ ++ case "debug_all_block_states": { ++ generator = Types.NBT.createEmptyMap(); ++ generator.setString("type", "minecraft:debug"); ++ break; ++ } ++ ++ case "buffet": { ++ final MapType generatorOptions = data.getMap("generatorOptions"); ++ final MapType chunkGenerator = generatorOptions == null ? null : generatorOptions.getMap("chunk_generator"); ++ final String chunkGeneratorType = chunkGenerator == null ? null : chunkGenerator.getString("type"); ++ ++ final String newType; ++ if ("minecraft:caves".equals(chunkGeneratorType)) { ++ newType = "minecraft:caves"; ++ caves = true; ++ } else if ("minecraft:floating_islands".equals(chunkGeneratorType)) { ++ newType = "minecraft:floating_islands"; ++ } else { ++ newType = "minecraft:overworld"; ++ } ++ ++ MapType biomeSource = generatorOptions == null ? null : generatorOptions.getMap("biome_source"); ++ if (biomeSource == null) { ++ biomeSource = Types.NBT.createEmptyMap(); ++ biomeSource.setString("type", "minecraft:fixed"); ++ } ++ ++ if ("minecraft:fixed".equals(biomeSource.getString("type"))) { ++ final MapType options = biomeSource.getMap("options"); ++ final ListType biomes = options == null ? null : options.getList("biomes", ObjectType.STRING); ++ final String biome = biomes == null || biomes.size() == 0 ? "minecraft:ocean" : biomes.getString(0); ++ biomeSource.remove("options"); ++ biomeSource.setString("biome", biome); ++ } ++ ++ generator = noise(seed, newType, biomeSource); ++ break; ++ } ++ ++ default: { ++ boolean defaultGen = generatorName.equals("default"); ++ boolean default11Gen = generatorName.equals("default_1_1") || defaultGen && data.getInt("generatorVersion") == 0; ++ boolean amplified = generatorName.equals("amplified"); ++ boolean largeBiomes = generatorName.equals("largebiomes"); ++ ++ generator = noise(seed, amplified ? "minecraft:amplified" : "minecraft:overworld", ++ vanillaBiomeSource(seed, default11Gen, largeBiomes)); ++ break; ++ } ++ } ++ } ++ ++ final boolean mapFeatures = data.getBoolean("MapFeatures", true); ++ final boolean bonusChest = data.getBoolean("BonusChest", false); ++ ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setLong("seed", seed); ++ ret.setBoolean("generate_features", mapFeatures); ++ ret.setBoolean("bonus_chest", bonusChest); ++ ret.setMap("dimensions", vanillaLevels(seed, generator, caves)); ++ if (legacyCustomOptions != null) { ++ ret.setString("legacy_custom_options", legacyCustomOptions); ++ } ++ ++ return ret; ++ } ++ }); ++ } ++ ++ public static MapType noise(final long seed, final String worldType, final MapType biomeSource) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setString("type", "minecraft:noise"); ++ ret.setMap("biome_source", biomeSource); ++ ret.setLong("seed", seed); ++ ret.setString("settings", worldType); ++ ++ return ret; ++ } ++ ++ public static MapType vanillaBiomeSource(final long seed, final boolean default11Gen, final boolean largeBiomes) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setString("type", "minecraft:vanilla_layered"); ++ ret.setLong("seed", seed); ++ ret.setBoolean("large_biomes", largeBiomes); ++ if (default11Gen) { ++ ret.setBoolean("legacy_biome_init_layer", default11Gen); ++ } ++ ++ return ret; ++ } ++ ++ public static MapType fixFlatStructures(final MapType generatorOptions) { ++ int distance = 32; ++ int spread = 3; ++ int count = 128; ++ boolean stronghold = false; ++ final Map newStructures = new HashMap<>(); ++ ++ if (generatorOptions == null) { ++ stronghold = true; ++ newStructures.put("minecraft:village", DEFAULTS.get("minecraft:village")); ++ } ++ ++ final MapType oldStructures = generatorOptions == null ? null : generatorOptions.getMap("structures"); ++ if (oldStructures != null) { ++ for (final String structureName : oldStructures.keys()) { ++ final MapType structureValues = oldStructures.getMap(structureName); ++ if (structureValues == null) { ++ continue; ++ } ++ ++ for (final String structureValueKey : structureValues.keys()) { ++ final String structureValue = structureValues.getString(structureValueKey); ++ ++ if ("stronghold".equals(structureName)) { ++ stronghold = true; ++ switch (structureValueKey) { ++ case "distance": ++ distance = getInt(structureValue, distance, 1); ++ break; ++ case "spread": ++ spread = getInt(structureValue, spread, 1); ++ break; ++ case "count": ++ count = getInt(structureValue, count, 1); ++ break; ++ } ++ } else { ++ switch (structureValueKey) { ++ case "distance": ++ switch (structureName) { ++ case "village": ++ setSpacing(newStructures, "minecraft:village", structureValue, 9); ++ break; ++ case "biome_1": ++ setSpacing(newStructures, "minecraft:desert_pyramid", structureValue, 9); ++ setSpacing(newStructures, "minecraft:igloo", structureValue, 9); ++ setSpacing(newStructures, "minecraft:jungle_pyramid", structureValue, 9); ++ setSpacing(newStructures, "minecraft:swamp_hut", structureValue, 9); ++ setSpacing(newStructures, "minecraft:pillager_outpost", structureValue, 9); ++ break; ++ case "endcity": ++ setSpacing(newStructures, "minecraft:endcity", structureValue, 1); ++ break; ++ case "mansion": ++ setSpacing(newStructures, "minecraft:mansion", structureValue, 1); ++ break; ++ default: ++ break; ++ } ++ case "separation": ++ if ("oceanmonument".equals(structureName)) { ++ final StructureFeatureConfiguration structure = newStructures.getOrDefault("minecraft:monument", DEFAULTS.get("minecraft:monument")); ++ final int newSpacing = getInt(structureValue, structure.separation, 1); ++ newStructures.put("minecraft:monument", new StructureFeatureConfiguration(newSpacing, structure.separation, structure.salt)); ++ } ++ ++ break; ++ case "spacing": ++ if ("oceanmonument".equals(structureName)) { ++ setSpacing(newStructures, "minecraft:monument", structureValue, 1); ++ } ++ ++ break; ++ } ++ } ++ } ++ } ++ } ++ ++ final MapType ret = Types.NBT.createEmptyMap(); ++ final MapType structuresSerialized = Types.NBT.createEmptyMap(); ++ ret.setMap("structures", structuresSerialized); ++ for (final String key : newStructures.keySet()) { ++ structuresSerialized.setMap(key, newStructures.get(key).serialize()); ++ } ++ ++ if (stronghold) { ++ final MapType strongholdData = Types.NBT.createEmptyMap(); ++ ret.setMap("stronghold", strongholdData); ++ ++ strongholdData.setInt("distance", distance); ++ strongholdData.setInt("spread", spread); ++ strongholdData.setInt("count", count); ++ } ++ ++ return ret; ++ } ++ ++ public static MapType vanillaLevels(final long seed, final MapType generator, final boolean caves) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ final MapType overworld = Types.NBT.createEmptyMap(); ++ final MapType nether = Types.NBT.createEmptyMap(); ++ final MapType end = Types.NBT.createEmptyMap(); ++ ++ ret.setMap("minecraft:overworld", overworld); ++ ret.setMap("minecraft:the_nether", nether); ++ ret.setMap("minecraft:the_end", end); ++ ++ // overworld ++ overworld.setString("type", caves ? "minecraft:overworld_caves" : "minecraft:overworld"); ++ overworld.setMap("generator", generator); ++ ++ // nether ++ nether.setString("type", "minecraft:the_nether"); ++ final MapType netherBiomeSource = Types.NBT.createEmptyMap(); ++ netherBiomeSource.setString("type", "minecraft:multi_noise"); ++ netherBiomeSource.setLong("seed", seed); ++ netherBiomeSource.setString("preset", "minecraft:nether"); ++ ++ nether.setMap("generator", noise(seed, "minecraft:nether", netherBiomeSource)); ++ ++ // end ++ end.setString("type", "minecraft:the_end"); ++ final MapType endBiomeSource = Types.NBT.createEmptyMap(); ++ endBiomeSource.setString("type", "minecraft:the_end"); ++ endBiomeSource.setLong("seed", seed); ++ end.setMap("generator", noise(seed,"minecraft:end", endBiomeSource)); ++ ++ return ret; ++ } ++ ++ public static MapType defaultOverworld(final long seed) { ++ return noise(seed, "minecraft:overworld", vanillaBiomeSource(seed, false, false)); ++ } ++ ++ private static int getInt(final String value, final int dfl) { ++ return NumberUtils.toInt(value, dfl); ++ } ++ ++ private static int getInt(final String value, final int dfl, final int minVal) { ++ return Math.max(minVal, getInt(value, dfl)); ++ } ++ ++ private static void setSpacing(final Map structures, final String structureName, ++ final String value, final int minVal) { ++ final StructureFeatureConfiguration structure = structures.getOrDefault(structureName, DEFAULTS.get(structureName)); ++ final int newSpacing = getInt(value, structure.spacing, minVal); ++ ++ structures.put(structureName, new StructureFeatureConfiguration(newSpacing, structure.separation, structure.salt)); ++ } ++ ++ private V2550() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2551.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2551.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8d31193df65ec1abc6aa26c0fd2dd454316c4f60 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2551.java +@@ -0,0 +1,103 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2551 { ++ ++ private static final int VERSION = MCVersions.V20W20B + 14; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ if (dimensions == null) { ++ return null; ++ } ++ ++ for (final String dimension : dimensions.keys()) { ++ final MapType dimensionData = dimensions.getMap(dimension); ++ if (dimensionData == null) { ++ continue; ++ } ++ ++ final MapType generator = dimensionData.getMap("generator"); ++ if (generator == null) { ++ continue; ++ } ++ ++ final String type = generator.getString("type"); ++ if (type == null) { ++ continue; ++ } ++ ++ switch (type) { ++ case "minecraft:flat": { ++ final MapType settings = generator.getMap("settings"); ++ if (settings == null) { ++ continue; ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.BIOME, settings, "biome", fromVersion, toVersion); ++ ++ final ListType layers = settings.getList("layers", ObjectType.MAP); ++ if (layers != null) { ++ for (int i = 0, len = layers.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, layers.getMap(i), "block", fromVersion, toVersion); ++ } ++ } ++ ++ break; ++ } ++ case "minecraft:noise": { ++ final MapType settings = generator.getMap("settings"); ++ if (settings != null) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, settings, "default_block", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, settings, "default_fluid", fromVersion, toVersion); ++ } ++ ++ final MapType biomeSource = generator.getMap("biome_source"); ++ if (biomeSource != null) { ++ final String biomeSourceType = biomeSource.getString("type", ""); ++ switch (biomeSourceType) { ++ case "minecraft:fixed": { ++ WalkerUtils.convert(MCTypeRegistry.BIOME, biomeSource, "biome", fromVersion, toVersion); ++ break; ++ } ++ ++ case "minecraft:multi_noise": { ++ // Vanilla's schema is wrong. It should be DSL.fields("biomes", DSL.list(DSL.fields("biome"))) ++ // But it just contains the list part. That obviously can never be the case, because ++ // the root object is a compound, not a list. ++ ++ final ListType biomes = biomeSource.getList("biomes", ObjectType.MAP); ++ if (biomes != null) { ++ for (int i = 0, len = biomes.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.BIOME, biomes.getMap(i), "biome", fromVersion, toVersion); ++ } ++ } ++ break; ++ } ++ ++ case "minecraft:checkerboard": { ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, biomeSource, "biomes", fromVersion, toVersion); ++ break; ++ } ++ } ++ } ++ ++ break; ++ } ++ } ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V2551() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2552.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2552.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9e6c7dc40d509cf424976831382425ab7eceb024 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2552.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2552 { ++ ++ private static final int VERSION = MCVersions.V20W20B + 15; ++ ++ public static void register() { ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.BIOME, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:nether", "minecraft:nether_wastes" ++ ) ++ )::get); ++ } ++ ++ private V2552() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2553.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2553.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f019774923bf08fc0f7dc7cafd5fb66fdd7427f8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2553.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2553 { ++ ++ private static final int VERSION = MCVersions.V20W20B + 16; ++ ++ public static final Map BIOME_RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:extreme_hills", "minecraft:mountains") ++ .put("minecraft:swampland", "minecraft:swamp") ++ .put("minecraft:hell", "minecraft:nether_wastes") ++ .put("minecraft:sky", "minecraft:the_end") ++ .put("minecraft:ice_flats", "minecraft:snowy_tundra") ++ .put("minecraft:ice_mountains", "minecraft:snowy_mountains") ++ .put("minecraft:mushroom_island", "minecraft:mushroom_fields") ++ .put("minecraft:mushroom_island_shore", "minecraft:mushroom_field_shore") ++ .put("minecraft:beaches", "minecraft:beach") ++ .put("minecraft:forest_hills", "minecraft:wooded_hills") ++ .put("minecraft:smaller_extreme_hills", "minecraft:mountain_edge") ++ .put("minecraft:stone_beach", "minecraft:stone_shore") ++ .put("minecraft:cold_beach", "minecraft:snowy_beach") ++ .put("minecraft:roofed_forest", "minecraft:dark_forest") ++ .put("minecraft:taiga_cold", "minecraft:snowy_taiga") ++ .put("minecraft:taiga_cold_hills", "minecraft:snowy_taiga_hills") ++ .put("minecraft:redwood_taiga", "minecraft:giant_tree_taiga") ++ .put("minecraft:redwood_taiga_hills", "minecraft:giant_tree_taiga_hills") ++ .put("minecraft:extreme_hills_with_trees", "minecraft:wooded_mountains") ++ .put("minecraft:savanna_rock", "minecraft:savanna_plateau") ++ .put("minecraft:mesa", "minecraft:badlands") ++ .put("minecraft:mesa_rock", "minecraft:wooded_badlands_plateau") ++ .put("minecraft:mesa_clear_rock", "minecraft:badlands_plateau") ++ .put("minecraft:sky_island_low", "minecraft:small_end_islands") ++ .put("minecraft:sky_island_medium", "minecraft:end_midlands") ++ .put("minecraft:sky_island_high", "minecraft:end_highlands") ++ .put("minecraft:sky_island_barren", "minecraft:end_barrens") ++ .put("minecraft:void", "minecraft:the_void") ++ .put("minecraft:mutated_plains", "minecraft:sunflower_plains") ++ .put("minecraft:mutated_desert", "minecraft:desert_lakes") ++ .put("minecraft:mutated_extreme_hills", "minecraft:gravelly_mountains") ++ .put("minecraft:mutated_forest", "minecraft:flower_forest") ++ .put("minecraft:mutated_taiga", "minecraft:taiga_mountains") ++ .put("minecraft:mutated_swampland", "minecraft:swamp_hills") ++ .put("minecraft:mutated_ice_flats", "minecraft:ice_spikes") ++ .put("minecraft:mutated_jungle", "minecraft:modified_jungle") ++ .put("minecraft:mutated_jungle_edge", "minecraft:modified_jungle_edge") ++ .put("minecraft:mutated_birch_forest", "minecraft:tall_birch_forest") ++ .put("minecraft:mutated_birch_forest_hills", "minecraft:tall_birch_hills") ++ .put("minecraft:mutated_roofed_forest", "minecraft:dark_forest_hills") ++ .put("minecraft:mutated_taiga_cold", "minecraft:snowy_taiga_mountains") ++ .put("minecraft:mutated_redwood_taiga", "minecraft:giant_spruce_taiga") ++ .put("minecraft:mutated_redwood_taiga_hills", "minecraft:giant_spruce_taiga_hills") ++ .put("minecraft:mutated_extreme_hills_with_trees", "minecraft:modified_gravelly_mountains") ++ .put("minecraft:mutated_savanna", "minecraft:shattered_savanna") ++ .put("minecraft:mutated_savanna_rock", "minecraft:shattered_savanna_plateau") ++ .put("minecraft:mutated_mesa", "minecraft:eroded_badlands") ++ .put("minecraft:mutated_mesa_rock", "minecraft:modified_wooded_badlands_plateau") ++ .put("minecraft:mutated_mesa_clear_rock", "minecraft:modified_badlands_plateau") ++ .put("minecraft:warm_deep_ocean", "minecraft:deep_warm_ocean") ++ .put("minecraft:lukewarm_deep_ocean", "minecraft:deep_lukewarm_ocean") ++ .put("minecraft:cold_deep_ocean", "minecraft:deep_cold_ocean") ++ .put("minecraft:frozen_deep_ocean", "minecraft:deep_frozen_ocean") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.BIOME, BIOME_RENAMES::get); ++ } ++ ++ private V2553() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2558.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2558.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cfb17deec6d53fc99a6562dce1fcc2f6dea8e26b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2558.java +@@ -0,0 +1,48 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.options.ConverterAbstractOptionsRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2558 { ++ ++ private static final int VERSION = MCVersions.V1_16_PRE2 + 1; ++ ++ public static void register() { ++ ConverterAbstractOptionsRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "key_key.swapHands", "key_key.swapOffhand" ++ ) ++ )::get); ++ ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ MapType dimensions = data.getMap("dimensions"); ++ if (dimensions == null) { ++ dimensions = Types.NBT.createEmptyMap(); ++ data.setMap("dimensions", dimensions); ++ } ++ ++ if (dimensions.isEmpty()) { ++ data.setMap("dimensions", recreateSettings(data)); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private static MapType recreateSettings(final MapType data) { ++ final long seed = data.getLong("seed"); ++ ++ return V2550.vanillaLevels(seed, V2550.defaultOverworld(seed), false); ++ } ++ ++ private V2558() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2568.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2568.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a50146d1dba4d62da3bb54a5869ae879f573f0e5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2568.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2568 { ++ ++ private static final int VERSION = MCVersions.V1_16_1 + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:piglin_brute"); // changed to simple in 1.21.5 ++ } ++ ++ private V2568() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2671.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2671.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ad6c4c4427fc17d7ad743115773cb48dad1b415d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2671.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2671 { ++ ++ private static final int VERSION = MCVersions.V1_16_5 + 85; ++ ++ public static void register() { ++ //registerMob("minecraft:goat"); // changed to simple in 1.21.5 ++ } ++ ++ private V2671() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2679.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2679.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f8b0cdc05116ebf07eee98e6288b2d7d9eb0e8b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2679.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2679 { ++ ++ private static final int VERSION = MCVersions.V1_16_5 + 93; ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:cauldron".equals(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ ++ if (properties == null) { ++ return null; ++ } ++ ++ if (properties.getString("level", "0").equals("0")) { ++ data.remove("Properties"); ++ return null; ++ } else { ++ data.setString("Name", "minecraft:water_cauldron"); ++ return null; ++ } ++ } ++ }); ++ } ++ ++ private V2679() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2680.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2680.java +new file mode 100644 +index 0000000000000000000000000000000000000000..87cbe1c717635908a30c57028346a1abeb21e6a6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2680.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2680 { ++ ++ private static final int VERSION = MCVersions.V1_16_5 + 94; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:grass_path", "minecraft:dirt_path" ++ ) ++ )::get); ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:grass_path", "minecraft:dirt_path" ++ ) ++ )::get); ++ } ++ ++ private V2680() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2684.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2684.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0c996642f561d2471a506a34f5efe6dae5cd1fb3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2684.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.game_event.GameEventListenerWalker; ++ ++public final class V2684 { ++ ++ private static final int VERSION = MCVersions.V20W48A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:sculk_sensor", new GameEventListenerWalker()); ++ } ++ ++ private V2684() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2686.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2686.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4cfb211c6e557a7f2a3535c8430049e4c720eae9 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2686.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V2686 { ++ ++ private static final int VERSION = MCVersions.V20W49A + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:axolotl"); // changed to simple in 1.21.5 ++ } ++ ++ private V2686() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2688.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2688.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f971b5284950db483fb9b80599572b27a59755b5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2688.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V2688 { ++ ++ private static final int VERSION = MCVersions.V20W51A + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:glow_squid"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:glow_item_frame", new DataWalkerItems("Item")); ++ } ++ ++ private V2688() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2690.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2690.java +new file mode 100644 +index 0000000000000000000000000000000000000000..39ffcec6e78229dd62abfd42c1ac64c3ccccc6dc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2690.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2690 { ++ ++ private static final int VERSION = MCVersions.V21W05A; ++ ++ private static final Map RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:weathered_copper_block", "minecraft:oxidized_copper_block") ++ .put("minecraft:semi_weathered_copper_block", "minecraft:weathered_copper_block") ++ .put("minecraft:lightly_weathered_copper_block", "minecraft:exposed_copper_block") ++ .put("minecraft:weathered_cut_copper", "minecraft:oxidized_cut_copper") ++ .put("minecraft:semi_weathered_cut_copper", "minecraft:weathered_cut_copper") ++ .put("minecraft:lightly_weathered_cut_copper", "minecraft:exposed_cut_copper") ++ .put("minecraft:weathered_cut_copper_stairs", "minecraft:oxidized_cut_copper_stairs") ++ .put("minecraft:semi_weathered_cut_copper_stairs", "minecraft:weathered_cut_copper_stairs") ++ .put("minecraft:lightly_weathered_cut_copper_stairs", "minecraft:exposed_cut_copper_stairs") ++ .put("minecraft:weathered_cut_copper_slab", "minecraft:oxidized_cut_copper_slab") ++ .put("minecraft:semi_weathered_cut_copper_slab", "minecraft:weathered_cut_copper_slab") ++ .put("minecraft:lightly_weathered_cut_copper_slab", "minecraft:exposed_cut_copper_slab") ++ .put("minecraft:waxed_semi_weathered_copper", "minecraft:waxed_weathered_copper") ++ .put("minecraft:waxed_lightly_weathered_copper", "minecraft:waxed_exposed_copper") ++ .put("minecraft:waxed_semi_weathered_cut_copper", "minecraft:waxed_weathered_cut_copper") ++ .put("minecraft:waxed_lightly_weathered_cut_copper", "minecraft:waxed_exposed_cut_copper") ++ .put("minecraft:waxed_semi_weathered_cut_copper_stairs", "minecraft:waxed_weathered_cut_copper_stairs") ++ .put("minecraft:waxed_lightly_weathered_cut_copper_stairs", "minecraft:waxed_exposed_cut_copper_stairs") ++ .put("minecraft:waxed_semi_weathered_cut_copper_slab", "minecraft:waxed_weathered_cut_copper_slab") ++ .put("minecraft:waxed_lightly_weathered_cut_copper_slab", "minecraft:waxed_exposed_cut_copper_slab") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, RENAMES::get); ++ ConverterAbstractBlockRename.register(VERSION, RENAMES::get); ++ } ++ ++ private V2690() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2691.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2691.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bb87bcedfc2ed8d19b266e925beca0f54b50a0ab +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2691.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2691 { ++ ++ private static final int VERSION = MCVersions.V21W05A + 1; ++ ++ private static final Map RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:waxed_copper", "minecraft:waxed_copper_block") ++ .put("minecraft:oxidized_copper_block", "minecraft:oxidized_copper") ++ .put("minecraft:weathered_copper_block", "minecraft:weathered_copper") ++ .put("minecraft:exposed_copper_block", "minecraft:exposed_copper") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, RENAMES::get); ++ ConverterAbstractBlockRename.register(VERSION, RENAMES::get); ++ } ++ ++ private V2691() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2693.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2693.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a242e8e9a7a7c80c00ec0d64542b3d7dc3103e24 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2693.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.AddFlagIfAbsent; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V2693 { ++ ++ private static final int VERSION = MCVersions.V21W05B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new AddFlagIfAbsent(VERSION, "has_increased_height_already", false)); ++ } ++ ++ private V2693() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2696.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2696.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ce568002e54924e001c12271f0bde7183bc23c61 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2696.java +@@ -0,0 +1,42 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2696 { ++ ++ private static final int VERSION = MCVersions.V21W07A + 1; ++ ++ private static final Map RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:grimstone", "minecraft:deepslate") ++ .put("minecraft:grimstone_slab", "minecraft:cobbled_deepslate_slab") ++ .put("minecraft:grimstone_stairs", "minecraft:cobbled_deepslate_stairs") ++ .put("minecraft:grimstone_wall", "minecraft:cobbled_deepslate_wall") ++ .put("minecraft:polished_grimstone", "minecraft:polished_deepslate") ++ .put("minecraft:polished_grimstone_slab", "minecraft:polished_deepslate_slab") ++ .put("minecraft:polished_grimstone_stairs", "minecraft:polished_deepslate_stairs") ++ .put("minecraft:polished_grimstone_wall", "minecraft:polished_deepslate_wall") ++ .put("minecraft:grimstone_tiles", "minecraft:deepslate_tiles") ++ .put("minecraft:grimstone_tile_slab", "minecraft:deepslate_tile_slab") ++ .put("minecraft:grimstone_tile_stairs", "minecraft:deepslate_tile_stairs") ++ .put("minecraft:grimstone_tile_wall", "minecraft:deepslate_tile_wall") ++ .put("minecraft:grimstone_bricks", "minecraft:deepslate_bricks") ++ .put("minecraft:grimstone_brick_slab", "minecraft:deepslate_brick_slab") ++ .put("minecraft:grimstone_brick_stairs", "minecraft:deepslate_brick_stairs") ++ .put("minecraft:grimstone_brick_wall", "minecraft:deepslate_brick_wall") ++ .put("minecraft:chiseled_grimstone", "minecraft:chiseled_deepslate") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, RENAMES::get); ++ ConverterAbstractBlockRename.register(VERSION, RENAMES::get); ++ } ++ ++ private V2696() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2700.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2700.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e6a2f29b20aa6d7cd431fc63c2d8ed70dc9a2ab8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2700.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2700 { ++ ++ private static final int VERSION = MCVersions.V21W10A + 1; ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:cave_vines_head", "minecraft:cave_vines", ++ "minecraft:cave_vines_body", "minecraft:cave_vines_plant" ++ ) ++ )::get); ++ } ++ ++ private V2700() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2701.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2701.java +new file mode 100644 +index 0000000000000000000000000000000000000000..58535aa2e949bfca9b73bdc1b8f4f5f0a5b4384e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2701.java +@@ -0,0 +1,205 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.Sets; ++import java.util.Set; ++import java.util.regex.Matcher; ++import java.util.regex.Pattern; ++ ++public final class V2701 { ++ ++ private static final int VERSION = MCVersions.V21W10A + 2; ++ ++ private static final Pattern INDEX_PATTERN = Pattern.compile("\\[(\\d+)\\]"); ++ ++ private static final Set PIECE_TYPE = Sets.newHashSet( ++ "minecraft:jigsaw", ++ "minecraft:nvi", ++ "minecraft:pcp", ++ "minecraft:bastionremnant", ++ "minecraft:runtime" ++ ); ++ private static final Set FEATURES = Sets.newHashSet( ++ "minecraft:tree", ++ "minecraft:flower", ++ "minecraft:block_pile", ++ "minecraft:random_patch" ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.STRUCTURE_FEATURE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType children = data.getList("Children", ObjectType.MAP); ++ ++ if (children == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = children.size(); i < len; ++i) { ++ final MapType child = children.getMap(i); ++ ++ if (!PIECE_TYPE.contains(child.getString("id"))) { ++ continue; ++ } ++ ++ final String poolElement = child.getString("pool_element"); ++ if (!"minecraft:feature_pool_element".equals(poolElement)) { ++ continue; ++ } ++ ++ final MapType feature = child.getMap("feature"); ++ if (feature == null) { ++ continue; ++ } ++ ++ final String replacement = convertToString(feature); ++ ++ if (replacement != null) { ++ child.setString("feature", replacement); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private static String getNestedString(final MapType root, final String... paths) { ++ if (paths.length == 0) { ++ throw new IllegalArgumentException("Missing path"); ++ } ++ ++ Object current = root.getGeneric(paths[0]); ++ ++ for (int i = 1; i < paths.length; ++i) { ++ final String path = paths[i]; ++ ++ final Matcher indexMatcher = INDEX_PATTERN.matcher(path); ++ if (!indexMatcher.matches()) { ++ current = (current instanceof MapType) ? ((MapType)current).getGeneric(path) : null; ++ if (current == null) { ++ break; ++ } ++ continue; ++ } ++ ++ final int index = Integer.parseInt(indexMatcher.group(1)); ++ if (!(current instanceof ListType)) { ++ current = null; ++ break; ++ } else { ++ final ListType list = (ListType)current; ++ if (index >= 0 && index < list.size()) { ++ current = list.getGeneric(index); ++ } else { ++ current = null; ++ break; ++ } ++ } ++ } ++ ++ return current instanceof String ? (String)current : ""; ++ } ++ ++ private static String convertToString(final MapType feature) { ++ return getReplacement( ++ getNestedString(feature, "type"), ++ getNestedString(feature, "name"), ++ getNestedString(feature, "config", "state_provider", "type"), ++ getNestedString(feature, "config", "state_provider", "state", "Name"), ++ getNestedString(feature, "config", "state_provider", "entries", "[0]", "data", "Name"), ++ getNestedString(feature, "config", "foliage_placer", "type"), ++ getNestedString(feature, "config", "leaves_provider", "state", "Name") ++ ); ++ } ++ ++ private static String getReplacement(final String type, final String name, final String stateType, final String stateName, ++ final String firstEntryName, final String foliageName, final String leavesName) { ++ final String actualType; ++ if (!type.isEmpty()) { ++ actualType = type; ++ } else { ++ if (name.isEmpty()) { ++ return null; ++ } ++ ++ if ("minecraft:normal_tree".equals(name)) { ++ actualType = "minecraft:tree"; ++ } else { ++ actualType = name; ++ } ++ } ++ ++ if (FEATURES.contains(actualType)) { ++ if ("minecraft:random_patch".equals(actualType)) { ++ if ("minecraft:simple_state_provider".equals(stateType)) { ++ if ("minecraft:sweet_berry_bush".equals(stateName)) { ++ return "minecraft:patch_berry_bush"; ++ } ++ ++ if ("minecraft:cactus".equals(stateName)) { ++ return "minecraft:patch_cactus"; ++ } ++ } else if ("minecraft:weighted_state_provider".equals(stateType) && ("minecraft:grass".equals(firstEntryName) || "minecraft:fern".equals(firstEntryName))) { ++ return "minecraft:patch_taiga_grass"; ++ } ++ } else if ("minecraft:block_pile".equals(actualType)) { ++ if (!"minecraft:simple_state_provider".equals(stateType) && !"minecraft:rotated_block_provider".equals(stateType)) { ++ if ("minecraft:weighted_state_provider".equals(stateType)) { ++ if ("minecraft:packed_ice".equals(firstEntryName) || "minecraft:blue_ice".equals(firstEntryName)) { ++ return "minecraft:pile_ice"; ++ } ++ ++ if ("minecraft:jack_o_lantern".equals(firstEntryName) || "minecraft:pumpkin".equals(firstEntryName)) { ++ return "minecraft:pile_pumpkin"; ++ } ++ } ++ } else { ++ if ("minecraft:hay_block".equals(stateName)) { ++ return "minecraft:pile_hay"; ++ } ++ ++ if ("minecraft:melon".equals(stateName)) { ++ return "minecraft:pile_melon"; ++ } ++ ++ if ("minecraft:snow".equals(stateName)) { ++ return "minecraft:pile_snow"; ++ } ++ } ++ } else { ++ if ("minecraft:flower".equals(actualType)) { ++ return "minecraft:flower_plain"; ++ } ++ ++ if ("minecraft:tree".equals(actualType)) { ++ if ("minecraft:acacia_foliage_placer".equals(foliageName)) { ++ return "minecraft:acacia"; ++ } ++ ++ if ("minecraft:blob_foliage_placer".equals(foliageName) && "minecraft:oak_leaves".equals(leavesName)) { ++ return "minecraft:oak"; ++ } ++ ++ if ("minecraft:pine_foliage_placer".equals(foliageName)) { ++ return "minecraft:pine"; ++ } ++ ++ if ("minecraft:spruce_foliage_placer".equals(foliageName)) { ++ return "minecraft:spruce"; ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ ++ private V2701() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2702.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2702.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e8af14493078e2e458d0679404ae6bce46289519 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2702.java +@@ -0,0 +1,35 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2702 { ++ ++ private static final int VERSION = MCVersions.V21W10A + 3; ++ ++ public static void register() { ++ final DataConverter arrowConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.hasKey("pickup")) { ++ return null; ++ } ++ ++ final boolean player = data.getBoolean("player", true); ++ data.remove("player"); ++ ++ data.setByte("pickup", player ? (byte)1 : (byte)0); ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:arrow", arrowConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:spectral_arrow", arrowConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:trident", arrowConverter); ++ } ++ ++ private V2702() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2707.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2707.java +new file mode 100644 +index 0000000000000000000000000000000000000000..45c809b9e62437afdf17d47b0bea7b574e4cbd34 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2707.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.AddFlagIfAbsent; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V2707 { ++ ++ private static final int VERSION = MCVersions.V21W14A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new AddFlagIfAbsent(VERSION, "has_increased_height_already", true)); ++ ++ //registerMob("minecraft:marker"); // changed to simple in 1.21.5 ++ } ++ ++ private V2707() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2710.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2710.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0967c8c794869a972c1283cab6b3f3cef1d77aec +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2710.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.stats.ConverterAbstractStatsRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2710 { ++ ++ private static final int VERSION = MCVersions.V21W15A + 1; ++ ++ public static void register() { ++ ConverterAbstractStatsRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:play_one_minute", "minecraft:play_time" ++ ) ++ )::get); ++ } ++ ++ private V2710() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2717.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2717.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e0d6b2f6b00e0bfce205efa889de1765ef22793a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2717.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2717 { ++ ++ private static final int VERSION = MCVersions.V1_17_PRE1 + 1; ++ ++ public static void register() { ++ final Map rename = new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:azalea_leaves_flowers", "minecraft:flowering_azalea_leaves" ++ ) ++ ); ++ ConverterAbstractItemRename.register(VERSION, rename::get); ++ ConverterAbstractBlockRename.register(VERSION, rename::get); ++ } ++ ++ private V2717() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2825.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2825.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cd00c9398791967be6dd10f7183c61902431b27a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2825.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.AddFlagIfAbsent; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V2825 { ++ ++ private static final int VERSION = MCVersions.V1_17_1 + 95; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new AddFlagIfAbsent(VERSION, "has_increased_height_already", false)); ++ } ++ ++ private V2825() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2831.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2831.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a133c1eaf04cbd5a6a701ee2c4ad11553dd84343 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2831.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V2831 { ++ ++ private static final int VERSION = MCVersions.V1_17_1 + 101; ++ ++ public static void register() { ++ MCTypeRegistry.UNTAGGED_SPAWNER.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "SpawnPotentials", "data", "entity", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, root.getMap("SpawnData"), "entity", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.UNTAGGED_SPAWNER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType spawnData = root.getMap("SpawnData"); ++ if (spawnData != null) { ++ final MapType wrapped = Types.NBT.createEmptyMap(); ++ root.setMap("SpawnData", wrapped); ++ ++ wrapped.setMap("entity", spawnData); ++ } ++ ++ final ListType spawnPotentials = root.getList("SpawnPotentials", ObjectType.MAP); ++ if (spawnPotentials != null) { ++ for (int i = 0, len = spawnPotentials.size(); i < len; ++i) { ++ final MapType spawnPotential = spawnPotentials.getMap(i); ++ ++ // new format of weighted list (SpawnPotentials): ++ // root.data -> data ++ // root.weight -> weight ++ ++ final MapType entity = spawnPotential.getMap("Entity"); ++ final int weight = spawnPotential.getInt("Weight", 1); ++ spawnPotential.remove("Entity"); ++ spawnPotential.remove("Weight"); ++ spawnPotential.setInt("weight", weight); ++ ++ final MapType data = Types.NBT.createEmptyMap(); ++ spawnPotential.setMap("data", data); ++ ++ data.setMap("entity", entity); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2831() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2832.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2832.java +new file mode 100644 +index 0000000000000000000000000000000000000000..53f8474cdd9331d1cc293c360d3f4f14640eedd3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2832.java +@@ -0,0 +1,917 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.mojang.logging.LogUtils; ++import it.unimi.dsi.fastutil.ints.Int2IntLinkedOpenHashMap; ++import it.unimi.dsi.fastutil.ints.IntIterator; ++import it.unimi.dsi.fastutil.ints.IntOpenHashSet; ++import org.apache.commons.lang3.mutable.MutableBoolean; ++import org.slf4j.Logger; ++import java.util.Arrays; ++import java.util.BitSet; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V2832 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V1_17_1 + 102; ++ ++ private static final String[] BIOMES_BY_ID = new String[256]; // rip datapacks ++ static { ++ BIOMES_BY_ID[0] = "minecraft:ocean"; ++ BIOMES_BY_ID[1] = "minecraft:plains"; ++ BIOMES_BY_ID[2] = "minecraft:desert"; ++ BIOMES_BY_ID[3] = "minecraft:mountains"; ++ BIOMES_BY_ID[4] = "minecraft:forest"; ++ BIOMES_BY_ID[5] = "minecraft:taiga"; ++ BIOMES_BY_ID[6] = "minecraft:swamp"; ++ BIOMES_BY_ID[7] = "minecraft:river"; ++ BIOMES_BY_ID[8] = "minecraft:nether_wastes"; ++ BIOMES_BY_ID[9] = "minecraft:the_end"; ++ BIOMES_BY_ID[10] = "minecraft:frozen_ocean"; ++ BIOMES_BY_ID[11] = "minecraft:frozen_river"; ++ BIOMES_BY_ID[12] = "minecraft:snowy_tundra"; ++ BIOMES_BY_ID[13] = "minecraft:snowy_mountains"; ++ BIOMES_BY_ID[14] = "minecraft:mushroom_fields"; ++ BIOMES_BY_ID[15] = "minecraft:mushroom_field_shore"; ++ BIOMES_BY_ID[16] = "minecraft:beach"; ++ BIOMES_BY_ID[17] = "minecraft:desert_hills"; ++ BIOMES_BY_ID[18] = "minecraft:wooded_hills"; ++ BIOMES_BY_ID[19] = "minecraft:taiga_hills"; ++ BIOMES_BY_ID[20] = "minecraft:mountain_edge"; ++ BIOMES_BY_ID[21] = "minecraft:jungle"; ++ BIOMES_BY_ID[22] = "minecraft:jungle_hills"; ++ BIOMES_BY_ID[23] = "minecraft:jungle_edge"; ++ BIOMES_BY_ID[24] = "minecraft:deep_ocean"; ++ BIOMES_BY_ID[25] = "minecraft:stone_shore"; ++ BIOMES_BY_ID[26] = "minecraft:snowy_beach"; ++ BIOMES_BY_ID[27] = "minecraft:birch_forest"; ++ BIOMES_BY_ID[28] = "minecraft:birch_forest_hills"; ++ BIOMES_BY_ID[29] = "minecraft:dark_forest"; ++ BIOMES_BY_ID[30] = "minecraft:snowy_taiga"; ++ BIOMES_BY_ID[31] = "minecraft:snowy_taiga_hills"; ++ BIOMES_BY_ID[32] = "minecraft:giant_tree_taiga"; ++ BIOMES_BY_ID[33] = "minecraft:giant_tree_taiga_hills"; ++ BIOMES_BY_ID[34] = "minecraft:wooded_mountains"; ++ BIOMES_BY_ID[35] = "minecraft:savanna"; ++ BIOMES_BY_ID[36] = "minecraft:savanna_plateau"; ++ BIOMES_BY_ID[37] = "minecraft:badlands"; ++ BIOMES_BY_ID[38] = "minecraft:wooded_badlands_plateau"; ++ BIOMES_BY_ID[39] = "minecraft:badlands_plateau"; ++ BIOMES_BY_ID[40] = "minecraft:small_end_islands"; ++ BIOMES_BY_ID[41] = "minecraft:end_midlands"; ++ BIOMES_BY_ID[42] = "minecraft:end_highlands"; ++ BIOMES_BY_ID[43] = "minecraft:end_barrens"; ++ BIOMES_BY_ID[44] = "minecraft:warm_ocean"; ++ BIOMES_BY_ID[45] = "minecraft:lukewarm_ocean"; ++ BIOMES_BY_ID[46] = "minecraft:cold_ocean"; ++ BIOMES_BY_ID[47] = "minecraft:deep_warm_ocean"; ++ BIOMES_BY_ID[48] = "minecraft:deep_lukewarm_ocean"; ++ BIOMES_BY_ID[49] = "minecraft:deep_cold_ocean"; ++ BIOMES_BY_ID[50] = "minecraft:deep_frozen_ocean"; ++ BIOMES_BY_ID[127] = "minecraft:the_void"; ++ BIOMES_BY_ID[129] = "minecraft:sunflower_plains"; ++ BIOMES_BY_ID[130] = "minecraft:desert_lakes"; ++ BIOMES_BY_ID[131] = "minecraft:gravelly_mountains"; ++ BIOMES_BY_ID[132] = "minecraft:flower_forest"; ++ BIOMES_BY_ID[133] = "minecraft:taiga_mountains"; ++ BIOMES_BY_ID[134] = "minecraft:swamp_hills"; ++ BIOMES_BY_ID[140] = "minecraft:ice_spikes"; ++ BIOMES_BY_ID[149] = "minecraft:modified_jungle"; ++ BIOMES_BY_ID[151] = "minecraft:modified_jungle_edge"; ++ BIOMES_BY_ID[155] = "minecraft:tall_birch_forest"; ++ BIOMES_BY_ID[156] = "minecraft:tall_birch_hills"; ++ BIOMES_BY_ID[157] = "minecraft:dark_forest_hills"; ++ BIOMES_BY_ID[158] = "minecraft:snowy_taiga_mountains"; ++ BIOMES_BY_ID[160] = "minecraft:giant_spruce_taiga"; ++ BIOMES_BY_ID[161] = "minecraft:giant_spruce_taiga_hills"; ++ BIOMES_BY_ID[162] = "minecraft:modified_gravelly_mountains"; ++ BIOMES_BY_ID[163] = "minecraft:shattered_savanna"; ++ BIOMES_BY_ID[164] = "minecraft:shattered_savanna_plateau"; ++ BIOMES_BY_ID[165] = "minecraft:eroded_badlands"; ++ BIOMES_BY_ID[166] = "minecraft:modified_wooded_badlands_plateau"; ++ BIOMES_BY_ID[167] = "minecraft:modified_badlands_plateau"; ++ BIOMES_BY_ID[168] = "minecraft:bamboo_jungle"; ++ BIOMES_BY_ID[169] = "minecraft:bamboo_jungle_hills"; ++ BIOMES_BY_ID[170] = "minecraft:soul_sand_valley"; ++ BIOMES_BY_ID[171] = "minecraft:crimson_forest"; ++ BIOMES_BY_ID[172] = "minecraft:warped_forest"; ++ BIOMES_BY_ID[173] = "minecraft:basalt_deltas"; ++ BIOMES_BY_ID[174] = "minecraft:dripstone_caves"; ++ BIOMES_BY_ID[175] = "minecraft:lush_caves"; ++ BIOMES_BY_ID[177] = "minecraft:meadow"; ++ BIOMES_BY_ID[178] = "minecraft:grove"; ++ BIOMES_BY_ID[179] = "minecraft:snowy_slopes"; ++ BIOMES_BY_ID[180] = "minecraft:snowcapped_peaks"; ++ BIOMES_BY_ID[181] = "minecraft:lofty_peaks"; ++ BIOMES_BY_ID[182] = "minecraft:stony_peaks"; ++ } ++ ++ private static final String[] HEIGHTMAP_TYPES = new String[] { ++ "WORLD_SURFACE_WG", ++ "WORLD_SURFACE", ++ "WORLD_SURFACE_IGNORE_SNOW", ++ "OCEAN_FLOOR_WG", ++ "OCEAN_FLOOR", ++ "MOTION_BLOCKING", ++ "MOTION_BLOCKING_NO_LEAVES" ++ }; ++ ++ private static final Set STATUS_IS_OR_AFTER_SURFACE = new HashSet<>(Arrays.asList( ++ "surface", ++ "carvers", ++ "liquid_carvers", ++ "features", ++ "light", ++ "spawn", ++ "heightmaps", ++ "full" ++ )); ++ private static final Set STATUS_IS_OR_AFTER_NOISE = new HashSet<>(Arrays.asList( ++ "noise", ++ "surface", ++ "carvers", ++ "liquid_carvers", ++ "features", ++ "light", ++ "spawn", ++ "heightmaps", ++ "full" ++ )); ++ private static final Set BLOCKS_BEFORE_FEATURE_STATUS = new HashSet<>(Arrays.asList( ++ "minecraft:air", ++ "minecraft:basalt", ++ "minecraft:bedrock", ++ "minecraft:blackstone", ++ "minecraft:calcite", ++ "minecraft:cave_air", ++ "minecraft:coarse_dirt", ++ "minecraft:crimson_nylium", ++ "minecraft:dirt", ++ "minecraft:end_stone", ++ "minecraft:grass_block", ++ "minecraft:gravel", ++ "minecraft:ice", ++ "minecraft:lava", ++ "minecraft:mycelium", ++ "minecraft:nether_wart_block", ++ "minecraft:netherrack", ++ "minecraft:orange_terracotta", ++ "minecraft:packed_ice", ++ "minecraft:podzol", ++ "minecraft:powder_snow", ++ "minecraft:red_sand", ++ "minecraft:red_sandstone", ++ "minecraft:sand", ++ "minecraft:sandstone", ++ "minecraft:snow_block", ++ "minecraft:soul_sand", ++ "minecraft:soul_soil", ++ "minecraft:stone", ++ "minecraft:terracotta", ++ "minecraft:warped_nylium", ++ "minecraft:warped_wart_block", ++ "minecraft:water", ++ "minecraft:white_terracotta" ++ )); ++ ++ private static int getObjectsPerValue(final long[] val) { ++ return (4096 + val.length - 1) / (val.length); // expression is invalid if it returns > 64 ++ } ++ ++ private static long[] resize(final long[] val, final int oldBitsPerObject, final int newBitsPerObject) { ++ final long oldMask = (1L << oldBitsPerObject) - 1; // works even if bitsPerObject == 64 ++ final long newMask = (1L << newBitsPerObject) - 1; ++ final int oldObjectsPerValue = 64 / oldBitsPerObject; ++ final int newObjectsPerValue = 64 / newBitsPerObject; ++ ++ if (newBitsPerObject == oldBitsPerObject) { ++ return val; ++ } ++ ++ final int items = 4096; ++ ++ final long[] ret = new long[(items + newObjectsPerValue - 1) / newObjectsPerValue]; ++ ++ final int expectedSize = ((items + oldObjectsPerValue - 1) / oldObjectsPerValue); ++ if (val.length != expectedSize) { ++ throw new IllegalStateException("Expected size: " + expectedSize + ", got: " + val.length); ++ } ++ ++ int shift = 0; ++ int idx = 0; ++ long newCurr = 0L; ++ ++ int currItem = 0; ++ for (int i = 0; i < val.length; ++i) { ++ final long oldCurr = val[i]; ++ ++ for (int objIdx = 0; currItem < items && objIdx + oldBitsPerObject <= 64; objIdx += oldBitsPerObject, ++currItem) { ++ final long value = (oldCurr >> objIdx) & oldMask; ++ ++ if ((value & newMask) != value) { ++ throw new IllegalStateException("Old data storage has values that cannot be moved into new palette (would erase data)!"); ++ } ++ ++ newCurr |= value << shift; ++ shift += newBitsPerObject; ++ ++ if (shift + newBitsPerObject > 64) { // will next write overflow? ++ // must move to next idx ++ ret[idx++] = newCurr; ++ shift = 0; ++ newCurr = 0L; ++ } ++ } ++ } ++ ++ // don't forget to write the last one ++ if (shift != 0) { ++ ret[idx] = newCurr; ++ } ++ ++ return ret; ++ } ++ ++ private static void fixLithiumChunks(final MapType data) { ++ // See https://github.com/CaffeineMC/lithium-fabric/issues/279 ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return; ++ } ++ ++ final int chunkX = level.getInt("xPos"); ++ final int chunkZ = level.getInt("zPos"); ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections == null) { ++ return; ++ } ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final int sectionY = section.getInt("Y"); ++ ++ final ListType palette = section.getList("Palette", ObjectType.MAP); ++ final long[] blockStates = section.getLongs("BlockStates"); ++ ++ if (palette == null || blockStates == null) { ++ continue; ++ } ++ ++ final int expectedBits = Math.max(4, ceilLog2(palette.size())); ++ final int gotObjectsPerValue = getObjectsPerValue(blockStates); ++ final int gotBits = 64 / gotObjectsPerValue; ++ ++ if (expectedBits == gotBits) { ++ continue; ++ } ++ ++ try { ++ section.setLongs("BlockStates", resize(blockStates, gotBits, expectedBits)); ++ } catch (final Exception ex) { ++ LOGGER.error("Failed to rewrite mismatched palette and data storage for section y: " + sectionY ++ + " for chunk [" + chunkX + "," + chunkZ + "], palette entries: " + palette.size() + ", data storage size: " ++ + blockStates.length, ++ ex ++ ); ++ } ++ } ++ } ++ ++ public static void register() { ++ // See V2551 for the layout of world gen settings ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // converters were added to older versions note whether the world has increased height already or not ++ final boolean noHeightFlag = !data.hasKey("has_increased_height_already"); ++ final boolean hasIncreasedHeight = data.getBoolean("has_increased_height_already", true); ++ data.remove("has_increased_height_already"); ++ ++ final MapType dimensions = data.getMap("dimensions"); ++ if (dimensions == null) { ++ // wat ++ return null; ++ } ++ ++ // only care about overworld ++ final MapType overworld = dimensions.getMap("minecraft:overworld"); ++ if (overworld == null) { ++ // wat ++ return null; ++ } ++ ++ final MapType generator = overworld.getMap("generator"); ++ if (generator == null) { ++ // wat ++ return null; ++ } ++ ++ final String type = generator.getString("type", ""); ++ switch (type) { ++ case "minecraft:noise": { ++ final MapType biomeSource = generator.getMap("biome_source"); ++ final String sourceType = biomeSource.getString("type"); ++ ++ boolean largeBiomes = false; ++ ++ if ("minecraft:vanilla_layered".equals(sourceType) || (noHeightFlag && "minecraft:multi_noise".equals(sourceType))) { ++ largeBiomes = biomeSource.getBoolean("large_biomes"); ++ ++ final MapType newBiomeSource = Types.NBT.createEmptyMap(); ++ generator.setMap("biome_source", newBiomeSource); ++ ++ newBiomeSource.setString("preset", "minecraft:overworld"); ++ newBiomeSource.setString("type", "minecraft:multi_noise"); ++ } ++ ++ if (largeBiomes) { ++ if ("minecraft:overworld".equals(generator.getString("settings"))) { ++ generator.setString("settings", "minecraft:large_biomes"); ++ } ++ } ++ ++ break; ++ } ++ case "minecraft:flat": { ++ if (!hasIncreasedHeight) { ++ final MapType settings = generator.getMap("settings"); ++ if (settings == null) { ++ break; ++ } ++ ++ updateLayers(settings.getList("layers", ObjectType.MAP)); ++ } ++ break; ++ } ++ default: ++ // do nothing ++ break; ++ } ++ ++ return null; ++ } ++ }); ++ ++ ++ // It looks like DFU will only support worlds in the old height format or the new one, any custom one isn't supported ++ // and by not supported I mean it will just treat it as the old format... maybe at least throw in that case? ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // The below covers padPaletteEntries - this was written BEFORE that code was added to the datafixer - ++ // and this still works, so I'm keeping it. Don't fix what isn't broken. ++ fixLithiumChunks(data); // See https://github.com/CaffeineMC/lithium-fabric/issues/279 ++ ++ final MapType level = data.getMap("Level"); ++ ++ if (level == null) { ++ return null; ++ } ++ ++ final MapType context = data.getMap("__context"); // Passed through by ChunkStorage ++ final String dimension = context == null ? "" : context.getString("dimension", ""); ++ final String generator = context == null ? "" : context.getString("generator", ""); ++ final boolean isOverworld = "minecraft:overworld".equals(dimension); ++ final int minSection = isOverworld ? -4 : 0; ++ final MutableBoolean isAlreadyExtended = new MutableBoolean(); ++ ++ final MapType[] newBiomes = createBiomeSections(level, isOverworld, minSection, isAlreadyExtended); ++ final MapType wrappedEmptyBlockPalette = getEmptyBlockPalette(); ++ ++ ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections == null) { ++ level.setList("Sections", sections = Types.NBT.createEmptyList()); ++ } ++ ++ // must update sections for two things: ++ // 1. the biomes are now stored per section, so we must insert the biomes palette into each section (and create them if they don't exist) ++ // 2. each section must now have block states (or at least DFU is ensuring they do, but current code does not require) ++ V2841.SimplePaletteReader bottomSection = null; ++ final Set allBlocks = new HashSet<>(); ++ final IntOpenHashSet existingSections = new IntOpenHashSet(); ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final int y = section.getInt("Y"); ++ final int sectionIndex = y - minSection; ++ ++ existingSections.add(y); ++ ++ // add in relevant biome section ++ if (sectionIndex >= 0 && sectionIndex < newBiomes.length) { ++ // exclude out of bounds sections (i.e the light sections above and below the world) ++ section.setMap("biomes", newBiomes[sectionIndex]); ++ } ++ ++ // update palette ++ final ListType palette = section.getList("Palette", ObjectType.MAP); ++ final long[] blockStates = section.getLongs("BlockStates"); ++ ++ section.remove("Palette"); ++ section.remove("BlockStates"); ++ ++ if (palette != null) { ++ for (int j = 0, len2 = palette.size(); j < len2; ++j) { ++ allBlocks.add(V2841.getBlockId(palette.getMap(j))); ++ } ++ } ++ ++ final MapType palettedContainer; ++ if (palette != null && blockStates != null) { ++ // only if both exist, same as DFU, same as legacy chunk loading code ++ section.setMap("block_states", palettedContainer = wrapPaletteOptimised(palette, blockStates)); ++ } else { ++ section.setMap("block_states", palettedContainer = wrappedEmptyBlockPalette.copy()); // must write a palette now, copy so that later edits do not edit them all ++ } ++ ++ if (section.getInt("Y", Integer.MAX_VALUE) == 0) { ++ bottomSection = new V2841.SimplePaletteReader(palettedContainer.getList("palette", ObjectType.MAP), palettedContainer.getLongs("data")); ++ } ++ } ++ ++ // all existing sections updated, now we must create new sections just for the biomes migration ++ for (int sectionIndex = 0; sectionIndex < newBiomes.length; ++sectionIndex) { ++ final int sectionY = sectionIndex + minSection; ++ if (!existingSections.add(sectionY)) { ++ // exists already ++ continue; ++ } ++ ++ final MapType newSection = Types.NBT.createEmptyMap(); ++ sections.addMap(newSection); ++ ++ newSection.setByte("Y", (byte)sectionY); ++ // must write a palette now, copy so that later edits do not edit them all ++ newSection.setMap("block_states", wrappedEmptyBlockPalette.copy()); ++ ++ newSection.setGeneric("biomes", newBiomes[sectionIndex]); ++ } ++ ++ // update status so interpolation can take place ++ predictChunkStatusBeforeSurface(level, allBlocks); ++ ++ // done with sections, update the rest of the chunk ++ updateChunkData(level, isOverworld, isAlreadyExtended.getValue(), "minecraft:noise".equals(generator), bottomSection); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ if (dimensions == null) { ++ return null; ++ } ++ ++ for (final String dimension : dimensions.keys()) { ++ final MapType dimensionData = dimensions.getMap(dimension); ++ if (dimensionData == null) { ++ continue; ++ } ++ ++ final MapType generator = dimensionData.getMap("generator"); ++ if (generator == null) { ++ continue; ++ } ++ ++ final String type = generator.getString("type"); ++ if (type == null) { ++ continue; ++ } ++ ++ switch (type) { ++ case "minecraft:flat": { ++ final MapType settings = generator.getMap("settings"); ++ if (settings == null) { ++ continue; ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.BIOME, settings, "biome", fromVersion, toVersion); ++ ++ WalkerUtils.convertListPath(MCTypeRegistry.BLOCK_NAME, settings, "layers", "block", fromVersion, toVersion); ++ ++ break; ++ } ++ case "minecraft:noise": { ++ final MapType settings = generator.getMap("settings"); ++ if (settings != null) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, settings, "default_block", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, settings, "default_fluid", fromVersion, toVersion); ++ } ++ ++ final MapType biomeSource = generator.getMap("biome_source"); ++ if (biomeSource != null) { ++ final String biomeSourceType = biomeSource.getString("type", ""); ++ switch (biomeSourceType) { ++ case "minecraft:fixed": { ++ WalkerUtils.convert(MCTypeRegistry.BIOME, biomeSource, "biome", fromVersion, toVersion); ++ break; ++ } ++ ++ case "minecraft:multi_noise": { ++ WalkerUtils.convert(MCTypeRegistry.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST, biomeSource, "preset", fromVersion, toVersion); ++ ++ // Vanilla's schema is _still_ wrong. It should be DSL.fields("biomes", DSL.list(DSL.fields("biome"))) ++ // But it just contains the list part. That obviously can never be the case, because ++ // the root object is a compound, not a list. ++ WalkerUtils.convertListPath(MCTypeRegistry.BIOME, biomeSource, "biomes", "biome", fromVersion, toVersion); ++ break; ++ } ++ ++ case "minecraft:checkerboard": { ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, biomeSource, "biomes", fromVersion, toVersion); ++ break; ++ } ++ } ++ } ++ ++ break; ++ } ++ } ++ } ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, level, "Entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, level, "TileEntities", fromVersion, toVersion); ++ ++ final ListType tileTicks = level.getList("TileTicks", ObjectType.MAP); ++ if (tileTicks != null) { ++ for (int i = 0, len = tileTicks.size(); i < len; ++i) { ++ final MapType tileTick = tileTicks.getMap(i); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, tileTick, "i", fromVersion, toVersion); ++ } ++ } ++ ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, section.getMap("biomes"), "palette", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section.getMap("block_states"), "palette", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, level.getMap("Structures"), "Starts", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private static void predictChunkStatusBeforeSurface(final MapType level, final Set chunkBlocks) { ++ final String status = level.getString("Status", "empty"); ++ if (STATUS_IS_OR_AFTER_SURFACE.contains(status)) { ++ return; ++ } ++ ++ chunkBlocks.remove("minecraft:air"); ++ final boolean chunkNotEmpty = !chunkBlocks.isEmpty(); ++ chunkBlocks.removeAll(BLOCKS_BEFORE_FEATURE_STATUS); ++ final boolean chunkFeatureStatus = !chunkBlocks.isEmpty(); ++ ++ final String update; ++ if (chunkFeatureStatus) { ++ update = "liquid_carvers"; ++ } else if (!"noise".equals(status) && !chunkNotEmpty) { ++ update = "biomes".equals(status) ? "structure_references" : status; ++ } else { ++ update = "noise"; ++ } ++ ++ level.setString("Status", update); ++ } ++ ++ private static MapType getEmptyBlockPalette() { ++ final MapType airBlockState = Types.NBT.createEmptyMap(); ++ airBlockState.setString("Name", "minecraft:air"); ++ ++ final ListType emptyBlockPalette = Types.NBT.createEmptyList(); ++ emptyBlockPalette.addMap(airBlockState); ++ ++ return V2832.wrapPalette(emptyBlockPalette); ++ } ++ ++ private static void shiftUpgradeData(final MapType upgradeData, final int shift) { ++ if (upgradeData == null) { ++ return; ++ } ++ ++ final MapType indices = upgradeData.getMap("Indices"); ++ if (indices == null) { ++ return; ++ } ++ ++ RenameHelper.renameKeys(indices, (final String input) -> { ++ return Integer.toString(Integer.parseInt(input) + shift); ++ }); ++ } ++ ++ private static void updateChunkData(final MapType level, final boolean wantExtendedHeight, final boolean isAlreadyExtended, ++ final boolean onNoiseGenerator, final V2841.SimplePaletteReader bottomSection) { ++ level.remove("Biomes"); ++ if (!wantExtendedHeight) { ++ padCarvingMasks(level, 16, 0); ++ return; ++ } ++ ++ if (isAlreadyExtended) { ++ padCarvingMasks(level, 24, 0); ++ return; ++ } ++ ++ offsetHeightmaps(level); ++ // Difference from DFU: Still convert the Lights data. Just because it's being removed in a later version doesn't mean ++ // that it should be removed here. ++ // Generally, converters act only on the current version to bring it to the next. This principle allows the converter ++ // for the next version to assume that it acts on its current version, not some in-between of the current version ++ // and some future version that did not exist at the time it was written. This allows converters to be written and tested ++ // only with knowledge of the current version and the next version. ++ addEmptyListPadding(level, "Lights"); ++ addEmptyListPadding(level, "LiquidsToBeTicked"); ++ addEmptyListPadding(level, "PostProcessing"); ++ addEmptyListPadding(level, "ToBeTicked"); ++ shiftUpgradeData(level.getMap("UpgradeData"), 4); // https://bugs.mojang.com/browse/MC-238076 - fixed now, Mojang fix is identical. No change required. ++ padCarvingMasks(level, 24, 4); ++ ++ if (!onNoiseGenerator) { ++ return; ++ } ++ ++ final String status = level.getString("Status"); ++ if (status == null || "empty".equals(status)) { ++ return; ++ } ++ ++ final MapType blendingData = Types.NBT.createEmptyMap(); ++ level.setMap("blending_data", blendingData); ++ ++ blendingData.setBoolean("old_noise", STATUS_IS_OR_AFTER_NOISE.contains(status)); ++ ++ if (bottomSection == null) { ++ return; ++ } ++ ++ final BitSet missingBedrock = new BitSet(256); ++ boolean hasBedrock = status.equals("noise"); ++ ++ for (int z = 0; z <= 15; ++z) { ++ for (int x = 0; x <= 15; ++x) { ++ final MapType state = bottomSection.getState(x, 0, z); ++ final String blockId = V2841.getBlockId(state); ++ final boolean isBedrock = state != null && "minecraft:bedrock".equals(blockId); ++ final boolean isAir = state != null && "minecraft:air".equals(blockId); ++ if (isAir) { ++ missingBedrock.set((z << 4) | x); ++ } ++ ++ hasBedrock |= isBedrock; ++ } ++ } ++ ++ if (hasBedrock && missingBedrock.cardinality() != missingBedrock.size()) { ++ final String targetStatus = "full".equals(status) ? "heightmaps" : status; ++ ++ final MapType belowZeroRetrogen = Types.NBT.createEmptyMap(); ++ level.setMap("below_zero_retrogen", belowZeroRetrogen); ++ ++ belowZeroRetrogen.setString("target_status", targetStatus); ++ belowZeroRetrogen.setLongs("missing_bedrock", missingBedrock.toLongArray()); ++ ++ level.setString("Status", "empty"); ++ } ++ ++ level.setBoolean("isLightOn", false); ++ } ++ ++ private static void padCarvingMasks(final MapType level, final int newSize, final int offset) { ++ final MapType carvingMasks = level.getMap("CarvingMasks"); ++ if (carvingMasks == null) { ++ // if empty, DFU still writes ++ level.setMap("CarvingMasks", Types.NBT.createEmptyMap()); ++ return; ++ } ++ ++ for (final String key : carvingMasks.keys()) { ++ final long[] old = BitSet.valueOf(carvingMasks.getBytes(key)).toLongArray(); ++ final long[] newVal = new long[64 * newSize]; ++ ++ System.arraycopy(old, 0, newVal, 64 * offset, old.length); ++ ++ carvingMasks.setLongs(key, newVal); // no CME: key exists already ++ } ++ } ++ ++ private static void addEmptyListPadding(final MapType level, final String path) { ++ ListType list = level.getListUnchecked(path); ++ if (list != null && list.size() == 24) { ++ return; ++ } ++ ++ if (list == null) { ++ // difference from DFU: Don't create the damn thing! ++ return; ++ } ++ ++ ++ // offset the section array to the new format ++ for (int i = 0; i < 4; ++i) { ++ // always create new copies, so that modifying one doesn't modify ALL of them! ++ list.addList(0, Types.NBT.createEmptyList()); // add below ++ list.addList(Types.NBT.createEmptyList()); // add above ++ } ++ } ++ ++ private static void offsetHeightmaps(final MapType level) { ++ final MapType heightmaps = level.getMap("Heightmaps"); ++ if (heightmaps == null) { ++ return; ++ } ++ ++ for (final String key : HEIGHTMAP_TYPES) { ++ offsetHeightmap(heightmaps.getLongs(key)); ++ } ++ } ++ ++ private static void offsetHeightmap(final long[] heightmap) { ++ if (heightmap == null) { ++ return; ++ } ++ ++ // heightmaps are configured to have 9 bits per value, with 256 total values ++ // heightmaps are also relative to the lowest position ++ for (int idx = 0, len = heightmap.length; idx < len; ++idx) { ++ long curr = heightmap[idx]; ++ long next = 0L; ++ ++ for (int objIdx = 0; objIdx + 9 <= 64; objIdx += 9) { ++ final long value = (curr >> objIdx) & 511L; ++ if (value != 0L) { ++ final long offset = Math.min(511L, value + 64L); ++ ++ next |= (offset << objIdx); ++ } ++ } ++ ++ heightmap[idx] = next; ++ } ++ } ++ ++ private static MapType[] createBiomeSections(final MapType level, final boolean wantExtendedHeight, ++ final int minSection, final MutableBoolean isAlreadyExtended) { ++ final MapType[] ret = new MapType[wantExtendedHeight ? 24 : 16]; ++ ++ final int[] biomes = level.getInts("Biomes"); ++ ++ if (biomes != null && biomes.length == 1536) { // magic value for 24 sections of biomes (24 * 4^3) ++ isAlreadyExtended.setValue(true); ++ for (int sectionIndex = 0; sectionIndex < 24; ++sectionIndex) { ++ ret[sectionIndex] = createBiomeSection(biomes, sectionIndex * 64, -1); // -1 is all 1s ++ } ++ } else if (biomes != null && biomes.length == 1024) { // magic value for 24 sections of biomes (16 * 4^3) ++ for (int sectionY = 0; sectionY < 16; ++sectionY) { ++ ret[sectionY - minSection] = createBiomeSection(biomes, sectionY * 64, -1); // -1 is all 1s ++ } ++ ++ if (wantExtendedHeight) { ++ // must set the new sections at top and bottom ++ final MapType bottomCopy = createBiomeSection(biomes, 0, 15); // just want the biomes at y = 0 ++ final MapType topCopy = createBiomeSection(biomes, 1008, 15); // just want the biomes at y = 252 ++ ++ for (int sectionIndex = 0; sectionIndex < 4; ++sectionIndex) { ++ ret[sectionIndex] = bottomCopy.copy(); // copy palette so that later possible modifications don't trash all sections ++ } ++ ++ for (int sectionIndex = 20; sectionIndex < 24; ++sectionIndex) { ++ ret[sectionIndex] = topCopy.copy(); // copy palette so that later possible modifications don't trash all sections ++ } ++ } ++ } else { ++ final ListType palette = Types.NBT.createEmptyList(); ++ palette.addString("minecraft:plains"); ++ ++ for (int i = 0; i < ret.length; ++i) { ++ ret[i] = wrapPalette(palette.copy()); // copy palette so that later possible modifications don't trash all sections ++ } ++ } ++ ++ return ret; ++ } ++ ++ private static MapType createBiomeSection(final int[] biomes, final int offset, final int mask) { ++ final Int2IntLinkedOpenHashMap paletteId = new Int2IntLinkedOpenHashMap(); ++ ++ for (int idx = 0; idx < 64; ++idx) { ++ final int biome = biomes[offset + (idx & mask)]; ++ paletteId.putIfAbsent(biome, paletteId.size()); ++ } ++ ++ final ListType paletteString = Types.NBT.createEmptyList(); ++ for (final IntIterator iterator = paletteId.keySet().iterator(); iterator.hasNext();) { ++ final int biomeId = iterator.nextInt(); ++ final String biome = biomeId >= 0 && biomeId < BIOMES_BY_ID.length ? BIOMES_BY_ID[biomeId] : null; ++ paletteString.addString(biome == null ? "minecraft:plains" : biome); ++ } ++ ++ final int bitsPerObject = ceilLog2(paletteString.size()); ++ if (bitsPerObject == 0) { ++ return wrapPalette(paletteString); ++ } ++ ++ // manually create packed integer data ++ final int objectsPerValue = 64 / bitsPerObject; ++ final long[] packed = new long[(64 + objectsPerValue - 1) / objectsPerValue]; ++ ++ int shift = 0; ++ int idx = 0; ++ long curr = 0; ++ ++ for (int biome_idx = 0; biome_idx < 64; ++biome_idx) { ++ final int biome = biomes[offset + (biome_idx & mask)]; ++ ++ curr |= ((long)paletteId.get(biome)) << shift; ++ ++ shift += bitsPerObject; ++ ++ if (shift + bitsPerObject > 64) { // will next write overflow? ++ // must move to next idx ++ packed[idx++] = curr; ++ shift = 0; ++ curr = 0L; ++ } ++ } ++ ++ // don't forget to write the last one ++ if (shift != 0) { ++ packed[idx] = curr; ++ } ++ ++ return wrapPalette(paletteString, packed); ++ } ++ ++ private static MapType wrapPalette(final ListType palette) { ++ return wrapPalette(palette, null); ++ } ++ ++ private static MapType wrapPalette(final ListType palette, final long[] blockStates) { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ret.setList("palette", palette); ++ if (blockStates != null) { ++ ret.setLongs("data", blockStates); ++ } ++ ++ return ret; ++ } ++ ++ private static MapType wrapPaletteOptimised(final ListType palette, final long[] blockStates) { ++ if (palette.size() == 1) { ++ return wrapPalette(palette); ++ } ++ ++ return wrapPalette(palette, blockStates); ++ } ++ ++ public static int ceilLog2(final int value) { ++ return value == 0 ? 0 : Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros ++ } ++ ++ private static void updateLayers(final ListType layers) { ++ if (layers == null) { ++ return; ++ } ++ ++ layers.addMap(0, createEmptyLayer()); // add at the bottom ++ } ++ ++ private static MapType createEmptyLayer() { ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ret.setInt("height", 64); ++ ret.setString("block", "minecraft:air"); ++ ++ return ret; ++ } ++ ++ private V2832() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2833.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2833.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0db6fcec914d25680ac936cfb67a22f950b66d47 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2833.java +@@ -0,0 +1,31 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2833 { ++ ++ private static final int VERSION = MCVersions.V1_17_1 + 103; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ for (final String dimensionKey : dimensions.keys()) { ++ final MapType dimension = dimensions.getMap(dimensionKey); ++ if (!dimension.hasKey("type")) { ++ throw new IllegalStateException("Unable load old custom worlds."); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2833() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2838.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2838.java +new file mode 100644 +index 0000000000000000000000000000000000000000..356963228d884a0a74e6d7c9922b4ced627bbfb0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2838.java +@@ -0,0 +1,62 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2838 { ++ ++ private static final int VERSION = MCVersions.V21W40A; ++ ++ public static final Map BIOME_UPDATE = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:badlands_plateau", "minecraft:badlands") ++ .put("minecraft:bamboo_jungle_hills", "minecraft:bamboo_jungle") ++ .put("minecraft:birch_forest_hills", "minecraft:birch_forest") ++ .put("minecraft:dark_forest_hills", "minecraft:dark_forest") ++ .put("minecraft:desert_hills", "minecraft:desert") ++ .put("minecraft:desert_lakes", "minecraft:desert") ++ .put("minecraft:giant_spruce_taiga_hills", "minecraft:old_growth_spruce_taiga") ++ .put("minecraft:giant_spruce_taiga", "minecraft:old_growth_spruce_taiga") ++ .put("minecraft:giant_tree_taiga_hills", "minecraft:old_growth_pine_taiga") ++ .put("minecraft:giant_tree_taiga", "minecraft:old_growth_pine_taiga") ++ .put("minecraft:gravelly_mountains", "minecraft:windswept_gravelly_hills") ++ .put("minecraft:jungle_edge", "minecraft:sparse_jungle") ++ .put("minecraft:jungle_hills", "minecraft:jungle") ++ .put("minecraft:modified_badlands_plateau", "minecraft:badlands") ++ .put("minecraft:modified_gravelly_mountains", "minecraft:windswept_gravelly_hills") ++ .put("minecraft:modified_jungle_edge", "minecraft:sparse_jungle") ++ .put("minecraft:modified_jungle", "minecraft:jungle") ++ .put("minecraft:modified_wooded_badlands_plateau", "minecraft:wooded_badlands") ++ .put("minecraft:mountain_edge", "minecraft:windswept_hills") ++ .put("minecraft:mountains", "minecraft:windswept_hills") ++ .put("minecraft:mushroom_field_shore", "minecraft:mushroom_fields") ++ .put("minecraft:shattered_savanna", "minecraft:windswept_savanna") ++ .put("minecraft:shattered_savanna_plateau", "minecraft:windswept_savanna") ++ .put("minecraft:snowy_mountains", "minecraft:snowy_plains") ++ .put("minecraft:snowy_taiga_hills", "minecraft:snowy_taiga") ++ .put("minecraft:snowy_taiga_mountains", "minecraft:snowy_taiga") ++ .put("minecraft:snowy_tundra", "minecraft:snowy_plains") ++ .put("minecraft:stone_shore", "minecraft:stony_shore") ++ .put("minecraft:swamp_hills", "minecraft:swamp") ++ .put("minecraft:taiga_hills", "minecraft:taiga") ++ .put("minecraft:taiga_mountains", "minecraft:taiga") ++ .put("minecraft:tall_birch_forest", "minecraft:old_growth_birch_forest") ++ .put("minecraft:tall_birch_hills", "minecraft:old_growth_birch_forest") ++ .put("minecraft:wooded_badlands_plateau", "minecraft:wooded_badlands") ++ .put("minecraft:wooded_hills", "minecraft:forest") ++ .put("minecraft:wooded_mountains", "minecraft:windswept_forest") ++ .put("minecraft:lofty_peaks", "minecraft:jagged_peaks") ++ .put("minecraft:snowcapped_peaks", "minecraft:frozen_peaks") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.BIOME, BIOME_UPDATE::get); ++ } ++ ++ private V2838() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2841.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2841.java +new file mode 100644 +index 0000000000000000000000000000000000000000..52ae7b4dbd1387327cb709c5939fa55cf1f10f7c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2841.java +@@ -0,0 +1,210 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import ca.spottedleaf.dataconverter.util.IntegerUtil; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V2841 { ++ ++ private static final int VERSION = MCVersions.V21W42A + 1; ++ ++ private static final Set ALWAYS_WATERLOGGED = new HashSet<>( ++ Arrays.asList( ++ "minecraft:bubble_column", ++ "minecraft:kelp", ++ "minecraft:kelp_plant", ++ "minecraft:seagrass", ++ "minecraft:tall_seagrass" ++ ) ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType level = root.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ { ++ // Why it's renamed here and not the next data version is beyond me. ++ final MapType liquidTicks = level.getMap("LiquidTicks"); ++ if (liquidTicks != null) { ++ level.remove("LiquidTicks"); ++ level.setMap("fluid_ticks", liquidTicks); ++ } ++ } ++ ++ final Int2ObjectOpenHashMap sectionBlocks = new Int2ObjectOpenHashMap<>(); ++ final ListType sections = level.getList("Sections", ObjectType.MAP); ++ int minSection = 0; // TODO wtf is this ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final int sectionY = section.getInt("Y"); ++ if (sectionY < minSection && section.hasKey("biomes")) { ++ minSection = sectionY; ++ } ++ ++ final MapType blockStates = section.getMap("block_states"); ++ if (blockStates == null) { ++ continue; ++ } ++ ++ sectionBlocks.put(sectionY, new SimplePaletteReader(section.getList("palette", ObjectType.MAP), section.getLongs("data"))); ++ } ++ } ++ ++ level.setByte("yPos", (byte)minSection); // TODO ??????????????????????????????????????? ++ ++ if (level.hasKey("fluid_ticks") || level.hasKey("TileTicks")) { ++ return null; ++ } ++ ++ final int sectionX = level.getInt("xPos"); ++ final int sectionZ = level.getInt("zPos"); ++ ++ final ListType fluidTicks = level.getList("LiquidsToBeTicked", ObjectType.LIST); ++ final ListType blockTicks = level.getList("ToBeTicked", ObjectType.LIST); ++ level.remove("LiquidsToBeTicked"); ++ level.remove("ToBeTicked"); ++ ++ level.setList("fluid_ticks", migrateTickList(fluidTicks, false, sectionBlocks, sectionX, minSection, sectionZ)); ++ level.setList("TileTicks", migrateTickList(blockTicks, true, sectionBlocks, sectionX, minSection, sectionZ)); ++ ++ return null; ++ } ++ }); ++ } ++ ++ public static ListType migrateTickList(final ListType ticks, final boolean blockTicks, final Int2ObjectOpenHashMap sectionBlocks, ++ final int sectionX, final int minSection, final int sectionZ) { ++ final ListType ret = Types.NBT.createEmptyList(); ++ ++ if (ticks == null) { ++ return ret; ++ } ++ ++ for (int sectionIndex = 0, totalSections = ticks.size(); sectionIndex < totalSections; ++sectionIndex) { ++ final int sectionY = sectionIndex + minSection; ++ final ListType sectionTicks = ticks.getList(sectionIndex); ++ final SimplePaletteReader palette = sectionBlocks.get(sectionY); ++ ++ for (int i = 0, len = sectionTicks.size(); i < len; ++i) { ++ final int localIndex = sectionTicks.getShort(i) & 0xFFFF; ++ final MapType blockState = palette == null ? null : palette.getState(localIndex); ++ final String subjectId = blockTicks ? getBlockId(blockState) : getLiquidId(blockState); ++ ++ ret.addMap(createNewTick(subjectId, localIndex, sectionX, sectionY, sectionZ)); ++ } ++ } ++ ++ return ret; ++ } ++ ++ public static MapType createNewTick(final String subjectId, final int localIndex, final int sectionX, final int sectionY, final int sectionZ) { ++ final int newX = (localIndex & 15) + (sectionX << 4); ++ final int newZ = ((localIndex >> 4) & 15) + (sectionZ << 4); ++ final int newY = ((localIndex >> 8) & 15) + (sectionY << 4); ++ ++ final MapType ret = Types.NBT.createEmptyMap(); ++ ++ ret.setString("i", subjectId); ++ ret.setInt("x", newX); ++ ret.setInt("y", newY); ++ ret.setInt("z", newZ); ++ ret.setInt("t", 0); ++ ret.setInt("p", 0); ++ ++ return ret; ++ } ++ ++ public static String getBlockId(final MapType blockState) { ++ return blockState == null ? "minecraft:air" : blockState.getString("Name", "minecraft:air"); ++ } ++ ++ private static String getLiquidId(final MapType blockState) { ++ if (blockState == null) { ++ return "minecraft:empty"; ++ } ++ ++ final String name = blockState.getString("Name"); ++ if (ALWAYS_WATERLOGGED.contains(name)) { ++ return "minecraft:water"; ++ } ++ ++ final MapType properties = blockState.getMap("Properties"); ++ // Correctly read block state properties as strings - https://github.com/PaperMC/DataConverter/issues/6 ++ if ("minecraft:water".equals(name)) { ++ return properties != null && "0".equals(properties.getString("level")) ? "minecraft:water" : "minecraft:flowing_water"; ++ } else if ("minecraft:lava".equals(name)) { ++ return properties != null && "0".equals(properties.getString("level")) ? "minecraft:lava" : "minecraft:flowing_lava"; ++ } ++ ++ return (properties != null && "true".equals(properties.getString("waterlogged"))) ? "minecraft:water" : "minecraft:empty"; ++ } ++ ++ private V2841() {} ++ ++ public static final class SimplePaletteReader { ++ ++ public final ListType palette; ++ public final long[] data; ++ private final int bitsPerValue; ++ private final long mask; ++ private final int valuesPerLong; ++ ++ public SimplePaletteReader(final ListType palette, final long[] data) { ++ this.palette = palette == null ? null : (palette.size() == 0 ? null : palette); ++ this.data = data; ++ this.bitsPerValue = Math.max(4, IntegerUtil.ceilLog2(this.palette == null ? 0 : this.palette.size())); ++ this.mask = (1L << this.bitsPerValue) - 1L; ++ this.valuesPerLong = (int)(64L / this.bitsPerValue); ++ } ++ ++ public MapType getState(final int x, final int y, final int z) { ++ final int index = x | (z << 4) | (y << 8); ++ return this.getState(index); ++ } ++ ++ public MapType getState(final int index) { ++ final ListType palette = this.palette; ++ if (palette == null) { ++ return null; ++ } ++ ++ final int paletteSize = palette.size(); ++ if (paletteSize == 1) { ++ return palette.getMap(0); ++ } ++ ++ // x86 div computes mod. no loss here using mod ++ // if needed, can compute magic mul and shift for div values using IntegerUtil ++ final int dataIndex = index / this.valuesPerLong; ++ final int localIndex = (index % this.valuesPerLong) * this.bitsPerValue; ++ final long[] data = this.data; ++ if (dataIndex < 0 || dataIndex >= data.length) { ++ return null; ++ } ++ ++ final long value = data[dataIndex]; ++ final int paletteIndex = (int)((value >>> localIndex) & this.mask); ++ if (paletteIndex < 0 || paletteIndex >= paletteSize) { ++ return null; ++ } ++ ++ return palette.getMap(paletteIndex); ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2842.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2842.java +new file mode 100644 +index 0000000000000000000000000000000000000000..82581d4d4f68842a7def842c50dd94980064e14f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2842.java +@@ -0,0 +1,78 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V2842 { ++ ++ private static final int VERSION = MCVersions.V21W42A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType level = root.getMap("Level"); ++ root.remove("Level"); ++ ++ if (!root.isEmpty()) { ++ for (final String key : root.keys()) { ++ if (level.hasKey(key)) { ++ // Don't clobber Level's data ++ continue; ++ } ++ level.setGeneric(key, root.getGeneric(key)); ++ } ++ } ++ ++ // Rename top level first ++ RenameHelper.renameSingle(level, "TileEntities", "block_entities"); ++ RenameHelper.renameSingle(level, "TileTicks", "block_ticks"); ++ RenameHelper.renameSingle(level, "Entities", "entities"); ++ RenameHelper.renameSingle(level, "Sections", "sections"); ++ RenameHelper.renameSingle(level, "Structures", "structures"); ++ ++ // 2nd level ++ final MapType structures = level.getMap("structures"); ++ if (structures != null) { ++ RenameHelper.renameSingle(structures, "Starts", "starts"); ++ } ++ ++ return level; // Level is now root tag. ++ } ++ }); ++ ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, data, "block_entities", fromVersion, toVersion); ++ ++ final ListType blockTicks = data.getList("block_ticks", ObjectType.MAP); ++ if (blockTicks != null) { ++ for (int i = 0, len = blockTicks.size(); i < len; ++i) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, blockTicks.getMap(i), "i", fromVersion, toVersion); ++ } ++ } ++ ++ final ListType sections = data.getList("sections", ObjectType.MAP); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, section.getMap("biomes"), "palette", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section.getMap("block_states"), "palette", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, data.getMap("structures"), "starts", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private V2842() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2843.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2843.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c3e916a84e67d3d9243e5be2ea6985edd17c7151 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2843.java +@@ -0,0 +1,101 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V2843 { ++ ++ private static final int VERSION = MCVersions.V21W42A + 3; ++ ++ public static void register() { ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.BIOME, ++ new HashMap<>( ++ Map.of("minecraft:deep_warm_ocean", "minecraft:warm_ocean") ++ )::get ++ ); ++ ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static void moveOutOfBoundTicks(final ListType ticks, final MapType chunkRoot, final int chunkX, final int chunkZ, final String intoKey) { ++ if (ticks == null) { ++ return; ++ } ++ ++ ListType outOfBounds = null; ++ for (int i = 0, len = ticks.size(); i < len; ++i) { ++ final MapType tick = ticks.getMap(i); ++ final int x = tick.getInt("x"); ++ final int z = tick.getInt("z"); ++ // anything > 1 is lost, anything less than 1 stays. ++ if (Math.max(Math.abs(chunkX - (x >> 4)), Math.abs(chunkZ - (z >> 4))) == 1) { ++ // DFU doesn't remove, so neither do we. ++ if (outOfBounds == null) { ++ outOfBounds = Types.NBT.createEmptyList(); ++ } ++ outOfBounds.addMap(tick.copy()); ++ } ++ } ++ ++ if (outOfBounds != null) { ++ MapType upgradeData = chunkRoot.getMap("UpgradeData"); ++ if (upgradeData == null) { ++ chunkRoot.setMap("UpgradeData", upgradeData = Types.NBT.createEmptyMap()); ++ } ++ upgradeData.setList(intoKey, outOfBounds); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // After renames, so use new names ++ final int x = data.getInt("xPos"); ++ final int z = data.getInt("zPos"); ++ ++ moveOutOfBoundTicks(data.getList("block_ticks", ObjectType.MAP), data, x, z, "neighbor_block_ticks"); ++ moveOutOfBoundTicks(data.getList("fluid_ticks", ObjectType.MAP), data, x, z, "neighbor_fluid_ticks"); ++ ++ return null; ++ } ++ }); ++ ++ // DFU is missing schema for UpgradeData block names ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, data, "block_entities", fromVersion, toVersion); ++ ++ WalkerUtils.convertListPath(MCTypeRegistry.BLOCK_NAME, data, "block_ticks", "i", fromVersion, toVersion); ++ ++ // Even though UpgradeData will retrieve the block from the World when the type no longer exists, ++ // the type from the world may not match what was actually queued. So, even though it may look like we ++ // can skip the walker here, we actually don't if we want to be thorough. ++ WalkerUtils.convertListPath(MCTypeRegistry.BLOCK_NAME, data.getMap("UpgradeData"), "neighbor_block_ticks", "i", fromVersion, toVersion); ++ ++ final ListType sections = data.getListUnchecked("sections"); ++ if (sections != null) { ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i, null); ++ if (section == null) { ++ continue; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.BIOME, section.getMap("biomes"), "palette", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, section.getMap("block_states"), "palette", fromVersion, toVersion); ++ } ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, data.getMap("structures"), "starts", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ private V2843() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2846.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2846.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e32224267d53d82ba15942141a5cb7a19eb380f2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2846.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterAbstractAdvancementsRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V2846 { ++ ++ private static final int VERSION = MCVersions.V21W44A + 1; ++ ++ public static void register() { ++ ConverterAbstractAdvancementsRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:husbandry/play_jukebox_in_meadows", "minecraft:adventure/play_jukebox_in_meadows", ++ "minecraft:adventure/caves_and_cliff", "minecraft:adventure/fall_from_world_height", ++ "minecraft:adventure/ride_strider_in_overworld_lava", "minecraft:nether/ride_strider_in_overworld_lava" ++ ) ++ )::get); ++ } ++ ++ private V2846() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2852.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2852.java +new file mode 100644 +index 0000000000000000000000000000000000000000..843e54be50563a647c946ca032a59a8606f0a246 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2852.java +@@ -0,0 +1,31 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2852 { ++ ++ private static final int VERSION = MCVersions.V1_18_PRE5 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ for (final String dimensionKey : dimensions.keys()) { ++ final MapType dimension = dimensions.getMap(dimensionKey); ++ if (!dimension.hasKey("type")) { ++ throw new IllegalStateException("Unable load old custom worlds."); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2852() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9f5771a22c25d4c37a7c6181e9f81151bb6fe7aa +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2967.java +@@ -0,0 +1,58 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V2967 { ++ ++ private static final int VERSION = MCVersions.V22W05A; ++ ++ public static void register() { ++ MCTypeRegistry.WORLD_GEN_SETTINGS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType dimensions = data.getMap("dimensions"); ++ ++ if (dimensions == null) { ++ return null; ++ } ++ ++ for (final String dimension : dimensions.keys()) { ++ final MapType dimensionData = dimensions.getMap(dimension); ++ if (dimensionData == null) { ++ continue; ++ } ++ ++ final MapType generator = dimensionData.getMap("generator"); ++ if (generator == null) { ++ continue; ++ } ++ ++ final MapType settings = generator.getMap("settings"); ++ if (settings == null) { ++ continue; ++ } ++ ++ final MapType structures = settings.getMap("structures"); ++ if (structures == null) { ++ continue; ++ } ++ ++ for (final String structureKey : structures.keys()) { ++ structures.getMap(structureKey).setString("type", "minecraft:random_spread"); ++ } ++ ++ final MapType stronghold = structures.getMap("stronghold"); ++ stronghold.setString("type", "minecraft:concentric_rings"); ++ structures.setMap("minecraft:stronghold", stronghold.copy()); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2967() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java b/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9dab902eb5c2d581516c6fab9afa579997c2faa6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V2970.java +@@ -0,0 +1,209 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.ImmutableMap; ++import com.mojang.logging.LogUtils; ++import it.unimi.dsi.fastutil.objects.Object2IntMap; ++import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; ++import org.slf4j.Logger; ++import java.util.HashMap; ++import java.util.Iterator; ++import java.util.List; ++import java.util.Locale; ++import java.util.Map; ++ ++public final class V2970 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V22W07A + 1; ++ private static final Map CONVERSION_MAP = new HashMap<>( ++ ImmutableMap.builder() ++ .put("mineshaft", BiomeRemap.create(Map.of(List.of("minecraft:badlands", "minecraft:eroded_badlands", "minecraft:wooded_badlands"), "minecraft:mineshaft_mesa"), "minecraft:mineshaft")) ++ .put("shipwreck", BiomeRemap.create(Map.of(List.of("minecraft:beach", "minecraft:snowy_beach"), "minecraft:shipwreck_beached"), "minecraft:shipwreck")) ++ .put("ocean_ruin", BiomeRemap.create(Map.of(List.of("minecraft:warm_ocean", "minecraft:lukewarm_ocean", "minecraft:deep_lukewarm_ocean"), "minecraft:ocean_ruin_warm"), "minecraft:ocean_ruin_cold")) ++ .put("village", BiomeRemap.create(Map.of(List.of("minecraft:desert"), "minecraft:village_desert", List.of("minecraft:savanna"), "minecraft:village_savanna", List.of("minecraft:snowy_plains"), "minecraft:village_snowy", List.of("minecraft:taiga"), "minecraft:village_taiga"), "minecraft:village_plains")) ++ .put("ruined_portal", BiomeRemap.create(Map.of(List.of("minecraft:desert"), "minecraft:ruined_portal_desert", List.of("minecraft:badlands", "minecraft:eroded_badlands", "minecraft:wooded_badlands", "minecraft:windswept_hills", "minecraft:windswept_forest", "minecraft:windswept_gravelly_hills", "minecraft:savanna_plateau", "minecraft:windswept_savanna", "minecraft:stony_shore", "minecraft:meadow", "minecraft:frozen_peaks", "minecraft:jagged_peaks", "minecraft:stony_peaks", "minecraft:snowy_slopes"), "minecraft:ruined_portal_mountain", List.of("minecraft:bamboo_jungle", "minecraft:jungle", "minecraft:sparse_jungle"), "minecraft:ruined_portal_jungle", List.of("minecraft:deep_frozen_ocean", "minecraft:deep_cold_ocean", "minecraft:deep_ocean", "minecraft:deep_lukewarm_ocean", "minecraft:frozen_ocean", "minecraft:ocean", "minecraft:cold_ocean", "minecraft:lukewarm_ocean", "minecraft:warm_ocean"), "minecraft:ruined_portal_ocean"), "minecraft:ruined_portal")) // Fix MC-248814, ruined_portal_standard->ruined_portal ++ .put("pillager_outpost", BiomeRemap.create("minecraft:pillager_outpost")) ++ .put("mansion", BiomeRemap.create("minecraft:mansion")) ++ .put("jungle_pyramid", BiomeRemap.create("minecraft:jungle_pyramid")) ++ .put("desert_pyramid", BiomeRemap.create("minecraft:desert_pyramid")) ++ .put("igloo", BiomeRemap.create("minecraft:igloo")) ++ .put("swamp_hut", BiomeRemap.create("minecraft:swamp_hut")) ++ .put("stronghold", BiomeRemap.create("minecraft:stronghold")) ++ .put("monument", BiomeRemap.create("minecraft:monument")) ++ .put("fortress", BiomeRemap.create("minecraft:fortress")) ++ .put("endcity", BiomeRemap.create("minecraft:end_city")) ++ .put("buried_treasure", BiomeRemap.create("minecraft:buried_treasure")) ++ .put("nether_fossil", BiomeRemap.create("minecraft:nether_fossil")) ++ .put("bastion_remnant", BiomeRemap.create("minecraft:bastion_remnant")) ++ .build() ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static Object2IntOpenHashMap countBiomes(final MapType chunk) { ++ final ListType sections = chunk.getList("sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ final Object2IntOpenHashMap ret = new Object2IntOpenHashMap<>(); ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ final MapType biomes = section.getMap("biomes"); ++ ++ if (biomes == null) { ++ continue; ++ } ++ ++ final ListType palette = biomes.getList("palette", ObjectType.STRING); ++ ++ if (palette == null) { ++ continue; ++ } ++ ++ for (int k = 0, len2 = palette.size(); k < len2; ++k) { ++ ret.addTo(palette.getString(k), 1); ++ } ++ } ++ ++ return ret; ++ } ++ ++ private static String getStructureConverted(String id, final Object2IntOpenHashMap biomeCount) { ++ id = id.toLowerCase(Locale.ROOT); ++ final BiomeRemap remap = CONVERSION_MAP.get(id); ++ if (remap == null) { ++ return null; ++ } ++ if (remap.biomeToNewStructure == null || biomeCount == null) { ++ return remap.dfl; ++ } ++ ++ final Object2IntOpenHashMap remapCount = new Object2IntOpenHashMap<>(); ++ ++ for (final Iterator> iterator = biomeCount.object2IntEntrySet().fastIterator(); iterator.hasNext();) { ++ final Object2IntMap.Entry entry = iterator.next(); ++ final String remappedStructure = remap.biomeToNewStructure.get(entry.getKey()); ++ if (remappedStructure != null) { ++ remapCount.addTo(remappedStructure, entry.getIntValue()); ++ } ++ } ++ ++ String converted = remap.dfl; ++ int maxCount = 0; ++ ++ for (final Iterator> iterator = remapCount.object2IntEntrySet().fastIterator(); iterator.hasNext();) { ++ final Object2IntMap.Entry entry = iterator.next(); ++ final int count = entry.getIntValue(); ++ if (count > maxCount) { ++ maxCount = count; ++ converted = entry.getKey(); ++ } ++ } ++ ++ return converted; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType structures = data.getMap("structures"); ++ if (structures == null || structures.isEmpty()) { ++ return null; ++ } ++ ++ final Object2IntOpenHashMap biomeCounts = countBiomes(data); ++ ++ final MapType starts = structures.getMap("starts"); ++ final MapType references = structures.getMap("References"); ++ ++ if (starts != null) { ++ final MapType newStarts = data.getTypeUtil().createEmptyMap(); ++ structures.setMap("starts", newStarts); ++ ++ for (final String key : starts.keys()) { ++ final MapType value = starts.getMap(key); ++ if ("INVALID".equals(value.getString("id", "INVALID"))) { ++ continue; ++ } ++ ++ final String remapped = getStructureConverted(key, biomeCounts); ++ ++ if (remapped == null) { ++ LOGGER.warn("Encountered unknown structure in dataconverter: " + key); ++ continue; ++ } ++ ++ value.setString("id", remapped); ++ newStarts.setMap(remapped, value); ++ } ++ } ++ ++ // This TRULY is a guess, no idea what biomes the referent has. ++ if (references != null) { ++ final MapType newReferences = data.getTypeUtil().createEmptyMap(); ++ structures.setMap("References", newReferences); ++ for (final String key : references.keys()) { ++ final long[] value = references.getLongs(key); ++ if (value.length == 0) { ++ continue; ++ } ++ ++ final String newKey = getStructureConverted(key, biomeCounts); ++ if (newKey == null) { ++ LOGGER.warn("Encountered unknown structure reference in dataconverter: " + key); ++ continue; ++ } ++ ++ newReferences.setLongs(newKey, value); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V2970() {} ++ ++ private static final class BiomeRemap { ++ ++ public final Map biomeToNewStructure; ++ public final String dfl; ++ ++ private BiomeRemap(final Map biomeToNewStructure, final String dfl) { ++ this.biomeToNewStructure = biomeToNewStructure; ++ this.dfl = dfl; ++ } ++ ++ public static BiomeRemap create(final String newId) { ++ return new BiomeRemap(null, newId); ++ } ++ ++ public static BiomeRemap create(final Map, String> biomeMap, final String newId) { ++ final Map biomeToNewStructure = new HashMap<>(); ++ ++ for (final Map.Entry, String> entry : biomeMap.entrySet()) { ++ final List biomes = entry.getKey(); ++ final String newBiomeStructure = entry.getValue(); ++ ++ for (int i = 0, len = biomes.size(); i < len; ++i) { ++ final String biome = biomes.get(i); ++ if (biomeToNewStructure.putIfAbsent(biome, newBiomeStructure) != null) { ++ throw new IllegalStateException("Duplicate biome remap: " + biome + " -> " + newBiomeStructure + ", but already mapped to " + biomeToNewStructure.get(biome)); ++ } ++ } ++ } ++ ++ return new BiomeRemap(biomeToNewStructure, newId); ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3077.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3077.java +new file mode 100644 +index 0000000000000000000000000000000000000000..61d77841d0ce4ecb22922c8777886917ac54e39f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3077.java +@@ -0,0 +1,40 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3077 { ++ ++ private static final int VERSION = MCVersions.V1_18_2 + 102; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final boolean isLightOn = data.getBoolean("isLightOn"); ++ if (isLightOn) { ++ return null; ++ } ++ ++ final ListType sections = data.getList("sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ section.remove("BlockLight"); ++ section.remove("SkyLight"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3077() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3078.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3078.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e7e13f2b60c80a04749763e05875212655ff42cf +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3078.java +@@ -0,0 +1,19 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.game_event.GameEventListenerWalker; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3078 { ++ ++ private static final int VERSION = MCVersions.V1_18_2 + 103; ++ ++ public static void register() { ++ //registerMob("minecraft:frog"); // changed to simple in 1.21.5 ++ //registerMob("minecraft:tadpole"); // changed to simple in 1.21.5 ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:sculk_shrieker", new GameEventListenerWalker()); ++ } ++ ++ private V3078() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3081.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3081.java +new file mode 100644 +index 0000000000000000000000000000000000000000..776b0f7d507e8fa7f62f25bd251c97c86eea3961 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3081.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.game_event.GameEventListenerWalker; ++ ++public final class V3081 { ++ ++ private static final int VERSION = MCVersions.V22W11A + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:warden"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:warden", new GameEventListenerWalker()); ++ } ++ ++ private V3081() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3082.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3082.java +new file mode 100644 +index 0000000000000000000000000000000000000000..79768b25a32a5333f8cb6ec6e8c422478a6891df +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3082.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3082 { ++ ++ private static final int VERSION = MCVersions.V22W11A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:chest_boat", new DataWalkerItemLists("Items")); ++ } ++ ++ private V3082() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3083.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3083.java +new file mode 100644 +index 0000000000000000000000000000000000000000..35df14855a519c6bed1bc01f6b2bda491bf29441 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3083.java +@@ -0,0 +1,19 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.game_event.GameEventListenerWalker; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3083 { ++ ++ private static final int VERSION = MCVersions.V22W12A + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:allay"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:allay", new DataWalkerItemLists("Inventory")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:allay", new GameEventListenerWalker()); ++ } ++ ++ private V3083() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3084.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3084.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6a096226995e89285054b4ab35ed3e14ae4da694 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3084.java +@@ -0,0 +1,42 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3084 { ++ ++ private static final int VERSION = MCVersions.V22W12A + 2; ++ ++ private static final Map GAME_EVENT_RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("minecraft:block_press", "minecraft:block_activate") ++ .put("minecraft:block_switch", "minecraft:block_activate") ++ .put("minecraft:block_unpress", "minecraft:block_deactivate") ++ .put("minecraft:block_unswitch", "minecraft:block_deactivate") ++ .put("minecraft:drinking_finish", "minecraft:drink") ++ .put("minecraft:elytra_free_fall", "minecraft:elytra_glide") ++ .put("minecraft:entity_damaged", "minecraft:entity_damage") ++ .put("minecraft:entity_dying", "minecraft:entity_die") ++ .put("minecraft:entity_killed", "minecraft:entity_die") ++ .put("minecraft:mob_interact", "minecraft:entity_interact") ++ .put("minecraft:ravager_roar", "minecraft:entity_roar") ++ .put("minecraft:ring_bell", "minecraft:block_change") ++ .put("minecraft:shulker_close", "minecraft:container_close") ++ .put("minecraft:shulker_open", "minecraft:container_open") ++ .put("minecraft:wolf_shaking", "minecraft:entity_shake") ++ .build() ++ ); ++ ++ public static void register() { ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.GAME_EVENT_NAME, (final String name) -> { ++ return GAME_EVENT_RENAMES.get(NamespaceUtil.correctNamespace(name)); ++ }); ++ } ++ ++ private V3084() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3086.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3086.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f06412a417ba12111c9e8f30b747ed3ad6dcbcb6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3086.java +@@ -0,0 +1,54 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterCriteriaRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterEntityToVariant; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import com.google.common.collect.ImmutableMap; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3086 { ++ ++ private static final int VERSION = MCVersions.V22W13A + 1; ++ ++ private static final Int2ObjectOpenHashMap CAT_ID_CONVERSION = new Int2ObjectOpenHashMap<>(); ++ static { ++ CAT_ID_CONVERSION.defaultReturnValue("minecraft:tabby"); ++ CAT_ID_CONVERSION.put(0, "minecraft:tabby"); ++ CAT_ID_CONVERSION.put(1, "minecraft:black"); ++ CAT_ID_CONVERSION.put(2, "minecraft:red"); ++ CAT_ID_CONVERSION.put(3, "minecraft:siamese"); ++ CAT_ID_CONVERSION.put(4, "minecraft:british"); ++ CAT_ID_CONVERSION.put(5, "minecraft:calico"); ++ CAT_ID_CONVERSION.put(6, "minecraft:persian"); ++ CAT_ID_CONVERSION.put(7, "minecraft:ragdoll"); ++ CAT_ID_CONVERSION.put(8, "minecraft:white"); ++ CAT_ID_CONVERSION.put(9, "minecraft:jellie"); ++ CAT_ID_CONVERSION.put(10, "minecraft:all_black"); ++ } ++ ++ private static final Map CAT_ADVANCEMENTS_CONVERSION = new HashMap<>( ++ ImmutableMap.builder() ++ .put("textures/entity/cat/tabby.png", "minecraft:tabby") ++ .put("textures/entity/cat/black.png", "minecraft:black") ++ .put("textures/entity/cat/red.png", "minecraft:red") ++ .put("textures/entity/cat/siamese.png", "minecraft:siamese") ++ .put("textures/entity/cat/british_shorthair.png", "minecraft:british") ++ .put("textures/entity/cat/calico.png", "minecraft:calico") ++ .put("textures/entity/cat/persian.png", "minecraft:persian") ++ .put("textures/entity/cat/ragdoll.png", "minecraft:ragdoll") ++ .put("textures/entity/cat/white.png", "minecraft:white") ++ .put("textures/entity/cat/jellie.png", "minecraft:jellie") ++ .put("textures/entity/cat/all_black.png", "minecraft:all_black") ++ .build() ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:cat", new ConverterEntityToVariant(VERSION, "CatType", CAT_ID_CONVERSION::get)); ++ MCTypeRegistry.ADVANCEMENTS.addStructureConverter(new ConverterCriteriaRename(VERSION, "minecraft:husbandry/complete_catalogue", CAT_ADVANCEMENTS_CONVERSION::get)); ++ } ++ ++ private V3086() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3087.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3087.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b296229502491b54f6352ee1f9db0023296b36ec +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3087.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterEntityToVariant; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++public final class V3087 { ++ ++ private static final int VERSION = MCVersions.V22W13A + 2; ++ ++ private static final Int2ObjectOpenHashMap FROG_ID_CONVERSION = new Int2ObjectOpenHashMap<>(); ++ static { ++ FROG_ID_CONVERSION.put(0, "minecraft:temperate"); ++ FROG_ID_CONVERSION.put(1, "minecraft:warm"); ++ FROG_ID_CONVERSION.put(2, "minecraft:cold"); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:frog", new ConverterEntityToVariant(VERSION, "Variant", FROG_ID_CONVERSION::get)); ++ } ++ ++ private V3087() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3088.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3088.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2752dfd1a7ff896e2ed736846980da5adde6e657 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3088.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterAddBlendingData; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V3088 { ++ ++ // this class originally targeted 3079 but was changed to target a later version without changing the converter, zero clue why ++ // this class then targeted 3088 but was changed to target 3441 ++ // to maintain integrity of the data version, I chose to extract the converter to a separate class and use it in both versions ++ // the reason it is important to never change old converters once released is that it creates _two_ versions under the same id. ++ // Consider the case where a user force upgrades their world, but does not load the chunk. Then, consider the case where ++ // the user does not force upgrade their world. Then, Mojang comes along and makes a decision like this and now both ++ // players load the chunk - they went through a different conversion process, which ultimately creates two versions. ++ // Unfortunately this fix doesn't exactly resolve it, as anyone running Mojang's converters will now be different ++ // from DataConverter's. It's broadly a dumb situation all around that could be avoided if Mojang wasn't being careless here. ++ private static final int VERSION = MCVersions.V22W14A; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterAddBlendingData(VERSION)); ++ } ++ ++ private V3088() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3090.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3090.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e9ad7b4f734ae2c1a19d7a0c5dd7a3cca0e4084f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3090.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3090 { ++ ++ private static final int VERSION = MCVersions.V22W15A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:painting", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Motive", "variant"); ++ RenameHelper.renameSingle(data, "Facing", "facing"); ++ return null; ++ } ++ }); ++ } ++ ++ private V3090() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3093.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3093.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c1cb70feb6815eebe2d2b547cf75841837332240 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3093.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3093 { ++ ++ private static final int VERSION = MCVersions.V22W17A; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:goat", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setBoolean("HasLeftHorn", true); ++ data.setBoolean("HasRightHorn", true); ++ return null; ++ } ++ }); ++ } ++ ++ private V3093() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3094.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3094.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a856d65f411b3fe91eebb429a7dab58dff9520ba +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3094.java +@@ -0,0 +1,44 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3094 { ++ ++ private static final int VERSION = MCVersions.V22W17A + 1; ++ ++ private static final String[] SOUND_VARIANT_TO_INSTRUMENT = new String[] { ++ "minecraft:ponder_goat_horn", ++ "minecraft:sing_goat_horn", ++ "minecraft:seek_goat_horn", ++ "minecraft:feel_goat_horn", ++ "minecraft:admire_goat_horn", ++ "minecraft:call_goat_horn", ++ "minecraft:yearn_goat_horn", ++ "minecraft:dream_goat_horn" ++ }; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:goat_horn", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ ++ if (tag == null) { ++ return null; ++ } ++ ++ final int soundVariant = tag.getInt("SoundVariant"); ++ tag.remove("SoundVariant"); ++ ++ tag.setString("instrument", SOUND_VARIANT_TO_INSTRUMENT[soundVariant < 0 || soundVariant >= SOUND_VARIANT_TO_INSTRUMENT.length ? 0 : soundVariant]); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3094() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3097.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3097.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a86aee0c6acd1afeb647df4c8d27c333a78f1c47 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3097.java +@@ -0,0 +1,63 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterCriteriaRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterEntityVariantRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.poi.ConverterPoiDelete; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class V3097 { ++ ++ private static final int VERSION = MCVersions.V22W19A + 1; ++ ++ public static void register() { ++ final DataConverter removeFilteredBookText = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ tag.remove("filtered_title"); ++ tag.remove("filtered_pages"); ++ ++ return null; ++ } ++ }; ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:writable_book", removeFilteredBookText); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:written_book", removeFilteredBookText); ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:sign", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.remove("FilteredText1"); ++ data.remove("FilteredText2"); ++ data.remove("FilteredText3"); ++ data.remove("FilteredText4"); ++ ++ return null; ++ } ++ }); ++ ++ final Map britishRenamer = new HashMap<>(Map.of( ++ "minecraft:british", "minecraft:british_shorthair" ++ )); ++ final Set poiRemove = new HashSet<>(Set.of( ++ "minecraft:unemployed", ++ "minecraft:nitwit" ++ )); ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:cat", new ConverterEntityVariantRename(VERSION, britishRenamer::get)); ++ MCTypeRegistry.ADVANCEMENTS.addStructureConverter(new ConverterCriteriaRename(VERSION, "minecraft:husbandry/complete_catalogue", britishRenamer::get)); ++ MCTypeRegistry.POI_CHUNK.addStructureConverter(new ConverterPoiDelete(VERSION, poiRemove::contains)); ++ } ++ ++ private V3097() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3108.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3108.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7393cf136f6753c3d58bdd33d5087a2dc0de7db3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3108.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3108 { ++ ++ private static final int VERSION = MCVersions.V1_19_1_PRE1 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType context = data.getMap("__context"); ++ if ("minecraft:overworld".equals(context == null ? null : context.getString("dimension"))) { ++ return null; ++ } ++ ++ data.remove("blending_data"); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3108() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3201.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3201.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bd4b0f27e73e2ea26e1fa2237061055e8a7ded82 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3201.java +@@ -0,0 +1,35 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3201 { ++ ++ private static final int VERSION = MCVersions.V1_19_2 + 81; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ private static void fixList(final MapType data, final String target) { ++ if (data == null) { ++ return; ++ } ++ final String curr = data.getString(target); ++ if (curr == null) { ++ return; ++ } ++ data.setString(target, curr.replace("\"programer_art\"", "\"programmer_art\"")); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ fixList(data, "resourcePacks"); ++ fixList(data, "incompatibleResourcePacks"); ++ return null; ++ } ++ }); ++ } ++ ++ private V3201() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3202.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3202.java +new file mode 100644 +index 0000000000000000000000000000000000000000..697b2fd839312f97877703a8d60b35c59c95ede3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3202.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V3202 { ++ ++ private static final int VERSION = MCVersions.V1_19_2 + 82; ++ ++ public static void register() { ++ V99.registerSign(VERSION, "minecraft:hanging_sign"); ++ } ++ ++ private V3202() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3203.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3203.java +new file mode 100644 +index 0000000000000000000000000000000000000000..bc8339de34a9edb1396479d70e5e76757e0264f8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3203.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3203 { ++ ++ private static final int VERSION = MCVersions.V1_19_2 + 83; ++ ++ public static void register() { ++ //registerMob("minecraft:camel"); // changed to simple in 1.21.5 ++ } ++ ++ private V3203() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3204.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3204.java +new file mode 100644 +index 0000000000000000000000000000000000000000..87053c0c1de258770e7630830307ab484915aad8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3204.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3204 { ++ ++ private static final int VERSION = MCVersions.V1_19_2 + 84; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:chiseled_bookshelf", new DataWalkerItemLists("Items")); ++ } ++ ++ private V3204() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3209.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3209.java +new file mode 100644 +index 0000000000000000000000000000000000000000..85270a36c5f75b1c6be49e461b302c3339c95750 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3209.java +@@ -0,0 +1,18 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterFlattenSpawnEgg; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V3209 { ++ ++ private static final int VERSION = MCVersions.V22W45A + 1; ++ ++ public static void register() { ++ // Note: This converter reads entity id from its sub data, but we need no breakpoint because entity ids are not ++ // remapped this version ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:pig_spawn_egg", new ConverterFlattenSpawnEgg(VERSION, 0)); ++ } ++ ++ private V3209() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3214.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3214.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c7ef09ed0c145d0e5adef04e9e969c837904c5ce +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3214.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3214 { ++ ++ private static final int VERSION = MCVersions.V1_19_3_PRE3 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String value = data.getString("ao"); ++ ++ if ("0".equals(value)) { ++ data.setString("ao", "false"); ++ } else if ("1".equals(value) || "2".equals(value)) { ++ data.setString("ao", "true"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3214() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3319.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3319.java +new file mode 100644 +index 0000000000000000000000000000000000000000..98944037c86cefb42f89674a2eb1abe20a90c800 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3319.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3319 { ++ ++ private static final int VERSION = MCVersions.V1_19_3 + 101; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setString("onboardAccessibility", "false"); ++ return null; ++ } ++ }); ++ } ++ ++ private V3319() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3322.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3322.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5e09176559a30272ef86754f29265afe686ea2ad +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3322.java +@@ -0,0 +1,84 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V3322 { ++ ++ private static final int VERSION = MCVersions.V23W04A + 1; ++ ++ private static final Set EFFECT_ITEM_TYPES = new HashSet<>( ++ Set.of( ++ "minecraft:potion", ++ "minecraft:splash_potion", ++ "minecraft:lingering_potion", ++ "minecraft:tipped_arrow" ++ ) ++ ); ++ ++ private static void updateEffectList(final MapType root, final String path) { ++ if (root == null) { ++ return; ++ } ++ ++ final ListType effects = root.getList(path, ObjectType.MAP); ++ ++ if (effects == null) { ++ return; ++ } ++ ++ for (int i = 0, len = effects.size(); i < len; ++i) { ++ final MapType data = effects.getMap(i); ++ final MapType factorData = data.getMap("FactorCalculationData"); ++ if (factorData == null) { ++ continue; ++ } ++ ++ final int timestamp = factorData.getInt("effect_changed_timestamp", -1); ++ factorData.remove("effect_changed_timestamp"); ++ ++ final int duration = data.getInt("Duration", -1); ++ ++ final int ticksActive = timestamp - duration; ++ factorData.setInt("ticks_active", ticksActive); ++ } ++ } ++ ++ public static void register() { ++ final DataConverter entityEffectFix = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateEffectList(data, "Effects"); ++ updateEffectList(data, "ActiveEffects"); ++ updateEffectList(data, "CustomPotionEffects"); ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.PLAYER.addStructureConverter(entityEffectFix); ++ MCTypeRegistry.ENTITY.addStructureConverter(entityEffectFix); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (!EFFECT_ITEM_TYPES.contains(id)) { ++ return null; ++ } ++ ++ updateEffectList(data.getMap("tag"), "CustomPotionEffects"); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3322() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3325.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3325.java +new file mode 100644 +index 0000000000000000000000000000000000000000..eeba493c110f645b8f95e8229a256a6b90e03e85 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3325.java +@@ -0,0 +1,19 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V3325 { ++ ++ private static final int VERSION = MCVersions.V23W05A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:item_display", new DataWalkerItems("item")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:block_display", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "block_state")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:text_display", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "text")); ++ } ++ ++ private V3325() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3326.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3326.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9e72885b5f7f15b3a02a99ab3fb054f7f6375aa8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3326.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3326 { ++ ++ private static final int VERSION = MCVersions.V23W06A; ++ ++ public static void register() { ++ //registerMob("minecraft:sniffer"); // changed to simple in 1.21.5 ++ } ++ ++ private V3326() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3327.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3327.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7051d4f01b6f43f3d435d21d65b83ba702ffda41 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3327.java +@@ -0,0 +1,19 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerListPaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V3327 { ++ ++ private static final int VERSION = MCVersions.V23W06A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:decorated_pot", new DataWalkerListPaths<>(MCTypeRegistry.ITEM_NAME, "shards")); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:decorated_pot", new DataWalkerItems("item")); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:suspicious_sand", new DataWalkerItems("item")); ++ } ++ ++ private V3327() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3328.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3328.java +new file mode 100644 +index 0000000000000000000000000000000000000000..75a3cbc8e6749abd4bceff710d2f7c3ca6df9d70 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3328.java +@@ -0,0 +1,15 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V3328 { ++ ++ private static final int VERSION = MCVersions.V23W06A + 2; ++ ++ public static void register() { ++ // registers simple entity "minecraft:interaction" ++ } ++ ++ private V3328() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3438.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3438.java +new file mode 100644 +index 0000000000000000000000000000000000000000..203dfd16e37870b549e92ddd1483adeebbdbd9a4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3438.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.tileentity.ConverterAbstractTileEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3438 { ++ ++ public static final int VERSION = MCVersions.V1_19_4 + 101; ++ ++ public static void register() { ++ // brushable block rename ++ MCTypeRegistry.TILE_ENTITY.copyWalkers(VERSION, "minecraft:suspicious_sand", "minecraft:brushable_block"); ++ ++ ConverterAbstractTileEntityRename.register(VERSION, new HashMap<>(Map.of( ++ "minecraft:suspicious_sand", "minecraft:brushable_block" ++ ))::get); ++ ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:brushable_block", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "loot_table", "LootTable"); ++ RenameHelper.renameSingle(data, "loot_table_seed", "LootTableSeed"); ++ return null; ++ } ++ }); ++ ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ Map.of( ++ "minecraft:pottery_shard_archer", "minecraft:archer_pottery_shard", ++ "minecraft:pottery_shard_prize", "minecraft:prize_pottery_shard", ++ "minecraft:pottery_shard_arms_up", "minecraft:arms_up_pottery_shard", ++ "minecraft:pottery_shard_skull", "minecraft:skull_pottery_shard" ++ ) ++ )::get); ++ } ++ ++ private V3438() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3439.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3439.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d449c62b7be3748dfc34c11cf4d929974c9a5191 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3439.java +@@ -0,0 +1,119 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3439 { ++ ++ private static final int VERSION = MCVersions.V1_19_4 + 102; ++ ++ private static void handleSignText(final MapType text, final long fromVersion, final long toVersion) { ++ if (text == null) { ++ return; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, text, "messages", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, text, "filtered_messages", fromVersion, toVersion); ++ } ++ ++ static void registerSign(final int version, final String id) { ++ MCTypeRegistry.TILE_ENTITY.addWalker(version, id, (final MapType data, final long fromVersion, final long toVersion) -> { ++ handleSignText(data.getMap("front_text"), fromVersion, toVersion); ++ handleSignText(data.getMap("back_text"), fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ public static void register() { ++ final DataConverter signTileUpdater = new DataConverter<>(VERSION) { ++ private static final String DEFAULT_COLOR = "black"; ++ ++ private static ListType migrateToList(final MapType root, final String prefix) { ++ if (root == null) { ++ return null; ++ } ++ ++ final ListType ret = root.getTypeUtil().createEmptyList(); ++ ++ ret.addString(root.getString(prefix.concat("1"), ComponentUtils.EMPTY)); ++ ret.addString(root.getString(prefix.concat("2"), ComponentUtils.EMPTY)); ++ ret.addString(root.getString(prefix.concat("3"), ComponentUtils.EMPTY)); ++ ret.addString(root.getString(prefix.concat("4"), ComponentUtils.EMPTY)); ++ ++ return ret; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ // front text ++ final MapType frontText = data.getTypeUtil().createEmptyMap(); ++ data.setMap("front_text", frontText); ++ ++ final ListType frontMessages = migrateToList(data, "Text"); ++ frontText.setList("messages", frontMessages); ++ ++ ListType frontFilteredMessages = null; ++ ++ for (int i = 0; i < 4; ++i) { ++ final String filtered = data.getString("FilteredText" + i); ++ if (filtered == null) { ++ if (frontFilteredMessages != null) { ++ frontFilteredMessages.addString(frontMessages.getString(i)); ++ } ++ continue; ++ } ++ ++ if (frontFilteredMessages == null) { ++ frontFilteredMessages = data.getTypeUtil().createEmptyList(); ++ for (int k = 0; k < i; ++k) { ++ frontFilteredMessages.addString(frontMessages.getString(k)); ++ } ++ } ++ ++ frontFilteredMessages.addString(filtered); ++ } ++ ++ if (frontFilteredMessages != null) { ++ frontText.setList("filtered_messages", frontFilteredMessages); ++ } ++ ++ frontText.setString("color", data.getString("Color", DEFAULT_COLOR)); ++ frontText.setBoolean("has_glowing_text", data.getBoolean("GlowingText", false)); ++ frontText.setBoolean("_filtered_correct", true); ++ ++ // back text ++ final MapType backText = data.getTypeUtil().createEmptyMap(); ++ data.setMap("back_text", backText); ++ ++ final ListType blankMessages = data.getTypeUtil().createEmptyList(); ++ backText.setList("messages", blankMessages); ++ ++ for (int i = 0; i < 4; ++i) { ++ blankMessages.addString(ComponentUtils.EMPTY); ++ } ++ ++ backText.setString("color", DEFAULT_COLOR); ++ backText.setBoolean("has_glowing_text", false); ++ ++ // misc ++ data.setBoolean("is_waxed", false); ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:sign", signTileUpdater); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:hanging_sign", signTileUpdater); ++ ++ registerSign(VERSION, "minecraft:sign"); ++ // in 1.21.6 this was changed to a subversion. I don't see why we need that change. ++ registerSign(VERSION, "minecraft:hanging_sign"); ++ } ++ ++ private V3439() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3440.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3440.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5cc9844fb342731e997b449e9b711c3b6d8e5762 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3440.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.ConverterAbstractStringValueTypeRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++import java.util.Arrays; ++import java.util.HashSet; ++ ++public final class V3440 { ++ ++ private static final int VERSION = MCVersions.V1_19_4 + 103; ++ ++ public static void register() { ++ // Note: MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST is namespaced string ++ ConverterAbstractStringValueTypeRename.register(VERSION, MCTypeRegistry.MULTI_NOISE_BIOME_SOURCE_PARAMETER_LIST, (final String in) -> { ++ return "minecraft:overworld_update_1_20".equals(NamespaceUtil.correctNamespace(in)) ? "minecraft:overworld" : null; ++ }); ++ MCTypeRegistry.LIGHTWEIGHT_LEVEL.addStructureConverter(new ConverterRemoveFeatureFlag(VERSION, new HashSet<>( ++ Arrays.asList( ++ "minecraft:update_1_20" ++ ) ++ ))); ++ } ++ ++ private V3440() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3441.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3441.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2cf41561b4a229ba4d60540f85ba0a8946bb9753 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3441.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterAddBlendingData; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V3441 { ++ ++ private static final int VERSION = MCVersions.V1_19_4 + 104; ++ ++ public static void register() { ++ // See V3088 for why this converter is duplicated here and in V3088 ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterAddBlendingData(VERSION)); ++ } ++ ++ private V3441() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3447.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3447.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5db4a5222bf80f01c128d97ec849b89003837beb +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3447.java +@@ -0,0 +1,49 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3447 { ++ ++ private static final int VERSION = MCVersions.V23W14A + 2; ++ ++ public static void register() { ++ final String[] targets = new String[] { ++ "minecraft:angler_pottery_shard", ++ "minecraft:archer_pottery_shard", ++ "minecraft:arms_up_pottery_shard", ++ "minecraft:blade_pottery_shard", ++ "minecraft:brewer_pottery_shard", ++ "minecraft:burn_pottery_shard", ++ "minecraft:danger_pottery_shard", ++ "minecraft:explorer_pottery_shard", ++ "minecraft:friend_pottery_shard", ++ "minecraft:heart_pottery_shard", ++ "minecraft:heartbreak_pottery_shard", ++ "minecraft:howl_pottery_shard", ++ "minecraft:miner_pottery_shard", ++ "minecraft:mourner_pottery_shard", ++ "minecraft:plenty_pottery_shard", ++ "minecraft:prize_pottery_shard", ++ "minecraft:sheaf_pottery_shard", ++ "minecraft:shelter_pottery_shard", ++ "minecraft:skull_pottery_shard", ++ "minecraft:snort_pottery_shard" ++ }; ++ // shard->sherd ++ final Map rename = new HashMap<>(targets.length); ++ ++ for (final String target : targets) { ++ final String replace = target.replace("_pottery_shard", "_pottery_sherd"); ++ if (rename.put(target, replace) != null) { ++ throw new IllegalArgumentException("Duplicate target " + target); ++ } ++ } ++ ++ ConverterAbstractItemRename.register(VERSION, rename::get); ++ } ++ ++ private V3447() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3448.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3448.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b9d7e81938320a30fb881a6be9e377aea4c75cec +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3448.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerListPaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3448 { ++ ++ private static final int VERSION = MCVersions.V23W14A + 3; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:decorated_pot", new DataWalkerListPaths<>(MCTypeRegistry.ITEM_NAME, "sherds")); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:decorated_pot", new DataWalkerItems("item")); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:decorated_pot", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "shards", "sherds"); ++ return null; ++ } ++ }); ++ } ++ ++ private V3448() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3450.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3450.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9e7f34a40280a7704c4a4d1c03a7dda8e030aff5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3450.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterRenameStatus; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3450 { ++ ++ private static final int VERSION = MCVersions.V23W16A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterRenameStatus(VERSION, new HashMap<>( ++ Map.of( ++ "minecraft:liquid_carvers", "minecraft:carvers", ++ "minecraft:heightmaps", "minecraft:spawn" ++ ) ++ )::get)); ++ } ++ ++ private V3450() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3451.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3451.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7383d49edd6998ce93b13e135dcad43145c4e23a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3451.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3451 { ++ ++ private static final int VERSION = MCVersions.V23W16A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.remove("isLightOn"); ++ ++ final ListType sections = data.getList("sections", ObjectType.MAP); ++ if (sections == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = sections.size(); i < len; ++i) { ++ final MapType section = sections.getMap(i); ++ ++ section.remove("BlockLight"); ++ section.remove("SkyLight"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3451() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3459.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3459.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6ef8c0f17c49405e38f299891c98791905e572de +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3459.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3459 { ++ ++ private static final int VERSION = MCVersions.V1_20_PRE5 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.LEVEL.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.hasKey("DragonFight")) { ++ return null; ++ } ++ ++ final MapType dimensionData = data.getMap("DimensionData"); ++ if (dimensionData == null) { ++ return null; ++ } ++ ++ final MapType endData = dimensionData.getMap("1"); ++ if (endData != null) { ++ final MapType dragonFight = endData.getMap("DragonFight", endData.getTypeUtil().createEmptyMap()).copy(); ++ V3807.flattenBlockPos(dragonFight, "ExitPortalLocation"); ++ data.setMap("DragonFight", dragonFight); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3459() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3564.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3564.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8448981de260b7af33ea8ed62866b6fb95f544e5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3564.java +@@ -0,0 +1,94 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3564 { ++ ++ private static final int VERSION = MCVersions.V1_20_1 + 99; ++ ++ public static void register() { ++ final DataConverter converter = new DataConverter<>(VERSION) { ++ ++ private static final String[] LEGACY_FIELDS = new String[] { ++ "Text1", ++ "Text2", ++ "Text3", ++ "Text4", ++ ++ "FilteredText1", ++ "FilteredText2", ++ "FilteredText3", ++ "FilteredText4", ++ ++ "Color", ++ ++ "GlowingText" ++ }; ++ ++ ++ private static void updateText(final MapType text) { ++ if (text == null) { ++ return; ++ } ++ ++ if (text.getBoolean("_filtered_correct", false)) { ++ text.remove("_filtered_correct"); ++ return; ++ } ++ ++ final ListType filteredMessages = text.getList("filtered_messages", ObjectType.STRING); ++ ++ if (filteredMessages == null || filteredMessages.size() == 0) { ++ return; ++ } ++ ++ // should treat null here as empty list ++ final ListType messages = text.getList("messages", ObjectType.STRING); ++ ++ final ListType newFilteredList = filteredMessages.getTypeUtil().createEmptyList(); ++ boolean newFilteredIsEmpty = true; ++ ++ for (int i = 0, len = filteredMessages.size(); i < len; ++i) { ++ final String filtered = filteredMessages.getString(i); ++ final String message = messages != null && i < messages.size() ? messages.getString(i) : ComponentUtils.EMPTY; ++ ++ final String newFiltered = ComponentUtils.EMPTY.equals(filtered) ? message : filtered; ++ ++ newFilteredList.addString(newFiltered); ++ ++ newFilteredIsEmpty = newFilteredIsEmpty && ComponentUtils.EMPTY.equals(newFiltered); ++ } ++ ++ if (newFilteredIsEmpty) { ++ text.remove("filtered_messages"); ++ } else { ++ text.setList("filtered_messages", newFilteredList); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ updateText(data.getMap("front_text")); ++ updateText(data.getMap("back_text")); ++ ++ for (final String toRemove : LEGACY_FIELDS) { ++ data.remove(toRemove); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:sign", converter); ++ // I don't know why this was moved to a sub version, but we don't need to do that. ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:hanging_sign", converter); ++ } ++ ++ private V3564() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3565.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3565.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d0e6bcd9c4b48743a522ea2b79fa97fe27eb8cc8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3565.java +@@ -0,0 +1,32 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3565 { ++ ++ private static final int VERSION = MCVersions.V1_20_1 + 100; ++ ++ public static void register() { ++ MCTypeRegistry.SAVED_DATA_RANDOM_SEQUENCES.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType oldData = root.getMap("data"); ++ if (oldData == null) { ++ return null; ++ } ++ ++ final MapType newData = root.getTypeUtil().createEmptyMap(); ++ root.setMap("data", newData); ++ ++ newData.setMap("sequences", oldData); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3565() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3566.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3566.java +new file mode 100644 +index 0000000000000000000000000000000000000000..cae496fd174ac38b36885bdfa36805cd5c8321be +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3566.java +@@ -0,0 +1,58 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3566 { ++ ++ private static final int VERSION = MCVersions.V1_20_1 + 101; ++ ++ public static void register() { ++ MCTypeRegistry.SAVED_DATA_SCOREBOARD.addStructureConverter(new DataConverter<>(VERSION) { ++ ++ private static final Map SLOT_RENAMES = new HashMap<>( ++ ImmutableMap.builder() ++ .put("slot_0", "list") ++ .put("slot_1", "sidebar") ++ .put("slot_2", "below_name") ++ .put("slot_3", "sidebar.team.black") ++ .put("slot_4", "sidebar.team.dark_blue") ++ .put("slot_5", "sidebar.team.dark_green") ++ .put("slot_6", "sidebar.team.dark_aqua") ++ .put("slot_7", "sidebar.team.dark_red") ++ .put("slot_8", "sidebar.team.dark_purple") ++ .put("slot_9", "sidebar.team.gold") ++ .put("slot_10", "sidebar.team.gray") ++ .put("slot_11", "sidebar.team.dark_gray") ++ .put("slot_12", "sidebar.team.blue") ++ .put("slot_13", "sidebar.team.green") ++ .put("slot_14", "sidebar.team.aqua") ++ .put("slot_15", "sidebar.team.red") ++ .put("slot_16", "sidebar.team.light_purple") ++ .put("slot_17", "sidebar.team.yellow") ++ .put("slot_18", "sidebar.team.white") ++ .build() ++ ); ++ ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ RenameHelper.renameKeys(data.getMap("DisplaySlots"), SLOT_RENAMES::get); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3566() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3568.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3568.java +new file mode 100644 +index 0000000000000000000000000000000000000000..96a7c836b278a150164c7632a5b88c14a2978d52 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3568.java +@@ -0,0 +1,245 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class V3568 { ++ ++ private static final int VERSION = MCVersions.V23W31A + 1; ++ ++ private static final String[] EFFECT_ID_MAP = new String[34]; ++ static { ++ EFFECT_ID_MAP[1] = "minecraft:speed"; ++ EFFECT_ID_MAP[2] = "minecraft:slowness"; ++ EFFECT_ID_MAP[3] = "minecraft:haste"; ++ EFFECT_ID_MAP[4] = "minecraft:mining_fatigue"; ++ EFFECT_ID_MAP[5] = "minecraft:strength"; ++ EFFECT_ID_MAP[6] = "minecraft:instant_health"; ++ EFFECT_ID_MAP[7] = "minecraft:instant_damage"; ++ EFFECT_ID_MAP[8] = "minecraft:jump_boost"; ++ EFFECT_ID_MAP[9] = "minecraft:nausea"; ++ EFFECT_ID_MAP[10] = "minecraft:regeneration"; ++ EFFECT_ID_MAP[11] = "minecraft:resistance"; ++ EFFECT_ID_MAP[12] = "minecraft:fire_resistance"; ++ EFFECT_ID_MAP[13] = "minecraft:water_breathing"; ++ EFFECT_ID_MAP[14] = "minecraft:invisibility"; ++ EFFECT_ID_MAP[15] = "minecraft:blindness"; ++ EFFECT_ID_MAP[16] = "minecraft:night_vision"; ++ EFFECT_ID_MAP[17] = "minecraft:hunger"; ++ EFFECT_ID_MAP[18] = "minecraft:weakness"; ++ EFFECT_ID_MAP[19] = "minecraft:poison"; ++ EFFECT_ID_MAP[20] = "minecraft:wither"; ++ EFFECT_ID_MAP[21] = "minecraft:health_boost"; ++ EFFECT_ID_MAP[22] = "minecraft:absorption"; ++ EFFECT_ID_MAP[23] = "minecraft:saturation"; ++ EFFECT_ID_MAP[24] = "minecraft:glowing"; ++ EFFECT_ID_MAP[25] = "minecraft:levitation"; ++ EFFECT_ID_MAP[26] = "minecraft:luck"; ++ EFFECT_ID_MAP[27] = "minecraft:unluck"; ++ EFFECT_ID_MAP[28] = "minecraft:slow_falling"; ++ EFFECT_ID_MAP[29] = "minecraft:conduit_power"; ++ EFFECT_ID_MAP[30] = "minecraft:dolphins_grace"; ++ EFFECT_ID_MAP[31] = "minecraft:bad_omen"; ++ EFFECT_ID_MAP[32] = "minecraft:hero_of_the_village"; ++ EFFECT_ID_MAP[33] = "minecraft:darkness"; ++ } ++ private static final Set EFFECT_ITEMS = ++ new HashSet<>( ++ Set.of( ++ "minecraft:potion", ++ "minecraft:splash_potion", ++ "minecraft:lingering_potion", ++ "minecraft:tipped_arrow" ++ ) ++ ); ++ ++ private static String readLegacyEffect(final MapType data, final String path) { ++ final Number id = data.getNumber(path); ++ if (id == null) { ++ return null; ++ } ++ ++ final int castedId = id.intValue(); ++ return castedId >= 0 && castedId < EFFECT_ID_MAP.length ? EFFECT_ID_MAP[castedId] : null; ++ } ++ ++ private static void convertLegacyEffect(final MapType data, final String legacyPath, final String newPath) { ++ final Number id = data.getNumber(legacyPath); ++ data.remove(legacyPath); ++ ++ if (id == null) { ++ return; ++ } ++ ++ final int castedId = id.intValue(); ++ final String newId = castedId >= 0 && castedId < EFFECT_ID_MAP.length ? EFFECT_ID_MAP[castedId] : null; ++ ++ if (newId == null) { ++ return; ++ } ++ ++ data.setString(newPath, newId); ++ } ++ ++ private static final Map MOB_EFFECT_RENAMES = new HashMap<>(); ++ static { ++ MOB_EFFECT_RENAMES.put("Ambient", "ambient"); ++ MOB_EFFECT_RENAMES.put("Amplifier", "amplifier"); ++ MOB_EFFECT_RENAMES.put("Duration", "duration"); ++ MOB_EFFECT_RENAMES.put("ShowParticles", "show_particles"); ++ MOB_EFFECT_RENAMES.put("ShowIcon", "show_icon"); ++ MOB_EFFECT_RENAMES.put("FactorCalculationData", "factor_calculation_data"); ++ MOB_EFFECT_RENAMES.put("HiddenEffect", "hidden_effect"); ++ } ++ ++ private static void convertMobEffect(final MapType mobEffect) { ++ if (mobEffect == null) { ++ return; ++ } ++ ++ convertLegacyEffect(mobEffect, "Id", "id"); ++ ++ for (final Map.Entry rename : MOB_EFFECT_RENAMES.entrySet()) { ++ RenameHelper.renameSingle(mobEffect, rename.getKey(), rename.getValue()); ++ } ++ ++ convertMobEffect(mobEffect.getMap("hidden_effect")); ++ } ++ ++ private static void convertMobEffectList(final MapType data, final String oldPath, final String newPath) { ++ final ListType effects = data.getList(oldPath, ObjectType.MAP); ++ if (effects == null) { ++ return; ++ } ++ ++ for (int i = 0, len = effects.size(); i < len; ++i) { ++ convertMobEffect(effects.getMap(i)); ++ } ++ ++ data.remove(oldPath); ++ data.setList(newPath, effects); ++ } ++ ++ private static void removeAndSet(final MapType data, final String toRemovePath, ++ final String toSetPath, final Object toSet) { ++ data.remove(toRemovePath); ++ if (toSet != null) { ++ data.setGeneric(toSetPath, toSet); ++ } ++ } ++ ++ private static void updateSuspiciousStew(final MapType from, final MapType into) { ++ removeAndSet(into, "EffectId", "id", readLegacyEffect(from, "EffectId")); ++ removeAndSet(into, "EffectDuration", "duration", from.getGeneric("EffectDuration")); ++ } ++ ++ public static void register() { ++ final DataConverter beaconConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertLegacyEffect(data, "Primary", "primary_effect"); ++ convertLegacyEffect(data, "Secondary", "secondary_effect"); ++ ++ return null; ++ } ++ }; ++ ++ final DataConverter mooshroomConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType newEffect = data.getTypeUtil().createEmptyMap(); ++ updateSuspiciousStew(data, newEffect); ++ ++ data.remove("EffectId"); ++ data.remove("EffectDuration"); ++ ++ if (!newEffect.isEmpty()) { ++ final ListType stewEffects = data.getTypeUtil().createEmptyList(); ++ data.setList("stew_effects", stewEffects); ++ ++ stewEffects.addMap(newEffect); ++ } ++ ++ return null; ++ } ++ }; ++ final DataConverter arrowConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertMobEffectList(data, "CustomPotionEffects", "custom_potion_effects"); ++ return null; ++ } ++ }; ++ final DataConverter areaEffectCloudConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertMobEffectList(data, "Effects", "effects"); ++ return null; ++ } ++ }; ++ final DataConverter livingEntityConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertMobEffectList(data, "ActiveEffects", "active_effects"); ++ return null; ++ } ++ }; ++ ++ final DataConverter itemConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final String id = root.getString("id"); ++ ++ final MapType tag = root.getMap("tag"); ++ ++ if (tag == null) { ++ return null; ++ } ++ ++ if ("minecraft:suspicious_stew".equals(id)) { ++ RenameHelper.renameSingle(tag, "Effects", "effects"); ++ ++ final ListType effects = tag.getList("effects", ObjectType.MAP); ++ ++ if (effects != null) { ++ for (int i = 0, len = effects.size(); i < len; ++i) { ++ final MapType effect = effects.getMap(i); ++ updateSuspiciousStew(effect, effect); ++ } ++ } ++ ++ return null; ++ } ++ ++ if (EFFECT_ITEMS.contains(id)) { ++ convertMobEffectList(tag, "CustomPotionEffects", "custom_potion_effects"); ++ return null; ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:beacon", beaconConverter); ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:mooshroom", mooshroomConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:arrow", arrowConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:area_effect_cloud", areaEffectCloudConverter); ++ MCTypeRegistry.ENTITY.addStructureConverter(livingEntityConverter); ++ ++ MCTypeRegistry.PLAYER.addStructureConverter(livingEntityConverter); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(itemConverter); ++ } ++ ++ private V3568() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3682.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3682.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ba7e9c7c17a36222e384c78f6a260a97490a3610 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3682.java +@@ -0,0 +1,16 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V3682 { ++ ++ private static final int VERSION = MCVersions.V23W41A + 1; ++ ++ public static void register() { ++ V1458.namedInventory(VERSION, "minecraft:crafter"); ++ } ++ ++ private V3682() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3683.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3683.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d91b8d638af2d104de989bdf727f74914727fbd8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3683.java +@@ -0,0 +1,33 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3683 { ++ ++ private static final int VERSION = MCVersions.V23W41A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:tnt", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Fuse", "fuse"); ++ ++ final MapType defaultState = data.getTypeUtil().createEmptyMap(); ++ data.setMap("block_state", defaultState); ++ ++ defaultState.setString("Name", "minecraft:tnt"); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:tnt", new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "block_state")); ++ } ++ ++ private V3683() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3685.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3685.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4393d5395259f9aaf941ad15352ac6615f44841a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3685.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++ ++public final class V3685 { ++ ++ private static final int VERSION = MCVersions.V23W42A + 1; ++ ++ private static String getType(final MapType arrow) { ++ return "minecraft:empty".equals(arrow.getString("Potion", "minecraft:empty")) ? "minecraft:arrow" : "minecraft:tipped_arrow"; ++ } ++ ++ private static MapType createItem(final TypeUtil util, final String id, final int count) { ++ final MapType ret = util.createEmptyMap(); ++ ++ ret.setString("id", id); ++ ret.setInt("Count", count); ++ ++ return ret; ++ } ++ ++ private static void registerArrowEntity(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState")); ++ // new: item ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItems("item")); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:trident", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Trident", "item"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:arrow", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setMap("item", createItem(data.getTypeUtil(), getType(data), 1)); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:spectral_arrow", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setMap("item", createItem(data.getTypeUtil(), "minecraft:spectral_arrow", 1)); ++ return null; ++ } ++ }); ++ ++ registerArrowEntity("minecraft:trident"); ++ registerArrowEntity("minecraft:spectral_arrow"); ++ registerArrowEntity("minecraft:arrow"); ++ } ++ ++ private V3685() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3689.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3689.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b3a8af24d80ed3fa9f205eb8d97bbd1defb9cbc8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3689.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3689 { ++ ++ private static final int VERSION = MCVersions.V23W44A + 1; ++ ++ public static void register() { ++ //registerMob("minecraft:breeze"); // changed to simple in 1.21.5 ++ // minecraft:wind_charge is a simple entity ++ // minecraft:breeze_wind_charge is a simple entity ++ ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:trial_spawner", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, data, "spawn_potentials", "data", "entity", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("spawn_data"), "entity", fromVersion, toVersion); ++ return null; ++ }); ++ } ++ ++ private V3689() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3692.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3692.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1fc62f9cadb990790420376d5c80b14775b71a48 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3692.java +@@ -0,0 +1,25 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.blockname.ConverterAbstractBlockRename; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3692 { ++ ++ private static final int VERSION = MCVersions.V23W46A + 1; ++ ++ private static final Map GRASS_RENAME = new HashMap<>( ++ Map.of( ++ "minecraft:grass", "minecraft:short_grass" ++ ) ++ ); ++ ++ public static void register() { ++ ConverterAbstractBlockRename.register(VERSION, GRASS_RENAME::get); ++ ConverterAbstractItemRename.register(VERSION, GRASS_RENAME::get); ++ } ++ ++ private V3692() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3799.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3799.java +new file mode 100644 +index 0000000000000000000000000000000000000000..546d69f22b52f00cf2fa9bacc5fda6d2f116f148 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3799.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V3799 { ++ ++ private static final int VERSION = MCVersions.V1_20_4 + 99; ++ ++ public static void register() { ++ //V100.registerEquipment(VERSION, "minecraft:armadillo"); // changed to simple in 1.21.5 ++ } ++ ++ private V3799() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3800.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3800.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a40397feb5962bd5f4a44cc85bb359f5f99ff03a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3800.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3800 { ++ ++ private static final int VERSION = MCVersions.V1_20_4 + 100; ++ ++ public static void register() { ++ final Map renames = new HashMap<>( ++ Map.of( ++ "minecraft:scute", "minecraft:turtle_scute" ++ ) ++ ); ++ ++ ConverterAbstractItemRename.register(VERSION, renames::get); ++ } ++ ++ private V3800() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3803.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3803.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7ff5e2f1a386d75b6d0d6fc3160f2241bf74b262 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3803.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterEnchantmentsRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3803 { ++ ++ private static final int VERSION = MCVersions.V23W51B + 1; ++ ++ public static void register() { ++ final Map renames = new HashMap<>( ++ Map.of( ++ "minecraft:sweeping", "minecraft:sweeping_edge" ++ ) ++ ); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new ConverterEnchantmentsRename(VERSION, renames::get)); ++ } ++ ++ private V3803() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3807.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3807.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b329a8086c695c1c16ece6dd40c0cbfdc3d04835 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3807.java +@@ -0,0 +1,72 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3807 { ++ ++ private static final int VERSION = MCVersions.V24W04A + 1; ++ ++ public static void flattenBlockPos(final MapType data, final String path) { ++ if (data == null) { ++ return; ++ } ++ ++ final MapType pos = data.getMap(path); ++ if (pos == null) { ++ return; ++ } ++ ++ final Number x = pos.getNumber("X"); ++ final Number y = pos.getNumber("Y"); ++ final Number z = pos.getNumber("Z"); ++ ++ if (x == null || y == null || z == null) { ++ return; ++ } ++ ++ data.setInts(path, new int[] { x.intValue(), y.intValue(), z.intValue() }); ++ } ++ ++ public static void register() { ++ // Step 0 ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:vault", (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root.getMap("config"), "key_item", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root.getMap("server_data"), "items_to_eject", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root.getMap("shared_data"), "display_item", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Step 1 ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureConverter(new DataConverter<>(VERSION, 1) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ ++ if (data == null) { ++ return null; ++ } ++ ++ final ListType banners = data.getList("banners", ObjectType.MAP); ++ ++ if (banners == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = banners.size(); i < len; ++i) { ++ V3807.flattenBlockPos(banners.getMap(i), "Pos"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3807() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3808.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3808.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c7c4f912d9baf6df0392aee3c73f8f0a8ad938c3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3808.java +@@ -0,0 +1,79 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3808 { ++ ++ private static final int VERSION = MCVersions.V24W04A + 2; ++ ++ public static void register() { ++ class BodyArmorConverter extends DataConverter { ++ private final String path; ++ private final boolean clearArmor; ++ ++ public BodyArmorConverter(final int toVersion, final String path, final boolean clearArmor) { ++ this(toVersion, 0, path, clearArmor); ++ } ++ ++ public BodyArmorConverter(final int toVersion, final int versionStep, final String path, final boolean clearArmor) { ++ super(toVersion, versionStep); ++ ++ this.path = path; ++ this.clearArmor = clearArmor; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType prev = data.getMap(this.path); ++ ++ if (prev == null) { ++ return null; ++ } ++ ++ data.remove(this.path); ++ ++ data.setMap("body_armor_item", prev); ++ data.setFloat("body_armor_drop_chance", 2.0F); ++ ++ if (this.clearArmor) { ++ final ListType armor = data.getList("ArmorItems", ObjectType.MAP); ++ if (armor != null && armor.size() > 2) { ++ armor.setMap(2, data.getTypeUtil().createEmptyMap()); ++ } ++ ++ final ListType chances = data.getList("ArmorDropChances", ObjectType.FLOAT); ++ if (chances != null && chances.size() > 2) { ++ chances.setFloat(2, 0.085F); ++ } ++ } ++ ++ return null; ++ } ++ } ++ ++ // Step 0 ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:horse", new BodyArmorConverter(VERSION, "ArmorItem", true)); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:horse", new DataWalkerItems("SaddleItem")); ++ ++ // Step 1 ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:llama", new BodyArmorConverter(VERSION, 1, "DecorItem", false)); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 1, "minecraft:llama", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 1, "minecraft:llama", new DataWalkerItems("SaddleItem")); ++ ++ // Step 2 ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:trader_llama", new BodyArmorConverter(VERSION, 2, "DecorItem", false)); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 2, "minecraft:trader_llama", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, 2, "minecraft:trader_llama", new DataWalkerItems("SaddleItem")); ++ } ++ ++ private V3808() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3809.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3809.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a5d3efbf4b32e813a66c2be700123a6f4cae4f28 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3809.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3809 { ++ ++ private static final int VERSION = MCVersions.V24W05A; ++ ++ public static void register() { ++ final DataConverter slotConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType items = data.getList("Items", ObjectType.MAP); ++ if (items == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = items.size(); i < len; ++i) { ++ final MapType item = items.getMap(i); ++ ++ final int slot = item.getInt("Slot", 2); ++ item.setByte("Slot", (byte)(slot - 2)); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:llama", slotConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:trader_llama", slotConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:mule", slotConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:donkey", slotConverter); ++ } ++ ++ private V3809() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3812.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3812.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8465ca45a23c940bcab16450598562cf8c037051 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3812.java +@@ -0,0 +1,48 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public final class V3812 { ++ ++ private static final int VERSION = MCVersions.V24W05B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:wolf", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ boolean doubleHealth = false; ++ ++ final ListType attributes = data.getList("Attributes", ObjectType.MAP); ++ if (attributes != null) { ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ final MapType attribute = attributes.getMap(i); ++ ++ if (!"minecraft:generic.max_health".equals(NamespaceUtil.correctNamespace(attribute.getString("Name")))) { ++ continue; ++ } ++ ++ final double base = attribute.getDouble("Base", 0.0D); ++ if (base == 20.0D) { ++ attribute.setDouble("Base", 40.0D); ++ doubleHealth = true; ++ } ++ } ++ } ++ ++ if (doubleHealth) { ++ data.setFloat("Health", data.getFloat("Health", 0.0F) * 2.0F); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3812() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3813.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3813.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8169c681b04f0d6dfd21c890ae4123d638ca4513 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3813.java +@@ -0,0 +1,137 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++ ++public final class V3813 { ++ ++ private static final int VERSION = MCVersions.V24W05B + 2; ++ ++ private static final String[] PATROLLING_MOBS = new String[] { ++ "minecraft:witch", ++ "minecraft:ravager", ++ "minecraft:pillager", ++ "minecraft:illusioner", ++ "minecraft:evoker", ++ "minecraft:vindicator" ++ }; ++ ++ public static void register() { ++ class RootPositionConverter extends DataConverter { ++ private final RenamePair[] convert; ++ ++ public RootPositionConverter(final int toVersion, final RenamePair[] convert) { ++ this(toVersion, 0, convert); ++ } ++ ++ public RootPositionConverter(final int toVersion, final int versionStep, final RenamePair[] convert) { ++ super(toVersion, versionStep); ++ this.convert = convert; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ for (final RenamePair rename : this.convert) { ++ V3807.flattenBlockPos(data, rename.from); ++ RenameHelper.renameSingle(data, rename.from, rename.to); ++ } ++ return null; ++ } ++ } ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:bee", new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("HivePos", "hive_pos"), ++ new RenamePair("FlowerPos", "flower_pos") ++ })); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:end_crystal", new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("BeamTarget", "beam_target"), ++ })); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:wandering_trader", new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("WanderTarget", "wander_target"), ++ })); ++ ++ final RootPositionConverter patrolConverter = new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("PatrolTarget", "patrol_target"), ++ }); ++ for (final String id : PATROLLING_MOBS) { ++ MCTypeRegistry.ENTITY.addConverterForId(id, patrolConverter); ++ } ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("Leash", "leash"), ++ })); ++ ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:beehive", new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("FlowerPos", "flower_pos"), ++ })); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:end_gateway", new RootPositionConverter(VERSION, new RenamePair[] { ++ new RenamePair("ExitPortal", "exit_portal"), ++ })); ++ ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ ++ if (data == null) { ++ return null; ++ } ++ ++ final ListType frames = data.getList("frames", ObjectType.MAP); ++ if (frames != null) { ++ for (int i = 0, len = frames.size(); i < len; ++i) { ++ final MapType frame = frames.getMap(i); ++ ++ V3807.flattenBlockPos(frame, "Pos"); ++ ++ RenameHelper.renameSingle(frame, "Pos", "pos"); ++ RenameHelper.renameSingle(frame, "Rotation", "rotation"); ++ RenameHelper.renameSingle(frame, "EntityId", "entity_id"); ++ } ++ } ++ ++ final ListType banners = data.getList("banners", ObjectType.MAP); ++ for (int i = 0, len = banners.size(); i < len; ++i) { ++ final MapType banner = banners.getMap(i); ++ ++ RenameHelper.renameSingle(banner, "Pos", "pos"); ++ RenameHelper.renameSingle(banner, "Color", "color"); ++ RenameHelper.renameSingle(banner, "Name", "name"); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:compass", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ ++ if (tag == null) { ++ return null; ++ } ++ ++ V3807.flattenBlockPos(tag, "LodestonePos"); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, root.getMap("data"), "banners", "name", fromVersion, toVersion); ++ return null; ++ }); ++ } ++ ++ private V3813() {} ++ ++ private static record RenamePair(String from, String to) {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c4cc52620afb728533efe988bf2066ffc947f2d6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3814.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractOldAttributesRename; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3814 { ++ ++ private static final int VERSION = MCVersions.V24W05B + 3; ++ ++ public static void register() { ++ final Map renames = new HashMap<>( ++ Map.of("minecraft:horse.jump_strength", "minecraft:generic.jump_strength") ++ ); ++ ++ ConverterAbstractOldAttributesRename.register(VERSION, renames::get); ++ } ++ ++ private V3814() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3816.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3816.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b339e9559a3b5cadfab5e0c79327acace4df04b8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3816.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V3816 { ++ ++ private static final int VERSION = MCVersions.V24W06A + 1; ++ ++ public static void register() { ++ //V100.registerEquipment(VERSION, "minecraft:bogged"); // changed to simple in 1.21.5 ++ } ++ ++ private V3816() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java +new file mode 100644 +index 0000000000000000000000000000000000000000..96f21374468614655e8c25e314e18c92eba7b41a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3818.java +@@ -0,0 +1,361 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterItemStackToDataComponents; ++import ca.spottedleaf.dataconverter.minecraft.converters.particle.ConverterParticleToNBT; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.Types; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V3818 { ++ ++ private static final int VERSION = MCVersions.V24W07A + 1; ++ ++ private static final String[] BANNER_COLOURS = new String[] { ++ "white", ++ "orange", ++ "magenta", ++ "light_blue", ++ "yellow", ++ "lime", ++ "pink", ++ "gray", ++ "light_gray", ++ "cyan", ++ "purple", ++ "blue", ++ "brown", ++ "green", ++ "red", ++ "black", ++ }; ++ ++ public static String getBannerColour(final int id) { ++ return id >= 0 && id < BANNER_COLOURS.length ? BANNER_COLOURS[id] : BANNER_COLOURS[0]; ++ } ++ ++ public static void register() { ++ // Step 0 ++ // Note: No breakpoint needed, nothing nests hotbar ++ MCTypeRegistry.HOTBAR.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ for (final String key : data.keys()) { ++ final ListType itemList = data.getList(key, ObjectType.MAP); ++ if (itemList != null) { ++ for (int i = 0, len = itemList.size(); i < len; ++i) { ++ final MapType item = itemList.getMap(i); ++ ++ final String id = item.getString("id"); ++ final int count = item.getInt("Count"); ++ ++ if ("minecraft:air".equals(id) || count <= 0) { ++ itemList.setMap(i, item.getTypeUtil().createEmptyMap()); ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:beehive", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Bees", "bees"); ++ ++ final ListType bees = data.getList("bees", ObjectType.MAP); ++ if (bees != null) { ++ for (int i = 0, len = bees.size(); i < len; ++i) { ++ final MapType bee = bees.getMap(i); ++ ++ RenameHelper.renameSingle(bee, "EntityData", "entity_data"); ++ RenameHelper.renameSingle(bee, "TicksInHive", "ticks_in_hive"); ++ RenameHelper.renameSingle(bee, "MinOccupationTicks", "min_ticks_in_hive"); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:beehive", (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "bees", "entity_data", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Step 1 ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION, 1) { ++ private static final Map PATTERN_UPDATE = new HashMap<>(); ++ static { ++ PATTERN_UPDATE.put("b", "minecraft:base"); ++ PATTERN_UPDATE.put("bl", "minecraft:square_bottom_left"); ++ PATTERN_UPDATE.put("br", "minecraft:square_bottom_right"); ++ PATTERN_UPDATE.put("tl", "minecraft:square_top_left"); ++ PATTERN_UPDATE.put("tr", "minecraft:square_top_right"); ++ PATTERN_UPDATE.put("bs", "minecraft:stripe_bottom"); ++ PATTERN_UPDATE.put("ts", "minecraft:stripe_top"); ++ PATTERN_UPDATE.put("ls", "minecraft:stripe_left"); ++ PATTERN_UPDATE.put("rs", "minecraft:stripe_right"); ++ PATTERN_UPDATE.put("cs", "minecraft:stripe_center"); ++ PATTERN_UPDATE.put("ms", "minecraft:stripe_middle"); ++ PATTERN_UPDATE.put("drs", "minecraft:stripe_downright"); ++ PATTERN_UPDATE.put("dls", "minecraft:stripe_downleft"); ++ PATTERN_UPDATE.put("ss", "minecraft:small_stripes"); ++ PATTERN_UPDATE.put("cr", "minecraft:cross"); ++ PATTERN_UPDATE.put("sc", "minecraft:straight_cross"); ++ PATTERN_UPDATE.put("bt", "minecraft:triangle_bottom"); ++ PATTERN_UPDATE.put("tt", "minecraft:triangle_top"); ++ PATTERN_UPDATE.put("bts", "minecraft:triangles_bottom"); ++ PATTERN_UPDATE.put("tts", "minecraft:triangles_top"); ++ PATTERN_UPDATE.put("ld", "minecraft:diagonal_left"); ++ PATTERN_UPDATE.put("rd", "minecraft:diagonal_up_right"); ++ PATTERN_UPDATE.put("lud", "minecraft:diagonal_up_left"); ++ PATTERN_UPDATE.put("rud", "minecraft:diagonal_right"); ++ PATTERN_UPDATE.put("mc", "minecraft:circle"); ++ PATTERN_UPDATE.put("mr", "minecraft:rhombus"); ++ PATTERN_UPDATE.put("vh", "minecraft:half_vertical"); ++ PATTERN_UPDATE.put("hh", "minecraft:half_horizontal"); ++ PATTERN_UPDATE.put("vhr", "minecraft:half_vertical_right"); ++ PATTERN_UPDATE.put("hhb", "minecraft:half_horizontal_bottom"); ++ PATTERN_UPDATE.put("bo", "minecraft:border"); ++ PATTERN_UPDATE.put("cbo", "minecraft:curly_border"); ++ PATTERN_UPDATE.put("gra", "minecraft:gradient"); ++ PATTERN_UPDATE.put("gru", "minecraft:gradient_up"); ++ PATTERN_UPDATE.put("bri", "minecraft:bricks"); ++ PATTERN_UPDATE.put("glb", "minecraft:globe"); ++ PATTERN_UPDATE.put("cre", "minecraft:creeper"); ++ PATTERN_UPDATE.put("sku", "minecraft:skull"); ++ PATTERN_UPDATE.put("flo", "minecraft:flower"); ++ PATTERN_UPDATE.put("moj", "minecraft:mojang"); ++ PATTERN_UPDATE.put("pig", "minecraft:piglin"); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType patterns = data.getList("Patterns", ObjectType.MAP); ++ if (patterns != null) { ++ for (int i = 0, len = patterns.size(); i < len; ++i) { ++ final MapType pattern = patterns.getMap(i); ++ ++ final String patternName = pattern.getString("Pattern"); ++ if (patternName != null) { ++ final String renamed = PATTERN_UPDATE.get(patternName); ++ if (renamed != null) { ++ pattern.setString("Pattern", renamed); ++ } ++ } ++ RenameHelper.renameSingle(pattern, "Pattern", "pattern"); ++ ++ final String newColour = getBannerColour(pattern.getInt("Color")); ++ pattern.setString("Color", newColour); ++ RenameHelper.renameSingle(pattern, "Color", "color"); ++ } ++ } ++ RenameHelper.renameSingle(data, "Patterns", "patterns"); ++ ++ return null; ++ } ++ }); ++ ++ // Step 2 ++ // Note: there is nothing after the previous breakpoint (1.19.4) that reads nested entity item ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:arrow", new DataConverter<>(VERSION, 2) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Object potion = data.getGeneric("Potion"); ++ final Object customPotionEffects = data.getGeneric("custom_potion_effects"); ++ final Object color = data.getGeneric("Color"); ++ ++ if (potion == null && customPotionEffects == null && color == null) { ++ return null; ++ } ++ ++ data.remove("Potion"); ++ data.remove("custom_potion_effects"); ++ data.remove("Color"); ++ ++ final MapType item = data.getMap("item"); ++ if (item == null) { ++ return null; ++ } ++ ++ final MapType tag = item.getOrCreateMap("tag"); ++ ++ if (potion != null) { ++ tag.setGeneric("Potion", potion); ++ } ++ if (customPotionEffects != null) { ++ tag.setGeneric("custom_potion_effects", customPotionEffects); ++ } ++ if (color != null) { ++ tag.setGeneric("CustomPotionColor", color); ++ } ++ ++ return null; ++ } ++ }); ++ ++ // Step 3 ++ // next version: 4059 ++ MCTypeRegistry.DATA_COMPONENTS.addStructureWalker(VERSION, 3, new DataWalker<>() { ++ private static void walkBlockPredicates(final MapType root, final long fromVersion, final long toVersion) { ++ if (root.hasKey("blocks", ObjectType.STRING)) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } else if (root.hasKey("blocks", ObjectType.LIST)) { ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } ++ } ++ ++ @Override ++ public MapType walk(final MapType root, final long fromVersion, final long toVersion) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "minecraft:bees", "entity_data", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TILE_ENTITY, root, "minecraft:block_entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:bundle_contents", fromVersion, toVersion); ++ ++ final MapType canBreak = root.getMap("minecraft:can_break"); ++ if (canBreak != null) { ++ final ListType predicates = canBreak.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canBreak, fromVersion, toVersion); ++ } ++ ++ final MapType canPlaceOn = root.getMap("minecraft:can_place_on"); ++ if (canPlaceOn != null) { ++ final ListType predicates = canPlaceOn.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canPlaceOn, fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:charged_projectiles", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.ITEM_STACK, root, "minecraft:container", "item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, root, "minecraft:entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_NAME, root, "minecraft:pot_decorations", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root.getMap("minecraft:food"), "using_converts_to", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:custom_name", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:item_name", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:lore", fromVersion, toVersion); ++ ++ final MapType writtenBookContent = root.getMap("minecraft:written_book_content"); ++ if (writtenBookContent != null) { ++ // This logic is OK up until we need to convert TEXT_COMPONENT to NBT. ++ // But that's for the next walker to handle. ++ final ListType pages = writtenBookContent.getListUnchecked("pages"); ++ if (pages != null) { ++ for (int i = 0, len = pages.size(); i < len; ++i) { ++ final Object pageGeneric = pages.getGeneric(i); ++ if (pageGeneric instanceof String string) { ++ final Object convertedGeneric = MCTypeRegistry.TEXT_COMPONENT.convert(string, fromVersion, toVersion); ++ if (convertedGeneric != null) { ++ pages.setGeneric(i, convertedGeneric); ++ } ++ } else if (pageGeneric instanceof MapType mapType) { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "raw", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "filtered", fromVersion, toVersion); ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ // Step 4 ++ MCTypeRegistry.PARTICLE.addStructureConverter(new DataConverter<>(VERSION, 4) { ++ @Override ++ public MapType convert(final Object input, final long sourceVersion, final long toVersion) { ++ if (!(input instanceof String flat)) { ++ return null; ++ } ++ ++ return ConverterParticleToNBT.convert(flat, Types.NBT); ++ } ++ }); ++ ++ MCTypeRegistry.PARTICLE.addStructureWalker(VERSION, 4, (final Object input, final long fromVersion, final long toVersion) -> { ++ if (!(input instanceof MapType)) { ++ return null; ++ } ++ ++ final MapType root = (MapType)input; ++ ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_STATE, root, "block_state", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Step 5 ++ // Note: needs breakpoint, reads nested tile entity data ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION, 5) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ return ConverterItemStackToDataComponents.convertItem(data); ++ } ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureWalker(VERSION, 5, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_NAME, root, "id", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.DATA_COMPONENTS, root, "components", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Step 6 ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:area_effect_cloud", new DataConverter<>(VERSION, 6) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Object color = data.getGeneric("Color"); ++ final Object effects = data.getGeneric("effects"); ++ final Object potion = data.getGeneric("Potion"); ++ ++ if (color == null && effects == null && potion == null) { ++ return null; ++ } ++ data.remove("Color"); ++ data.remove("effects"); ++ data.remove("Potion"); ++ ++ final MapType potionContents = data.getTypeUtil().createEmptyMap(); ++ data.setMap("potion_contents", potionContents); ++ ++ if (color != null) { ++ potionContents.setGeneric("custom_color", color); ++ } ++ ++ if (effects != null) { ++ potionContents.setGeneric("custom_effects", effects); ++ } ++ ++ if (potion != null) { ++ potionContents.setGeneric("potion", potion); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3818() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3820.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3820.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8672d40af44a92516256a97d9912a08a6dcb446c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3820.java +@@ -0,0 +1,81 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemstack.ConverterItemStackToDataComponents; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3820 { ++ ++ private static final int VERSION = MCVersions.V24W09A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:skull", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final Object skullOwner = data.getGeneric("SkullOwner"); ++ final Object extraType = data.getGeneric("ExtraType"); ++ ++ if (skullOwner == null && extraType == null) { ++ return null; ++ } ++ ++ data.remove("SkullOwner"); ++ data.remove("ExtraType"); ++ ++ data.setMap( ++ "profile", ++ ConverterItemStackToDataComponents.convertProfile( ++ skullOwner == null ? extraType : skullOwner, data.getTypeUtil() ++ ) ++ ); ++ ++ return null; ++ } ++ }); ++ // I don't see why this converter is necessary, V3818 should have converted correctly... ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ ++ if (components == null) { ++ return null; ++ } ++ ++ final MapType oldTarget = components.getMap("minecraft:lodestone_target"); ++ if (oldTarget == null) { ++ return null; ++ } ++ ++ components.remove("minecraft:lodestone_target"); ++ components.setMap("minecraft:lodestone_tracker", oldTarget); ++ ++ final Object pos = oldTarget.getGeneric("pos"); ++ final Object dim = oldTarget.getGeneric("dimension"); ++ ++ if (pos == null || dim == null) { ++ return null; ++ } ++ ++ oldTarget.remove("pos"); ++ oldTarget.remove("dimension"); ++ ++ final MapType target = oldTarget.getTypeUtil().createEmptyMap(); ++ oldTarget.setMap("target", target); ++ ++ target.setGeneric("pos", pos); ++ target.setGeneric("dimension", dim); ++ ++ return null; ++ } ++ }); ++ ++ // Moved from V99 to here, as 21w10a is when custom_name was added ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:skull", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "custom_name")); ++ } ++ ++ private V3820() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3825.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3825.java +new file mode 100644 +index 0000000000000000000000000000000000000000..547c7fe79f4602aefee5910335b147669acde031 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3825.java +@@ -0,0 +1,153 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V3825 { ++ ++ private static final int VERSION = MCVersions.V24W12A + 1; ++ ++ private static final Set BANNER_NAMES = new HashSet<>( ++ Arrays.asList( ++ "block.minecraft.ominous_banner" ++ ) ++ ); ++ private static final Set MAP_NAMES = new HashSet<>( ++ Arrays.asList( ++ "filled_map.buried_treasure", ++ "filled_map.explorer_jungle", ++ "filled_map.explorer_swamp", ++ "filled_map.mansion", ++ "filled_map.monument", ++ "filled_map.trial_chambers", ++ "filled_map.village_desert", ++ "filled_map.village_plains", ++ "filled_map.village_savanna", ++ "filled_map.village_snowy", ++ "filled_map.village_taiga" ++ ) ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static void convertName(final MapType components, final Set standardNames) { ++ final String customName = components.getString("minecraft:custom_name"); ++ if (customName == null) { ++ return; ++ } ++ ++ final String translation = ComponentUtils.retrieveTranslationString(customName); ++ if (translation == null) { ++ return; ++ } ++ ++ if (standardNames.contains(translation)) { ++ components.remove("minecraft:custom_name"); ++ components.setString("minecraft:item_name", customName); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ final String id = data.getString("id"); ++ if (id == null) { ++ return null; ++ } ++ ++ switch (id) { ++ case "minecraft:white_banner": { ++ convertName(components, BANNER_NAMES); ++ break; ++ } ++ case "minecraft:filled_map": { ++ convertName(components, MAP_NAMES); ++ break; ++ } ++ } ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String customName = data.getString("CustomName"); ++ if (customName == null || !"block.minecraft.ominous_banner".equals(ComponentUtils.retrieveTranslationString(customName))) { ++ return null; ++ } ++ ++ data.remove("CustomName"); ++ ++ final MapType components = data.getOrCreateMap("components"); ++ ++ components.setString("minecraft:item_name", customName); ++ components.setMap("minecraft:hide_additional_tooltip", components.getTypeUtil().createEmptyMap()); ++ ++ return null; ++ } ++ }); ++ // DFU does not change the schema, even though it moves spawn_potentials ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:trial_spawner", (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType normalConfig = data.getMap("normal_config"); ++ if (normalConfig != null) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, normalConfig, "spawn_potentials", "data", "entity", fromVersion, toVersion); ++ } ++ final MapType ominousConfig = data.getMap("ominous_config"); ++ if (ominousConfig != null) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, ominousConfig, "spawn_potentials", "data", "entity", fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("spawn_data"), "entity", fromVersion, toVersion); ++ return null; ++ }); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:trial_spawner", new DataConverter<>(VERSION) { ++ private static final String[] NORMAL_CONFIG_KEYS = new String[] { ++ "spawn_range", ++ "total_mobs", ++ "simultaneous_mobs", ++ "total_mobs_added_per_player", ++ "simultaneous_mobs_added_per_player", ++ "ticks_between_spawn", ++ "spawn_potentials", ++ "loot_tables_to_eject", ++ "items_to_drop_when_ominous" ++ }; ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType normalConfig = data.getTypeUtil().createEmptyMap(); ++ ++ for (final String normalKey : NORMAL_CONFIG_KEYS) { ++ final Object normalValue = data.getGeneric(normalKey); ++ if (normalValue != null) { ++ data.remove(normalKey); ++ normalConfig.setGeneric(normalKey, normalValue); ++ } ++ } ++ ++ if (!normalConfig.isEmpty()) { ++ data.setMap("normal_config", normalConfig); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:ominous_item_spawner", new DataWalkerItems("item")); ++ } ++ ++ private V3825() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3828.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3828.java +new file mode 100644 +index 0000000000000000000000000000000000000000..084b61402b954f4b29156a08d53b29d6c08fe692 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3828.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public final class V3828 { ++ ++ private static final int VERSION = MCVersions.V24W14A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.VILLAGER_TRADE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType buyB = data.getMap("buyB"); ++ ++ if (buyB == null) { ++ return null; ++ } ++ ++ final String id = NamespaceUtil.correctNamespace(buyB.getString("id", "minecraft:air")); ++ final int count = buyB.getInt("count", 0); ++ ++ // Fix DFU: use count <= 0 instead of count == 0 ++ if ("minecraft:air".equals(id) || count <= 0) { ++ data.remove("buyB"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3828() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c4f0152c8c1b1dacd09b880e5415c2ca05f93956 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3833.java +@@ -0,0 +1,36 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public final class V3833 { ++ ++ private static final int VERSION = MCVersions.V1_20_5_PRE4 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:brushable_block", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType item = data.getMap("item"); ++ if (item == null) { ++ return null; ++ } ++ ++ final String id = NamespaceUtil.correctNamespace(item.getString("id", "minecraft:air")); ++ final int count = item.getInt("count", 0); ++ ++ // Fix DFU: use count <= 0 instead of count == 0 ++ if ("minecraft:air".equals(id) || count <= 0) { ++ data.remove("item"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3833() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2a6d144c2f074403bde8a62377ca6986c0c12a84 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3938.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++ ++public final class V3938 { ++ ++ private static final int VERSION = MCVersions.V1_20_6 + 99; ++ ++ private static void registerArrow(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerTypePaths<>(MCTypeRegistry.BLOCK_STATE, "inBlockState")); ++ // new: weapon ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItems("item", "weapon")); ++ } ++ ++ public static void register() { ++ registerArrow("minecraft:spectral_arrow"); ++ registerArrow("minecraft:arrow"); ++ } ++ ++ private V3938() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2bcacb82a57bcdca6af699936b22db0ebe925f1b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3939.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.Arrays; ++import java.util.HashSet; ++ ++public final class V3939 { ++ ++ private static final int VERSION = MCVersions.V1_20_6 + 100; ++ ++ public static void register() { ++ MCTypeRegistry.LIGHTWEIGHT_LEVEL.addStructureConverter(new ConverterRemoveFeatureFlag(VERSION, new HashSet<>( ++ Arrays.asList( ++ "minecraft:update_1_21" ++ ) ++ ))); ++ } ++ ++ private V3939() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5bbfb32568d0367422f801a1402409f497959eb8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3943.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V3943 { ++ ++ private static final int VERSION = MCVersions.V24W19B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String oldRange = data.getString("menuBackgroundBlurriness", "0.5"); ++ ++ int newRange; ++ try { ++ newRange = (int)Math.round(Double.parseDouble(oldRange) * 10.0); ++ } catch (final NumberFormatException ex) { ++ newRange = 5; ++ } ++ ++ // note: options are always string, so DFU is wrong to use int ++ data.setString("menuBackgroundBlurriness", Integer.toString(newRange)); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3943() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java b/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java +new file mode 100644 +index 0000000000000000000000000000000000000000..28f2c6f6562bb5f11c6519a7beae5f86e37541a7 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V3945.java +@@ -0,0 +1,244 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++import java.util.LinkedHashMap; ++import java.util.Locale; ++import java.util.Map; ++import java.util.UUID; ++ ++public final class V3945 { ++ ++ private static final int VERSION = MCVersions.V24W20A + 1; ++ ++ private static final Map UUID_TO_ID = new HashMap<>( ++ ImmutableMap.builder() ++ .put(UUID.fromString("736565d2-e1a7-403d-a3f8-1aeb3e302542"), "minecraft:creative_mode_block_range") ++ .put(UUID.fromString("98491ef6-97b1-4584-ae82-71a8cc85cf73"), "minecraft:creative_mode_entity_range") ++ .put(UUID.fromString("91AEAA56-376B-4498-935B-2F7F68070635"), "minecraft:effect.speed") ++ .put(UUID.fromString("7107DE5E-7CE8-4030-940E-514C1F160890"), "minecraft:effect.slowness") ++ .put(UUID.fromString("AF8B6E3F-3328-4C0A-AA36-5BA2BB9DBEF3"), "minecraft:effect.haste") ++ .put(UUID.fromString("55FCED67-E92A-486E-9800-B47F202C4386"), "minecraft:effect.mining_fatigue") ++ .put(UUID.fromString("648D7064-6A60-4F59-8ABE-C2C23A6DD7A9"), "minecraft:effect.strength") ++ .put(UUID.fromString("C0105BF3-AEF8-46B0-9EBC-92943757CCBE"), "minecraft:effect.jump_boost") ++ .put(UUID.fromString("22653B89-116E-49DC-9B6B-9971489B5BE5"), "minecraft:effect.weakness") ++ .put(UUID.fromString("5D6F0BA2-1186-46AC-B896-C61C5CEE99CC"), "minecraft:effect.health_boost") ++ .put(UUID.fromString("EAE29CF0-701E-4ED6-883A-96F798F3DAB5"), "minecraft:effect.absorption") ++ .put(UUID.fromString("03C3C89D-7037-4B42-869F-B146BCB64D2E"), "minecraft:effect.luck") ++ .put(UUID.fromString("CC5AF142-2BD2-4215-B636-2605AED11727"), "minecraft:effect.unluck") ++ .put(UUID.fromString("6555be74-63b3-41f1-a245-77833b3c2562"), "minecraft:evil") ++ .put(UUID.fromString("1eaf83ff-7207-4596-b37a-d7a07b3ec4ce"), "minecraft:powder_snow") ++ .put(UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"), "minecraft:sprinting") ++ .put(UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"), "minecraft:attacking") ++ .put(UUID.fromString("766bfa64-11f3-11ea-8d71-362b9e155667"), "minecraft:baby") ++ .put(UUID.fromString("7E0292F2-9434-48D5-A29F-9583AF7DF27F"), "minecraft:covered") ++ .put(UUID.fromString("9e362924-01de-4ddd-a2b2-d0f7a405a174"), "minecraft:suffocating") ++ .put(UUID.fromString("5CD17E52-A79A-43D3-A529-90FDE04B181E"), "minecraft:drinking") ++ .put(UUID.fromString("B9766B59-9566-4402-BC1F-2EE2A276D836"), "minecraft:baby") ++ .put(UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"), "minecraft:attacking") ++ .put(UUID.fromString("845DB27C-C624-495F-8C9F-6020A9A58B6B"), "minecraft:armor.boots") ++ .put(UUID.fromString("D8499B04-0E66-4726-AB29-64469D734E0D"), "minecraft:armor.leggings") ++ .put(UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E"), "minecraft:armor.chestplate") ++ .put(UUID.fromString("2AD3F246-FEE1-4E67-B886-69FD380BB150"), "minecraft:armor.helmet") ++ .put(UUID.fromString("C1C72771-8B8E-BA4A-ACE0-81A93C8928B2"), "minecraft:armor.body") ++ .put(UUID.fromString("b572ecd2-ac0c-4071-abde-9594af072a37"), "minecraft:enchantment.fire_protection") ++ .put(UUID.fromString("40a9968f-5c66-4e2f-b7f4-2ec2f4b3e450"), "minecraft:enchantment.blast_protection") ++ .put(UUID.fromString("07a65791-f64d-4e79-86c7-f83932f007ec"), "minecraft:enchantment.respiration") ++ .put(UUID.fromString("60b1b7db-fffd-4ad0-817c-d6c6a93d8a45"), "minecraft:enchantment.aqua_affinity") ++ .put(UUID.fromString("11dc269a-4476-46c0-aff3-9e17d7eb6801"), "minecraft:enchantment.depth_strider") ++ .put(UUID.fromString("87f46a96-686f-4796-b035-22e16ee9e038"), "minecraft:enchantment.soul_speed") ++ .put(UUID.fromString("b9716dbd-50df-4080-850e-70347d24e687"), "minecraft:enchantment.soul_speed") ++ .put(UUID.fromString("92437d00-c3a7-4f2e-8f6c-1f21585d5dd0"), "minecraft:enchantment.swift_sneak") ++ .put(UUID.fromString("5d3d087b-debe-4037-b53e-d84f3ff51f17"), "minecraft:enchantment.sweeping_edge") ++ .put(UUID.fromString("3ceb37c0-db62-46b5-bd02-785457b01d96"), "minecraft:enchantment.efficiency") ++ .put(UUID.fromString("CB3F55D3-645C-4F38-A497-9C13A33DB5CF"), "minecraft:base_attack_damage") ++ .put(UUID.fromString("FA233E1C-4180-4865-B01B-BCCE9785ACA3"), "minecraft:base_attack_speed") ++ .build() ++ ); ++ private static final Map NAME_TO_ID = new HashMap<>( ++ Map.of( ++ "Random spawn bonus", "minecraft:random_spawn_bonus", ++ "Random zombie-spawn bonus", "minecraft:zombie_random_spawn_bonus", ++ "Leader zombie bonus", "minecraft:leader_zombie_bonus", ++ "Zombie reinforcement callee charge", "minecraft:reinforcement_callee_charge", ++ "Zombie reinforcement caller charge", "minecraft:reinforcement_caller_charge" ++ ) ++ ); ++ ++ private static UUID makeUUID(final int[] arr) { ++ if (arr == null || arr.length != 4) { ++ return null; ++ } ++ ++ final long most = ((long)arr[0] << 32) | ((long)arr[1] & 0xFFFFFFFFL); ++ final long least = ((long)arr[2] << 32) | ((long)arr[3] & 0xFFFFFFFFL); ++ ++ return new UUID(most, least); ++ } ++ ++ private static ListType remapModifiers(final ListType list) { ++ final Map ret = new LinkedHashMap<>(); ++ ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType modifier = list.getMap(i).copy(); ++ ++ final UUID uuid = makeUUID(modifier.getInts("uuid")); ++ final String name = modifier.getString("name", ""); ++ ++ final String remappedUUID = UUID_TO_ID.get(uuid); ++ final String remappedName = NAME_TO_ID.get(name); ++ ++ if (remappedUUID != null) { ++ modifier.remove("uuid"); ++ modifier.remove("name"); ++ ++ modifier.setString("id", remappedUUID); ++ ++ ret.put(remappedUUID, modifier); ++ } else if (remappedName != null) { ++ final MapType existing = ret.get(remappedName); ++ if (existing != null) { ++ existing.setDouble("amount", ++ existing.getDouble("amount", 0.0) + modifier.getDouble("amount", 0.0) ++ ); ++ } else { ++ modifier.remove("uuid"); ++ modifier.remove("name"); ++ ++ modifier.setString("id", remappedName); ++ ++ ret.put(remappedName, modifier); ++ } ++ } else { ++ final String id = "minecraft:" + (uuid == null ? "unknown" : uuid.toString().toLowerCase(Locale.ROOT)); ++ ++ modifier.setString("id", id); ++ ++ ret.put(id, modifier); ++ } ++ } ++ ++ final ListType retList = list.getTypeUtil().createEmptyList(); ++ ++ for (final MapType modifier : ret.values()) { ++ retList.addMap(modifier); ++ } ++ ++ return retList; ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ final MapType attributeModifiers = components.getMap("minecraft:attribute_modifiers"); ++ if (attributeModifiers == null) { ++ return null; ++ } ++ ++ final ListType modifiers = attributeModifiers.getList("modifiers", ObjectType.MAP); ++ if (modifiers == null) { ++ return null; ++ } ++ ++ attributeModifiers.setList("modifiers", remapModifiers(modifiers)); ++ ++ return null; ++ } ++ }); ++ ++ final DataConverter entityConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Attributes", "attributes"); ++ ++ final ListType attributes = data.getList("attributes", ObjectType.MAP); ++ if (attributes == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = attributes.size(); i < len; ++i) { ++ final MapType attribute = attributes.getMap(i); ++ ++ RenameHelper.renameSingle(attribute, "Name", "id"); ++ RenameHelper.renameSingle(attribute, "Base", "base"); ++ RenameHelper.renameSingle(attribute, "Modifiers", "modifiers"); ++ ++ final ListType modifiers = attribute.getList("modifiers", ObjectType.MAP); ++ ++ if (modifiers == null) { ++ continue; ++ } ++ ++ for (int j = 0, len2 = modifiers.size(); j < len2; ++j) { ++ final MapType modifier = modifiers.getMap(j); ++ ++ RenameHelper.renameSingle(modifier, "UUID", "uuid"); ++ RenameHelper.renameSingle(modifier, "Name", "name"); ++ RenameHelper.renameSingle(modifier, "Amount", "amount"); ++ final String newOp; ++ switch (modifier.getInt("Operation", 0)) { ++ case 0: { ++ newOp = "add_value"; ++ break; ++ } ++ case 1: { ++ newOp = "add_multiplied_base"; ++ break; ++ } ++ case 2: { ++ newOp = "add_multiplied_total"; ++ break; ++ } ++ default: { ++ newOp = "invalid"; ++ break; ++ } ++ } ++ modifier.remove("Operation"); ++ modifier.setString("operation", newOp); ++ } ++ ++ attribute.setList("modifiers", remapModifiers(modifiers)); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(entityConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(entityConverter); ++ ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:jukebox", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final long playingFor = data.getLong("TickCount") - data.getLong("RecordStartTick"); ++ ++ data.remove("IsPlaying"); ++ data.remove("TickCount"); ++ data.remove("RecordStartTick"); ++ ++ if (playingFor > 0L) { ++ data.setLong("ticks_since_song_started", playingFor); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V3945() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1a76415944b6ad8b98f917acd3c7157e9fccdd5f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4054.java +@@ -0,0 +1,46 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.util.ComponentUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4054 { ++ ++ private static final int VERSION = MCVersions.V1_21_1 + 99; ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertComponents(data.getMap("components")); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:white_banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertComponents(data.getMap("components")); ++ return null; ++ } ++ }); ++ } ++ ++ private static void convertComponents(final MapType components) { ++ if (components == null) { ++ return; ++ } ++ ++ final String itemNameKey = ComponentUtils.retrieveTranslationString(components.getString("minecraft:item_name")); ++ ++ if (!"block.minecraft.ominous_banner".equals(itemNameKey)) { ++ return; ++ } ++ ++ components.setString("minecraft:rarity", "uncommon"); ++ components.setString("minecraft:item_name", ComponentUtils.createTranslatableComponent("block.minecraft.ominous_banner")); ++ } ++ ++ private V4054() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java +new file mode 100644 +index 0000000000000000000000000000000000000000..45b141a651d954554fcca68f36c0b3344328d902 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4055.java +@@ -0,0 +1,41 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterAbstractAttributesRename; ++import ca.spottedleaf.dataconverter.util.NamespaceUtil; ++ ++public final class V4055 { ++ ++ private static final int VERSION = MCVersions.V1_21_1 + 100; ++ ++ private static final Prefix[] PREFIXES_TO_REMOVE = new Prefix[] { ++ new Prefix("generic."), ++ new Prefix("horse."), ++ new Prefix("player."), ++ new Prefix("zombie.") ++ }; ++ ++ private static record Prefix(String raw, String namespaced) { ++ public Prefix(final String raw) { ++ this(raw, NamespaceUtil.correctNamespace(raw)); ++ } ++ } ++ ++ public static void register() { ++ ConverterAbstractAttributesRename.register(VERSION, (final String input) -> { ++ final String namespacedInput = NamespaceUtil.correctNamespace(input); ++ ++ for (final Prefix prefix : PREFIXES_TO_REMOVE) { ++ if (!namespacedInput.startsWith(prefix.namespaced())) { ++ continue; ++ } ++ ++ return "minecraft:".concat(namespacedInput.substring(prefix.namespaced().length())); ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V4055() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4165efcb182a52d4f1d52f25e684ab8f36cf4c79 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4057.java +@@ -0,0 +1,33 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4057 { ++ ++ private static final int VERSION = MCVersions.V1_21_1 + 102; ++ ++ public static void register() { ++ MCTypeRegistry.CHUNK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType carvingMasks = data.getMap("CarvingMasks"); ++ if (carvingMasks == null) { ++ return null; ++ } ++ data.remove("CarvingMasks"); ++ ++ final long[] airMask = carvingMasks.getLongs("AIR"); ++ if (airMask != null) { ++ data.setLongs("carving_mask", airMask); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4057() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e4a1bb8aa512203d28fb683d204762f322862921 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4059.java +@@ -0,0 +1,164 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++ ++public final class V4059 { ++ ++ private static final int VERSION = MCVersions.V24W33A + 1; ++ ++ public static void register() { ++ // previous version: 3818.3 ++ // next version: 4307 ++ MCTypeRegistry.DATA_COMPONENTS.addStructureWalker(VERSION, new DataWalker<>() { ++ private static void walkBlockPredicates(final MapType root, final long fromVersion, final long toVersion) { ++ if (root.hasKey("blocks", ObjectType.STRING)) { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } else if (root.hasKey("blocks", ObjectType.LIST)) { ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, root, "blocks", fromVersion, toVersion); ++ } ++ } ++ ++ @Override ++ public MapType walk(final MapType root, final long fromVersion, final long toVersion) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "minecraft:bees", "entity_data", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TILE_ENTITY, root, "minecraft:block_entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:bundle_contents", fromVersion, toVersion); ++ ++ final MapType canBreak = root.getMap("minecraft:can_break"); ++ if (canBreak != null) { ++ final ListType predicates = canBreak.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canBreak, fromVersion, toVersion); ++ } ++ ++ final MapType canPlaceOn = root.getMap("minecraft:can_place_on"); ++ if (canPlaceOn != null) { ++ final ListType predicates = canPlaceOn.getList("predicates", ObjectType.MAP); ++ if (predicates != null) { ++ for (int i = 0, len = predicates.size(); i < len; ++i) { ++ walkBlockPredicates(predicates.getMap(i), fromVersion, toVersion); ++ } ++ } ++ // Not handled by DFU: simple encoding does not require "predicates" ++ walkBlockPredicates(canPlaceOn, fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:charged_projectiles", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.ITEM_STACK, root, "minecraft:container", "item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, root, "minecraft:entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_NAME, root, "minecraft:pot_decorations", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "minecraft:use_remainder", fromVersion, toVersion); ++ ++ final MapType equippable = root.getMap("minecraft:equippable"); ++ if (equippable != null) { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:custom_name", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:item_name", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:lore", fromVersion, toVersion); ++ ++ final MapType writtenBookContent = root.getMap("minecraft:written_book_content"); ++ if (writtenBookContent != null) { ++ final ListType pages = writtenBookContent.getListUnchecked("pages"); ++ // This logic needs to correctly handle both the NBT format of TEXT_COMPONENT and the JSON format. ++ if (pages != null) { ++ for (int i = 0, len = pages.size(); i < len; ++i) { ++ final Object pageGeneric = pages.getGeneric(i); ++ final boolean isNBTFormat = fromVersion >= DataConverter.encodeVersions(V4290.VERSION, 0); ++ // Note: We only parse ListType for 4290 and above as only a String was valid JSON. List of anything was not valid. ++ if (pageGeneric instanceof String || (isNBTFormat && pageGeneric instanceof ListType)) { // handles: String case (JSON/NBT), ListType case (NBT) ++ final Object convertedGeneric = MCTypeRegistry.TEXT_COMPONENT.convert(pageGeneric, fromVersion, toVersion); ++ if (convertedGeneric != null) { ++ pages.setGeneric(i, convertedGeneric); ++ } ++ } else if (pageGeneric instanceof MapType mapType) { ++ // Need to handle: Filterable format and regular NBT Component format are both MapType... ++ if (mapType.hasKey("raw") || mapType.hasKey("filtered")) { ++ // Assume filterable format ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "raw", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "filtered", fromVersion, toVersion); ++ } else if (isNBTFormat) { ++ final Object convertedGeneric = MCTypeRegistry.TEXT_COMPONENT.convert(mapType, fromVersion, toVersion); ++ if (convertedGeneric != null) { ++ pages.setGeneric(i, convertedGeneric); ++ } ++ } // else: invalid data ++ } // else: invalid data ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType food = data.getMap("minecraft:food"); ++ if (food == null) { ++ return null; ++ } ++ ++ final TypeUtil typeUtil = data.getTypeUtil(); ++ ++ final float eatSeconds = food.getFloat("eat_seconds", 1.6F); ++ ++ final ListType oldEffects = food.getList("effects", ObjectType.MAP); ++ final ListType newEffects = typeUtil.createEmptyList(); ++ if (oldEffects != null) { ++ for (int i = 0, len = oldEffects.size(); i < len; ++i) { ++ final MapType oldEffect = oldEffects.getMap(i); ++ ++ final MapType newEffect = typeUtil.createEmptyMap(); ++ newEffects.addMap(newEffect); ++ ++ newEffect.setString("type", "minecraft:apply_effects"); ++ ++ final Object oldEffectEffect = oldEffect.getGeneric("effect"); ++ final ListType newEffectEffects = typeUtil.createEmptyList(); ++ newEffectEffects.addGeneric(oldEffectEffect); ++ newEffect.setList("effects", newEffectEffects); ++ ++ newEffect.setFloat("probability", oldEffect.getFloat("probability", 1.0F)); ++ } ++ } ++ ++ final Object convertsTo = food.getGeneric("using_converts_to"); ++ if (convertsTo != null) { ++ data.setGeneric("minecraft:use_remainder", convertsTo); ++ } ++ ++ food.remove("eat_seconds"); ++ food.remove("effects"); ++ food.remove("using_converts_to"); ++ ++ final MapType consumable = typeUtil.createEmptyMap(); ++ data.setMap("minecraft:consumable", consumable); ++ ++ consumable.setFloat("consume_seconds", eatSeconds); ++ consumable.setList("on_consume_effects", newEffects); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4059() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b092188f5e4f0fa3224fac3cd36f5c1ee6a7f0a4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4061.java +@@ -0,0 +1,112 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import com.mojang.brigadier.exceptions.CommandSyntaxException; ++import com.mojang.datafixers.util.Pair; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.TagParser; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V4061 { ++ ++ private static final int VERSION = MCVersions.V24W34A + 1; ++ ++ private static final Map, String> CONVERT_MAP = new HashMap<>(); ++ static { ++ addConversion("trial_chamber/breeze", "{simultaneous_mobs: 1.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:breeze\"}}, weight: 1}], ticks_between_spawn: 20, total_mobs: 2.0f, total_mobs_added_per_player: 1.0f}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 2.0f, total_mobs: 4.0f}"); ++ addConversion("trial_chamber/melee/husk", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:husk\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:husk\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/melee/spider", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:spider\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/melee/zombie", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:zombie\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:zombie\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/poison_skeleton", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/skeleton", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/ranged/stray", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/poison_skeleton", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:bogged\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/skeleton", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {id: \"minecraft:skeleton\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/slow_ranged/stray", "{simultaneous_mobs: 4.0f, simultaneous_mobs_added_per_player: 2.0f, spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}}, weight: 1}], ticks_between_spawn: 160}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}],spawn_potentials: [{data: {entity: {id: \"minecraft:stray\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_ranged\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/small_melee/baby_zombie", "{simultaneous_mobs: 2.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {IsBaby: 1b, id: \"minecraft:zombie\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], spawn_potentials: [{data: {entity: {IsBaby: 1b, id: \"minecraft:zombie\"}, equipment: {loot_table: \"minecraft:equipment/trial_chamber_melee\", slot_drop_chances: 0.0f}}, weight: 1}]}"); ++ addConversion("trial_chamber/small_melee/cave_spider", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:cave_spider\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/small_melee/silverfish", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {id: \"minecraft:silverfish\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ addConversion("trial_chamber/small_melee/slime", "{simultaneous_mobs: 3.0f, simultaneous_mobs_added_per_player: 0.5f, spawn_potentials: [{data: {entity: {Size: 1, id: \"minecraft:slime\"}}, weight: 3}, {data: {entity: {Size: 2, id: \"minecraft:slime\"}}, weight: 1}], ticks_between_spawn: 20}", "{loot_tables_to_eject: [{data: \"minecraft:spawners/ominous/trial_chamber/key\", weight: 3}, {data: \"minecraft:spawners/ominous/trial_chamber/consumables\", weight: 7}], simultaneous_mobs: 4.0f, total_mobs: 12.0f}"); ++ } ++ ++ private static void addConversion(final String keyPath, final String normalsNBT, final String ominoussNBT) { ++ final String fullKey = "minecraft:".concat(keyPath); ++ ++ final CompoundTag normalNBT = parseNBT(normalsNBT); ++ final MapType normalMapType = new NBTMapType(normalNBT); ++ final CompoundTag ominousNBT = parseNBT(ominoussNBT); ++ ++ final CompoundTag ominousMerged = normalNBT.copy().merge(ominousNBT); ++ ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(ominousNBT)), fullKey); ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(ominousMerged)), fullKey); ++ CONVERT_MAP.put(Pair.of(normalMapType, new NBTMapType(removeDefaults(ominousMerged.copy()))), fullKey); ++ } ++ ++ private static CompoundTag parseNBT(final String sNBT) { ++ try { ++ return TagParser.parseCompoundFully(sNBT); ++ } catch (final CommandSyntaxException ex) { ++ throw new IllegalArgumentException("Failed to parse NBT: " + sNBT, ex); ++ } ++ } ++ ++ private static CompoundTag removeDefaults(final CompoundTag config) { ++ if (config.getIntOr("spawn_range", 0) == 4) { ++ config.remove("spawn_range"); ++ } ++ ++ if (config.getFloatOr("total_mobs", 0.0F) == 6.0F) { ++ config.remove("total_mobs"); ++ } ++ ++ if (config.getFloatOr("simultaneous_mobs", 0.0F) == 2.0F) { ++ config.remove("simultaneous_mobs"); ++ } ++ ++ if (config.getFloatOr("total_mobs_added_per_player", 0.0F) == 2.0F) { ++ config.remove("total_mobs_added_per_player"); ++ } ++ ++ if (config.getFloatOr("simultaneous_mobs_added_per_player", 0.0F) == 1.0F) { ++ config.remove("simultaneous_mobs_added_per_player"); ++ } ++ ++ if (config.getIntOr("ticks_between_spawn", 0) == 40) { ++ config.remove("ticks_between_spawn"); ++ } ++ ++ return config; ++ } ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:trial_spawner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType normalConfig = data.getMap("normal_config"); ++ final MapType ominousConfig = data.getMap("ominous_config"); ++ ++ if (normalConfig == null || ominousConfig == null) { ++ return null; ++ } ++ ++ final String newKey = CONVERT_MAP.get(new Pair<>(normalConfig, ominousConfig)); ++ if (newKey == null) { ++ return null; ++ } ++ ++ data.setString("normal_config", newKey.concat("/normal")); ++ data.setString("ominous_config", newKey.concat("/ominous")); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4061() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a3bde5f57589d8ec3f1b1d1332ec8a1780bd1f47 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4064.java +@@ -0,0 +1,36 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4064 { ++ ++ private static final int VERSION = MCVersions.V24W36A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ if (components.hasKey("minecraft:fire_resistant")) { ++ components.remove("minecraft:fire_resistant"); ++ ++ final MapType damageResistant = components.getTypeUtil().createEmptyMap(); ++ components.setMap("minecraft:damage_resistant", damageResistant); ++ ++ damageResistant.setString("types", "#minecraft:is_fire"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4064() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java +new file mode 100644 +index 0000000000000000000000000000000000000000..1f3d0dc9353444a3826d77272f974a3362e845e1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4067.java +@@ -0,0 +1,143 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.Arrays; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++ ++public final class V4067 { ++ ++ private static final int VERSION = MCVersions.V24W38A + 1; ++ ++ private static final record BoatType(String name, String suffix) {} ++ private static final BoatType[] BOAT_TYPES = new BoatType[] { ++ new BoatType("oak", "boat"), ++ new BoatType("spruce", "boat"), ++ new BoatType("birch", "boat"), ++ new BoatType("jungle", "boat"), ++ new BoatType("acacia", "boat"), ++ new BoatType("cherry", "boat"), ++ new BoatType("dark_oak", "boat"), ++ new BoatType("mangrove", "boat"), ++ new BoatType("bamboo", "raft") ++ }; ++ ++ private static void registerChestBoat(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItemLists("Items")); ++ } ++ ++ public static void register() { ++ // minecraft:oak_boat is a simple entity ++ // minecraft:spruce_boat is a simple entity ++ // minecraft:birch_boat is a simple entity ++ // minecraft:jungle_boat is a simple entity ++ // minecraft:acacia_boat is a simple entity ++ // minecraft:cherry_boat is a simple entity ++ // minecraft:dark_oak_boat is a simple entity ++ // minecraft:mangrove_boat is a simple entity ++ // minecraft:bamboo_raft is a simple entity ++ ++ registerChestBoat("minecraft:oak_chest_boat"); ++ registerChestBoat("minecraft:spruce_chest_boat"); ++ registerChestBoat("minecraft:birch_chest_boat"); ++ registerChestBoat("minecraft:jungle_chest_boat"); ++ registerChestBoat("minecraft:acacia_chest_boat"); ++ registerChestBoat("minecraft:cherry_chest_boat"); ++ registerChestBoat("minecraft:dark_oak_chest_boat"); ++ registerChestBoat("minecraft:mangrove_chest_boat"); ++ registerChestBoat("minecraft:bamboo_chest_raft"); ++ ++ // we do not update V704 to set the new boat types, as the new ids are only registered here ++ // if we updated V704 to set the new boat types, then the registered walkers for the chest_boat would not run before ++ // V4067 as they are only registered here ++ ++ // to ensure that the id is correctly set eventually, we will force Type to the correct value based on the item id ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Map BOAT_TYPES_BY_ITEM_ID = new HashMap<>(); ++ static { ++ for (final BoatType boatType : BOAT_TYPES) { ++ BOAT_TYPES_BY_ITEM_ID.put(boatType.name() + "_" + boatType.suffix(), boatType.name()); ++ BOAT_TYPES_BY_ITEM_ID.put(boatType.name() + "_chest_" + boatType.suffix(), boatType.name()); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ final String boatType = BOAT_TYPES_BY_ITEM_ID.get(id); ++ ++ if (boatType == null) { ++ return null; ++ } ++ ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ final MapType entityData = components.getMap("minecraft:entity_data"); ++ if (entityData == null) { ++ return null; ++ } ++ ++ entityData.setString("Type", boatType); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Map NORMAL_REMAPPING = new HashMap<>(BOAT_TYPES.length); ++ static { ++ for (final BoatType type : BOAT_TYPES) { ++ NORMAL_REMAPPING.put(type.name(), type.name() + "_" + type.suffix()); ++ } ++ } ++ private static final Map CHEST_REMAPPING = new HashMap<>(BOAT_TYPES.length); ++ static { ++ for (final BoatType type : BOAT_TYPES) { ++ CHEST_REMAPPING.put(type.name(), type.name() + "_chest_" + type.suffix()); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (id == null) { ++ // wat ++ return null; ++ } ++ ++ final boolean normalBoat = id.equals("minecraft:boat"); ++ final boolean chestBoat = id.equals("minecraft:chest_boat"); ++ ++ if (!normalBoat && !chestBoat) { ++ return null; ++ } ++ ++ final String type = data.getString("Type"); ++ data.remove("Type"); ++ ++ if (normalBoat) { ++ data.setString("id", NORMAL_REMAPPING.getOrDefault(type, "minecraft:oak_boat")); ++ } else { ++ data.setString("id", CHEST_REMAPPING.getOrDefault(type, "minecraft:oak_chest_boat")); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.LIGHTWEIGHT_LEVEL.addStructureConverter( ++ new ConverterRemoveFeatureFlag(VERSION, new HashSet<>(Arrays.asList("minecraft:bundle"))) ++ ); ++ } ++ ++ private V4067() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d24c33863e66010f4a6394a9afcc8ad7600969de +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4068.java +@@ -0,0 +1,65 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import com.google.common.escape.Escaper; ++import com.google.common.escape.Escapers; ++ ++public final class V4068 { ++ public static final Escaper ESCAPER = Escapers.builder().addEscape('"', "\\\"").addEscape('\\', "\\\\").build(); ++ ++ private static final int VERSION = MCVersions.V24W38A + 2; ++ ++ private static void convertLock(final MapType root, final String srcPath, final String dstPath) { ++ if (root == null) { ++ return; ++ } ++ ++ final Object lockGeneric = root.getGeneric(srcPath); ++ if (lockGeneric == null) { ++ return; ++ } ++ ++ final TypeUtil typeUtil = root.getTypeUtil(); ++ ++ root.remove(srcPath); ++ ++ if (lockGeneric instanceof String lock && !lock.isEmpty()) { ++ final MapType newLock = typeUtil.createEmptyMap(); ++ root.setMap(dstPath, newLock); ++ ++ final MapType lockComponents = typeUtil.createEmptyMap(); ++ newLock.setMap("components", lockComponents); ++ ++ lockComponents.setString("minecraft:custom_name", ESCAPER.escape(lock)); ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ convertLock(components, "minecraft:lock", "minecraft:lock"); ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ convertLock(data, "Lock", "lock"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4068() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b85673d792d4b1c317d312ba607a0d30c2f57ea9 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4070.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++ ++public final class V4070 { ++ ++ private static final int VERSION = MCVersions.V24W39A + 1; ++ ++ private static void registerChestBoat(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerItemLists("Items")); ++ } ++ ++ public static void register() { ++ // minecraft:pale_oak_boat is a simple entity ++ ++ registerChestBoat("minecraft:pale_oak_chest_boat"); ++ } ++ ++ private V4070() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d00e834ebb7ebdd544f4934375a5a8ba1882d89e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4071.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V4071 { ++ ++ private static final int VERSION = MCVersions.V24W39A + 2; ++ ++ public static void register() { ++ //registerMob("minecraft:creaking"); // changed to simple in 1.21.5 ++ //registerMob("minecraft:creaking_transient"); // changed to simple in 1.21.5 ++ ++ // minecraft:creaking_heart is a simple tile entity ++ } ++ ++ private V4071() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java +new file mode 100644 +index 0000000000000000000000000000000000000000..214dd539edabc44ada373012b1256747ca373e92 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4081.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4081 { ++ ++ private static final int VERSION = MCVersions.V1_21_2 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:salmon", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if ("large".equals(data.getString("type"))) { ++ return null; ++ } ++ ++ data.setString("type", "medium"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4081() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4173.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4173.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e9cff7ce434ca60196c25c44cd98e28dc5b9d151 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4173.java +@@ -0,0 +1,24 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4173 { ++ ++ private static final int VERSION = MCVersions.V1_21_3 + 91; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "TNTFuse", "fuse"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4173() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4175.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4175.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5812c07643dc21d0db4ebe808ffda0612454c00f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4175.java +@@ -0,0 +1,40 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++ ++public final class V4175 { ++ ++ private static final int VERSION = MCVersions.V24W44A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data.getMap("minecraft:equippable"), "model", "asset_id"); ++ ++ final Number modelData = data.getNumber("minecraft:custom_model_data"); ++ if (modelData != null) { ++ final TypeUtil typeUtil = data.getTypeUtil(); ++ ++ final MapType newModelData = typeUtil.createEmptyMap(); ++ data.setMap("minecraft:custom_model_data", newModelData); ++ ++ final ListType floats = typeUtil.createEmptyList(); ++ newModelData.setList("floats", floats); ++ ++ floats.addFloat(modelData.floatValue()); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4175() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4176.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4176.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c60f6da5422cc31a92164b5bc62f2afb8e962b00 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4176.java +@@ -0,0 +1,44 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4176 { ++ ++ private static final int VERSION = MCVersions.V24W44A + 2; ++ ++ private static void fixInvalidLock(final MapType root, final String path) { ++ final MapType lock = root.getMap(path); ++ if (lock == null || lock.size() != 1) { ++ return; ++ } ++ ++ final MapType components = lock.getMap("components"); ++ if (components == null || components.size() != 1 || !"\"\"".equals(components.getString("minecraft:custom_name"))) { ++ return; ++ } ++ ++ root.remove(path); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ fixInvalidLock(data, "lock"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ fixInvalidLock(data, "minecraft:lock"); ++ return null; ++ } ++ }); ++ } ++ ++ private V4176() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4180.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4180.java +new file mode 100644 +index 0000000000000000000000000000000000000000..76eeb8739d9c517a7843545f230853d214ecb8b2 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4180.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.Arrays; ++import java.util.HashSet; ++ ++public final class V4180 { ++ ++ private static final int VERSION = MCVersions.V1_21_4_PRE1 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.LIGHTWEIGHT_LEVEL.addStructureConverter(new ConverterRemoveFeatureFlag(VERSION, new HashSet<>( ++ Arrays.asList( ++ "minecraft:winter_drop" ++ ) ++ ))); ++ } ++ ++ private V4180() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4181.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4181.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8533e5924f5d5542692f511c11487c05bf61f486 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4181.java +@@ -0,0 +1,36 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4181 { ++ ++ private static final int VERSION = MCVersions.V1_21_4_PRE1 + 2; ++ ++ public static void register() { ++ final DataConverter furnaceConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "CookTime", "cooking_time_spent"); ++ RenameHelper.renameSingle(data, "CookTimeTotal", "cooking_total_time"); ++ RenameHelper.renameSingle(data, "BurnTime", "lit_time_remaining"); ++ ++ final Object litTotalTime = data.getGeneric("lit_time_remaining"); ++ if (litTotalTime != null) { ++ data.setGeneric("lit_total_time", litTotalTime); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:furnace", furnaceConverter); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:smoker", furnaceConverter); ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:blast_furnace", furnaceConverter); ++ } ++ ++ private V4181() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4185.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4185.java +new file mode 100644 +index 0000000000000000000000000000000000000000..8b4041d3d3a4a001bf06eaedbddad1b297122b12 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4185.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterAddBlendingData; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V4185 { ++ ++ private static final int VERSION = MCVersions.V1_21_4_RC1 + 1; ++ ++ public static void register() { ++ // See V3088 for why this converter is duplicated in here, V3441, and V3088 ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterAddBlendingData(VERSION)); ++ } ++ ++ private V4185() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4187.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4187.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7d09c4218d0db8119d1681bf95900be830557fa3 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4187.java +@@ -0,0 +1,69 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.attributes.ConverterEntityAttributesBaseValueUpdater; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V4187 { ++ ++ private static final int VERSION = MCVersions.V1_21_4_RC2 + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:villager", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 48.0 ? 16.0 : curr; ++ } ++ ) ++ ); ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:bee", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 48.0 ? 16.0 : curr; ++ } ++ ) ++ ); ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:allay", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 48.0 ? 16.0 : curr; ++ } ++ ) ++ ); ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:llama", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 48.0 ? 16.0 : curr; ++ } ++ ) ++ ); ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:piglin_brute", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 16.0 ? 12.0 : curr; ++ } ++ ) ++ ); ++ MCTypeRegistry.ENTITY.addConverterForId( ++ "minecraft:warden", ++ new ConverterEntityAttributesBaseValueUpdater( ++ VERSION, "minecraft:follow_range", ++ (final double curr) -> { ++ return curr == 16.0 ? 24.0 : curr; ++ } ++ ) ++ ); ++ } ++ ++ private V4187() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4290.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4290.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4197a5e89aec77f2893f0f118a927b96d5377ec1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4290.java +@@ -0,0 +1,248 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.minecraft.MCDataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.Types; ++import ca.spottedleaf.dataconverter.types.nbt.NBTMapType; ++import com.google.gson.JsonElement; ++import com.google.gson.JsonParseException; ++import com.google.gson.JsonParser; ++import com.mojang.logging.LogUtils; ++import net.minecraft.nbt.TagParser; ++import org.slf4j.Logger; ++ ++public final class V4290 { ++ ++ public static final int VERSION = MCVersions.V1_21_4 + 101; ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static void convertNestedList(final ListType components) { ++ if (components == null) { ++ return; ++ } ++ for (int i = 0, len = components.size(); i < len; ++i) { ++ convertNested(components.getGeneric(i)); ++ } ++ } ++ ++ private static void convertNested(final Object component) { ++ if (component instanceof ListType listType) { ++ convertNestedList(listType); ++ } else if (component instanceof MapType root) { ++ convertLegacyHover(root); ++ ++ convertNestedList(root.getListUnchecked("extra")); ++ convertNested(root.getGeneric("separator")); ++ ++ final MapType hoverEvent = root.getMap("hoverEvent"); ++ if (hoverEvent != null) { ++ switch (hoverEvent.getString("action", "")) { ++ case "show_text": { ++ convertNested(hoverEvent.getGeneric("contents")); ++ break; ++ } ++ case "show_item": { ++ break; ++ } ++ case "show_entity": { ++ convertNested(hoverEvent.getGeneric("name")); ++ break; ++ } ++ // default: do nothing ++ } ++ } ++ } // else: should only be string ++ } ++ ++ private static void convertLegacyHover(final MapType textComponent) { ++ final TypeUtil typeUtil = textComponent.getTypeUtil(); ++ final MapType hoverEvent = textComponent.getMap("hoverEvent"); ++ if (hoverEvent == null) { ++ return; ++ } ++ ++ final Object legacyValue = hoverEvent.getGeneric("value"); ++ if (legacyValue == null) { ++ // nothing to do here ++ return; ++ } ++ ++ switch (hoverEvent.getString("action", "")) { ++ case "show_text": { ++ // value -> another text component; all we need to do is just move it to contents ++ hoverEvent.remove("value"); ++ hoverEvent.setGeneric("contents", legacyValue); ++ break; ++ } ++ case "show_item": { ++ // value -> snbt of serialized item ++ hoverEvent.remove("value"); ++ if (!(legacyValue instanceof String legacyItemStr)) { ++ LOGGER.error("Legacy HoverEvent with action=show_item has invalid value, expected string: " + legacyValue); ++ break; ++ } ++ ++ final MapType legacyItem; ++ try { ++ legacyItem = new NBTMapType(TagParser.parseCompoundFully(legacyItemStr)); ++ } catch (final Exception ex) { ++ LOGGER.error("Failed to parse SNBT for legacy item HoverEvent: " + legacyItemStr, ex); ++ break; ++ } ++ ++ // note: blindly take precedence over non-legacy data ++ hoverEvent.setMap("contents", legacyItem); ++ break; ++ } ++ case "show_entity": { ++ // value -> snbt of {name:,type:,id:} ++ hoverEvent.remove("value"); ++ if (!(legacyValue instanceof String legacyEntityStr)) { ++ LOGGER.error("Legacy HoverEvent with action=show_entity has invalid value, expected string: " + legacyValue); ++ break; ++ } ++ ++ final MapType legacyEntity; ++ try { ++ legacyEntity = new NBTMapType(TagParser.parseCompoundFully(legacyEntityStr)); ++ } catch (final Exception ex) { ++ LOGGER.error("Failed to parse SNBT for legacy entity HoverEvent: " + legacyEntityStr, ex); ++ break; ++ } ++ ++ final MapType newContents = typeUtil.createEmptyMap(); ++ // note: blindly take precedence over non-legacy data ++ hoverEvent.setMap("contents", newContents); ++ ++ final String name = legacyEntity.getString("name"); ++ if (name != null) { ++ newContents.setString("name", name); ++ } ++ final String type = legacyEntity.getString("type"); ++ if (type != null) { ++ newContents.setString("type", type); ++ } ++ final String id = legacyEntity.getString("id"); ++ if (id != null) { ++ newContents.setString("id", id); ++ } ++ ++ break; ++ } ++ // default: do nothing ++ } ++ } ++ ++ public static void register() { ++ MCTypeRegistry.TEXT_COMPONENT.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (data instanceof ListType) { ++ // will be iterated by walker ++ return null; ++ } ++ if (data instanceof MapType) { ++ // (probably) iterated by walker ++ return null; ++ } ++ if (data instanceof Number number) { ++ // text component parsed as list of numbers, which was then iterated by walker ++ // we need to convert to correct type, which is string ++ return number.toString(); ++ } ++ if (data instanceof Boolean bool) { ++ // text component parsed as list of booleans, which was then iterated by walker ++ // we need to convert to correct type, which is string ++ return bool.toString(); ++ } ++ ++ if (!(data instanceof String unparsedJson)) { ++ throw new IllegalArgumentException("Wrong type for text component: " + data); ++ } ++ ++ try { ++ final JsonElement json = JsonParser.parseString(unparsedJson); ++ ++ if (!json.isJsonNull()) { ++ final Object generic = Types.JSON.convertFromBaseToGeneric(json, Types.NBT); ++ final Object ret = switch (generic) { ++ case Number nt -> nt.toString(); // json may parse as integer, need to convert to string ++ case Boolean bt -> bt.toString(); // json may parse as boolean, need to convert to string ++ case String s -> s; // simple string component ++ case ListType lt -> lt; // list of text components ++ case MapType ct -> ct; // complex text component ++ case byte[] bt -> throw new IllegalStateException("Unexpected byte[] output from JsonTypeUtil"); ++ case int[] it -> throw new IllegalStateException("Unexpected int[] output from JsonTypeUtil"); ++ case long[] lt -> throw new IllegalStateException("Unexpected long[] output from JsonTypeUtil"); ++ // null is handled by isJsonNull() ++ default -> throw new IllegalStateException("Unknown nbt type: " + generic); ++ }; ++ ++ convertNested(ret); ++ return ret; ++ } ++ } catch (final JsonParseException ex) { ++ LOGGER.error("Failed to convert json to nbt: " + unparsedJson, ex); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TEXT_COMPONENT.addStructureWalker(VERSION, (final Object input, final long fromVersion, final long toVersion) -> { ++ if (input instanceof ListType listType) { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, listType, fromVersion, toVersion); ++ } else if (input instanceof MapType root) { ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, root, "extra", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "separator", fromVersion, toVersion); ++ ++ final MapType clickEvent = root.getMap("clickEvent"); ++ if (clickEvent != null) { ++ switch (clickEvent.getString("action", "")) { ++ case "run_command": ++ case "suggest_command": { ++ WalkerUtils.convert(MCTypeRegistry.DATACONVERTER_CUSTOM_TYPE_COMMAND, clickEvent, "value", fromVersion, toVersion); ++ break; ++ } ++ } ++ } ++ ++ final MapType hoverEvent = root.getMap("hoverEvent"); ++ if (hoverEvent != null) { ++ switch (hoverEvent.getString("action", "")) { ++ case "show_text": { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, hoverEvent, "contents", fromVersion, toVersion); ++ break; ++ } ++ case "show_item": { ++ if (hoverEvent.hasKey("contents", ObjectType.STRING)) { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_NAME, hoverEvent, "contents", fromVersion, toVersion); ++ } else { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, hoverEvent, "contents", fromVersion, toVersion); ++ } ++ break; ++ } ++ case "show_entity": { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, hoverEvent, "type", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, hoverEvent, "name", fromVersion, toVersion); ++ break; ++ } ++ // default: do nothing ++ } ++ } ++ } // else: should only be string ++ return null; ++ }); ++ } ++ ++ private V4290() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4291.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4291.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9c01fa1f41735dd54641533ce6eefec381270993 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4291.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4291 { ++ ++ public static final int VERSION = MCVersions.V1_21_4 + 102; ++ ++ public static void register() { ++ // V4290 correctly handles legacy hover events, so we skip that converter. ++ MCTypeRegistry.TEXT_COMPONENT.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final String[] BOOLEAN_PATHS_TO_CONVERT = new String[] { ++ "bold", ++ "italic", ++ "underlined", ++ "strikethrough", ++ "obfuscated", ++ // add extra interpret field ++ "interpret", ++ }; ++ ++ private static void convertToBoolean(final MapType data, final String path) { ++ final String value = data.getString(path); ++ if (value != null) { ++ data.setBoolean(path, Boolean.parseBoolean(value)); ++ } ++ } ++ ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (data instanceof MapType root) { ++ for (final String path : BOOLEAN_PATHS_TO_CONVERT) { ++ convertToBoolean(root, path); ++ } ++ } // else: list -> handled by walker, string -> no formatting to convert ++ return null; ++ } ++ }); ++ } ++ ++ private V4291() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4292.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4292.java +new file mode 100644 +index 0000000000000000000000000000000000000000..34f20d3cb6595eaa11e00126804ef7bd3fafa05b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4292.java +@@ -0,0 +1,180 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.CopyHelper; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import java.net.URI; ++ ++public final class V4292 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 103; ++ ++ public static void register() { ++ MCTypeRegistry.TEXT_COMPONENT.addStructureConverter(new DataConverter<>(VERSION) { ++ private static boolean isWebUrl(final String value) { ++ try { ++ final String scheme = new URI(value).getScheme(); ++ ++ return "http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme); ++ } catch (final Exception ex) { ++ return false; ++ } ++ } ++ ++ private static boolean isValidCommandOrChat(final String value) { ++ for (int i = 0, len = value.length(); i < len; ++i) { ++ final char c = value.charAt(i); ++ ++ if (c < ' ' || c == 127 || c == 167) { ++ return false; ++ } ++ } ++ ++ return true; ++ } ++ ++ private static Integer parseInteger(final MapType root, final String path) { ++ final Object value = root.getGeneric(path); ++ if (value instanceof String string) { ++ try { ++ return Integer.parseInt(string); ++ } catch (final Exception ex) { ++ return null; ++ } ++ } else if (value instanceof Number number) { ++ return Integer.valueOf(number.intValue()); ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public Object convert(final Object data, final long sourceVersion, final long toVersion) { ++ if (!(data instanceof MapType root)) { ++ // list or string, don't care about formatting for those ++ return null; ++ } ++ ++ RenameHelper.renameSingle(root, "hoverEvent", "hover_event"); ++ final MapType hoverEvent = root.getMap("hover_event"); ++ if (hoverEvent != null) { ++ switch (hoverEvent.getString("action", "")) { ++ case "show_text": { ++ RenameHelper.renameSingle(hoverEvent, "contents", "value"); ++ break; ++ } ++ case "show_item": { ++ if (hoverEvent.hasKey("contents", ObjectType.STRING)) { ++ RenameHelper.renameSingle(hoverEvent, "contents", "id"); ++ } else { ++ final MapType contents = hoverEvent.getOrCreateMap("contents"); ++ hoverEvent.remove("contents"); ++ ++ CopyHelper.move(contents, "id", hoverEvent, "id"); ++ CopyHelper.move(contents, "count", hoverEvent, "count"); ++ CopyHelper.move(contents, "components", hoverEvent, "components"); ++ } ++ break; ++ } ++ case "show_entity": { ++ final MapType contents = hoverEvent.getOrCreateMap("contents"); ++ hoverEvent.remove("contents"); ++ ++ CopyHelper.move(contents, "id", hoverEvent, "uuid"); ++ CopyHelper.move(contents, "type", hoverEvent, "id"); ++ CopyHelper.move(contents, "name", hoverEvent, "name"); ++ ++ break; ++ } ++ ++ // default: do nothing ++ } ++ } ++ ++ RenameHelper.renameSingle(root, "clickEvent", "click_event"); ++ final MapType clickEvent = root.getMap("click_event"); ++ if (clickEvent != null) { ++ final String value = clickEvent.getString("value", ""); ++ ++ switch (clickEvent.getString("action", "")) { ++ case "open_url": { ++ if (!isWebUrl(value)) { ++ root.remove("click_event"); ++ break; ++ } ++ RenameHelper.renameSingle(clickEvent, "value", "url"); ++ break; ++ } ++ case "open_file": { ++ RenameHelper.renameSingle(clickEvent, "value", "path"); ++ break; ++ } ++ case "run_command": ++ case "suggest_command": { ++ if (!isValidCommandOrChat(value)) { ++ root.remove("click_event"); ++ break; ++ } ++ RenameHelper.renameSingle(clickEvent, "value", "command"); ++ break; ++ } ++ case "change_page": { ++ final Integer page = parseInteger(clickEvent, "value"); ++ if (page == null) { ++ root.remove("click_event"); ++ break; ++ } ++ clickEvent.remove("value"); ++ clickEvent.setInt("page", Math.max(1, page.intValue())); ++ } ++ ++ // default: do nothing ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TEXT_COMPONENT.addStructureWalker(VERSION, (final Object input, final long fromVersion, final long toVersion) -> { ++ if (input instanceof ListType listType) { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, listType, fromVersion, toVersion); ++ } else if (input instanceof MapType root) { ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, root, "extra", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "separator", fromVersion, toVersion); ++ ++ ++ WalkerUtils.convert(MCTypeRegistry.DATACONVERTER_CUSTOM_TYPE_COMMAND, root.getMap("clickEvent"), "command", fromVersion, toVersion); ++ ++ final MapType hoverEvent = root.getMap("hover_event"); ++ if (hoverEvent != null) { ++ switch (hoverEvent.getString("action", "")) { ++ case "show_text": { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, hoverEvent, "value", fromVersion, toVersion); ++ break; ++ } ++ case "show_item": { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "hover_event", fromVersion, toVersion); ++ break; ++ } ++ case "show_entity": { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, hoverEvent, "id", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, hoverEvent, "name", fromVersion, toVersion); ++ break; ++ } ++ // default: do nothing ++ } ++ } ++ } // else: should only be string ++ return null; ++ }); ++ } ++ ++ private V4292() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4293.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4293.java +new file mode 100644 +index 0000000000000000000000000000000000000000..aac34658c39c568baba069ae151bcd7802bdad27 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4293.java +@@ -0,0 +1,71 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4293 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 104; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final float DEFAULT = 0.085f; ++ ++ private static final String[] ARMOR_SLOTS = new String[] { ++ "feet", ++ "legs", ++ "chest", ++ "head" ++ }; ++ ++ private static final String[] HAND_SLOTS = new String[] { ++ "mainhand", ++ "offhand" ++ }; ++ ++ private static void convertDropChances(final MapType root, final String srcPath, final String[] names, final MapType dst) { ++ final ListType oldChances = root.getListUnchecked(srcPath); ++ ++ if (oldChances == null) { ++ return; ++ } ++ ++ for (int i = 0, len = Math.min(oldChances.size(), names.length); i < len; ++i) { ++ final float chance = oldChances.getFloat(i, DEFAULT); ++ if (chance != DEFAULT) { ++ dst.setFloat(names[i], chance); ++ } ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType dropChances = data.getTypeUtil().createEmptyMap(); ++ ++ convertDropChances(data, "ArmorDropChances", ARMOR_SLOTS, dropChances); ++ convertDropChances(data, "HandDropChances", HAND_SLOTS, dropChances); ++ ++ data.remove("ArmorDropChances"); ++ data.remove("HandDropChances"); ++ ++ final float body = data.getFloat("body_armor_drop_chance", DEFAULT); ++ data.remove("body_armor_drop_chance"); ++ ++ if (body != DEFAULT) { ++ dropChances.setFloat("body", body); ++ } ++ ++ if (!dropChances.isEmpty()) { ++ data.setMap("drop_chances", dropChances); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4293() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4294.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4294.java +new file mode 100644 +index 0000000000000000000000000000000000000000..86f4c268197d90270768786f3911258e841040ea +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4294.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4294 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 105; ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:creaking_heart".equals(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ if (properties == null) { ++ return null; ++ } ++ ++ final String active = properties.getString("active"); ++ if (active == null) { ++ return null; ++ } ++ properties.remove("active"); ++ properties.setString("creaking_heart_state", active.equals("true") ? "awake" : "uprooted"); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4294() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4295.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4295.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e85a156f21f826faf5e04a5f93df7e3b77ebc15c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4295.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.chunk.ConverterAddBlendingData; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++ ++public final class V4295 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 106; ++ ++ public static void register() { ++ // See V3088 for why this converter is duplicated in here, V4185, V3441, and V3088 ++ MCTypeRegistry.CHUNK.addStructureConverter(new ConverterAddBlendingData(VERSION)); ++ } ++ ++ private V4295() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4296.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4296.java +new file mode 100644 +index 0000000000000000000000000000000000000000..a22ee6dee2f14a61688734a1afa71dc55d90ff43 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4296.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4296 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 107; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:area_effect_cloud", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setFloat("potion_duration_scale", 0.25f); ++ return null; ++ } ++ }); ++ } ++ ++ private V4296() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4297.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4297.java +new file mode 100644 +index 0000000000000000000000000000000000000000..83c2c4e3e3c73e605d0f57b7c85db1bef64f982f +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4297.java +@@ -0,0 +1,51 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++ ++public final class V4297 { ++ ++ private static final int VERSION = MCVersions.V1_21_4 + 108; ++ ++ public static void register() { ++ MCTypeRegistry.SAVED_DATA_TICKETS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ final long[] forced = data.getLongs("Forced"); ++ if (forced == null) { ++ return null; ++ } ++ ++ data.remove("Forced"); ++ ++ final TypeUtil typeUtil = data.getTypeUtil(); ++ ++ final ListType tickets = typeUtil.createEmptyList(); ++ data.setList("tickets", tickets); ++ ++ for (final long coordinate : forced) { ++ final MapType ticket = typeUtil.createEmptyMap(); ++ tickets.addMap(ticket); ++ ++ ticket.setString("type", "minecraft:forced"); ++ ticket.setInt("level", 31); ++ ticket.setLong("ticks_left", 0L); ++ ticket.setLong("chunk_pos", coordinate); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4297() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4299.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4299.java +new file mode 100644 +index 0000000000000000000000000000000000000000..e09c5ed9bd872ddb4d809b28434d35d48b065564 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4299.java +@@ -0,0 +1,140 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++ ++public final class V4299 { ++ ++ private static final int VERSION = MCVersions.V25W02A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final String[] AXOLOTL_VARIANT_LOOKUP = new String[] { ++ "lucy", ++ "wild", ++ "gold", ++ "cyan", ++ "blue", ++ }; ++ ++ private static final Int2ObjectOpenHashMap FISH_PATTERN_LOOKUP = new Int2ObjectOpenHashMap<>(); ++ static { ++ FISH_PATTERN_LOOKUP.defaultReturnValue("kob"); ++ FISH_PATTERN_LOOKUP.put(1,"flopper"); ++ FISH_PATTERN_LOOKUP.put(256,"sunstreak"); ++ FISH_PATTERN_LOOKUP.put(257,"stripey"); ++ FISH_PATTERN_LOOKUP.put(512,"snooper"); ++ FISH_PATTERN_LOOKUP.put(513,"glitter"); ++ FISH_PATTERN_LOOKUP.put(768,"dasher"); ++ FISH_PATTERN_LOOKUP.put(769,"blockfish"); ++ FISH_PATTERN_LOOKUP.put(1024,"brinely"); ++ FISH_PATTERN_LOOKUP.put(1025,"betty"); ++ FISH_PATTERN_LOOKUP.put(1280,"spotty"); ++ FISH_PATTERN_LOOKUP.put(1281,"clayfish"); ++ } ++ ++ private static String lookupAxolotl(final int index) { ++ return index >= 0 && index < AXOLOTL_VARIANT_LOOKUP.length ? AXOLOTL_VARIANT_LOOKUP[index] : AXOLOTL_VARIANT_LOOKUP[0]; ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType components = data.getMap("components"); ++ if (components == null) { ++ return null; ++ } ++ ++ final String id = data.getString("id"); ++ switch (id) { ++ case "minecraft:axolotl_bucket": { ++ final MapType bucketEntityData = components.getMap("minecraft:bucket_entity_data"); ++ if (bucketEntityData == null) { ++ break; ++ } ++ ++ final Number variant = bucketEntityData.getNumber("Variant"); ++ if (variant == null) { ++ break; ++ } ++ ++ bucketEntityData.remove("Variant"); ++ components.setString("minecraft:axolotl/variant", lookupAxolotl(variant.intValue())); ++ ++ break; ++ } ++ case "minecraft:salmon_bucket": { ++ final MapType bucketEntityData = components.getMap("minecraft:bucket_entity_data"); ++ if (bucketEntityData == null) { ++ break; ++ } ++ ++ final Object type = bucketEntityData.getGeneric("type"); ++ if (type == null) { ++ break; ++ } ++ bucketEntityData.remove("type"); ++ components.setGeneric("minecraft:salmon/size", type); ++ ++ break; ++ } ++ case "minecraft:tropical_fish_bucket": { ++ final MapType bucketEntityData = components.getMap("minecraft:bucket_entity_data"); ++ if (bucketEntityData == null) { ++ break; ++ } ++ ++ final Number variantBoxed = bucketEntityData.getNumber("BucketVariantTag"); ++ if (variantBoxed == null) { ++ break; ++ } ++ bucketEntityData.remove("BucketVariantTag"); ++ ++ final int variant = variantBoxed.intValue(); ++ ++ final String fishPattern = FISH_PATTERN_LOOKUP.get(variant & 0xFFFF); ++ final String baseColour = V3818.getBannerColour((variant >>> 16) & 0xFF); ++ final String patternColour = V3818.getBannerColour((variant >>> 24) & 0xFF); ++ ++ components.setString("minecraft:tropical_fish/pattern", fishPattern); ++ components.setString("minecraft:tropical_fish/base_color", baseColour); ++ components.setString("minecraft:tropical_fish/pattern_color", patternColour); ++ ++ break; ++ } ++ case "minecraft:painting": { ++ final MapType entityData = components.getMap("minecraft:entity_data"); ++ ++ if (entityData == null) { ++ break; ++ } ++ ++ if (!"minecraft:painting".equals(entityData.getString("id"))) { ++ break; ++ } ++ ++ final Object variant = entityData.getGeneric("variant"); ++ if (variant != null) { ++ entityData.remove("variant"); ++ components.setGeneric("minecraft:painting/variant", variant); ++ } ++ if (entityData.size() == 1) { ++ components.remove("minecraft:entity_data"); ++ } ++ ++ break; ++ } ++ default: { ++ return null; ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4299() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4300.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4300.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0619fc8509177e8f66e6a33072249d2468789fef +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4300.java +@@ -0,0 +1,89 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.Arrays; ++import java.util.HashSet; ++import java.util.Set; ++ ++public final class V4300 { ++ ++ private static final int VERSION = MCVersions.V25W02A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Set SADDLE_ITEM_ENTITIES = new HashSet<>( ++ Arrays.asList( ++ "minecraft:horse", ++ "minecraft:skeleton_horse", ++ "minecraft:zombie_horse", ++ "minecraft:donkey", ++ "minecraft:mule", ++ "minecraft:camel", ++ "minecraft:llama", ++ "minecraft:trader_llama" ++ ) ++ ); ++ private static final Set SADDLE_FLAG_ENTITIES = new HashSet<>( ++ Arrays.asList( ++ "minecraft:pig", ++ "minecraft:strider" ++ ) ++ ); ++ ++ private static void setGuaranteedSaddleDropChance(final MapType data) { ++ data.getOrCreateMap("drop_chances").setFloat("saddle", 2.0f); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ ++ if (SADDLE_ITEM_ENTITIES.contains(id)) { ++ if (!RenameHelper.renameSingle(data, "SaddleItem", "saddle")) { ++ return null; ++ } ++ ++ setGuaranteedSaddleDropChance(data); ++ ++ return null; ++ } else if (SADDLE_FLAG_ENTITIES.contains(id)) { ++ final boolean saddle = data.getBoolean("Saddle"); ++ data.remove("Saddle"); ++ ++ if (!saddle) { ++ return null; ++ } ++ ++ final MapType saddleItem = data.getTypeUtil().createEmptyMap(); ++ data.setMap("saddle", saddleItem); ++ saddleItem.setString("id", "minecraft:saddle"); ++ saddleItem.setInt("count", 1); ++ ++ setGuaranteedSaddleDropChance(data); ++ ++ return null; ++ } ++ ++ return null; ++ } ++ }); ++ ++ // saddle item moved to `saddle`, which is now under ENTITY_EQUIPMENT ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:llama", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:trader_llama", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:donkey", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:mule", new DataWalkerItemLists("Items")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:horse", DataWalker.noOp()); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:skeleton_horse", DataWalker.noOp()); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:zombie_horse", DataWalker.noOp()); ++ } ++ ++ private V4300() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4301.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4301.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3eef93d9666ccf4fd748f137daa25613fefae548 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4301.java +@@ -0,0 +1,93 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4301 { ++ ++ private static final int VERSION = MCVersions.V25W02A + 3; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY_EQUIPMENT.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final String[] ARMOR_SLOTS = new String[] { ++ "feet", ++ "legs", ++ "chest", ++ "head" ++ }; ++ ++ private static final String[] HAND_SLOTS = new String[] { ++ "mainhand", ++ "offhand" ++ }; ++ ++ private static MapType filterItem(final MapType item) { ++ return item == null || item.hasKey("id") ? item : null; ++ } ++ ++ private static void setIfNonNull(final MapType dst, final String dstKey, final MapType value) { ++ if (value != null) { ++ dst.setMap(dstKey, value); ++ } ++ } ++ ++ private static void moveItems(final MapType src, final String srcPath, final String[] names, final MapType dst) { ++ final ListType items = src.getListUnchecked(srcPath); ++ if (items == null) { ++ return; ++ } ++ ++ for (int i = 0, len = Math.min(items.size(), names.length); i < len; ++i) { ++ final MapType item = filterItem(items.getMap(i, null)); ++ if (item != null) { ++ dst.setMap(names[i], item); ++ } ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType equipment = data.getTypeUtil().createEmptyMap(); ++ ++ setIfNonNull(equipment, "body", filterItem(data.getMap("body_armor_item"))); ++ setIfNonNull(equipment, "saddle", filterItem(data.getMap("saddle"))); ++ ++ moveItems(data, "ArmorItems", ARMOR_SLOTS, equipment); ++ moveItems(data, "HandItems", HAND_SLOTS, equipment); ++ ++ data.remove("ArmorItems"); ++ data.remove("HandItems"); ++ data.remove("body_armor_item"); ++ data.remove("saddle"); ++ ++ if (!equipment.isEmpty()) { ++ data.setMap("equipment", equipment); ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY_EQUIPMENT.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType equipment = data.getMap("equipment"); ++ if (equipment != null) { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "mainhand", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "offhand", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "feet", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "legs", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "chest", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "head", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "body", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, equipment, "saddle", fromVersion, toVersion); ++ } ++ ++ return null; ++ }); ++ } ++ ++ private V4301() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4302.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4302.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7eb1d865cf8ba91f15b0bb6460de7c26853bb21b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4302.java +@@ -0,0 +1,17 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V4302 { ++ ++ private static final int VERSION = MCVersions.V25W02A + 4; ++ ++ public static void register() { ++ ++ ++ // test_block is simple TE ++ // test_instance_block is simple TE ++ } ++ ++ private V4302() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4303.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4303.java +new file mode 100644 +index 0000000000000000000000000000000000000000..dd5827a250807c810ac352547a868151dbae95df +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4303.java +@@ -0,0 +1,30 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4303 { ++ ++ private static final int VERSION = MCVersions.V25W02A + 5; ++ ++ public static void register() { ++ final DataConverter fallConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final float fallDistance = data.getFloat("FallDistance", 0.0f); ++ data.remove("FallDistance"); ++ ++ data.setDouble("fall_distance", (double)fallDistance); ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(fallConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(fallConverter); ++ } ++ ++ private V4303() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4305.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4305.java +new file mode 100644 +index 0000000000000000000000000000000000000000..90bd5dad4efaa654adbda610a287fea26519a352 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4305.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4305 { ++ ++ private static final int VERSION = MCVersions.V25W03A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.BLOCK_STATE.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!"minecraft:test_block".equals(data.getString("Name"))) { ++ return null; ++ } ++ ++ final MapType properties = data.getMap("Properties"); ++ if (properties == null) { ++ return null; ++ } ++ ++ final String mode = properties.getString("test_block_mode"); ++ if (mode == null) { ++ return null; ++ } ++ properties.remove("test_block_mode"); ++ properties.setString("mode", mode); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4305() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4306.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4306.java +new file mode 100644 +index 0000000000000000000000000000000000000000..f5b46c9f10719ce0e2014eb2289648fc7f4aa904 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4306.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4306 { ++ ++ private static final int VERSION = MCVersions.V25W03A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:potion", new DataConverter<>(VERSION) { ++ private static boolean matchItem(final MapType item, final String id) { ++ if (item == null) { ++ return false; ++ } ++ ++ return id.equals(item.getString("id")); ++ } ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setString("id", matchItem(data.getMap("Item"), "minecraft:lingering_potion") ? "minecraft:lingering_potion" : "minecraft:splash_potion"); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:potion", "minecraft:splash_potion"); ++ MCTypeRegistry.ENTITY.copyWalkers(VERSION, "minecraft:potion", "minecraft:lingering_potion"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:potion", DataWalker.noOp()); ++ } ++ ++ private V4306() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d2877c20f389d0131e1dd208b464f590671e5d82 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java +@@ -0,0 +1,224 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import java.util.LinkedHashSet; ++import java.util.Set; ++ ++public final class V4307 { ++ ++ private static final int VERSION = MCVersions.V25W03A + 3; ++ ++ public static void register() { ++ MCTypeRegistry.DATA_COMPONENTS.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final String[] ADDITIONAL_TOOLTIP_COMPONENTS = new String[] { ++ "minecraft:banner_patterns", ++ "minecraft:bees", ++ "minecraft:block_entity_data", ++ "minecraft:block_state", ++ "minecraft:bundle_contents", ++ "minecraft:charged_projectiles", ++ "minecraft:container", ++ "minecraft:container_loot", ++ "minecraft:firework_explosion", ++ "minecraft:fireworks", ++ "minecraft:instrument", ++ "minecraft:map_id", ++ "minecraft:painting/variant", ++ "minecraft:pot_decorations", ++ "minecraft:potion_contents", ++ "minecraft:tropical_fish/pattern", ++ "minecraft:written_book_content" ++ }; ++ ++ private static void unwrapBlockPredicates(final MapType root, final String path, final Set hiddenComponents) { ++ final MapType component = root.getMap(path); ++ if (component == null) { ++ return; ++ } ++ ++ final Object predicates = component.getGeneric("predicates"); ++ if (predicates == null) { ++ return; ++ } ++ root.setGeneric(path, predicates); ++ if (!component.getBoolean("show_in_tooltip", true)) { ++ hiddenComponents.add(path); ++ } ++ } ++ ++ private static void updateComponent(final MapType root, final String path, final Set hiddenComponents) { ++ final MapType component = root.getMap(path); ++ if (component == null) { ++ return; ++ } ++ ++ if (!component.getBoolean("show_in_tooltip", true)) { ++ hiddenComponents.add(path); ++ } ++ ++ component.remove("show_in_tooltip"); ++ } ++ ++ private static void updateComponentAndUnwrap(final MapType root, final String componentPath, final String unwrapPath, final Set hiddenComponents) { ++ final MapType component = root.getMap(componentPath); ++ if (component == null) { ++ return; ++ } ++ ++ if (!component.getBoolean("show_in_tooltip", true)) { ++ hiddenComponents.add(componentPath); ++ } ++ ++ component.remove("show_in_tooltip"); ++ ++ final Object wrapped = component.getGeneric(unwrapPath); ++ if (wrapped != null) { ++ root.setGeneric(componentPath, wrapped); ++ } ++ } ++ ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final Set hiddenComponents = new LinkedHashSet<>(); ++ ++ unwrapBlockPredicates(root, "minecraft:can_break", hiddenComponents); ++ unwrapBlockPredicates(root, "minecraft:can_place_on", hiddenComponents); ++ ++ updateComponent(root, "minecraft:trim", hiddenComponents); ++ updateComponent(root, "minecraft:unbreakable", hiddenComponents); ++ ++ updateComponentAndUnwrap(root, "minecraft:dyed_color", "rgb", hiddenComponents); ++ updateComponentAndUnwrap(root, "minecraft:attribute_modifiers", "modifiers", hiddenComponents); ++ updateComponentAndUnwrap(root, "minecraft:enchantments", "levels", hiddenComponents); ++ updateComponentAndUnwrap(root, "minecraft:stored_enchantments", "levels", hiddenComponents); ++ updateComponentAndUnwrap(root, "minecraft:jukebox_playable", "song", hiddenComponents); ++ ++ final boolean hideTooltip = root.hasKey("minecraft:hide_tooltip"); ++ final boolean hideAdditionalTooltip = root.hasKey("minecraft:hide_additional_tooltip"); ++ ++ if (hideAdditionalTooltip) { ++ for (final String component : ADDITIONAL_TOOLTIP_COMPONENTS) { ++ if (root.hasKey(component)) { ++ hiddenComponents.add(component); ++ } ++ } ++ } ++ ++ root.remove("minecraft:hide_tooltip"); ++ root.remove("minecraft:hide_additional_tooltip"); ++ ++ if (hideTooltip || !hiddenComponents.isEmpty()) { ++ final TypeUtil typeUtil = root.getTypeUtil(); ++ ++ final MapType tooltipDisplay = typeUtil.createEmptyMap(); ++ final ListType hiddenComponentsList = typeUtil.createEmptyList(); ++ ++ root.setMap("minecraft:tooltip_display", tooltipDisplay); ++ tooltipDisplay.setBoolean("hide_tooltip", hideTooltip); ++ tooltipDisplay.setList("hidden_components", hiddenComponentsList); ++ ++ for (final String component : hiddenComponents) { ++ hiddenComponentsList.addString(component); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ ++ // previous version: 4059 ++ MCTypeRegistry.DATA_COMPONENTS.addStructureWalker(VERSION, new DataWalker<>() { ++ private static void walkBlockPredicate(final MapType data, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ if (data.hasKey("blocks", ObjectType.LIST)) { ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, data, "blocks", fromVersion, toVersion); ++ } else { ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, data, "blocks", fromVersion, toVersion); ++ } ++ } ++ ++ private static void walkBlockPredicates(final MapType root, final String path, final long fromVersion, final long toVersion) { ++ final Object value = root.getGeneric(path); ++ ++ if (value instanceof MapType data) { ++ walkBlockPredicate(data, fromVersion, toVersion); ++ } else if (value instanceof ListType list) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ walkBlockPredicate(list.getMap(i, null), fromVersion, toVersion); ++ } ++ } ++ } ++ ++ @Override ++ public MapType walk(final MapType root, final long fromVersion, final long toVersion) { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "minecraft:bees", "entity_data", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TILE_ENTITY, root, "minecraft:block_entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:bundle_contents", fromVersion, toVersion); ++ ++ walkBlockPredicates(root, "minecraft:can_break", fromVersion, toVersion); ++ walkBlockPredicates(root, "minecraft:can_place_on", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, root, "minecraft:charged_projectiles", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.ITEM_STACK, root, "minecraft:container", "item", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, root, "minecraft:entity_data", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_NAME, root, "minecraft:pot_decorations", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "minecraft:use_remainder", fromVersion, toVersion); ++ ++ final MapType equippable = root.getMap("minecraft:equippable"); ++ if (equippable != null) { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY_NAME, equippable, "allowed_entities", fromVersion, toVersion); ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:custom_name", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:item_name", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, root, "minecraft:lore", fromVersion, toVersion); ++ ++ final MapType writtenBookContent = root.getMap("minecraft:written_book_content"); ++ if (writtenBookContent != null) { ++ final ListType pages = writtenBookContent.getListUnchecked("pages"); ++ if (pages != null) { ++ for (int i = 0, len = pages.size(); i < len; ++i) { ++ final Object pageGeneric = pages.getGeneric(i); ++ if (pageGeneric instanceof String || pageGeneric instanceof ListType) { // handles: String case, ListType case ++ final Object convertedGeneric = MCTypeRegistry.TEXT_COMPONENT.convert(pageGeneric, fromVersion, toVersion); ++ if (convertedGeneric != null) { ++ pages.setGeneric(i, convertedGeneric); ++ } ++ } else if (pageGeneric instanceof MapType mapType) { ++ // Need to handle: Filterable format and regular NBT Component format are both MapType... ++ if (mapType.hasKey("raw") || mapType.hasKey("filtered")) { ++ // Assume filterable format ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "raw", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, mapType, "filtered", fromVersion, toVersion); ++ } else { ++ // Assume regular NBT format ++ final Object convertedGeneric = MCTypeRegistry.TEXT_COMPONENT.convert(pageGeneric, fromVersion, toVersion); ++ if (convertedGeneric != null) { ++ pages.setGeneric(i, convertedGeneric); ++ } ++ } ++ } ++ } ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4307() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4309.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4309.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6b73fcafb812f24aede33868ef87408a60ef19c8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4309.java +@@ -0,0 +1,109 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4309 { ++ ++ private static final int VERSION = MCVersions.V25W04A + 1; ++ ++ public static int[] makeBlockPosition(final Number x, final Number y, final Number z) { ++ return new int[] { x.intValue(), y.intValue(), z.intValue() }; ++ } ++ ++ public static void convertBlockPosition(final MapType data, final String xPath, final String yPath, final String zPath, ++ final String toPath) { ++ final Number x = data.getNumber(xPath); ++ final Number y = data.getNumber(yPath); ++ final Number z = data.getNumber(zPath); ++ ++ if (x == null || y == null || z == null) { ++ return; ++ } ++ ++ data.remove(xPath); ++ data.remove(yPath); ++ data.remove(zPath); ++ ++ data.setInts(toPath, makeBlockPosition(x, y, z)); ++ } ++ ++ public static void register() { ++ MCTypeRegistry.SAVED_DATA_RAIDS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ RenameHelper.renameSingle(data, "Raids", "raids"); ++ RenameHelper.renameSingle(data, "Tick", "tick"); ++ RenameHelper.renameSingle(data, "NextAvailableID", "next_id"); ++ ++ final ListType raids = data.getListUnchecked("raids"); ++ if (raids != null) { ++ for (int i = 0, len = raids.size(); i < len; ++i) { ++ final MapType raid = raids.getMap(i, null); ++ if (raid == null) { ++ continue; ++ } ++ ++ convertBlockPosition(raid, "CX", "CY", "CZ", "center"); ++ ++ RenameHelper.renameSingle(raid, "Id", "id"); ++ RenameHelper.renameSingle(raid, "Started", "started"); ++ RenameHelper.renameSingle(raid, "Active", "active"); ++ RenameHelper.renameSingle(raid, "TicksActive", "ticks_active"); ++ RenameHelper.renameSingle(raid, "BadOmenLevel", "raid_omen_level"); ++ RenameHelper.renameSingle(raid, "GroupsSpawned", "groups_spawned"); ++ RenameHelper.renameSingle(raid, "PreRaidTicks", "cooldown_ticks"); ++ RenameHelper.renameSingle(raid, "PostRaidTicks", "post_raid_ticks"); ++ RenameHelper.renameSingle(raid, "TotalHealth", "total_health"); ++ RenameHelper.renameSingle(raid, "NumGroups", "group_count"); ++ RenameHelper.renameSingle(raid, "Status", "status"); ++ RenameHelper.renameSingle(raid, "HeroesOfTheVillage", "heroes_of_the_village"); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ MCTypeRegistry.SAVED_DATA_TICKETS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ ++ final ListType tickets = data.getListUnchecked("tickets"); ++ if (tickets == null) { ++ return null; ++ } ++ ++ for (int i = 0, len = tickets.size(); i < len; ++i) { ++ final MapType ticket = tickets.getMap(i, null); ++ if (ticket == null) { ++ continue; ++ } ++ ++ if (ticket.hasKey("chunk_pos")) { ++ final long coordinate = ticket.getLong("chunk_pos", 0L); ++ ++ ticket.setInts("chunk_pos", new int[] { (int)coordinate, (int)(coordinate >>> 32) }); ++ } ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V4309() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4311.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4311.java +new file mode 100644 +index 0000000000000000000000000000000000000000..ec8dacda319762effbd01c58cb1d41ff00fc7aa1 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4311.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.advancements.ConverterAbstractAdvancementsRename; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V4311 { ++ ++ private static final int VERSION = MCVersions.V25W05A + 1; ++ ++ private static final Map ADVANCEMENTS_RENAME = new HashMap<>(); ++ static { ++ ADVANCEMENTS_RENAME.put("minecraft:nether/use_lodestone", "minecraft:adventure/use_lodestone"); ++ } ++ ++ public static void register() { ++ ConverterAbstractAdvancementsRename.register(VERSION, ADVANCEMENTS_RENAME::get); ++ } ++ ++ private V4311() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4312.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4312.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7015d97cb5b97d59ca41f63ba23da1edfb6bae0a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4312.java +@@ -0,0 +1,89 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; ++import java.util.Map; ++ ++public final class V4312 { ++ ++ private static final int VERSION = MCVersions.V25W05A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.PLAYER.addStructureConverter(new DataConverter<>(VERSION) { ++ private static final Int2ObjectOpenHashMap SLOT_MOVE_MAPPING = new Int2ObjectOpenHashMap<>( ++ Map.of( ++ 100, "feet", ++ 101, "legs", ++ 102, "chest", ++ 103, "head", ++ -106, "offhand" ++ ) ++ ); ++ ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final ListType inventory = data.getListUnchecked("Inventory"); ++ if (inventory == null) { ++ return null; ++ } ++ ++ final MapType equipment = data.getTypeUtil().createEmptyMap(); ++ ++ for (int i = 0; i < inventory.size(); ++i) { ++ final MapType item = inventory.getMap(i, null); ++ if (item == null) { ++ continue; ++ } ++ ++ final int slot = item.getInt("Slot", Integer.MIN_VALUE); ++ final String equipmentKey = SLOT_MOVE_MAPPING.get(slot); ++ ++ if (equipmentKey == null) { ++ continue; ++ } ++ ++ inventory.remove(i--); ++ ++ item.remove("Slot"); ++ equipment.setMap(equipmentKey, item); ++ } ++ ++ data.setMap("equipment", equipment); ++ ++ return null; ++ } ++ }); ++ ++ // Note: See V1458 for why we walk CustomName ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data.getMap("RootVehicle"), "Entity", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "ender_pearls", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "EnderItems", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityLeft", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "ShoulderEntityRight", fromVersion, toVersion); ++ ++ final MapType recipeBook = data.getMap("recipeBook"); ++ if (recipeBook != null) { ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "recipes", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.RECIPE, recipeBook, "toBeDisplayed", fromVersion, toVersion); ++ } ++ ++ // "From CB" ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "CustomName", fromVersion, toVersion); ++ ++ return MCTypeRegistry.ENTITY_EQUIPMENT.convert(data, fromVersion, toVersion); ++ }); ++ ++ } ++ ++ private V4312() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4314.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4314.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3b61eb6776c517b553c76a6bd3651d3f7c7155c5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4314.java +@@ -0,0 +1,110 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.CopyHelper; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++ ++public final class V4314 { ++ ++ private static final int VERSION = MCVersions.V25W06A + 1; ++ ++ public static void register() { ++ final DataConverter livingEntityConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ V4309.convertBlockPosition(data, "SleepingX", "SleepingY", "SleepingZ", "sleeping_pos"); ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.PLAYER.addStructureConverter(livingEntityConverter); ++ MCTypeRegistry.PLAYER.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { ++ final TypeUtil typeUtil = root.getTypeUtil(); ++ ++ final Number spawnX = root.getNumber("SpawnX"); ++ final Number spawnY = root.getNumber("SpawnY"); ++ final Number spawnZ = root.getNumber("SpawnZ"); ++ if (spawnX != null && spawnY != null && spawnZ != null) { ++ root.remove("SpawnX"); ++ root.remove("SpawnY"); ++ root.remove("SpawnZ"); ++ ++ final MapType respawn = typeUtil.createEmptyMap(); ++ root.setMap("respawn", respawn); ++ ++ respawn.setInts("pos", V4309.makeBlockPosition(spawnX, spawnY, spawnZ)); ++ ++ CopyHelper.move(root, "SpawnAngle", respawn, "angle"); ++ CopyHelper.move(root, "SpawnDimension", respawn, "dimension"); ++ CopyHelper.move(root, "SpawnForced", respawn, "forced"); ++ } ++ ++ final MapType netherPos = root.getMap("enteredNetherPosition"); ++ if (netherPos != null) { ++ root.remove("enteredNetherPosition"); ++ ++ final ListType newPos = typeUtil.createEmptyList(); ++ root.setList("entered_nether_pos", newPos); ++ ++ newPos.addDouble(netherPos.getDouble("x", 0.0)); ++ newPos.addDouble(netherPos.getDouble("y", 0.0)); ++ newPos.addDouble(netherPos.getDouble("z", 0.0)); ++ } ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addStructureConverter(livingEntityConverter); ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:vex", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ V4309.convertBlockPosition(data, "BoundX", "BoundY", "BoundZ", "bound_pos"); ++ RenameHelper.renameSingle(data, "LifeTicks", "life_ticks"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:phantom", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ V4309.convertBlockPosition(data, "AX", "AY", "AZ", "anchor_pos"); ++ RenameHelper.renameSingle(data, "Size", "size"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:turtle", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.remove("TravelPosX"); ++ data.remove("TravelPosY"); ++ data.remove("TravelPosZ"); ++ V4309.convertBlockPosition(data, "HomePosX", "HomePosY", "HomePosZ", "home_pos"); ++ RenameHelper.renameSingle(data, "HasEgg", "has_egg"); ++ return null; ++ } ++ }); ++ ++ final DataConverter attachedBlockConverter = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ V4309.convertBlockPosition(data, "TileX", "TileY", "TileZ", "block_pos"); ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:item_frame", attachedBlockConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:glow_item_frame", attachedBlockConverter); ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:painting", attachedBlockConverter); ++ // Note: Leash entities never wrote TileX/Y/Z and don't read block_pos... Why is this here then? ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:leash_knot", attachedBlockConverter); ++ } ++ ++ private V4314() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4420.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4420.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3d95461b89963acc2c999f31aada04cead295b96 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4420.java +@@ -0,0 +1,26 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V4420 { ++ ++ private static final int VERSION = MCVersions.V1_21_5 + 95; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:area_effect_cloud", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ RenameHelper.renameSingle(data, "Particle", "custom_particle"); ++ return null; ++ } ++ }); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:area_effect_cloud", new DataWalkerTypePaths<>(MCTypeRegistry.PARTICLE, "custom_particle")); ++ } ++ ++ private V4420() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4421.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4421.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3802412c0443cce233f897852a201eebbb0504bc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4421.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V4421 { ++ ++ private static final int VERSION = MCVersions.V1_21_5 + 96; ++ ++ public static void register() { ++ // happy_ghast is simple entity ++ } ++ ++ private V4421() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4424.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4424.java +new file mode 100644 +index 0000000000000000000000000000000000000000..690794c0963a4935390b4830202cb6b78dcf29da +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4424.java +@@ -0,0 +1,22 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.leveldat.ConverterRemoveFeatureFlag; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import java.util.Arrays; ++import java.util.HashSet; ++ ++public final class V4424 { ++ ++ private static final int VERSION = MCVersions.V25W15A + 2; ++ ++ public static void register() { ++ MCTypeRegistry.LIGHTWEIGHT_LEVEL.addStructureConverter(new ConverterRemoveFeatureFlag(VERSION, new HashSet<>( ++ Arrays.asList( ++ "minecraft:locator_bar" ++ ) ++ ))); ++ } ++ ++ private V4424() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V501.java b/ca/spottedleaf/dataconverter/minecraft/versions/V501.java +new file mode 100644 +index 0000000000000000000000000000000000000000..da5731090c1de479b77d0d9a1b66d217f7f4eeb5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V501.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++ ++public final class V501 { ++ ++ private static final int VERSION = MCVersions.V16W20A; ++ ++ public static void register() { ++ //registerMob("PolarBear"); // is now simple in 1.21.5 ++ } ++ ++ private V501() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V502.java b/ca/spottedleaf/dataconverter/minecraft/versions/V502.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2b6f3eef26a27e800f87a189c63250293b812e50 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V502.java +@@ -0,0 +1,45 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.concurrent.ThreadLocalRandom; ++ ++public final class V502 { ++ ++ private static final int VERSION = MCVersions.V16W20A + 1; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, (final String name) -> { ++ return "minecraft:cooked_fished".equals(name) ? "minecraft:cooked_fish" : null; ++ }); ++ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.getBoolean("IsVillager")) { ++ return null; ++ } ++ ++ data.remove("IsVillager"); ++ ++ if (data.hasKey("ZombieType")) { ++ return null; ++ } ++ ++ int type = data.getInt("VillagerProfession", -1); ++ // Vanilla doesn't remove the profession tag, so we don't! ++ if (type < 0 || type >= 6) { ++ type = ThreadLocalRandom.current().nextInt(6); ++ } ++ ++ data.setInt("ZombieType", type); ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V502() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V505.java b/ca/spottedleaf/dataconverter/minecraft/versions/V505.java +new file mode 100644 +index 0000000000000000000000000000000000000000..112e287bf2bd21650798f089d6860b9714f19067 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V505.java +@@ -0,0 +1,23 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V505 { ++ ++ private static final int VERSION = MCVersions.V16W21B + 1; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.setString("useVbo", "true"); ++ return null; ++ } ++ }); ++ } ++ ++ private V505() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V700.java b/ca/spottedleaf/dataconverter/minecraft/versions/V700.java +new file mode 100644 +index 0000000000000000000000000000000000000000..63e3c70cc817bd8729ad177df8d388036bb7241d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V700.java +@@ -0,0 +1,28 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V700 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 188; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Guardian", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (data.getBoolean("Elder")) { ++ data.setString("id", "ElderGuardian"); ++ } ++ data.remove("Elder"); ++ return null; ++ } ++ }); ++ ++ //registerMob("ElderGuardian"); // is now simple in 1.21.5 ++ } ++ ++ private V700() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V701.java b/ca/spottedleaf/dataconverter/minecraft/versions/V701.java +new file mode 100644 +index 0000000000000000000000000000000000000000..5fa1afd449c2a45efccc3966c34310bb695ad082 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V701.java +@@ -0,0 +1,37 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V701 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 189; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Skeleton", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int type = data.getInt("SkeletonType"); ++ data.remove("SkeletonType"); ++ ++ switch (type) { ++ case 1: ++ data.setString("id", "WitherSkeleton"); ++ break; ++ case 2: ++ data.setString("id", "Stray"); ++ break; ++ } ++ ++ return null; ++ } ++ }); ++ ++ //registerMob("WitherSkeleton"); // is now simple in 1.21.5 ++ //registerMob("Stray"); // is now simple in 1.21.5 ++ } ++ ++ private V701() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V702.java b/ca/spottedleaf/dataconverter/minecraft/versions/V702.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b2408f8e0c2e62155c51e8383448d5e64bbb58f5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V702.java +@@ -0,0 +1,51 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V702 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 190; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("Zombie", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int zombieType = data.getInt("ZombieType"); ++ data.remove("ZombieType"); ++ ++ switch (zombieType) { ++ case 0: ++ default: ++ break; ++ ++ case 1: ++ case 2: ++ case 3: ++ case 4: ++ case 5: ++ data.setString("id", "ZombieVillager"); ++ data.setInt("Profession", zombieType - 1); ++ break; ++ ++ case 6: ++ data.setString("id", "Husk"); ++ break; ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "ZombieVillager", (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.VILLAGER_TRADE, root.getMap("Offers"), "Recipes", fromVersion, toVersion); ++ return null; ++ }); ++ //registerMob("Husk"); // is now simple in 1.21.5 ++ } ++ ++ private V702() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V703.java b/ca/spottedleaf/dataconverter/minecraft/versions/V703.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d56ec81710d23b6bcbc6c5daad6e22a355df3056 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V703.java +@@ -0,0 +1,62 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V703 { ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 191; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("EntityHorse", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final int type = data.getInt("Type"); ++ data.remove("Type"); ++ ++ switch (type) { ++ case 0: ++ default: ++ data.setString("id", "Horse"); ++ break; ++ ++ case 1: ++ data.setString("id", "Donkey"); ++ break; ++ ++ case 2: ++ data.setString("id", "Mule"); ++ break; ++ ++ case 3: ++ data.setString("id", "ZombieHorse"); ++ break; ++ ++ case 4: ++ data.setString("id", "SkeletonHorse"); ++ break; ++ } ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Horse", new DataWalkerItems("ArmorItem", "SaddleItem")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Donkey", new DataWalkerItems("SaddleItem")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Donkey", new DataWalkerItemLists("Items")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Mule", new DataWalkerItems("SaddleItem")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Mule", new DataWalkerItemLists("Items")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "ZombieHorse", new DataWalkerItems("SaddleItem")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "SkeletonHorse", new DataWalkerItems("SaddleItem")); ++ } ++ ++ private V703() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V704.java b/ca/spottedleaf/dataconverter/minecraft/versions/V704.java +new file mode 100644 +index 0000000000000000000000000000000000000000..16e188ae63c8a545bbc57a58b30311bb9721b826 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V704.java +@@ -0,0 +1,467 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookEnforceNamespacedID; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.item_name.DataWalkerItemNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.util.Long2ObjectArraySortedMap; ++import com.mojang.logging.LogUtils; ++import net.minecraft.core.BlockPos; ++import net.minecraft.core.registries.BuiltInRegistries; ++import net.minecraft.world.item.BlockItem; ++import net.minecraft.world.item.Item; ++import net.minecraft.world.level.block.Block; ++import net.minecraft.world.level.block.EntityBlock; ++import net.minecraft.world.level.block.entity.BlockEntity; ++import net.minecraft.world.level.block.entity.BlockEntityType; ++import org.slf4j.Logger; ++import java.util.Arrays; ++import java.util.HashMap; ++import java.util.HashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class V704 { ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ private static final int VERSION = MCVersions.V1_10_2 + 192; ++ ++ public static final Map ITEM_ID_TO_TILE_ENTITY_ID = new HashMap<>() { ++ @Override ++ public String put(final String key, final String value) { ++ if (this.containsKey(key)) { ++ LOGGER.error("Duplicate item id to tile key: " + key); ++ throw new RuntimeException(); // only devs should see the consequence of this... at least start up the damn thing... ++ } ++ return super.put(key, value); ++ } ++ }; ++ static { ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:furnace", "minecraft:furnace"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lit_furnace", "minecraft:furnace"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:chest", "minecraft:chest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:trapped_chest", "minecraft:chest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:ender_chest", "minecraft:ender_chest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:jukebox", "minecraft:jukebox"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dispenser", "minecraft:dispenser"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dropper", "minecraft:dropper"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:mob_spawner", "minecraft:mob_spawner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:spawner", "minecraft:mob_spawner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:noteblock", "minecraft:noteblock"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:brewing_stand", "minecraft:brewing_stand"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:enhanting_table", "minecraft:enchanting_table"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:command_block", "minecraft:command_block"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:beacon", "minecraft:beacon"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:skull", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:daylight_detector", "minecraft:daylight_detector"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:hopper", "minecraft:hopper"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:flower_pot", "minecraft:flower_pot"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:repeating_command_block", "minecraft:command_block"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:chain_command_block", "minecraft:command_block"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:white_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:orange_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:magenta_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_blue_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:yellow_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lime_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:pink_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:gray_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:silver_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:cyan_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:purple_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:blue_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:brown_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:green_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:red_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:black_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_gray_shulker_box", "minecraft:shulker_box"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:white_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:orange_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:magenta_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_blue_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:yellow_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lime_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:pink_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:gray_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:silver_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:cyan_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:purple_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:blue_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:brown_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:green_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:red_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:black_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:standing_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:wall_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:piston_head", "minecraft:piston"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:daylight_detector_inverted", "minecraft:daylight_detector"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:unpowered_comparator", "minecraft:comparator"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:powered_comparator", "minecraft:comparator"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:wall_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:standing_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:structure_block", "minecraft:structure_block"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:end_portal", "minecraft:end_portal"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:end_gateway", "minecraft:end_gateway"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:shield", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:white_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:orange_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:magenta_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_blue_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:yellow_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lime_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:pink_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:gray_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:silver_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:cyan_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:purple_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:blue_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:brown_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:green_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:red_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:black_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:oak_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:spruce_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:birch_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:jungle_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:acacia_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dark_oak_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:crimson_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:warped_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:skeleton_skull", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:wither_skeleton_skull", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:zombie_head", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:player_head", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:creeper_head", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dragon_head", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:barrel", "minecraft:barrel"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:conduit", "minecraft:conduit"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:smoker", "minecraft:smoker"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:blast_furnace", "minecraft:blast_furnace"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lectern", "minecraft:lectern"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:bell", "minecraft:bell"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:jigsaw", "minecraft:jigsaw"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:campfire", "minecraft:campfire"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:bee_nest", "minecraft:beehive"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:beehive", "minecraft:beehive"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:sculk_sensor", "minecraft:sculk_sensor"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:decorated_pot", "minecraft:decorated_pot"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:crafter", "minecraft:crafter"); ++ ++ // These are missing from Vanilla up to 1.20.5 ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:enchanting_table", "minecraft:enchanting_table"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:comparator", "minecraft:comparator"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_gray_bed", "minecraft:bed"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:light_gray_banner", "minecraft:banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:soul_campfire", "minecraft:campfire"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:sculk_catalyst", "minecraft:sculk_catalyst"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:mangrove_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:sculk_shrieker", "minecraft:sculk_shrieker"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:chiseled_bookshelf", "minecraft:chiseled_bookshelf"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:bamboo_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:oak_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:spruce_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:birch_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:jungle_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:acacia_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dark_oak_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:mangrove_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:bamboo_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:crimson_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:warped_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:piglin_head", "minecraft:skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:suspicious_sand", "minecraft:brushable_block"); // note: this was renamed in the past, see special case in the itemstack walker ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:cherry_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:cherry_hanging_sign", "minecraft:sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:suspicious_gravel", "minecraft:brushable_block"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:calibrated_sculk_sensor", "minecraft:calibrated_sculk_sensor"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:trial_spawner", "minecraft:trial_spawner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:vault", "minecraft:vault"); ++ } ++ ++ // This class is responsible for also integrity checking the item id to tile id map here, we just use the item registry to figure it out ++ // No longer need to do this, as items now use components in 1.20.5 ++ /*static { ++ for (final Item item : BuiltInRegistries.ITEM) { ++ if (!(item instanceof BlockItem)) { ++ continue; ++ } ++ ++ if (!(((BlockItem)item).getBlock() instanceof EntityBlock entityBlock)) { ++ continue; ++ } ++ ++ String possibleId; ++ try { ++ final BlockEntity entity = entityBlock.newBlockEntity(new BlockPos(0, 0, 0), ((Block)entityBlock).defaultBlockState()); ++ if (entity != null) { ++ possibleId = BlockEntityType.getKey(entity.getType()).toString(); ++ } else { ++ possibleId = null; ++ } ++ } catch (final Throwable th) { ++ possibleId = null; ++ } ++ ++ final String itemName = BuiltInRegistries.ITEM.getKey(item).toString(); ++ final String mappedTo = ITEM_ID_TO_TILE_ENTITY_ID.get(itemName); ++ if (mappedTo == null) { ++ LOGGER.error("Item id " + itemName + " does not contain tile mapping! (V704)"); ++ } else if (possibleId != null && !mappedTo.equals(possibleId)) { ++ final boolean chestCase = mappedTo.equals("minecraft:chest") && possibleId.equals("minecraft:trapped_chest"); ++ final boolean signCase = mappedTo.equals("minecraft:sign") && possibleId.equals("minecraft:hanging_sign"); ++ // save data is identical for the chest and sign case, so we don't care ++ // it's also important to note that there is no versioning for this map, so it is possible ++ // that mapping them correctly could cause issues converting old data ++ if (!chestCase && !signCase) { ++ LOGGER.error("Item id " + itemName + " is mapped to the wrong tile entity! Mapped to: " + mappedTo + ", expected: " + possibleId); ++ } ++ } ++ } ++ }*/ ++ ++ private static Long2ObjectArraySortedMap makeSingle(final int k1, final String v1) { ++ final Long2ObjectArraySortedMap ret = new Long2ObjectArraySortedMap<>(); ++ ++ ret.put(DataConverter.encodeVersions(k1, 0), v1); ++ ++ return ret; ++ } ++ ++ private static Long2ObjectArraySortedMap makeDouble(final int k1, final String v1, ++ final int k2, final String v2) { ++ final Long2ObjectArraySortedMap ret = new Long2ObjectArraySortedMap<>(); ++ ++ ret.put(DataConverter.encodeVersions(k1, 0), v1); ++ ret.put(DataConverter.encodeVersions(k2, 0), v2); ++ ++ return ret; ++ } ++ ++ private static final Map> ITEM_ID_TO_ENTITY_ID = new HashMap<>(); ++ static { ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:armor_stand", makeDouble(V99.VERSION, "ArmorStand", V705.VERSION, "minecraft:armor_stand")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:painting", makeDouble(V99.VERSION, "Painting", V705.VERSION, "minecraft:painting")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:boat", makeDouble(V99.VERSION, "Boat", V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:oak_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:oak_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:spruce_boat",makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:spruce_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:birch_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:birch_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:jungle_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:jungle_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:acacia_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:acacia_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:cherry_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:cherry_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:dark_oak_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:dark_oak_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:mangrove_boat", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:mangrove_chest_boat", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:bamboo_raft", makeSingle(V705.VERSION, "minecraft:boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:bamboo_chest_raft", makeSingle(V705.VERSION, "minecraft:chest_boat")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:minecart", makeDouble(V99.VERSION, "MinecartRideable", V705.VERSION, "minecraft:minecart")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:chest_minecart", makeDouble(V99.VERSION, "MinecartChest", V705.VERSION, "minecraft:chest_minecart")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:furnace_minecart", makeDouble(V99.VERSION, "MinecartFurnace", V705.VERSION, "minecraft:furnace_minecart")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:tnt_minecart", makeDouble(V99.VERSION, "MinecartTNT", V705.VERSION, "minecraft:tnt_minecart")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:hopper_minecart", makeDouble(V99.VERSION, "MinecartHopper", V705.VERSION, "minecraft:hopper_minecart")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:item_frame", makeDouble(V99.VERSION, "ItemFrame", V705.VERSION, "minecraft:item_frame")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:glow_item_frame", makeSingle(V705.VERSION, "minecraft:glow_item_frame")); ++ ++ // Mojang missed these ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:pufferfish_bucket", makeSingle(V705.VERSION, "minecraft:pufferfish")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:salmon_bucket", makeSingle(V705.VERSION, "minecraft:salmon")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:cod_bucket", makeSingle(V705.VERSION, "minecraft:cod")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:tropical_fish_bucket", makeSingle(V705.VERSION, "minecraft:tropical_fish")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:axolotl_bucket", makeSingle(V705.VERSION, "minecraft:axolotl")); ++ ITEM_ID_TO_ENTITY_ID.put("minecraft:tadpole_bucket", makeSingle(V705.VERSION, "minecraft:tadpole")); ++ } ++ ++ private static final Map TILE_ID_UPDATE = new HashMap<>(); ++ static { ++ TILE_ID_UPDATE.put("Airportal", "minecraft:end_portal"); ++ TILE_ID_UPDATE.put("Banner", "minecraft:banner"); ++ TILE_ID_UPDATE.put("Beacon", "minecraft:beacon"); ++ TILE_ID_UPDATE.put("Cauldron", "minecraft:brewing_stand"); ++ TILE_ID_UPDATE.put("Chest", "minecraft:chest"); ++ TILE_ID_UPDATE.put("Comparator", "minecraft:comparator"); ++ TILE_ID_UPDATE.put("Control", "minecraft:command_block"); ++ TILE_ID_UPDATE.put("DLDetector", "minecraft:daylight_detector"); ++ TILE_ID_UPDATE.put("Dropper", "minecraft:dropper"); ++ TILE_ID_UPDATE.put("EnchantTable", "minecraft:enchanting_table"); ++ TILE_ID_UPDATE.put("EndGateway", "minecraft:end_gateway"); ++ TILE_ID_UPDATE.put("EnderChest", "minecraft:ender_chest"); ++ TILE_ID_UPDATE.put("FlowerPot", "minecraft:flower_pot"); ++ TILE_ID_UPDATE.put("Furnace", "minecraft:furnace"); ++ TILE_ID_UPDATE.put("Hopper", "minecraft:hopper"); ++ TILE_ID_UPDATE.put("MobSpawner", "minecraft:mob_spawner"); ++ TILE_ID_UPDATE.put("Music", "minecraft:noteblock"); ++ TILE_ID_UPDATE.put("Piston", "minecraft:piston"); ++ TILE_ID_UPDATE.put("RecordPlayer", "minecraft:jukebox"); ++ TILE_ID_UPDATE.put("Sign", "minecraft:sign"); ++ TILE_ID_UPDATE.put("Skull", "minecraft:skull"); ++ TILE_ID_UPDATE.put("Structure", "minecraft:structure_block"); ++ TILE_ID_UPDATE.put("Trap", "minecraft:dispenser"); ++ } ++ ++ // These do not need a walker, so we can ignore them not being registered. ++ private static final Set IGNORE_ABSENT_WALKERS = new HashSet<>( ++ Arrays.asList( ++ "Airportal", ++ "DLDetector", ++ "Comparator", ++ "EnchantTable", ++ "EndGateway", ++ "Music", ++ "Beacon", ++ // note: contains blockId and blockData, but handled by flattening converters ++ "Piston", ++ "Structure", ++ "EnderChest", ++ // See V99 ++ "Skull", ++ "Banner" ++ ) ++ ); ++ ++ public static void register() { ++ MCTypeRegistry.TILE_ENTITY.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String id = data.getString("id"); ++ if (id == null) { ++ return null; ++ } ++ ++ data.setString("id", TILE_ID_UPDATE.getOrDefault(id, id)); ++ return null; ++ } ++ }); ++ ++ ++ for (final Map.Entry entry : TILE_ID_UPDATE.entrySet()) { ++ final String oldId = entry.getKey(); ++ final String newId = entry.getValue(); ++ ++ if (!MCTypeRegistry.TILE_ENTITY.hasWalkers(oldId) && !IGNORE_ABSENT_WALKERS.contains(oldId)) { ++ LOGGER.error("(V704) Failed to find walkers for " + oldId); ++ } ++ ++ MCTypeRegistry.TILE_ENTITY.copyWalkers(VERSION, oldId, newId); ++ } ++ ++ MCTypeRegistry.ITEM_STACK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_NAME, data, "id", fromVersion, toVersion); ++ ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final String itemId = data.getString("id"); ++ ++ // only things here are in tag, if changed update if above ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, tag, "Items", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, tag, "ChargedProjectiles", fromVersion, toVersion); ++ if ("minecraft:written_book".equals(itemId)) { ++ // These are only text component for WRITTEN books! DFU blindly will mark this as TEXT_COMPONENT. ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, tag, "pages", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, tag, "filtered_pages", fromVersion, toVersion); ++ } ++ // Vanilla blindly marks these as TEXT_COMPONENT even though they are only converted after the versions noted ++ // below. ++ if (toVersion >= DataConverter.encodeVersions(V1458.VERSION, 0)) { ++ final MapType display = tag.getMap("display"); ++ if (display != null) { ++ // only TEXT_COMPONENT in V1458 ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, display, "Name", fromVersion, toVersion); ++ if (toVersion >= DataConverter.encodeVersions(V1803.VERSION, 0)) { ++ // only TEXT_COMPONENT in V1803 ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, display, "Lore", fromVersion, toVersion); ++ } ++ } ++ } ++ ++ MapType entityTag = tag.getMap("EntityTag"); ++ if (entityTag != null) { ++ final String entityId; ++ if (itemId != null && itemId.contains("_spawn_egg")) { ++ // V1451 changes spawn eggs to have the sub entity id be a part of the item id, but of course Mojang never ++ // bothered to write in logic to set the sub entity id, so we have to. ++ // format is ALWAYS :_spawn_egg post flattening ++ entityId = itemId.substring(0, itemId.indexOf("_spawn_egg")); ++ } else { ++ final Long2ObjectArraySortedMap mappingByVersion = ITEM_ID_TO_ENTITY_ID.get(itemId); ++ final String mapped = mappingByVersion == null ? null : mappingByVersion.getFloor(fromVersion); ++ entityId = mapped == null ? entityTag.getString("id") : mapped; ++ } ++ ++ if (entityId == null) { ++ if (!"minecraft:air".equals(itemId)) { ++ LOGGER.warn("Unable to resolve Entity for ItemStack (V704): " + itemId); ++ } ++ } else { ++ if (!entityTag.hasKey("id", ObjectType.STRING)) { ++ entityTag.setString("id", entityId); ++ } ++ } ++ ++ final MapType replace = MCTypeRegistry.ENTITY.convert(entityTag, fromVersion, toVersion); ++ ++ if (replace != null) { ++ entityTag = replace; ++ tag.setMap("EntityTag", entityTag); ++ } ++ } ++ ++ MapType blockEntityTag = tag.getMap("BlockEntityTag"); ++ if (blockEntityTag != null) { ++ final String entityId; ++ if (fromVersion < DataConverter.encodeVersions(V3438.VERSION, 0) && "minecraft:suspicious_sand".equals(itemId)) { ++ // renamed after this version, and since the id is a mapping to just string we need to special case this ++ entityId = "minecraft:suspicious_sand"; ++ } else { ++ entityId = ITEM_ID_TO_TILE_ENTITY_ID.get(itemId); ++ } ++ ++ if (entityId == null) { ++ if (!"minecraft:air".equals(itemId)) { ++ LOGGER.warn("Unable to resolve BlockEntity for ItemStack (V704): " + itemId); ++ } ++ } else { ++ if (!blockEntityTag.hasKey("id", ObjectType.STRING)) { ++ blockEntityTag.setString("id", entityId); ++ } ++ } ++ final MapType replace = MCTypeRegistry.TILE_ENTITY.convert(blockEntityTag, fromVersion, toVersion); ++ if (replace != null) { ++ blockEntityTag = replace; ++ tag.setMap("BlockEntityTag", blockEntityTag); ++ } ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, tag, "CanDestroy", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, tag, "CanPlaceOn", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Enforce namespace for ids ++ MCTypeRegistry.TILE_ENTITY.addStructureHook(VERSION, new DataHookEnforceNamespacedID()); ++ } ++ ++ private V704() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V705.java b/ca/spottedleaf/dataconverter/minecraft/versions/V705.java +new file mode 100644 +index 0000000000000000000000000000000000000000..333a86b4a041df2f9679799f64037ebea33746c0 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V705.java +@@ -0,0 +1,209 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.entity.ConverterAbstractEntityRename; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookEnforceNamespacedID; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookValueTypeEnforceNamespaced; ++import ca.spottedleaf.dataconverter.minecraft.walkers.block_name.DataWalkerBlockNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.minecraft.walkers.tile_entity.DataWalkerTileEntities; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V705 { ++ ++ public static final int VERSION = MCVersions.V1_10_2 + 193; ++ ++ private static final Map ENTITY_ID_UPDATE = new HashMap<>(); ++ static { ++ ENTITY_ID_UPDATE.put("AreaEffectCloud", "minecraft:area_effect_cloud"); ++ ENTITY_ID_UPDATE.put("ArmorStand", "minecraft:armor_stand"); ++ ENTITY_ID_UPDATE.put("Arrow", "minecraft:arrow"); ++ ENTITY_ID_UPDATE.put("Bat", "minecraft:bat"); ++ ENTITY_ID_UPDATE.put("Blaze", "minecraft:blaze"); ++ ENTITY_ID_UPDATE.put("Boat", "minecraft:boat"); ++ ENTITY_ID_UPDATE.put("CaveSpider", "minecraft:cave_spider"); ++ ENTITY_ID_UPDATE.put("Chicken", "minecraft:chicken"); ++ ENTITY_ID_UPDATE.put("Cow", "minecraft:cow"); ++ ENTITY_ID_UPDATE.put("Creeper", "minecraft:creeper"); ++ ENTITY_ID_UPDATE.put("Donkey", "minecraft:donkey"); ++ ENTITY_ID_UPDATE.put("DragonFireball", "minecraft:dragon_fireball"); ++ ENTITY_ID_UPDATE.put("ElderGuardian", "minecraft:elder_guardian"); ++ ENTITY_ID_UPDATE.put("EnderCrystal", "minecraft:ender_crystal"); ++ ENTITY_ID_UPDATE.put("EnderDragon", "minecraft:ender_dragon"); ++ ENTITY_ID_UPDATE.put("Enderman", "minecraft:enderman"); ++ ENTITY_ID_UPDATE.put("Endermite", "minecraft:endermite"); ++ ENTITY_ID_UPDATE.put("EyeOfEnderSignal", "minecraft:eye_of_ender_signal"); ++ ENTITY_ID_UPDATE.put("FallingSand", "minecraft:falling_block"); ++ ENTITY_ID_UPDATE.put("Fireball", "minecraft:fireball"); ++ ENTITY_ID_UPDATE.put("FireworksRocketEntity", "minecraft:fireworks_rocket"); ++ ENTITY_ID_UPDATE.put("Ghast", "minecraft:ghast"); ++ ENTITY_ID_UPDATE.put("Giant", "minecraft:giant"); ++ ENTITY_ID_UPDATE.put("Guardian", "minecraft:guardian"); ++ ENTITY_ID_UPDATE.put("Horse", "minecraft:horse"); ++ ENTITY_ID_UPDATE.put("Husk", "minecraft:husk"); ++ ENTITY_ID_UPDATE.put("Item", "minecraft:item"); ++ ENTITY_ID_UPDATE.put("ItemFrame", "minecraft:item_frame"); ++ ENTITY_ID_UPDATE.put("LavaSlime", "minecraft:magma_cube"); ++ ENTITY_ID_UPDATE.put("LeashKnot", "minecraft:leash_knot"); ++ ENTITY_ID_UPDATE.put("MinecartChest", "minecraft:chest_minecart"); ++ ENTITY_ID_UPDATE.put("MinecartCommandBlock", "minecraft:commandblock_minecart"); ++ ENTITY_ID_UPDATE.put("MinecartFurnace", "minecraft:furnace_minecart"); ++ ENTITY_ID_UPDATE.put("MinecartHopper", "minecraft:hopper_minecart"); ++ ENTITY_ID_UPDATE.put("MinecartRideable", "minecraft:minecart"); ++ ENTITY_ID_UPDATE.put("MinecartSpawner", "minecraft:spawner_minecart"); ++ ENTITY_ID_UPDATE.put("MinecartTNT", "minecraft:tnt_minecart"); ++ ENTITY_ID_UPDATE.put("Mule", "minecraft:mule"); ++ ENTITY_ID_UPDATE.put("MushroomCow", "minecraft:mooshroom"); ++ ENTITY_ID_UPDATE.put("Ozelot", "minecraft:ocelot"); ++ ENTITY_ID_UPDATE.put("Painting", "minecraft:painting"); ++ ENTITY_ID_UPDATE.put("Pig", "minecraft:pig"); ++ ENTITY_ID_UPDATE.put("PigZombie", "minecraft:zombie_pigman"); ++ ENTITY_ID_UPDATE.put("PolarBear", "minecraft:polar_bear"); ++ ENTITY_ID_UPDATE.put("PrimedTnt", "minecraft:tnt"); ++ ENTITY_ID_UPDATE.put("Rabbit", "minecraft:rabbit"); ++ ENTITY_ID_UPDATE.put("Sheep", "minecraft:sheep"); ++ ENTITY_ID_UPDATE.put("Shulker", "minecraft:shulker"); ++ ENTITY_ID_UPDATE.put("ShulkerBullet", "minecraft:shulker_bullet"); ++ ENTITY_ID_UPDATE.put("Silverfish", "minecraft:silverfish"); ++ ENTITY_ID_UPDATE.put("Skeleton", "minecraft:skeleton"); ++ ENTITY_ID_UPDATE.put("SkeletonHorse", "minecraft:skeleton_horse"); ++ ENTITY_ID_UPDATE.put("Slime", "minecraft:slime"); ++ ENTITY_ID_UPDATE.put("SmallFireball", "minecraft:small_fireball"); ++ ENTITY_ID_UPDATE.put("SnowMan", "minecraft:snowman"); ++ ENTITY_ID_UPDATE.put("Snowball", "minecraft:snowball"); ++ ENTITY_ID_UPDATE.put("SpectralArrow", "minecraft:spectral_arrow"); ++ ENTITY_ID_UPDATE.put("Spider", "minecraft:spider"); ++ ENTITY_ID_UPDATE.put("Squid", "minecraft:squid"); ++ ENTITY_ID_UPDATE.put("Stray", "minecraft:stray"); ++ ENTITY_ID_UPDATE.put("ThrownEgg", "minecraft:egg"); ++ ENTITY_ID_UPDATE.put("ThrownEnderpearl", "minecraft:ender_pearl"); ++ ENTITY_ID_UPDATE.put("ThrownExpBottle", "minecraft:xp_bottle"); ++ ENTITY_ID_UPDATE.put("ThrownPotion", "minecraft:potion"); ++ ENTITY_ID_UPDATE.put("Villager", "minecraft:villager"); ++ ENTITY_ID_UPDATE.put("VillagerGolem", "minecraft:villager_golem"); ++ ENTITY_ID_UPDATE.put("Witch", "minecraft:witch"); ++ ENTITY_ID_UPDATE.put("WitherBoss", "minecraft:wither"); ++ ENTITY_ID_UPDATE.put("WitherSkeleton", "minecraft:wither_skeleton"); ++ ENTITY_ID_UPDATE.put("WitherSkull", "minecraft:wither_skull"); ++ ENTITY_ID_UPDATE.put("Wolf", "minecraft:wolf"); ++ ENTITY_ID_UPDATE.put("XPOrb", "minecraft:xp_orb"); ++ ENTITY_ID_UPDATE.put("Zombie", "minecraft:zombie"); ++ ENTITY_ID_UPDATE.put("ZombieHorse", "minecraft:zombie_horse"); ++ ENTITY_ID_UPDATE.put("ZombieVillager", "minecraft:zombie_villager"); ++ } ++ ++ private static void registerThrowableProjectile(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerBlockNames("inTile")); ++ } ++ ++ public static void register() { ++ ConverterAbstractEntityRename.register(VERSION, ENTITY_ID_UPDATE::get); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:area_effect_cloud", new DataWalkerTypePaths<>(MCTypeRegistry.PARTICLE, "Particle")); ++ //registerMob("minecraft:armor_stand"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:arrow", new DataWalkerBlockNames("inTile")); ++ //registerMob("minecraft:bat"); // now simple in 1.21.5 ++ //registerMob("minecraft:blaze"); // now simple in 1.21.5 ++ //registerMob("minecraft:cave_spider"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:chest_minecart", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:chest_minecart", new DataWalkerItemLists("Items")); ++ //registerMob("minecraft:chicken"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:commandblock_minecart", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:commandblock_minecart", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "LastOutput")); ++ //registerMob("minecraft:cow"); // now simple in 1.21.5 ++ //registerMob("minecraft:creeper"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:donkey", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:donkey", new DataWalkerItems("SaddleItem")); ++ registerThrowableProjectile("minecraft:egg"); ++ //registerMob("minecraft:elder_guardian"); // now simple in 1.21.5 ++ //registerMob("minecraft:ender_dragon"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:enderman", new DataWalkerBlockNames("carried")); ++ //registerMob("minecraft:endermite"); // now simple in 1.21.5 ++ registerThrowableProjectile("minecraft:ender_pearl"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:falling_block", new DataWalkerBlockNames("Block")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:falling_block", new DataWalkerTileEntities("TileEntityData")); ++ registerThrowableProjectile("minecraft:fireball"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:fireworks_rocket", new DataWalkerItems("FireworksItem")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:furnace_minecart", new DataWalkerBlockNames("DisplayTile")); ++ //registerMob("minecraft:ghast"); // now simple in 1.21.5 ++ //registerMob("minecraft:giant"); // now simple in 1.21.5 ++ //registerMob("minecraft:guardian"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:hopper_minecart", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:hopper_minecart", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:horse", new DataWalkerItems("ArmorItem", "SaddleItem")); ++ //registerMob("minecraft:husk"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:item", new DataWalkerItems("Item")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:item_frame", new DataWalkerItems("Item")); ++ //registerMob("minecraft:magma_cube"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:minecart", new DataWalkerBlockNames("DisplayTile")); ++ //registerMob("minecraft:mooshroom"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:mule", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:mule", new DataWalkerItems("SaddleItem")); ++ //registerMob("minecraft:ocelot"); // now simple in 1.21.5 ++ //registerMob("minecraft:pig"); // now simple in 1.21.5 ++ //registerMob("minecraft:polar_bear"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:potion", new DataWalkerItems("Potion")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:potion", new DataWalkerBlockNames("inTile")); ++ //registerMob("minecraft:rabbit"); // now simple in 1.21.5 ++ //registerMob("minecraft:sheep"); // now simple in 1.21.5 ++ //registerMob("minecraft:shulker"); // now simple in 1.21.5 ++ //registerMob("minecraft:silverfish"); // now simple in 1.21.5 ++ //registerMob("minecraft:skeleton"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:skeleton_horse", new DataWalkerItems("SaddleItem")); ++ //registerMob("minecraft:slime"); // now simple in 1.21.5 ++ registerThrowableProjectile("minecraft:small_fireball"); ++ registerThrowableProjectile("minecraft:snowball"); ++ //registerMob("minecraft:snowman"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:spawner_minecart", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:spawner_minecart", (final MapType data, final long fromVersion, final long toVersion) -> { ++ return MCTypeRegistry.UNTAGGED_SPAWNER.convert(data, fromVersion, toVersion); ++ }); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:spectral_arrow", new DataWalkerBlockNames("inTile")); ++ //registerMob("minecraft:spider"); // now simple in 1.21.5 ++ //registerMob("minecraft:squid"); // now simple in 1.21.5 ++ //registerMob("minecraft:stray"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:tnt_minecart", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:villager", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, data, "Inventory", fromVersion, toVersion); ++ ++ WalkerUtils.convertList(MCTypeRegistry.VILLAGER_TRADE, data.getMap("Offers"), "Recipes", fromVersion, toVersion); ++ ++ return null; ++ }); ++ //registerMob("minecraft:villager_golem"); // now simple in 1.21.5 ++ //registerMob("minecraft:witch"); // now simple in 1.21.5 ++ //registerMob("minecraft:wither"); // now simple in 1.21.5 ++ //registerMob("minecraft:wither_skeleton"); // now simple in 1.21.5 ++ registerThrowableProjectile("minecraft:wither_skull"); ++ //registerMob("minecraft:wolf"); // now simple in 1.21.5 ++ registerThrowableProjectile("minecraft:xp_bottle"); ++ //registerMob("minecraft:zombie"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:zombie_horse", new DataWalkerItems("SaddleItem")); ++ //registerMob("minecraft:zombie_pigman"); // now simple in 1.21.5 ++ //registerMob("minecraft:zombie_villager"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:zombie_villager", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.VILLAGER_TRADE, data.getMap("Offers"), "Recipes", fromVersion, toVersion); ++ ++ return null; ++ }); ++ //registerMob("minecraft:evocation_illager"); // now simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:llama", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "minecraft:llama", new DataWalkerItems("SaddleItem", "DecorItem")); ++ //registerMob("minecraft:vex"); // now simple in 1.21.5 ++ //registerMob("minecraft:vindication_illager"); // now simple in 1.21.5 ++ // Don't need to re-register itemstack walker, the V704 will correctly choose the right id for armorstand based on ++ // the source version ++ ++ // Enforce namespace for ids ++ MCTypeRegistry.ENTITY.addStructureHook(VERSION, new DataHookEnforceNamespacedID()); ++ MCTypeRegistry.ENTITY_NAME.addStructureHook(VERSION, new DataHookValueTypeEnforceNamespaced()); ++ } ++ ++ private V705() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V804.java b/ca/spottedleaf/dataconverter/minecraft/versions/V804.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7f71c76352bf32d91826dab2e0b8dc8393afcfdc +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V804.java +@@ -0,0 +1,59 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V804 { ++ ++ private static final int VERSION = MCVersions.V16W35A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:banner", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType blockEntity = tag.getMap("BlockEntityTag"); ++ if (blockEntity == null) { ++ return null; ++ } ++ ++ if (!blockEntity.hasKey("Base", ObjectType.NUMBER)) { ++ return null; ++ } ++ ++ data.setShort("Damage", (short)(blockEntity.getShort("Base") & 15)); ++ ++ final MapType display = tag.getMap("display"); ++ if (display != null) { ++ final ListType lore = display.getList("Lore", ObjectType.STRING); ++ if (lore != null) { ++ if (lore.size() == 1 && "(+NBT)".equals(lore.getString(0))) { ++ return null; ++ } ++ } ++ } ++ ++ blockEntity.remove("Base"); ++ if (blockEntity.isEmpty()) { ++ tag.remove("BlockEntityTag"); ++ } ++ ++ if (tag.isEmpty()) { ++ data.remove("tag"); ++ } ++ ++ return null; ++ } ++ }); ++ } ++ ++ private V804() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V806.java b/ca/spottedleaf/dataconverter/minecraft/versions/V806.java +new file mode 100644 +index 0000000000000000000000000000000000000000..510262ad7ff4ab12548e04906a96b7334fe8271d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V806.java +@@ -0,0 +1,39 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.Types; ++ ++public final class V806 { ++ ++ private static final int VERSION = MCVersions.V16W36A + 1; ++ ++ public static void register() { ++ final DataConverter potionWaterUpdater = new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ tag = Types.NBT.createEmptyMap(); ++ data.setMap("tag", tag); ++ } ++ ++ if (!tag.hasKey("Potion", ObjectType.STRING)) { ++ tag.setString("Potion", "minecraft:water"); ++ } ++ ++ return null; ++ } ++ }; ++ ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:potion", potionWaterUpdater); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:splash_potion", potionWaterUpdater); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:lingering_potion", potionWaterUpdater); ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:tipped_arrow", potionWaterUpdater); ++ } ++ ++ private V806() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V808.java b/ca/spottedleaf/dataconverter/minecraft/versions/V808.java +new file mode 100644 +index 0000000000000000000000000000000000000000..c1bd8f279b3dd38296564fc4b1cf7322c7d1c686 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V808.java +@@ -0,0 +1,29 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V808 { ++ ++ private static final int VERSION = MCVersions.V16W38A + 1; ++ ++ public static void register() { ++ MCTypeRegistry.ENTITY.addConverterForId("minecraft:shulker", new DataConverter<>(VERSION, 1) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ if (!data.hasKey("Color", ObjectType.NUMBER)) { ++ data.setByte("Color", (byte)10); ++ } ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "minecraft:shulker_box", new DataWalkerItemLists("Items")); ++ } ++ ++ private V808() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V813.java b/ca/spottedleaf/dataconverter/minecraft/versions/V813.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0f79651b6d35464823988bd2aba57d08a0ac7613 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V813.java +@@ -0,0 +1,64 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class V813 { ++ ++ private static final int VERSION = MCVersions.V16W40A; ++ ++ private static final String[] SHULKER_ID_BY_COLOUR = new String[] { ++ "minecraft:white_shulker_box", ++ "minecraft:orange_shulker_box", ++ "minecraft:magenta_shulker_box", ++ "minecraft:light_blue_shulker_box", ++ "minecraft:yellow_shulker_box", ++ "minecraft:lime_shulker_box", ++ "minecraft:pink_shulker_box", ++ "minecraft:gray_shulker_box", ++ "minecraft:silver_shulker_box", ++ "minecraft:cyan_shulker_box", ++ "minecraft:purple_shulker_box", ++ "minecraft:blue_shulker_box", ++ "minecraft:brown_shulker_box", ++ "minecraft:green_shulker_box", ++ "minecraft:red_shulker_box", ++ "minecraft:black_shulker_box" ++ }; ++ ++ public static void register() { ++ MCTypeRegistry.ITEM_STACK.addConverterForId("minecraft:shulker_box", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final MapType blockEntity = tag.getMap("BlockEntityTag"); ++ if (blockEntity == null) { ++ return null; ++ } ++ ++ final int color = blockEntity.getInt("Color"); ++ blockEntity.remove("Color"); ++ ++ data.setString("id", SHULKER_ID_BY_COLOUR[color % SHULKER_ID_BY_COLOUR.length]); ++ ++ return null; ++ } ++ }); ++ ++ MCTypeRegistry.TILE_ENTITY.addConverterForId("minecraft:shulker_box", new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ data.remove("Color"); ++ return null; ++ } ++ }); ++ } ++ ++ private V813() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V816.java b/ca/spottedleaf/dataconverter/minecraft/versions/V816.java +new file mode 100644 +index 0000000000000000000000000000000000000000..edbf9c01a44a77f87bdc186bdfaf36b408a31f4e +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V816.java +@@ -0,0 +1,27 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.DataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.Locale; ++ ++public final class V816 { ++ ++ private static final int VERSION = MCVersions.V16W43A; ++ ++ public static void register() { ++ MCTypeRegistry.OPTIONS.addStructureConverter(new DataConverter<>(VERSION) { ++ @Override ++ public MapType convert(final MapType data, final long sourceVersion, final long toVersion) { ++ final String lang = data.getString("lang"); ++ if (lang != null) { ++ data.setString("lang", lang.toLowerCase(Locale.ROOT)); ++ } ++ return null; ++ } ++ }); ++ } ++ ++ private V816() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V820.java b/ca/spottedleaf/dataconverter/minecraft/versions/V820.java +new file mode 100644 +index 0000000000000000000000000000000000000000..0d59cb380e625bb2658216d4a6cb8faebdd147c5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V820.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.itemname.ConverterAbstractItemRename; ++import com.google.common.collect.ImmutableMap; ++import java.util.HashMap; ++ ++public final class V820 { ++ ++ private static final int VERSION = MCVersions.V1_11 + 1; ++ ++ public static void register() { ++ ConverterAbstractItemRename.register(VERSION, new HashMap<>( ++ ImmutableMap.of( ++ "minecraft:totem", "minecraft:totem_of_undying" ++ ) ++ )::get); ++ } ++ ++ private V820() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V99.java b/ca/spottedleaf/dataconverter/minecraft/versions/V99.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3a2a82bc7c18667bed10086203d995f9effe3399 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V99.java +@@ -0,0 +1,418 @@ ++package ca.spottedleaf.dataconverter.minecraft.versions; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataHook; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.MCDataConverter; ++import ca.spottedleaf.dataconverter.minecraft.MCVersions; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.HelperItemNameV102; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookEnforceNamespacedID; ++import ca.spottedleaf.dataconverter.minecraft.hooks.DataHookValueTypeEnforceNamespaced; ++import ca.spottedleaf.dataconverter.minecraft.walkers.block_name.DataWalkerBlockNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItemLists; ++import ca.spottedleaf.dataconverter.minecraft.walkers.item_name.DataWalkerItemNames; ++import ca.spottedleaf.dataconverter.minecraft.walkers.itemstack.DataWalkerItems; ++import ca.spottedleaf.dataconverter.minecraft.walkers.tile_entity.DataWalkerTileEntities; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import com.mojang.logging.LogUtils; ++import org.slf4j.Logger; ++import java.util.HashMap; ++import java.util.Map; ++ ++public final class V99 { ++ ++ // Structure for all data before data upgrading was added to minecraft (pre 15w32a) ++ ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ ++ public static final int VERSION = MCVersions.V15W32A - 1; ++ ++ private static final Map ITEM_ID_TO_TILE_ENTITY_ID = new HashMap<>(); ++ static { ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:furnace", "Furnace"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:lit_furnace", "Furnace"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:chest", "Chest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:trapped_chest", "Chest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:ender_chest", "EnderChest"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:jukebox", "RecordPlayer"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dispenser", "Trap"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:dropper", "Dropper"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:sign", "Sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:mob_spawner", "MobSpawner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:noteblock", "Music"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:brewing_stand", "Cauldron"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:enhanting_table", "EnchantTable"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:command_block", "CommandBlock"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:beacon", "Beacon"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:skull", "Skull"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:daylight_detector", "DLDetector"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:hopper", "Hopper"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:banner", "Banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:flower_pot", "FlowerPot"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:repeating_command_block", "CommandBlock"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:chain_command_block", "CommandBlock"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:standing_sign", "Sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:wall_sign", "Sign"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:piston_head", "Piston"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:daylight_detector_inverted", "DLDetector"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:unpowered_comparator", "Comparator"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:powered_comparator", "Comparator"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:wall_banner", "Banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:standing_banner", "Banner"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:structure_block", "Structure"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:end_portal", "Airportal"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:end_gateway", "EndGateway"); ++ ITEM_ID_TO_TILE_ENTITY_ID.put("minecraft:shield", "Banner"); ++ } ++ ++ private static void registerProjectile(final String id) { ++ MCTypeRegistry.ENTITY.addWalker(VERSION, id, new DataWalkerBlockNames("inTile")); ++ } ++ ++ private static void registerInventory(final String id) { ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, id, new DataWalkerItemLists("Items")); ++ } ++ ++ static void registerSign(final int version, final String id) { ++ // NOTE: In 1.7.10, the text was not TEXT_COMPONENT but in 1.8 it is. ++ MCTypeRegistry.TILE_ENTITY.addWalker(version, id, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "Text1", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "Text2", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "Text3", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "Text4", fromVersion, toVersion); ++ ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "FilteredText1", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "FilteredText2", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "FilteredText3", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, data, "FilteredText4", fromVersion, toVersion); ++ ++ return null; ++ }); ++ } ++ ++ public static void register() { ++ // entities ++ MCTypeRegistry.ENTITY.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ENTITY, data, "Riding", fromVersion, toVersion); ++ ++ return MCTypeRegistry.ENTITY_EQUIPMENT.convert(data, fromVersion, toVersion); ++ }); ++ MCTypeRegistry.ENTITY_EQUIPMENT.addStructureWalker(VERSION, new DataWalkerItemLists("Equipment")); ++ ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Item", new DataWalkerItems("Item")); ++ registerProjectile("ThrownEgg"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Arrow", new DataWalkerBlockNames("inTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "TippedArrow", new DataWalkerBlockNames("inTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "SpectralArrow", new DataWalkerBlockNames("inTile")); ++ registerProjectile("Snowball"); ++ registerProjectile("Fireball"); ++ registerProjectile("SmallFireball"); ++ registerProjectile("ThrownEnderpearl"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "ThrownPotion", new DataWalkerBlockNames("inTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "ThrownPotion", new DataWalkerItems("Potion")); ++ registerProjectile("ThrownExpBottle"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "ItemFrame", new DataWalkerItems("Item")); ++ registerProjectile("WitherSkull"); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "FallingSand", new DataWalkerBlockNames("Block")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "FallingSand", new DataWalkerTileEntities("TileEntityData")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "FireworksRocketEntity", new DataWalkerItems("FireworksItem")); ++ // Note: Minecart is the generic entity. It can be subtyped via an int to become one of the specific minecarts ++ // (i.e rideable, chest, furnace, tnt, etc) ++ // Because of this, we add all walkers to the generic type, even though they might not be needed. ++ // Vanilla does not make the generic minecart convert spawners, but we do. ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Minecart", new DataWalkerBlockNames("DisplayTile")); // for all minecart types ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Minecart", new DataWalkerItemLists("Items")); // for chest types ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Minecart", (final MapType data, final long fromVersion, final long toVersion) -> { ++ return MCTypeRegistry.UNTAGGED_SPAWNER.convert(data, fromVersion, toVersion); ++ }); // for spawner type ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartRideable", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartChest", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartChest", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartFurnace", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartTNT", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartSpawner", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartSpawner", (final MapType data, final long fromVersion, final long toVersion) -> { ++ return MCTypeRegistry.UNTAGGED_SPAWNER.convert(data, fromVersion, toVersion); ++ }); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartHopper", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartHopper", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartCommandBlock", new DataWalkerBlockNames("DisplayTile")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "MinecartCommandBlock", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "LastOutput")); ++ // mob -> simple as equipment is moved to base ENTITY ++ //registerMob("ArmorStand"); // changed to simple in 1.21.5 ++ //registerMob("Creeper"); // changed to simple in 1.21.5 ++ //registerMob("Skeleton"); // changed to simple in 1.21.5 ++ //registerMob("Spider"); // changed to simple in 1.21.5 ++ //registerMob("Giant"); // changed to simple in 1.21.5 ++ //registerMob("Zombie"); // changed to simple in 1.21.5 ++ //registerMob("Slime"); // changed to simple in 1.21.5 ++ //registerMob("Ghast"); // changed to simple in 1.21.5 ++ //registerMob("PigZombie"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Enderman", new DataWalkerBlockNames("carried")); ++ //registerMob("CaveSpider"); // changed to simple in 1.21.5 ++ //registerMob("Silverfish"); // changed to simple in 1.21.5 ++ //registerMob("Blaze"); // changed to simple in 1.21.5 ++ //registerMob("LavaSlime"); // changed to simple in 1.21.5 ++ //registerMob("EnderDragon"); // changed to simple in 1.21.5 ++ //registerMob("WitherBoss"); // changed to simple in 1.21.5 ++ //registerMob("Bat"); // changed to simple in 1.21.5 ++ //registerMob("Witch"); // changed to simple in 1.21.5 ++ //registerMob("Endermite"); // changed to simple in 1.21.5 ++ //registerMob("Guardian"); // changed to simple in 1.21.5 ++ //registerMob("Pig"); // changed to simple in 1.21.5 ++ //registerMob("Sheep"); // changed to simple in 1.21.5 ++ //registerMob("Cow"); // changed to simple in 1.21.5 ++ //registerMob("Chicken"); // changed to simple in 1.21.5 ++ //registerMob("Squid"); // changed to simple in 1.21.5 ++ //registerMob("Wolf"); // changed to simple in 1.21.5 ++ //registerMob("MushroomCow"); // changed to simple in 1.21.5 ++ //registerMob("SnowMan"); // changed to simple in 1.21.5 ++ //registerMob("Ozelot"); // changed to simple in 1.21.5 ++ //registerMob("VillagerGolem"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "EntityHorse", new DataWalkerItemLists("Items")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "EntityHorse", new DataWalkerItems("ArmorItem", "SaddleItem")); ++ //registerMob("Rabbit"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Villager", new DataWalkerItemLists("Inventory")); ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "Villager", (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.VILLAGER_TRADE, data.getMap("Offers"), "Recipes", fromVersion, toVersion); ++ ++ return null; ++ }); ++ //registerMob("Shulker"); // changed to simple in 1.21.5 ++ MCTypeRegistry.ENTITY.addWalker(VERSION, "AreaEffectCloud", new DataWalkerTypePaths<>(MCTypeRegistry.PARTICLE, "Particle")); ++ ++ // tile entities ++ MCTypeRegistry.TILE_ENTITY.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.DATA_COMPONENTS, data, "components", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Inventory -> new DataWalkerItemLists("Items") ++ registerInventory("Furnace"); ++ registerInventory("Chest"); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "RecordPlayer", new DataWalkerItems("RecordItem")); ++ registerInventory("Trap"); ++ registerInventory("Dropper"); ++ registerSign(VERSION, "Sign"); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "MobSpawner", (final MapType data, final long fromVersion, final long toVersion) -> { ++ return MCTypeRegistry.UNTAGGED_SPAWNER.convert(data, fromVersion, toVersion); ++ }); ++ registerInventory("Cauldron"); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "Control", ++ new DataWalkerTypePaths<>(MCTypeRegistry.DATACONVERTER_CUSTOM_TYPE_COMMAND, "Command") ++ ); ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "Control", new DataWalkerTypePaths<>(MCTypeRegistry.TEXT_COMPONENT, "LastOutput")); ++ // skull doesn't even have custom_name in legacy versions! Why is it being walked here in DFU????? ++ registerInventory("Hopper"); ++ // Banner CustomName is a string, not TEXT_COMPONENT. Fix Vanilla incorrectly converting this ++ // Note: Vanilla does not properly handle this case for FlowerPot, it will not convert int ids! ++ MCTypeRegistry.TILE_ENTITY.addWalker(VERSION, "FlowerPot", new DataWalkerItemNames("Item")); ++ ++ // rest ++ ++ MCTypeRegistry.LEVEL.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, data, "CustomBossEvents", "Name", fromVersion, toVersion); ++ ++ return MCTypeRegistry.LIGHTWEIGHT_LEVEL.convert(data, fromVersion, toVersion); ++ }); ++ ++ MCTypeRegistry.ITEM_STACK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_NAME, data, "id", fromVersion, toVersion); ++ ++ final MapType tag = data.getMap("tag"); ++ if (tag == null) { ++ return null; ++ } ++ ++ final String itemId = getStringId(data.getGeneric("id")); ++ ++ // only things here are in tag, if changed update if above ++ ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, tag, "Items", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.ITEM_STACK, tag, "ChargedProjectiles", fromVersion, toVersion); ++ if ("minecraft:written_book".equals(itemId)) { ++ // These are only text component for WRITTEN books! DFU blindly will mark this as TEXT_COMPONENT. ++ // Like signs, they are only a real TEXT_COMPONENT (possibly!) in 1.8. We really can't distinguish between ++ // them though. ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, tag, "pages", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEXT_COMPONENT, tag, "filtered_pages", fromVersion, toVersion); ++ } ++ // Note: In this version, display IS NEVER a TEXT_COMPONENT! This fixes incorrectly converting the display tag ++ ++ MapType entityTag = tag.getMap("EntityTag"); ++ if (entityTag != null) { ++ final String entityId; ++ if ("minecraft:armor_stand".equals(itemId)) { ++ // The check for version id is removed here. For whatever reason, the legacy ++ // data converters used entity id "minecraft:armor_stand" when version was greater-than 514, ++ // but entity ids were not namespaced until V705! So somebody fucked up the legacy converters. ++ // DFU agrees with my analysis here, it will only set the entityId here to the namespaced variant ++ // with the V705 schema. ++ entityId = "ArmorStand"; ++ } else if ("minecraft:item_frame".equals(itemId)) { ++ // add missing item_frame entity id ++ entityId = "ItemFrame"; ++ } else if ("minecraft:painting".equals(itemId)) { ++ entityId = "Painting"; ++ } else { ++ entityId = entityTag.getString("id"); ++ } ++ ++ final boolean removeId; ++ if (entityId == null) { ++ if (!"minecraft:air".equals(itemId)) { ++ LOGGER.warn("Unable to resolve Entity for ItemStack (V99): " + data.getGeneric("id")); ++ } ++ removeId = false; ++ } else { ++ removeId = !entityTag.hasKey("id", ObjectType.STRING); ++ if (removeId) { ++ entityTag.setString("id", entityId); ++ } ++ } ++ ++ final MapType replace = MCTypeRegistry.ENTITY.convert(entityTag, fromVersion, toVersion); ++ ++ if (replace != null) { ++ entityTag = replace; ++ tag.setMap("EntityTag", entityTag); ++ } ++ if (removeId) { ++ entityTag.remove("id"); ++ } ++ } ++ ++ MapType blockEntityTag = tag.getMap("BlockEntityTag"); ++ if (blockEntityTag != null) { ++ final String entityId = ITEM_ID_TO_TILE_ENTITY_ID.get(itemId); ++ final boolean removeId; ++ if (entityId == null) { ++ if (!"minecraft:air".equals(itemId)) { ++ LOGGER.warn("Unable to resolve BlockEntity for ItemStack (V99): " + data.getGeneric("id")); ++ } ++ removeId = false; ++ } else { ++ removeId = !blockEntityTag.hasKey("id", ObjectType.STRING); ++ blockEntityTag.setString("id", entityId); ++ } ++ final MapType replace = MCTypeRegistry.TILE_ENTITY.convert(blockEntityTag, fromVersion, toVersion); ++ if (replace != null) { ++ blockEntityTag = replace; ++ tag.setMap("BlockEntityTag", blockEntityTag); ++ } ++ if (removeId) { ++ blockEntityTag.remove("id"); ++ } ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, tag, "CanDestroy", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_NAME, tag, "CanPlaceOn", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.PLAYER.addStructureWalker(VERSION, new DataWalkerItemLists("Inventory", "EnderItems")); ++ ++ MCTypeRegistry.CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ final MapType level = data.getMap("Level"); ++ if (level == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, level, "Entities", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TILE_ENTITY, level, "TileEntities", fromVersion, toVersion); ++ ++ final ListType tileTicks = level.getList("TileTicks", ObjectType.MAP); ++ if (tileTicks != null) { ++ for (int i = 0, len = tileTicks.size(); i < len; ++i) { ++ final MapType tileTick = tileTicks.getMap(i); ++ WalkerUtils.convert(MCTypeRegistry.BLOCK_NAME, tileTick, "i", fromVersion, toVersion); ++ } ++ } ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.ENTITY_CHUNK.addStructureWalker(VERSION, (final MapType data, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertList(MCTypeRegistry.ENTITY, data, "Entities", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.SAVED_DATA_MAP_DATA.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, root, "banners", "Name", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, root.getMap("data"), "banners", "Name", fromVersion, toVersion); ++ return null; ++ }); ++ MCTypeRegistry.SAVED_DATA_SCOREBOARD.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertList(MCTypeRegistry.OBJECTIVE, data, "Objectives", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.TEAM, data, "Teams", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.TEXT_COMPONENT, data, "PlayerScores", "display", fromVersion, toVersion); ++ ++ return null; ++ }); ++ MCTypeRegistry.SAVED_DATA_STRUCTURE_FEATURE_INDICES.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ final MapType data = root.getMap("data"); ++ if (data == null) { ++ return null; ++ } ++ ++ WalkerUtils.convertValues(MCTypeRegistry.STRUCTURE_FEATURE, data, "Features", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.TEAM.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "MemberNamePrefix", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "MemberNameSuffix", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.TEXT_COMPONENT, root, "DisplayName", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.VILLAGER_TRADE.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "buy", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "buyB", fromVersion, toVersion); ++ WalkerUtils.convert(MCTypeRegistry.ITEM_STACK, root, "sell", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ MCTypeRegistry.STRUCTURE.addStructureWalker(VERSION, (final MapType root, final long fromVersion, final long toVersion) -> { ++ WalkerUtils.convertListPath(MCTypeRegistry.ENTITY, root, "entities", "nbt", fromVersion, toVersion); ++ WalkerUtils.convertListPath(MCTypeRegistry.TILE_ENTITY, root, "blocks", "nbt", fromVersion, toVersion); ++ WalkerUtils.convertList(MCTypeRegistry.BLOCK_STATE, root, "palette", fromVersion, toVersion); ++ ++ return null; ++ }); ++ ++ // Enforce namespacing for ids ++ MCTypeRegistry.BLOCK_NAME.addStructureHook(VERSION, new DataHookValueTypeEnforceNamespaced()); ++ MCTypeRegistry.ITEM_NAME.addStructureHook(VERSION, new DataHookValueTypeEnforceNamespaced()); ++ MCTypeRegistry.ITEM_STACK.addStructureHook(VERSION, new DataHookEnforceNamespacedID()); ++ ++ // Entity is absent; the String form is not yet namespaced, unlike the above. ++ } ++ ++ private static String getStringId(final Object id) { ++ if (id instanceof String string) { ++ return string; ++ } else if (id instanceof Number number) { ++ return HelperItemNameV102.getNameFromId(number.intValue()); ++ } else { ++ return null; ++ } ++ } ++ ++ private V99() {} ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/block_name/DataWalkerBlockNames.java b/ca/spottedleaf/dataconverter/minecraft/walkers/block_name/DataWalkerBlockNames.java +new file mode 100644 +index 0000000000000000000000000000000000000000..930e014858ef635ebe25f7f92dc81ba0eaac50a8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/block_name/DataWalkerBlockNames.java +@@ -0,0 +1,11 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.block_name; ++ ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++ ++public final class DataWalkerBlockNames extends DataWalkerTypePaths { ++ ++ public DataWalkerBlockNames(final String... paths) { ++ super(MCTypeRegistry.BLOCK_NAME, paths); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/game_event/GameEventListenerWalker.java b/ca/spottedleaf/dataconverter/minecraft/walkers/game_event/GameEventListenerWalker.java +new file mode 100644 +index 0000000000000000000000000000000000000000..618c6d141c30506123dc7acae793355a3f6ff02c +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/game_event/GameEventListenerWalker.java +@@ -0,0 +1,21 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.game_event; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.WalkerUtils; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class GameEventListenerWalker implements DataWalker { ++ ++ @Override ++ public MapType walk(final MapType data, final long fromVersion, final long toVersion) { ++ final MapType listener = data.getMap("listener"); ++ if (listener == null) { ++ return null; ++ } ++ ++ WalkerUtils.convert(MCTypeRegistry.GAME_EVENT_NAME, listener.getMap("event"), "game_event", fromVersion, toVersion); ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerListPaths.java b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerListPaths.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6fd706b2fc0b979a3b2b8175127b935ec3f8486d +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerListPaths.java +@@ -0,0 +1,38 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.generic; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public class DataWalkerListPaths implements DataWalker { ++ ++ protected final DataType type; ++ protected final String[] paths; ++ ++ public DataWalkerListPaths(final DataType type, final String... paths) { ++ this.type = type; ++ this.paths = paths; ++ } ++ ++ @Override ++ public final MapType walk(final MapType data, final long fromVersion, final long toVersion) { ++ final DataType type = this.type; ++ for (final String path : this.paths) { ++ final ListType list = data.getListUnchecked(path); ++ if (list == null) { ++ continue; ++ } ++ ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final Object current = list.getGeneric(i); ++ final Object converted = type.convert((T)current, fromVersion, toVersion); ++ if (converted != null) { ++ list.setGeneric(i, converted); ++ } ++ } ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerTypePaths.java b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerTypePaths.java +new file mode 100644 +index 0000000000000000000000000000000000000000..961da39f6d64a6b569071e4351648432961a6a33 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/DataWalkerTypePaths.java +@@ -0,0 +1,34 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.generic; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.converters.datatypes.DataWalker; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public class DataWalkerTypePaths implements DataWalker { ++ ++ protected final DataType type; ++ protected final String[] paths; ++ ++ public DataWalkerTypePaths(final DataType type, final String... paths) { ++ this.type = type; ++ this.paths = paths; ++ } ++ ++ @Override ++ public final MapType walk(final MapType data, final long fromVersion, final long toVersion) { ++ for (final String path : this.paths) { ++ final Object current = data.getGeneric(path); ++ if (current == null) { ++ continue; ++ } ++ ++ final Object converted = this.type.convert((T)current, fromVersion, toVersion); ++ ++ if (converted != null) { ++ data.setGeneric(path, converted); ++ } ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/generic/WalkerUtils.java b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/WalkerUtils.java +new file mode 100644 +index 0000000000000000000000000000000000000000..3c865e0c4e05cb3161e5003b5ce6f0b83ad40463 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/generic/WalkerUtils.java +@@ -0,0 +1,199 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.generic; ++ ++import ca.spottedleaf.dataconverter.converters.datatypes.DataType; ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.RenameHelper; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCDataType; ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCValueType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import java.util.ArrayList; ++ ++public final class WalkerUtils { ++ ++ public static void convert(final MCDataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final MapType map = data.getMap(path); ++ if (map != null) { ++ final MapType replace = type.convert(map, fromVersion, toVersion); ++ if (replace != null) { ++ data.setMap(path, replace); ++ } ++ } ++ } ++ ++ public static void convertList(final MCDataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(path); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType listVal = list.getMap(i, null); ++ if (listVal == null) { ++ continue; ++ } ++ ++ final MapType replace = type.convert(listVal, fromVersion, toVersion); ++ if (replace != null) { ++ list.setMap(i, replace); ++ } ++ } ++ } ++ } ++ ++ public static void convertListPath(final MCDataType type, final MapType data, final String listPath, final String elementPath, ++ final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(listPath); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ WalkerUtils.convert(type, list.getMap(i, null), elementPath, fromVersion, toVersion); ++ } ++ } ++ } ++ ++ public static void convertListPath(final MCDataType type, final MapType data, final String listPath, final String elementPath1, ++ final String elementPath2, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(listPath); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType listVal = list.getMap(i, null); ++ if (listVal == null) { ++ continue; ++ } ++ ++ WalkerUtils.convert(type, listVal.getMap(elementPath1), elementPath2, fromVersion, toVersion); ++ } ++ } ++ } ++ ++ public static void convert(final DataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final Object value = data.getGeneric(path); ++ if (value != null) { ++ final Object converted = type.convert(value, fromVersion, toVersion); ++ if (converted != null) { ++ data.setGeneric(path, converted); ++ } ++ } ++ } ++ ++ public static void convert(final DataType type, final ListType data, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ for (int i = 0, len = data.size(); i < len; ++i) { ++ final Object value = data.getGeneric(i); ++ final Object converted = type.convert(value, fromVersion, toVersion); ++ if (converted != null) { ++ data.setGeneric(i, converted); ++ } ++ } ++ } ++ ++ public static void convertList(final DataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(path); ++ if (list != null) { ++ convert(type, list, fromVersion, toVersion); ++ } ++ } ++ ++ public static void convertListPath(final DataType type, final MapType data, final String listPath, final String elementPath, ++ final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(listPath); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ WalkerUtils.convert(type, list.getMap(i, null), elementPath, fromVersion, toVersion); ++ } ++ } ++ } ++ ++ public static void convertListPath(final DataType type, final MapType data, final String listPath, final String elementPath1, ++ final String elementPath2, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final ListType list = data.getListUnchecked(listPath); ++ if (list != null) { ++ for (int i = 0, len = list.size(); i < len; ++i) { ++ final MapType listVal = list.getMap(i, null); ++ if (listVal == null) { ++ continue; ++ } ++ ++ WalkerUtils.convert(type, listVal.getMap(elementPath1), elementPath2, fromVersion, toVersion); ++ } ++ } ++ } ++ ++ public static void convertKeys(final DataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ final MapType map = data.getMap(path); ++ if (map != null) { ++ convertKeys(type, map, fromVersion, toVersion); ++ } ++ } ++ ++ public static void convertKeys(final DataType type, final MapType data, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ RenameHelper.renameKeys(data, (final String input) -> { ++ return (String)type.convert(input, fromVersion, toVersion); ++ }); ++ } ++ ++ public static void convertValues(final MCDataType type, final MapType data, final String path, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ convertValues(type, data.getMap(path), fromVersion, toVersion); ++ } ++ ++ public static void convertValues(final MCDataType type, final MapType data, final long fromVersion, final long toVersion) { ++ if (data == null) { ++ return; ++ } ++ ++ for (final String key : data.keys()) { ++ final MapType value = data.getMap(key); ++ if (value != null) { ++ final MapType replace = type.convert(value, fromVersion, toVersion); ++ if (replace != null) { ++ // no CME, key is in map already ++ data.setMap(key, replace); ++ } ++ } ++ } ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/item_name/DataWalkerItemNames.java b/ca/spottedleaf/dataconverter/minecraft/walkers/item_name/DataWalkerItemNames.java +new file mode 100644 +index 0000000000000000000000000000000000000000..14e291efd864d97dcf83db01c09b9daaae1949bd +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/item_name/DataWalkerItemNames.java +@@ -0,0 +1,11 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.item_name; ++ ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++ ++public final class DataWalkerItemNames extends DataWalkerTypePaths { ++ ++ public DataWalkerItemNames(final String... paths) { ++ super(MCTypeRegistry.ITEM_NAME, paths); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItemLists.java b/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItemLists.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4541d2e80f806e62ade419b8f54475fd0aa6d9e8 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItemLists.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.itemstack; ++ ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerListPaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public class DataWalkerItemLists extends DataWalkerListPaths { ++ ++ public DataWalkerItemLists(final String... paths) { ++ super(MCTypeRegistry.ITEM_STACK, paths); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItems.java b/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItems.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fac29551a3093459a8fd8eceb6323e615c729a97 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/itemstack/DataWalkerItems.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.itemstack; ++ ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public class DataWalkerItems extends DataWalkerTypePaths { ++ ++ public DataWalkerItems(final String... paths) { ++ super(MCTypeRegistry.ITEM_STACK, paths); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/minecraft/walkers/tile_entity/DataWalkerTileEntities.java b/ca/spottedleaf/dataconverter/minecraft/walkers/tile_entity/DataWalkerTileEntities.java +new file mode 100644 +index 0000000000000000000000000000000000000000..14d72f19a429ac12f38cc79f526d465b386c9a15 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/minecraft/walkers/tile_entity/DataWalkerTileEntities.java +@@ -0,0 +1,12 @@ ++package ca.spottedleaf.dataconverter.minecraft.walkers.tile_entity; ++ ++import ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry; ++import ca.spottedleaf.dataconverter.minecraft.walkers.generic.DataWalkerTypePaths; ++import ca.spottedleaf.dataconverter.types.MapType; ++ ++public final class DataWalkerTileEntities extends DataWalkerTypePaths { ++ ++ public DataWalkerTileEntities(final String... paths) { ++ super(MCTypeRegistry.TILE_ENTITY, paths); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/ListType.java b/ca/spottedleaf/dataconverter/types/ListType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..54a6b9db0bc3579735bb473f1e1f4a8c7d4bc6f6 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/ListType.java +@@ -0,0 +1,272 @@ ++package ca.spottedleaf.dataconverter.types; ++ ++public interface ListType { ++ ++ public TypeUtil getTypeUtil(); ++ ++ @Override ++ public int hashCode(); ++ ++ @Override ++ public boolean equals(final Object other); ++ ++ // Provides a deep copy of this list ++ public ListType copy(); ++ ++ // Returns the type of all elements in this list. Returns NONE if empty, returns UNDEFINED if not supported, MIXED if mixed types ++ public ObjectType getUniformType(); ++ ++ public int size(); ++ ++ public void remove(final int index); ++ ++ public Object getGeneric(final int index); ++ ++ public default void setGeneric(final int index, final Object to) { ++ if (to instanceof Number) { ++ if (to instanceof Byte b) { ++ this.setByte(index, b.byteValue()); ++ return; ++ } else if (to instanceof Short s) { ++ this.setShort(index, s.shortValue()); ++ return; ++ } else if (to instanceof Integer i) { ++ this.setInt(index, i.intValue()); ++ return; ++ } else if (to instanceof Long l) { ++ this.setLong(index, l.longValue()); ++ return; ++ } else if (to instanceof Float f) { ++ this.setFloat(index, f.floatValue()); ++ return; ++ } else if (to instanceof Double d) { ++ this.setDouble(index, d.doubleValue()); ++ return; ++ } // else fall through to throw ++ } else if (to instanceof MapType m) { ++ this.setMap(index, m); ++ return; ++ } else if (to instanceof ListType l) { ++ this.setList(index, l); ++ return; ++ } else if (to instanceof String s) { ++ this.setString(index, s); ++ return; ++ } else if (to.getClass().isArray()) { ++ if (to instanceof byte[] bytes) { ++ this.setBytes(index, bytes); ++ return; ++ } else if (to instanceof short[] shorts) { ++ this.setShorts(index, shorts); ++ return; ++ } else if (to instanceof int[] ints) { ++ this.setInts(index, ints); ++ return; ++ } else if (to instanceof long[] longs) { ++ this.setLongs(index, longs); ++ return; ++ } // else fall through to throw ++ } ++ ++ throw new IllegalArgumentException("Object " + to + " is not a valid type!"); ++ } ++ ++ // types here are strict. if the type on get does not match the underlying type, will throw - except for the ++ // default parameter methods, in such cases the default value will be returned. ++ ++ public Number getNumber(final int index); ++ ++ public Number getNumber(final int index, final Number dfl); ++ ++ // if the value at index is a Number but not a byte, then returns the number casted to byte. ++ public byte getByte(final int index); ++ ++ // if the value at index is a Number but not a byte, then returns the number casted to byte. ++ public byte getByte(final int index, final byte dfl); ++ ++ public void setByte(final int index, final byte to); ++ ++ // if the value at index is a Number but not a short, then returns the number casted to short. ++ public short getShort(final int index); ++ ++ // if the value at index is a Number but not a short, then returns the number casted to short. ++ public short getShort(final int index, final short dfl); ++ ++ public void setShort(final int index, final short to); ++ ++ // if the value at index is a Number but not a int, then returns the number casted to int. ++ public int getInt(final int index); ++ ++ // if the value at index is a Number but not a int, then returns the number casted to int. ++ public int getInt(final int index, final int dfl); ++ ++ public void setInt(final int index, final int to); ++ ++ // if the value at index is a Number but not a long, then returns the number casted to long. ++ public long getLong(final int index); ++ ++ // if the value at index is a Number but not a long, then returns the number casted to long. ++ public long getLong(final int index, final long dfl); ++ ++ public void setLong(final int index, final long to); ++ ++ // if the value at index is a Number but not a float, then returns the number casted to float. ++ public float getFloat(final int index); ++ ++ // if the value at index is a Number but not a float, then returns the number casted to float. ++ public float getFloat(final int index, final float dfl); ++ ++ public void setFloat(final int index, final float to); ++ ++ // if the value at index is a Number but not a double, then returns the number casted to double. ++ public double getDouble(final int index); ++ ++ // if the value at index is a Number but not a double, then returns the number casted to double. ++ public double getDouble(final int index, final double dfl); ++ ++ public void setDouble(final int index, final double to); ++ ++ public byte[] getBytes(final int index); ++ ++ public byte[] getBytes(final int index, final byte[] bytes); ++ ++ public void setBytes(final int index, final byte[] to); ++ ++ public short[] getShorts(final int index); ++ ++ public short[] getShorts(final int index, final short[] dfl); ++ ++ public void setShorts(final int index, final short[] to); ++ ++ public int[] getInts(final int index); ++ ++ public int[] getInts(final int index, final int[] dfl); ++ ++ public void setInts(final int index, final int[] to); ++ ++ public long[] getLongs(final int index); ++ ++ public long[] getLongs(final int index, final long[] dfl); ++ ++ public void setLongs(final int index, final long[] to); ++ ++ public ListType getList(final int index); ++ ++ public ListType getList(final int index, final ListType dfl); ++ ++ public void setList(final int index, final ListType list); ++ ++ public MapType getMap(final int index); ++ ++ public MapType getMap(final int index, final MapType dfl); ++ ++ public void setMap(final int index, final MapType to); ++ ++ public String getString(final int index); ++ ++ public String getString(final int index, final String dfl); ++ ++ public void setString(final int index, final String to); ++ ++ public default void addGeneric(final Object to) { ++ if (to instanceof Number) { ++ if (to instanceof Byte b) { ++ this.addByte(b.byteValue()); ++ return; ++ } else if (to instanceof Short s) { ++ this.addShort(s.shortValue()); ++ return; ++ } else if (to instanceof Integer i) { ++ this.addInt(i.intValue()); ++ return; ++ } else if (to instanceof Long l) { ++ this.addLong(l.longValue()); ++ return; ++ } else if (to instanceof Float f) { ++ this.addFloat(f.floatValue()); ++ return; ++ } else if (to instanceof Double d) { ++ this.addDouble(d.doubleValue()); ++ return; ++ } // else fall through to throw ++ } else if (to instanceof MapType m) { ++ this.addMap(m); ++ return; ++ } else if (to instanceof ListType l) { ++ this.addList(l); ++ return; ++ } else if (to instanceof String s) { ++ this.addString(s); ++ return; ++ } else if (to.getClass().isArray()) { ++ if (to instanceof byte[] bytes) { ++ this.addByteArray(bytes); ++ return; ++ } else if (to instanceof short[] shorts) { ++ this.addShortArray(shorts); ++ return; ++ } else if (to instanceof int[] ints) { ++ this.addIntArray(ints); ++ return; ++ } else if (to instanceof long[] longs) { ++ this.addLongArray(longs); ++ return; ++ } // else fall through to throw ++ } ++ ++ throw new IllegalArgumentException("Object " + to + " is not a valid type!"); ++ } ++ ++ public void addByte(final byte b); ++ ++ public void addByte(final int index, final byte b); ++ ++ public void addShort(final short s); ++ ++ public void addShort(final int index, final short s); ++ ++ public void addInt(final int i); ++ ++ public void addInt(final int index, final int i); ++ ++ public void addLong(final long l); ++ ++ public void addLong(final int index, final long l); ++ ++ public void addFloat(final float f); ++ ++ public void addFloat(final int index, final float f); ++ ++ public void addDouble(final double d); ++ ++ public void addDouble(final int index, final double d); ++ ++ public void addByteArray(final byte[] arr); ++ ++ public void addByteArray(final int index, final byte[] arr); ++ ++ public void addShortArray(final short[] arr); ++ ++ public void addShortArray(final int index, final short[] arr); ++ ++ public void addIntArray(final int[] arr); ++ ++ public void addIntArray(final int index, final int[] arr); ++ ++ public void addLongArray(final long[] arr); ++ ++ public void addLongArray(final int index, final long[] arr); ++ ++ public void addList(final ListType list); ++ ++ public void addList(final int index, final ListType list); ++ ++ public void addMap(final MapType map); ++ ++ public void addMap(final int index, final MapType map); ++ ++ public void addString(final String string); ++ ++ public void addString(final int index, final String string); ++ ++} +diff --git a/ca/spottedleaf/dataconverter/types/MapType.java b/ca/spottedleaf/dataconverter/types/MapType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..709edd3e92fb8f73b8f9ae192162a72ce7f99fac +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/MapType.java +@@ -0,0 +1,220 @@ ++package ca.spottedleaf.dataconverter.types; ++ ++import java.util.Set; ++ ++public interface MapType { ++ ++ public TypeUtil getTypeUtil(); ++ ++ @Override ++ public int hashCode(); ++ ++ @Override ++ public boolean equals(final Object other); ++ ++ public int size(); ++ ++ public boolean isEmpty(); ++ ++ public void clear(); ++ ++ public Set keys(); ++ ++ // Provides a deep copy of this map ++ public MapType copy(); ++ ++ public boolean hasKey(final String key); ++ ++ public boolean hasKey(final String key, final ObjectType type); ++ ++ public void remove(final String key); ++ ++ public Object getGeneric(final String key); ++ ++ // types here are not strict. if the key maps to a different type, default is always returned ++ // if default is not a parameter, then default is always null ++ ++ public Number getNumber(final String key); ++ ++ public Number getNumber(final String key, final Number dfl); ++ ++ public boolean getBoolean(final String key); ++ ++ public boolean getBoolean(final String key, final boolean dfl); ++ ++ public void setBoolean(final String key, final boolean val); ++ ++ // if the mapped value is a Number but not a byte, then the number is casted to byte. If the mapped value does not exist or is not a number, returns 0 ++ public byte getByte(final String key); ++ ++ // if the mapped value is a Number but not a byte, then the number is casted to byte. If the mapped value does not exist or is not a number, returns dfl ++ public byte getByte(final String key, final byte dfl); ++ ++ public void setByte(final String key, final byte val); ++ ++ // if the mapped value is a Number but not a short, then the number is casted to short. If the mapped value does not exist or is not a number, returns 0 ++ public short getShort(final String key); ++ ++ // if the mapped value is a Number but not a short, then the number is casted to short. If the mapped value does not exist or is not a number, returns dfl ++ public short getShort(final String key, final short dfl); ++ ++ public void setShort(final String key, final short val); ++ ++ // if the mapped value is a Number but not a int, then the number is casted to int. If the mapped value does not exist or is not a number, returns 0 ++ public int getInt(final String key); ++ ++ // if the mapped value is a Number but not a int, then the number is casted to int. If the mapped value does not exist or is not a number, returns dfl ++ public int getInt(final String key, final int dfl); ++ ++ public void setInt(final String key, final int val); ++ ++ // if the mapped value is a Number but not a long, then the number is casted to long. If the mapped value does not exist or is not a number, returns 0 ++ public long getLong(final String key); ++ ++ // if the mapped value is a Number but not a long, then the number is casted to long. If the mapped value does not exist or is not a number, returns dfl ++ public long getLong(final String key, final long dfl); ++ ++ public void setLong(final String key, final long val); ++ ++ // if the mapped value is a Number but not a float, then the number is casted to float. If the mapped value does not exist or is not a number, returns 0 ++ public float getFloat(final String key); ++ ++ // if the mapped value is a Number but not a float, then the number is casted to float. If the mapped value does not exist or is not a number, returns dfl ++ public float getFloat(final String key, final float dfl); ++ ++ public void setFloat(final String key, final float val); ++ ++ // if the mapped value is a Number but not a double, then the number is casted to double. If the mapped value does not exist or is not a number, returns 0 ++ public double getDouble(final String key); ++ ++ // if the mapped value is a Number but not a double, then the number is casted to double. If the mapped value does not exist or is not a number, returns dfl ++ public double getDouble(final String key, final double dfl); ++ ++ public void setDouble(final String key, final double val); ++ ++ public byte[] getBytes(final String key); ++ ++ public byte[] getBytes(final String key, final byte[] dfl); ++ ++ public void setBytes(final String key, final byte[] val); ++ ++ public short[] getShorts(final String key); ++ ++ public short[] getShorts(final String key, final short[] dfl); ++ ++ public void setShorts(final String key, final short[] val); ++ ++ public int[] getInts(final String key); ++ ++ public int[] getInts(final String key, final int[] dfl); ++ ++ public void setInts(final String key, final int[] val); ++ ++ public long[] getLongs(final String key); ++ ++ public long[] getLongs(final String key, final long[] dfl); ++ ++ public void setLongs(final String key, final long[] val); ++ ++ public ListType getListUnchecked(final String key); ++ ++ public ListType getListUnchecked(final String key, final ListType dfl); ++ ++ public default ListType getList(final String key, final ObjectType type) { ++ return this.getList(key, type, null); ++ } ++ ++ public default ListType getOrCreateList(final String key, final ObjectType type) { ++ ListType ret = this.getList(key, type); ++ if (ret == null) { ++ this.setList(key, ret = this.getTypeUtil().createEmptyList()); ++ } ++ ++ return ret; ++ } ++ ++ public default ListType getList(final String key, final ObjectType type, final ListType dfl) { ++ final ListType ret = this.getListUnchecked(key, null); ++ final ObjectType retType; ++ if (ret != null && ((retType = ret.getUniformType()) == type || retType == ObjectType.UNDEFINED || retType == ObjectType.NONE)) { ++ return ret; ++ } else { ++ return dfl; ++ } ++ } ++ ++ public void setList(final String key, final ListType val); ++ ++ public MapType getMap(final String key); ++ ++ public default MapType getOrCreateMap(final String key) { ++ MapType ret = this.getMap(key); ++ if (ret == null) { ++ this.setMap(key, ret = this.getTypeUtil().createEmptyMap()); ++ } ++ ++ return ret; ++ } ++ ++ public MapType getMap(final String key, final MapType dfl); ++ ++ public void setMap(final String key, final MapType val); ++ ++ public String getString(final String key); ++ ++ public String getString(final String key, final String dfl); ++ ++ public void setString(final String key, final String val); ++ ++ public default void setGeneric(final String key, final Object value) { ++ if (value instanceof Boolean bool) { ++ this.setBoolean(key, bool.booleanValue()); ++ return; ++ } else if (value instanceof Number) { ++ if (value instanceof Byte b) { ++ this.setByte(key, b.byteValue()); ++ return; ++ } else if (value instanceof Short s) { ++ this.setShort(key, s.shortValue()); ++ return; ++ } else if (value instanceof Integer i) { ++ this.setInt(key, i.intValue()); ++ return; ++ } else if (value instanceof Long l) { ++ this.setLong(key, l.longValue()); ++ return; ++ } else if (value instanceof Float f) { ++ this.setFloat(key, f.floatValue()); ++ return; ++ } else if (value instanceof Double d) { ++ this.setDouble(key, d.doubleValue()); ++ return; ++ } // else fall through to throw ++ } else if (value instanceof MapType map) { ++ this.setMap(key, map); ++ return; ++ } else if (value instanceof ListType list) { ++ this.setList(key, list); ++ return; ++ } else if (value instanceof String string) { ++ this.setString(key, string); ++ return; ++ } else if (value.getClass().isArray()) { ++ if (value instanceof byte[] bytes) { ++ this.setBytes(key, bytes); ++ return; ++ } else if (value instanceof short[] shorts) { ++ this.setShorts(key, shorts); ++ return; ++ } else if (value instanceof int[] ints) { ++ this.setInts(key, ints); ++ return; ++ } else if (value instanceof long[] longs) { ++ this.setLongs(key, longs); ++ return; ++ } // else fall through to throw ++ } ++ ++ throw new IllegalArgumentException("Object " + value + " is not a valid type!"); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/ObjectType.java b/ca/spottedleaf/dataconverter/types/ObjectType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..9775d810ba28e59d4eec6c79643c4bcaeb97fc31 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/ObjectType.java +@@ -0,0 +1,73 @@ ++package ca.spottedleaf.dataconverter.types; ++ ++public enum ObjectType { ++ NONE(null), ++ BYTE(Byte.class), ++ SHORT(Short.class), ++ INT(Integer.class), ++ LONG(Long.class), ++ FLOAT(Float.class), ++ DOUBLE(Double.class), ++ NUMBER(Number.class), ++ BYTE_ARRAY(byte[].class), ++ SHORT_ARRAY(short[].class), ++ INT_ARRAY(int[].class), ++ LONG_ARRAY(long[].class), ++ LIST(ListType.class), ++ MAP(MapType.class), ++ STRING(String.class), ++ UNDEFINED(null), ++ MIXED(null); ++ ++ private final Class clazz; ++ private final boolean isNumber; ++ ++ private ObjectType(final Class clazz) { ++ this.clazz = clazz; ++ this.isNumber = clazz != null && Number.class.isAssignableFrom(clazz); ++ } ++ ++ public boolean isNumber() { ++ return this.isNumber; ++ } ++ ++ public Class getObjectClass() { ++ return this.clazz; ++ } ++ ++ public static ObjectType getType(final Object object) { ++ if (object instanceof Number) { ++ if (object instanceof Byte) { ++ return BYTE; ++ } else if (object instanceof Short) { ++ return SHORT; ++ } else if (object instanceof Integer) { ++ return INT; ++ } else if (object instanceof Long) { ++ return LONG; ++ } else if (object instanceof Float) { ++ return FLOAT; ++ } else if (object instanceof Double) { ++ return DOUBLE; ++ } // else return null ++ } else if (object instanceof MapType) { ++ return MAP; ++ } else if (object instanceof ListType) { ++ return LIST; ++ } else if (object instanceof String) { ++ return STRING; ++ } else if (object.getClass().isArray()) { ++ if (object instanceof byte[]) { ++ return BYTE_ARRAY; ++ } else if (object instanceof short[]) { ++ return SHORT_ARRAY; ++ } else if (object instanceof int[]) { ++ return INT_ARRAY; ++ } else if (object instanceof long[]) { ++ return LONG_ARRAY; ++ } // else return null ++ } ++ ++ return null; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/TypeUtil.java b/ca/spottedleaf/dataconverter/types/TypeUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4170c188d9e7150ef7b728d4992d10ec8dab4fa4 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/TypeUtil.java +@@ -0,0 +1,26 @@ ++package ca.spottedleaf.dataconverter.types; ++ ++public interface TypeUtil { ++ ++ public ListType createEmptyList(); ++ ++ public MapType createEmptyMap(); ++ ++ public default Object convertFromBaseToGeneric(final T input, final TypeUtil to) { ++ return this.convertTo(this.baseToGeneric(input), to); ++ } ++ ++ public default D convertBaseToBase(final T input, final TypeUtil to) { ++ return to.genericToBase(this.convertFromBaseToGeneric(input, to)); ++ } ++ ++ public default D convertGenericToBase(final Object valueGeneric, final TypeUtil to) { ++ return to.genericToBase(this.convertTo(valueGeneric, to)); ++ } ++ ++ public Object convertTo(final Object valueGeneric, final TypeUtil to); ++ ++ public Object baseToGeneric(final T input); ++ ++ public T genericToBase(final Object input); ++} +diff --git a/ca/spottedleaf/dataconverter/types/Types.java b/ca/spottedleaf/dataconverter/types/Types.java +new file mode 100644 +index 0000000000000000000000000000000000000000..750aa7b31732d81eb01c80b45b13a830ae7feb91 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/Types.java +@@ -0,0 +1,14 @@ ++package ca.spottedleaf.dataconverter.types; ++ ++import ca.spottedleaf.dataconverter.types.json.JsonTypeUtil; ++import ca.spottedleaf.dataconverter.types.nbt.NBTTypeUtil; ++ ++public interface Types { ++ ++ public static final NBTTypeUtil NBT = new NBTTypeUtil(); ++ ++ public static final JsonTypeUtil JSON = new JsonTypeUtil(false); ++ ++ // why does this exist ++ public static final JsonTypeUtil JSON_COMPRESSED = new JsonTypeUtil(true); ++} +diff --git a/ca/spottedleaf/dataconverter/types/json/JsonListType.java b/ca/spottedleaf/dataconverter/types/json/JsonListType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..58d0bf4931e7516b39d9d31b4807cfa28efeee0a +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/json/JsonListType.java +@@ -0,0 +1,510 @@ ++package ca.spottedleaf.dataconverter.types.json; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.gson.JsonArray; ++import com.google.gson.JsonElement; ++import com.google.gson.JsonObject; ++import com.google.gson.JsonPrimitive; ++ ++public final class JsonListType implements ListType { ++ ++ final JsonArray array; ++ final boolean compressed; ++ ++ public JsonListType(final boolean compressed) { ++ this.array = new JsonArray(); ++ this.compressed = compressed; ++ } ++ ++ public JsonListType(final JsonArray array, final boolean compressed) { ++ this.array = array; ++ this.compressed = compressed; ++ } ++ ++ @Override ++ public TypeUtil getTypeUtil() { ++ return this.compressed ? Types.JSON_COMPRESSED : Types.JSON; ++ } ++ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } ++ ++ if (obj == null || obj.getClass() != JsonListType.class) { ++ return false; ++ } ++ ++ return this.array.equals(((JsonListType)obj).array); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.array.hashCode(); ++ } ++ ++ @Override ++ public String toString() { ++ return "JsonListType{" + ++ "array=" + this.array + ++ ", compressed=" + this.compressed + ++ '}'; ++ } ++ ++ public JsonArray getJson() { ++ return this.array; ++ } ++ ++ @Override ++ public ListType copy() { ++ return new JsonListType(this.array.deepCopy(), this.compressed); ++ } ++ ++ @Override ++ public ObjectType getUniformType() { ++ return ObjectType.UNDEFINED; ++ } ++ ++ @Override ++ public int size() { ++ return this.array.size(); ++ } ++ ++ @Override ++ public void remove(final int index) { ++ this.array.remove(index); ++ } ++ ++ @Override ++ public Object getGeneric(final int index) { ++ return Types.JSON.baseToGeneric(this.array.get(index)); ++ } ++ ++ @Override ++ public Number getNumber(final int index) { ++ final JsonElement element = this.array.get(index); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isNumber()) { ++ return primitive.getAsNumber(); ++ } else if (primitive.isBoolean()) { ++ return primitive.getAsBoolean() ? Byte.valueOf((byte)1) : Byte.valueOf((byte)0); ++ } else if (this.compressed && primitive.isString()) { ++ try { ++ return Integer.valueOf(Integer.parseInt(primitive.getAsString())); ++ } catch (final NumberFormatException ex) { ++ return null; ++ } ++ } ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public Number getNumber(final int index, final Number dfl) { ++ final Number ret = this.getNumber(index); ++ return ret == null ? dfl : ret; ++ } ++ ++ @Override ++ public byte getByte(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? (byte)0 : number.byteValue(); ++ } ++ ++ @Override ++ public byte getByte(final int index, final byte dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.byteValue(); ++ } ++ ++ @Override ++ public void setByte(final int index, final byte to) { ++ this.array.set(index, new JsonPrimitive(Byte.valueOf(to))); ++ } ++ ++ @Override ++ public short getShort(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? (short)0 : number.shortValue(); ++ } ++ ++ @Override ++ public short getShort(final int index, final short dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.shortValue(); ++ } ++ ++ @Override ++ public void setShort(final int index, final short to) { ++ this.array.set(index, new JsonPrimitive(Short.valueOf(to))); ++ } ++ ++ @Override ++ public int getInt(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? 0 : number.intValue(); ++ } ++ ++ @Override ++ public int getInt(final int index, final int dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.intValue(); ++ } ++ ++ @Override ++ public void setInt(final int index, final int to) { ++ this.array.set(index, new JsonPrimitive(Integer.valueOf(to))); ++ } ++ ++ @Override ++ public long getLong(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? 0L : number.longValue(); ++ } ++ ++ @Override ++ public long getLong(final int index, final long dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.longValue(); ++ } ++ ++ @Override ++ public void setLong(final int index, final long to) { ++ this.array.set(index, new JsonPrimitive(Long.valueOf(to))); ++ } ++ ++ @Override ++ public float getFloat(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? 0.0f : number.floatValue(); ++ } ++ ++ @Override ++ public float getFloat(final int index, final float dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.floatValue(); ++ } ++ ++ @Override ++ public void setFloat(final int index, final float to) { ++ this.array.set(index, new JsonPrimitive(Float.valueOf(to))); ++ } ++ ++ @Override ++ public double getDouble(final int index) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? 0.0 : number.doubleValue(); ++ } ++ ++ @Override ++ public double getDouble(final int index, final double dfl) { ++ final Number number = this.getNumber(index); ++ ++ return number == null ? dfl : number.doubleValue(); ++ } ++ ++ @Override ++ public void setDouble(final int index, final double to) { ++ this.array.set(index, new JsonPrimitive(Double.valueOf(to))); ++ } ++ ++ @Override ++ public byte[] getBytes(final int index) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public byte[] getBytes(final int index, final byte[] dfl) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void setBytes(final int index, final byte[] to) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public short[] getShorts(final int index) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public short[] getShorts(final int index, final short[] dfl) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void setShorts(final int index, final short[] to) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int[] getInts(final int index) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int[] getInts(final int index, final int[] dfl) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void setInts(final int index, final int[] to) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public long[] getLongs(final int index) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public long[] getLongs(final int index, final long[] dfl) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void setLongs(final int index, final long[] to) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public ListType getList(final int index) { ++ final JsonElement element = this.array.get(index); ++ if (element instanceof JsonArray) { ++ return new JsonListType((JsonArray)element, this.compressed); ++ } ++ return null; ++ } ++ ++ @Override ++ public ListType getList(final int index, final ListType dfl) { ++ final ListType ret = this.getList(index); ++ return ret == null ? dfl : ret; ++ } ++ ++ @Override ++ public void setList(final int index, final ListType list) { ++ this.array.set(index, ((JsonListType)list).array); ++ } ++ ++ @Override ++ public MapType getMap(final int index) { ++ final JsonElement element = this.array.get(index); ++ if (element instanceof JsonObject) { ++ return new JsonMapType((JsonObject)element, this.compressed); ++ } ++ return null; ++ } ++ ++ @Override ++ public MapType getMap(final int index, final MapType dfl) { ++ final MapType ret = this.getMap(index); ++ return ret == null ? dfl : ret; ++ } ++ ++ @Override ++ public void setMap(final int index, final MapType to) { ++ this.array.set(index, ((JsonMapType)to).map); ++ } ++ ++ @Override ++ public String getString(final int index) { ++ final JsonElement element = this.array.get(index); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isString() || (this.compressed && primitive.isNumber())) { ++ return primitive.getAsString(); ++ } ++ } ++ ++ return null; ++ } ++ ++ @Override ++ public String getString(final int index, final String dfl) { ++ final String ret = this.getString(index); ++ return ret == null ? dfl : ret; ++ } ++ ++ @Override ++ public void setString(final int index, final String to) { ++ this.array.set(index, new JsonPrimitive(to)); ++ } ++ ++ @Override ++ public void addByte(final byte b) { ++ this.array.add(Byte.valueOf(b)); ++ } ++ ++ @Override ++ public void addByte(final int index, final byte b) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addShort(final short s) { ++ this.array.add(Short.valueOf(s)); ++ } ++ ++ @Override ++ public void addShort(final int index, final short s) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addInt(final int i) { ++ this.array.add(Integer.valueOf(i)); ++ } ++ ++ @Override ++ public void addInt(final int index, final int i) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addLong(final long l) { ++ this.array.add(Long.valueOf(l)); ++ } ++ ++ @Override ++ public void addLong(final int index, final long l) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addFloat(final float f) { ++ this.array.add(Float.valueOf(f)); ++ } ++ ++ @Override ++ public void addFloat(final int index, final float f) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addDouble(final double d) { ++ this.array.add(Double.valueOf(d)); ++ } ++ ++ @Override ++ public void addDouble(final int index, final double d) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addByteArray(final byte[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addByteArray(final int index, final byte[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addShortArray(final short[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addShortArray(final int index, final short[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addIntArray(final int[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addIntArray(final int index, final int[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addLongArray(final long[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addLongArray(final int index, final long[] arr) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addList(final ListType list) { ++ this.array.add(((JsonListType)list).array); ++ } ++ ++ @Override ++ public void addList(final int index, final ListType list) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addMap(final MapType map) { ++ this.array.add(((JsonMapType)map).map); ++ } ++ ++ @Override ++ public void addMap(final int index, final MapType map) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addString(final String string) { ++ this.array.add(string); ++ } ++ ++ @Override ++ public void addString(final int index, final String string) { ++ // doesn't implement any methods for adding at index... yee haw... ++ throw new UnsupportedOperationException(); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/json/JsonMapType.java b/ca/spottedleaf/dataconverter/types/json/JsonMapType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6704da4a40522a4f40cd770a4cbaaa8e6f67cc31 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/json/JsonMapType.java +@@ -0,0 +1,472 @@ ++package ca.spottedleaf.dataconverter.types.json; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.Types; ++import com.google.gson.JsonArray; ++import com.google.gson.JsonElement; ++import com.google.gson.JsonObject; ++import com.google.gson.JsonPrimitive; ++import java.util.LinkedHashSet; ++import java.util.Map; ++import java.util.Set; ++ ++public final class JsonMapType implements MapType { ++ ++ final JsonObject map; ++ final boolean compressed; ++ ++ public JsonMapType(final boolean compressed) { ++ this.map = new JsonObject(); ++ this.compressed = compressed; ++ } ++ ++ public JsonMapType(final JsonObject map, final boolean compressed) { ++ this.map = map; ++ this.compressed = compressed; ++ } ++ ++ @Override ++ public TypeUtil getTypeUtil() { ++ return this.compressed ? Types.JSON_COMPRESSED : Types.JSON; ++ } ++ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } ++ ++ if (obj == null || obj.getClass() != JsonMapType.class) { ++ return false; ++ } ++ ++ return this.map.equals(((JsonMapType)obj).map); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.map.hashCode(); ++ } ++ ++ @Override ++ public String toString() { ++ return "JsonMapType{" + ++ "map=" + this.map + ++ ", compressed=" + this.compressed + ++ '}'; ++ } ++ ++ public JsonObject getJson() { ++ return this.map; ++ } ++ ++ @Override ++ public int size() { ++ return this.map.entrySet().size(); ++ } ++ ++ @Override ++ public boolean isEmpty() { ++ return this.map.entrySet().isEmpty(); ++ } ++ ++ @Override ++ public void clear() { ++ this.map.entrySet().clear(); ++ } ++ ++ @Override ++ public Set keys() { ++ // ah shit. no keyset method ++ final Set keys = new LinkedHashSet<>(); ++ ++ for (final Map.Entry entry : this.map.entrySet()) { ++ keys.add(entry.getKey()); ++ } ++ ++ return keys; ++ } ++ ++ @Override ++ public MapType copy() { ++ return new JsonMapType(this.map.deepCopy(), this.compressed); ++ } ++ ++ @Override ++ public boolean hasKey(final String key) { ++ return this.map.has(key); ++ } ++ ++ @Override ++ public boolean hasKey(final String key, final ObjectType type) { ++ final JsonElement element = this.map.get(key); ++ if (element == null) { ++ return false; ++ } ++ ++ if (type == ObjectType.UNDEFINED) { ++ return true; ++ } ++ ++ if (element.isJsonArray()) { ++ return type == ObjectType.LIST; ++ } else if (element.isJsonObject()) { ++ return type == ObjectType.MAP; ++ } else if (element.isJsonNull()) { ++ return false; ++ } ++ ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isString()) { ++ return type == ObjectType.STRING || (this.compressed && type == ObjectType.NUMBER); ++ } else if (primitive.isBoolean()) { ++ return type.isNumber(); ++ } else { ++ // is number ++ final Number number = primitive.getAsNumber(); ++ if (number instanceof Byte) { ++ return type == ObjectType.BYTE || (this.compressed && type == ObjectType.STRING); ++ } else if (number instanceof Short) { ++ return type == ObjectType.SHORT || (this.compressed && type == ObjectType.STRING); ++ } else if (number instanceof Integer) { ++ return type == ObjectType.INT || (this.compressed && type == ObjectType.STRING); ++ } else if (number instanceof Long) { ++ return type == ObjectType.LONG || (this.compressed && type == ObjectType.STRING); ++ } else if (number instanceof Float) { ++ return type == ObjectType.FLOAT || (this.compressed && type == ObjectType.STRING); ++ } else { ++ return type == ObjectType.DOUBLE || (this.compressed && type == ObjectType.STRING); ++ } ++ } ++ } ++ ++ @Override ++ public void remove(final String key) { ++ this.map.remove(key); ++ } ++ ++ @Override ++ public Object getGeneric(final String key) { ++ final JsonElement element = this.map.get(key); ++ if (element == null || element.isJsonNull()) { ++ return null; ++ } else if (element.isJsonObject()) { ++ return new JsonMapType((JsonObject)element, this.compressed); ++ } else if (element.isJsonArray()) { ++ return new JsonListType((JsonArray)element, this.compressed); ++ } else { ++ // primitive ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isNumber()) { ++ return primitive.getAsNumber(); ++ } else if (primitive.isString()) { ++ return primitive.getAsString(); ++ } else if (primitive.isBoolean()) { ++ return Boolean.valueOf(primitive.getAsBoolean()); ++ } else { ++ throw new IllegalStateException("Unknown json object " + element); ++ } ++ } ++ } ++ ++ @Override ++ public Number getNumber(final String key) { ++ return this.getNumber(key, null); ++ } ++ ++ @Override ++ public Number getNumber(final String key, final Number dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isNumber()) { ++ return primitive.getAsNumber(); ++ } else if (primitive.isBoolean()) { ++ return primitive.getAsBoolean() ? Byte.valueOf((byte)1) : Byte.valueOf((byte)0); ++ } else if (this.compressed && primitive.isString()) { ++ try { ++ return Integer.valueOf(Integer.parseInt(primitive.getAsString())); ++ } catch (final NumberFormatException ex) { ++ return null; ++ } ++ } ++ } ++ ++ return dfl; ++ } ++ ++ @Override ++ public boolean getBoolean(final String key) { ++ return this.getBoolean(key, false); ++ } ++ ++ @Override ++ public boolean getBoolean(final String key, final boolean dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isNumber()) { ++ return primitive.getAsNumber().byteValue() != 0; ++ } else if (primitive.isBoolean()) { ++ return primitive.getAsBoolean(); ++ } ++ } ++ ++ return dfl; ++ } ++ ++ @Override ++ public void setBoolean(final String key, final boolean val) { ++ this.map.addProperty(key, Boolean.valueOf(val)); ++ } ++ ++ @Override ++ public byte getByte(final String key) { ++ return this.getByte(key, (byte)0); ++ } ++ ++ @Override ++ public byte getByte(final String key, final byte dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.byteValue(); ++ } ++ ++ @Override ++ public void setByte(final String key, final byte val) { ++ this.map.addProperty(key, Byte.valueOf(val)); ++ } ++ ++ @Override ++ public short getShort(final String key) { ++ return this.getShort(key, (short)0); ++ } ++ ++ @Override ++ public short getShort(final String key, final short dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.shortValue(); ++ } ++ ++ @Override ++ public void setShort(final String key, final short val) { ++ this.map.addProperty(key, Short.valueOf(val)); ++ } ++ ++ @Override ++ public int getInt(final String key) { ++ return this.getInt(key, 0); ++ } ++ ++ @Override ++ public int getInt(final String key, final int dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.intValue(); ++ } ++ ++ @Override ++ public void setInt(final String key, final int val) { ++ this.map.addProperty(key, Integer.valueOf(val)); ++ } ++ ++ @Override ++ public long getLong(final String key) { ++ return this.getLong(key, 0L); ++ } ++ ++ @Override ++ public long getLong(final String key, final long dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.longValue(); ++ } ++ ++ @Override ++ public void setLong(final String key, final long val) { ++ this.map.addProperty(key, Long.valueOf(val)); ++ } ++ ++ @Override ++ public float getFloat(final String key) { ++ return this.getFloat(key, 0.0F); ++ } ++ ++ @Override ++ public float getFloat(final String key, final float dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.floatValue(); ++ } ++ ++ @Override ++ public void setFloat(final String key, final float val) { ++ this.map.addProperty(key, Float.valueOf(val)); ++ } ++ ++ @Override ++ public double getDouble(final String key) { ++ return this.getDouble(key, 0.0D); ++ } ++ ++ @Override ++ public double getDouble(final String key, final double dfl) { ++ final Number ret = this.getNumber(key, null); ++ return ret == null ? dfl : ret.doubleValue(); ++ } ++ ++ @Override ++ public void setDouble(final String key, final double val) { ++ this.map.addProperty(key, Double.valueOf(val)); ++ } ++ ++ @Override ++ public byte[] getBytes(final String key) { ++ return this.getBytes(key, null); ++ } ++ ++ @Override ++ public byte[] getBytes(final String key, final byte[] dfl) { ++ return dfl; ++ } ++ ++ @Override ++ public void setBytes(final String key, final byte[] val) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public short[] getShorts(final String key) { ++ return this.getShorts(key, null); ++ } ++ ++ @Override ++ public short[] getShorts(final String key, final short[] dfl) { ++ return dfl; ++ } ++ ++ @Override ++ public void setShorts(final String key, final short[] val) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int[] getInts(final String key) { ++ return this.getInts(key, null); ++ } ++ ++ @Override ++ public int[] getInts(final String key, final int[] dfl) { ++ return dfl; ++ } ++ ++ @Override ++ public void setInts(final String key, final int[] val) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public long[] getLongs(final String key) { ++ return this.getLongs(key, null); ++ } ++ ++ @Override ++ public long[] getLongs(final String key, final long[] dfl) { ++ return dfl; ++ } ++ ++ @Override ++ public void setLongs(final String key, final long[] val) { ++ // JSON does not support raw primitive arrays ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public ListType getListUnchecked(final String key) { ++ return this.getListUnchecked(key, null); ++ } ++ ++ @Override ++ public ListType getListUnchecked(final String key, final ListType dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonArray) { ++ return new JsonListType((JsonArray)element, this.compressed); ++ } ++ ++ return dfl; ++ } ++ ++ @Override ++ public void setList(final String key, final ListType val) { ++ this.map.add(key, ((JsonListType)val).getJson()); ++ } ++ ++ @Override ++ public MapType getMap(final String key) { ++ return this.getMap(key, null); ++ } ++ ++ @Override ++ public MapType getMap(final String key, final MapType dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonObject) { ++ return new JsonMapType((JsonObject)element, this.compressed); ++ } ++ ++ return dfl; ++ } ++ ++ @Override ++ public void setMap(final String key, final MapType val) { ++ this.map.add(key, ((JsonMapType)val).map); ++ } ++ ++ @Override ++ public String getString(final String key) { ++ return this.getString(key, null); ++ } ++ ++ @Override ++ public String getString(final String key, final String dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isString()) { ++ return primitive.getAsString(); ++ } else if (this.compressed && primitive.isNumber()) { ++ return primitive.getAsString(); ++ } ++ } ++ ++ return dfl; ++ } ++ ++ public String getForcedString(final String key) { ++ return this.getForcedString(key, null); ++ } ++ ++ public String getForcedString(final String key, final String dfl) { ++ final JsonElement element = this.map.get(key); ++ if (element instanceof JsonPrimitive) { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isString()) { ++ return primitive.getAsString(); ++ } else if (primitive.isNumber()) { ++ return primitive.getAsString(); ++ } ++ ++ return primitive.toString(); ++ } else if (element != null) { ++ return element.toString(); ++ } ++ ++ return dfl; ++ } ++ ++ @Override ++ public void setString(final String key, final String val) { ++ this.map.addProperty(key, val); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/json/JsonTypeUtil.java b/ca/spottedleaf/dataconverter/types/json/JsonTypeUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..d96808060623f73b08dec8eb6d6fdfca4d309d16 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/json/JsonTypeUtil.java +@@ -0,0 +1,189 @@ ++package ca.spottedleaf.dataconverter.types.json; ++ ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.CopyHelper; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import com.google.gson.JsonArray; ++import com.google.gson.JsonElement; ++import com.google.gson.JsonNull; ++import com.google.gson.JsonObject; ++import com.google.gson.JsonPrimitive; ++import java.math.BigDecimal; ++import java.util.Map; ++ ++public final class JsonTypeUtil implements TypeUtil { ++ ++ private final boolean compressed; ++ ++ public JsonTypeUtil(final boolean compressed) { ++ this.compressed = compressed; ++ } ++ ++ public boolean isCompressed() { ++ return this.compressed; ++ } ++ ++ @Override ++ public ListType createEmptyList() { ++ return new JsonListType(this.compressed); ++ } ++ ++ @Override ++ public MapType createEmptyMap() { ++ return new JsonMapType(this.compressed); ++ } ++ ++ @Override ++ public Object convertTo(final Object valueGeneric, final TypeUtil to) { ++ if (valueGeneric == null || valueGeneric instanceof String || valueGeneric instanceof Boolean) { ++ return valueGeneric; ++ } ++ if (valueGeneric instanceof Number number) { ++ if (CopyHelper.sanitizeNumber(number) == null) { ++ throw new IllegalStateException("Unknown type: " + number); ++ } ++ return number; ++ } ++ if (valueGeneric instanceof JsonListType listType) { ++ return convertJson(to, listType.array, this.compressed); // override input compression ++ } ++ if (valueGeneric instanceof JsonMapType mapType) { ++ return convertJson(to, mapType.map, this.compressed); // override input compression ++ } ++ throw new IllegalStateException("Unknown type: " + valueGeneric); ++ } ++ ++ @Override ++ public Object convertFromBaseToGeneric(final JsonElement input, final TypeUtil to) { ++ return convertJsonToGeneric(to, input, this.compressed); ++ } ++ ++ @Override ++ public Object baseToGeneric(final JsonElement input) { ++ if (input == null) { ++ return null; ++ } ++ if (input instanceof JsonObject jsonObject) { ++ return new JsonMapType(jsonObject, this.compressed); ++ } else if (input instanceof JsonArray array) { ++ return new JsonListType(array, this.compressed); ++ } else if (input instanceof JsonNull) { ++ return null; ++ } else { ++ final JsonPrimitive primitive = (JsonPrimitive)input; ++ if (primitive.isBoolean()) { ++ return Boolean.valueOf(primitive.getAsBoolean()); ++ } else if (primitive.isNumber()) { ++ final Number number = CopyHelper.sanitizeNumber(primitive.getAsNumber()); ++ return number != null ? number : convertBDToGeneric(primitive.getAsBigDecimal()); ++ } else if (primitive.isString()) { ++ return primitive.getAsString(); ++ } ++ } ++ ++ throw new IllegalStateException("Unrecognized type " + input); ++ } ++ ++ @Override ++ public JsonElement genericToBase(final Object input) { ++ if (input == null) { ++ return JsonNull.INSTANCE; ++ } else if (input instanceof JsonMapType mapType) { ++ return mapType.map; ++ } else if (input instanceof JsonListType listType) { ++ return listType.array; ++ } else if (input instanceof Boolean bool) { ++ return new JsonPrimitive(bool); ++ } else if (input instanceof Number number) { ++ return new JsonPrimitive(number); ++ } else if (input instanceof String string) { ++ return new JsonPrimitive(string); ++ } ++ ++ throw new IllegalStateException("Unrecognized type " + input); ++ } ++ ++ private static Number convertBDToGeneric(final BigDecimal input) { ++ try { ++ final long l = input.longValueExact(); ++ final byte b = (byte)l; ++ final short s = (short)l; ++ final int i = (int)l; ++ ++ if ((long)b == l) { ++ return Byte.valueOf(b); ++ } ++ if ((long)s == l) { ++ return Short.valueOf(s); ++ } ++ if ((long)i == l) { ++ return Integer.valueOf(i); ++ } ++ ++ return Long.valueOf(l); ++ } catch (final ArithmeticException ex) { ++ final double d = input.doubleValue(); // possibly lose precision! ++ final float f = (float)d; ++ ++ return (double)f == d ? Float.valueOf(f) : Double.valueOf(d); ++ } ++ } ++ ++ private static Object convertJsonToGeneric(final TypeUtil to, final JsonElement element, final boolean compressed) { ++ if (element == null) { ++ return null; ++ } ++ if (element instanceof JsonObject jsonObject) { ++ return convertJson(to, jsonObject, compressed); ++ } else if (element instanceof JsonArray array) { ++ return convertJson(to, array, compressed); ++ } else if (element instanceof JsonNull) { ++ return null; ++ } else { ++ final JsonPrimitive primitive = (JsonPrimitive)element; ++ if (primitive.isBoolean()) { ++ return Boolean.valueOf(primitive.getAsBoolean()); ++ } else if (primitive.isNumber()) { ++ final Number number = CopyHelper.sanitizeNumber(primitive.getAsNumber()); ++ return number != null ? number : convertBDToGeneric(primitive.getAsBigDecimal()); ++ } else if (primitive.isString()) { ++ return primitive.getAsString(); ++ } ++ } ++ ++ throw new IllegalStateException("Unrecognized type " + element); ++ } ++ ++ private static MapType convertJson(final TypeUtil to, final JsonObject json, final boolean compressed) { ++ final MapType ret = to.createEmptyMap(); ++ for (final Map.Entry entry : json.entrySet()) { ++ final Object obj = convertJsonToGeneric(to, entry.getValue(), compressed); ++ if (obj == null) { ++ continue; ++ } ++ ++ ret.setGeneric(entry.getKey(), obj); ++ } ++ ++ return ret; ++ } ++ ++ private static ListType convertJson(final TypeUtil to, final JsonArray json, final boolean compressed) { ++ final ListType ret = to.createEmptyList(); ++ ++ for (int i = 0, len = json.size(); i < len; ++i) { ++ ret.addGeneric(convertJsonToGeneric(to, json.get(i), compressed)); ++ } ++ ++ return ret; ++ } ++ ++ private static MapType convertJson(final TypeUtil to, final JsonMapType json) { ++ return convertJson(to, json.map, json.compressed); ++ } ++ ++ private static ListType convertJson(final TypeUtil to, final JsonListType json) { ++ return convertJson(to, json.array, json.compressed); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/nbt/NBTListType.java b/ca/spottedleaf/dataconverter/types/nbt/NBTListType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b4882e90c8845694032e4a43e75bbf35c5eed873 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/nbt/NBTListType.java +@@ -0,0 +1,582 @@ ++package ca.spottedleaf.dataconverter.types.nbt; ++ ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.Types; ++import net.minecraft.nbt.ByteArrayTag; ++import net.minecraft.nbt.ByteTag; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.DoubleTag; ++import net.minecraft.nbt.FloatTag; ++import net.minecraft.nbt.IntArrayTag; ++import net.minecraft.nbt.IntTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.LongArrayTag; ++import net.minecraft.nbt.LongTag; ++import net.minecraft.nbt.NumericTag; ++import net.minecraft.nbt.ShortTag; ++import net.minecraft.nbt.StringTag; ++import net.minecraft.nbt.Tag; ++ ++public final class NBTListType implements ListType { ++ ++ final ListTag list; ++ ++ public NBTListType() { ++ this.list = new ListTag(); ++ } ++ ++ public NBTListType(final ListTag tag) { ++ this.list = tag; ++ } ++ ++ @Override ++ public TypeUtil getTypeUtil() { ++ return Types.NBT; ++ } ++ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } ++ if (obj == null || obj.getClass() != NBTListType.class) { ++ return false; ++ } ++ ++ return this.list.equals(((NBTListType)obj).list); ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.list.hashCode(); ++ } ++ ++ @Override ++ public String toString() { ++ return "NBTListType{" + ++ "list=" + this.list + ++ '}'; ++ } ++ ++ public ListTag getTag() { ++ return this.list; ++ } ++ ++ @Override ++ public ListType copy() { ++ return new NBTListType(this.list.copy()); ++ } ++ ++ static ObjectType getType(final byte id) { ++ switch (id) { ++ case Tag.TAG_END: ++ return ObjectType.NONE; ++ case Tag.TAG_BYTE: ++ return ObjectType.BYTE; ++ case Tag.TAG_SHORT: ++ return ObjectType.SHORT; ++ case Tag.TAG_INT: ++ return ObjectType.INT; ++ case Tag.TAG_LONG: ++ return ObjectType.LONG; ++ case Tag.TAG_FLOAT: ++ return ObjectType.FLOAT; ++ case Tag.TAG_DOUBLE: ++ return ObjectType.DOUBLE; ++ case Tag.TAG_BYTE_ARRAY: ++ return ObjectType.BYTE_ARRAY; ++ case Tag.TAG_STRING: ++ return ObjectType.STRING; ++ case Tag.TAG_LIST: ++ return ObjectType.LIST; ++ case Tag.TAG_COMPOUND: ++ return ObjectType.MAP; ++ case Tag.TAG_INT_ARRAY: ++ return ObjectType.INT_ARRAY; ++ case Tag.TAG_LONG_ARRAY: ++ return ObjectType.LONG_ARRAY; ++ default: ++ throw new IllegalStateException("Unknown type: " + id); ++ } ++ } ++ ++ @Override ++ public ObjectType getUniformType() { ++ ObjectType curr = null; ++ ++ for (int i = 0, len = this.list.size(); i < len; ++i) { ++ final Tag tag = this.list.get(i); ++ final ObjectType tagType = getType(tag.getId()); ++ if (curr == null) { ++ curr = tagType; ++ } else if (tagType != curr) { ++ return ObjectType.MIXED; ++ } ++ } ++ ++ return curr == null ? ObjectType.NONE : curr; ++ } ++ ++ @Override ++ public int size() { ++ return this.list.size(); ++ } ++ ++ @Override ++ public void remove(final int index) { ++ this.list.remove(index); ++ } ++ ++ @Override ++ public Object getGeneric(final int index) { ++ return Types.NBT.baseToGeneric(this.list.get(index)); ++ } ++ ++ @Override ++ public Number getNumber(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.box(); ++ } ++ ++ @Override ++ public Number getNumber(final int index, final Number dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.box(); ++ } ++ ++ @Override ++ public byte getByte(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.byteValue(); ++ } ++ ++ @Override ++ public byte getByte(final int index, final byte dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.byteValue(); ++ } ++ ++ @Override ++ public void setByte(final int index, final byte to) { ++ this.list.set(index, ByteTag.valueOf(to)); ++ } ++ ++ @Override ++ public short getShort(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.shortValue(); ++ } ++ ++ @Override ++ public short getShort(final int index, final short dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.shortValue(); ++ } ++ ++ @Override ++ public void setShort(final int index, final short to) { ++ this.list.set(index, ShortTag.valueOf(to)); ++ } ++ ++ @Override ++ public int getInt(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.intValue(); ++ } ++ ++ @Override ++ public int getInt(final int index, final int dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.intValue(); ++ } ++ ++ @Override ++ public void setInt(final int index, final int to) { ++ this.list.set(index, IntTag.valueOf(to)); ++ } ++ ++ @Override ++ public long getLong(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.longValue(); ++ } ++ ++ @Override ++ public long getLong(final int index, final long dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.longValue(); ++ } ++ ++ @Override ++ public void setLong(final int index, final long to) { ++ this.list.set(index, LongTag.valueOf(to)); ++ } ++ ++ @Override ++ public float getFloat(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.floatValue(); ++ } ++ ++ @Override ++ public float getFloat(final int index, final float dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.floatValue(); ++ } ++ ++ @Override ++ public void setFloat(final int index, final float to) { ++ this.list.set(index, FloatTag.valueOf(to)); ++ } ++ ++ @Override ++ public double getDouble(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ throw new IllegalStateException(); ++ } ++ return numericTag.doubleValue(); ++ } ++ ++ @Override ++ public double getDouble(final int index, final double dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof NumericTag numericTag)) { ++ return dfl; ++ } ++ return numericTag.doubleValue(); ++ } ++ ++ @Override ++ public void setDouble(final int index, final double to) { ++ this.list.set(index, DoubleTag.valueOf(to)); ++ } ++ ++ @Override ++ public byte[] getBytes(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof ByteArrayTag bytes)) { ++ throw new IllegalStateException(); ++ } ++ return bytes.getAsByteArray(); ++ } ++ ++ ++ @Override ++ public byte[] getBytes(final int index, final byte[] dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof ByteArrayTag bytes)) { ++ return dfl; ++ } ++ return bytes.getAsByteArray(); ++ } ++ ++ @Override ++ public void setBytes(final int index, final byte[] to) { ++ this.list.set(index, new ByteArrayTag(to)); ++ } ++ ++ @Override ++ public short[] getShorts(final int index) { ++ // NBT does not support shorts ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public short[] getShorts(final int index, final short[] dfl) { ++ // NBT does not support shorts ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void setShorts(final int index, final short[] to) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int[] getInts(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof IntArrayTag ints)) { ++ throw new IllegalStateException(); ++ } ++ return ints.getAsIntArray(); ++ } ++ ++ @Override ++ public int[] getInts(final int index, final int[] dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof IntArrayTag ints)) { ++ return dfl; ++ } ++ return ints.getAsIntArray(); ++ } ++ ++ @Override ++ public void setInts(final int index, final int[] to) { ++ this.list.set(index, new IntArrayTag(to)); ++ } ++ ++ @Override ++ public long[] getLongs(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof LongArrayTag longs)) { ++ throw new IllegalStateException(); ++ } ++ return longs.getAsLongArray(); ++ } ++ ++ @Override ++ public long[] getLongs(final int index, final long[] dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof LongArrayTag longs)) { ++ return dfl; ++ } ++ return longs.getAsLongArray(); ++ } ++ ++ @Override ++ public void setLongs(final int index, final long[] to) { ++ this.list.set(index, new LongArrayTag(to)); ++ } ++ ++ @Override ++ public ListType getList(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof ListTag list)) { ++ throw new IllegalStateException(); ++ } ++ return new NBTListType(list); ++ } ++ ++ @Override ++ public ListType getList(final int index, final ListType dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof ListTag list)) { ++ return dfl; ++ } ++ return new NBTListType(list); ++ } ++ ++ @Override ++ public void setList(final int index, final ListType list) { ++ this.list.set(index, ((NBTListType)list).getTag()); ++ } ++ ++ @Override ++ public MapType getMap(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof CompoundTag compoundTag)) { ++ throw new IllegalStateException(); ++ } ++ return new NBTMapType(compoundTag); ++ } ++ ++ @Override ++ public MapType getMap(final int index, final MapType dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof CompoundTag compoundTag)) { ++ return dfl; ++ } ++ return new NBTMapType(compoundTag); ++ } ++ ++ @Override ++ public void setMap(final int index, final MapType to) { ++ this.list.set(index, ((NBTMapType)to).getTag()); ++ } ++ ++ @Override ++ public String getString(final int index) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof StringTag stringTag)) { ++ throw new IllegalStateException(); ++ } ++ return stringTag.value(); ++ } ++ ++ ++ @Override ++ public String getString(final int index, final String dfl) { ++ final Tag tag = this.list.get(index); // does bound checking for us ++ if (!(tag instanceof StringTag stringTag)) { ++ return dfl; ++ } ++ return stringTag.value(); ++ } ++ ++ @Override ++ public void setString(final int index, final String to) { ++ this.list.set(index, StringTag.valueOf(to)); ++ } ++ ++ @Override ++ public void addByte(final byte b) { ++ this.list.add(ByteTag.valueOf(b)); ++ } ++ ++ @Override ++ public void addByte(final int index, final byte b) { ++ this.list.add(index, ByteTag.valueOf(b)); ++ } ++ ++ @Override ++ public void addShort(final short s) { ++ this.list.add(ShortTag.valueOf(s)); ++ } ++ ++ @Override ++ public void addShort(final int index, final short s) { ++ this.list.add(index, ShortTag.valueOf(s)); ++ } ++ ++ @Override ++ public void addInt(final int i) { ++ this.list.add(IntTag.valueOf(i)); ++ } ++ ++ @Override ++ public void addInt(final int index, final int i) { ++ this.list.add(index, IntTag.valueOf(i)); ++ } ++ ++ @Override ++ public void addLong(final long l) { ++ this.list.add(LongTag.valueOf(l)); ++ } ++ ++ @Override ++ public void addLong(final int index, final long l) { ++ this.list.add(index, LongTag.valueOf(l)); ++ } ++ ++ @Override ++ public void addFloat(final float f) { ++ this.list.add(FloatTag.valueOf(f)); ++ } ++ ++ @Override ++ public void addFloat(final int index, final float f) { ++ this.list.add(index, FloatTag.valueOf(f)); ++ } ++ ++ @Override ++ public void addDouble(final double d) { ++ this.list.add(DoubleTag.valueOf(d)); ++ } ++ ++ @Override ++ public void addDouble(final int index, final double d) { ++ this.list.add(index, DoubleTag.valueOf(d)); ++ } ++ ++ @Override ++ public void addByteArray(final byte[] arr) { ++ this.list.add(new ByteArrayTag(arr)); ++ } ++ ++ @Override ++ public void addByteArray(final int index, final byte[] arr) { ++ this.list.add(index, new ByteArrayTag(arr)); ++ } ++ ++ @Override ++ public void addShortArray(final short[] arr) { ++ // NBT does not support short[] ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addShortArray(final int index, final short[] arr) { ++ // NBT does not support short[] ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public void addIntArray(final int[] arr) { ++ this.list.add(new IntArrayTag(arr)); ++ } ++ ++ @Override ++ public void addIntArray(final int index, final int[] arr) { ++ this.list.add(index, new IntArrayTag(arr)); ++ } ++ ++ @Override ++ public void addLongArray(final long[] arr) { ++ this.list.add(new LongArrayTag(arr)); ++ } ++ ++ @Override ++ public void addLongArray(final int index, final long[] arr) { ++ this.list.add(index, new LongArrayTag(arr)); ++ } ++ ++ @Override ++ public void addList(final ListType list) { ++ this.list.add(((NBTListType)list).getTag()); ++ } ++ ++ @Override ++ public void addList(final int index, final ListType list) { ++ this.list.add(index, ((NBTListType)list).getTag()); ++ } ++ ++ @Override ++ public void addMap(final MapType map) { ++ this.list.add(((NBTMapType)map).getTag()); ++ } ++ ++ @Override ++ public void addMap(final int index, final MapType map) { ++ this.list.add(index, ((NBTMapType)map).getTag()); ++ } ++ ++ @Override ++ public void addString(final String string) { ++ this.list.add(StringTag.valueOf(string)); ++ } ++ ++ @Override ++ public void addString(final int index, final String string) { ++ this.list.add(index, StringTag.valueOf(string)); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/nbt/NBTMapType.java b/ca/spottedleaf/dataconverter/types/nbt/NBTMapType.java +new file mode 100644 +index 0000000000000000000000000000000000000000..2558d9014e1daff6dd4a44ad85bbc0254c7de056 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/nbt/NBTMapType.java +@@ -0,0 +1,442 @@ ++package ca.spottedleaf.dataconverter.types.nbt; ++ ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.ObjectType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import ca.spottedleaf.dataconverter.types.Types; ++import net.minecraft.nbt.ByteArrayTag; ++import net.minecraft.nbt.ByteTag; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.IntArrayTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.LongArrayTag; ++import net.minecraft.nbt.NumericTag; ++import net.minecraft.nbt.StringTag; ++import net.minecraft.nbt.StringTagVisitor; ++import net.minecraft.nbt.Tag; ++ ++import java.util.Set; ++ ++public final class NBTMapType implements MapType { ++ ++ final CompoundTag map; ++ ++ public NBTMapType() { ++ this.map = new CompoundTag(); ++ } ++ ++ public NBTMapType(final CompoundTag tag) { ++ this.map = tag; ++ } ++ ++ @Override ++ public boolean equals(final Object obj) { ++ if (this == obj) { ++ return true; ++ } ++ if (obj == null || obj.getClass() != NBTMapType.class) { ++ return false; ++ } ++ ++ return this.map.equals(((NBTMapType)obj).map); ++ } ++ ++ @Override ++ public TypeUtil getTypeUtil() { ++ return Types.NBT; ++ } ++ ++ @Override ++ public int hashCode() { ++ return this.map.hashCode(); ++ } ++ ++ @Override ++ public String toString() { ++ return "NBTMapType{" + ++ "map=" + this.map + ++ '}'; ++ } ++ ++ @Override ++ public int size() { ++ return this.map.size(); ++ } ++ ++ @Override ++ public boolean isEmpty() { ++ return this.map.isEmpty(); ++ } ++ ++ @Override ++ public void clear() { ++ this.map.keySet().clear(); ++ } ++ ++ @Override ++ public Set keys() { ++ return this.map.keySet(); ++ } ++ ++ public CompoundTag getTag() { ++ return this.map; ++ } ++ ++ @Override ++ public MapType copy() { ++ return new NBTMapType(this.map.copy()); ++ } ++ ++ @Override ++ public boolean hasKey(final String key) { ++ return this.map.get(key) != null; ++ } ++ ++ @Override ++ public boolean hasKey(final String key, final ObjectType type) { ++ final Tag tag = this.map.get(key); ++ if (tag == null) { ++ return false; ++ } ++ ++ final ObjectType valueType = NBTListType.getType(tag.getId()); ++ ++ return valueType == type || (type == ObjectType.NUMBER && valueType.isNumber()); ++ } ++ ++ @Override ++ public void remove(final String key) { ++ this.map.remove(key); ++ } ++ ++ @Override ++ public Object getGeneric(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag == null) { ++ return null; ++ } ++ ++ switch (NBTListType.getType(tag.getId())) { ++ case BYTE: ++ case SHORT: ++ case INT: ++ case LONG: ++ case FLOAT: ++ case DOUBLE: ++ return ((NumericTag)tag).box(); ++ case MAP: ++ return new NBTMapType((CompoundTag)tag); ++ case LIST: ++ return new NBTListType((ListTag)tag); ++ case STRING: ++ return ((StringTag)tag).value(); ++ case BYTE_ARRAY: ++ return ((ByteArrayTag)tag).getAsByteArray(); ++ // Note: No short array tag! ++ case INT_ARRAY: ++ return ((IntArrayTag)tag).getAsIntArray(); ++ case LONG_ARRAY: ++ return ((LongArrayTag)tag).getAsLongArray(); ++ } ++ ++ throw new IllegalStateException("Unrecognized type " + tag); ++ } ++ ++ @Override ++ public Number getNumber(final String key) { ++ return this.getNumber(key, null); ++ } ++ ++ @Override ++ public Number getNumber(final String key, final Number dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numTag) { ++ return numTag.box(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public boolean getBoolean(final String key) { ++ return this.getByte(key) != 0; ++ } ++ ++ @Override ++ public boolean getBoolean(final String key, final boolean dfl) { ++ return this.getByte(key, dfl ? (byte)1 : (byte)0) != 0; ++ } ++ ++ @Override ++ public void setBoolean(final String key, final boolean val) { ++ this.setByte(key, val ? (byte)1 : (byte)0); ++ } ++ ++ @Override ++ public byte getByte(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.byteValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public byte getByte(final String key, final byte dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.byteValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setByte(final String key, final byte val) { ++ this.map.putByte(key, val); ++ } ++ ++ @Override ++ public short getShort(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.shortValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public short getShort(final String key, final short dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.shortValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setShort(final String key, final short val) { ++ this.map.putShort(key, val); ++ } ++ ++ @Override ++ public int getInt(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.intValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public int getInt(final String key, final int dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.intValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setInt(final String key, final int val) { ++ this.map.putInt(key, val); ++ } ++ ++ @Override ++ public long getLong(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.longValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public long getLong(final String key, final long dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.longValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setLong(final String key, final long val) { ++ this.map.putLong(key, val); ++ } ++ ++ @Override ++ public float getFloat(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.floatValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public float getFloat(final String key, final float dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.floatValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setFloat(final String key, final float val) { ++ this.map.putFloat(key, val); ++ } ++ ++ @Override ++ public double getDouble(final String key) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.doubleValue(); ++ } ++ return 0; ++ } ++ ++ @Override ++ public double getDouble(final String key, final double dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof NumericTag numericTag) { ++ return numericTag.doubleValue(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setDouble(final String key, final double val) { ++ this.map.putDouble(key, val); ++ } ++ ++ @Override ++ public byte[] getBytes(final String key) { ++ return this.getBytes(key, null); ++ } ++ ++ @Override ++ public byte[] getBytes(final String key, final byte[] dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof ByteArrayTag byteArrayTag) { ++ return byteArrayTag.getAsByteArray(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setBytes(final String key, final byte[] val) { ++ this.map.putByteArray(key, val); ++ } ++ ++ @Override ++ public short[] getShorts(final String key) { ++ return this.getShorts(key, null); ++ } ++ ++ @Override ++ public short[] getShorts(final String key, final short[] dfl) { ++ // NBT does not support short array ++ return dfl; ++ } ++ ++ @Override ++ public void setShorts(final String key, final short[] val) { ++ throw new UnsupportedOperationException(); ++ } ++ ++ @Override ++ public int[] getInts(final String key) { ++ return this.getInts(key, null); ++ } ++ ++ @Override ++ public int[] getInts(final String key, final int[] dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof IntArrayTag intArrayTag) { ++ return intArrayTag.getAsIntArray(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setInts(final String key, final int[] val) { ++ this.map.putIntArray(key, val); ++ } ++ ++ @Override ++ public long[] getLongs(final String key) { ++ return this.getLongs(key, null); ++ } ++ ++ @Override ++ public long[] getLongs(final String key, final long[] dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof LongArrayTag longArrayTag) { ++ return longArrayTag.getAsLongArray(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setLongs(final String key, final long[] val) { ++ this.map.putLongArray(key, val); ++ } ++ ++ @Override ++ public ListType getListUnchecked(final String key) { ++ return this.getListUnchecked(key, null); ++ } ++ ++ @Override ++ public ListType getListUnchecked(final String key, final ListType dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof ListTag listTag) { ++ return new NBTListType(listTag); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setList(final String key, final ListType val) { ++ this.map.put(key, ((NBTListType)val).getTag()); ++ } ++ ++ @Override ++ public MapType getMap(final String key) { ++ return this.getMap(key, null); ++ } ++ ++ @Override ++ public MapType getMap(final String key, final MapType dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof CompoundTag compoundTag) { ++ return new NBTMapType(compoundTag); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setMap(final String key, final MapType val) { ++ this.map.put(key, ((NBTMapType)val).getTag()); ++ } ++ ++ @Override ++ public String getString(final String key) { ++ return this.getString(key, null); ++ } ++ ++ @Override ++ public String getString(final String key, final String dfl) { ++ final Tag tag = this.map.get(key); ++ if (tag instanceof StringTag strTag) { ++ return strTag.value(); ++ } ++ return dfl; ++ } ++ ++ @Override ++ public void setString(final String key, final String val) { ++ this.map.putString(key, val); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/types/nbt/NBTTypeUtil.java b/ca/spottedleaf/dataconverter/types/nbt/NBTTypeUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..32d90fc5ab415b0261af8377b130404ad37e19ee +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/types/nbt/NBTTypeUtil.java +@@ -0,0 +1,136 @@ ++package ca.spottedleaf.dataconverter.types.nbt; ++ ++import ca.spottedleaf.dataconverter.minecraft.converters.helpers.CopyHelper; ++import ca.spottedleaf.dataconverter.types.ListType; ++import ca.spottedleaf.dataconverter.types.MapType; ++import ca.spottedleaf.dataconverter.types.TypeUtil; ++import net.minecraft.nbt.ByteArrayTag; ++import net.minecraft.nbt.ByteTag; ++import net.minecraft.nbt.CompoundTag; ++import net.minecraft.nbt.EndTag; ++import net.minecraft.nbt.IntArrayTag; ++import net.minecraft.nbt.IntTag; ++import net.minecraft.nbt.ListTag; ++import net.minecraft.nbt.LongArrayTag; ++import net.minecraft.nbt.LongTag; ++import net.minecraft.nbt.NumericTag; ++import net.minecraft.nbt.ShortTag; ++import net.minecraft.nbt.StringTag; ++import net.minecraft.nbt.Tag; ++ ++public final class NBTTypeUtil implements TypeUtil { ++ ++ @Override ++ public ListType createEmptyList() { ++ return new NBTListType(); ++ } ++ ++ @Override ++ public MapType createEmptyMap() { ++ return new NBTMapType(); ++ } ++ ++ @Override ++ public Object convertTo(final Object valueGeneric, final TypeUtil to) { ++ if (valueGeneric == null || valueGeneric instanceof String || valueGeneric instanceof Boolean) { ++ return valueGeneric; ++ } ++ if (valueGeneric instanceof Number number) { ++ if (CopyHelper.sanitizeNumber(number) == null) { ++ throw new IllegalStateException("Unknown type: " + number); ++ } ++ return number; ++ } ++ if (valueGeneric instanceof NBTListType listType) { ++ return convertNBT(to, listType.list); ++ } ++ if (valueGeneric instanceof NBTMapType mapType) { ++ return convertNBT(to, mapType.map); ++ } ++ throw new IllegalStateException("Unknown type: " + valueGeneric); ++ } ++ ++ @Override ++ public Object convertFromBaseToGeneric(final Tag input, final TypeUtil to) { ++ return convertNBTToGeneric(to, input); ++ } ++ ++ @Override ++ public Object baseToGeneric(final Tag input) { ++ return switch (input) { ++ case CompoundTag ct -> new NBTMapType(ct); ++ case ListTag lt -> new NBTListType(lt); ++ case EndTag endTag -> null; ++ case StringTag st -> st.value(); ++ case ByteArrayTag bt -> bt.getAsByteArray(); ++ case IntArrayTag it -> it.getAsIntArray(); ++ case LongArrayTag lt -> lt.getAsLongArray(); ++ case NumericTag nt -> nt.box(); ++ case null -> null; ++ default -> throw new IllegalStateException("Unknown tag: " + input); ++ }; ++ } ++ ++ @Override ++ public Tag genericToBase(final Object input) { ++ return switch (input) { ++ case null -> EndTag.INSTANCE; ++ case NBTMapType mapType -> mapType.map; ++ case NBTListType listType -> listType.list; ++ case String string -> StringTag.valueOf(string); ++ case Boolean bool -> ByteTag.valueOf(bool.booleanValue()); ++ case Byte b -> ByteTag.valueOf(b.byteValue()); ++ case Short s -> ShortTag.valueOf(s.shortValue()); ++ case Integer i -> IntTag.valueOf(i.intValue()); ++ case Long l -> LongTag.valueOf(l.longValue()); ++ case byte[] bytes -> new ByteArrayTag(bytes); ++ case int[] ints -> new IntArrayTag(ints); ++ case long[] longs -> new LongArrayTag(longs); ++ ++ default -> throw new IllegalStateException("Unrecognized type " + input); ++ }; ++ } ++ ++ private static Object convertNBTToGeneric(final TypeUtil to, final Tag nbt) { ++ return switch (nbt) { ++ case CompoundTag ct -> convertNBT(to, ct); ++ case ListTag lt -> convertNBT(to, lt); ++ case EndTag endTag -> null; ++ case StringTag st -> st.value(); ++ case ByteArrayTag bt -> bt.getAsByteArray(); ++ case IntArrayTag it -> it.getAsIntArray(); ++ case LongArrayTag lt -> lt.getAsLongArray(); ++ case NumericTag nt -> nt.box(); ++ case null -> null; ++ default -> throw new IllegalStateException("Unknown tag: " + nbt); ++ }; ++ } ++ ++ public static MapType convertNBT(final TypeUtil to, final CompoundTag nbt) { ++ final MapType ret = to.createEmptyMap(); ++ ++ for (final String key : nbt.keySet()) { ++ ret.setGeneric(key, convertNBTToGeneric(to, nbt.get(key))); ++ } ++ ++ return ret; ++ } ++ ++ public static ListType convertNBT(final TypeUtil to, final ListTag nbt) { ++ final ListType ret = to.createEmptyList(); ++ ++ for (int i = 0, len = nbt.size(); i < len; ++i) { ++ ret.addGeneric(convertNBTToGeneric(to, nbt.get(i))); ++ } ++ ++ return ret; ++ } ++ ++ public static MapType convertNBT(final TypeUtil to, final NBTMapType nbt) { ++ return convertNBT(to, nbt.map); ++ } ++ ++ public static ListType convertNBT(final TypeUtil to, final NBTListType nbt) { ++ return convertNBT(to, nbt.list); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/Int2IntArraySortedMap.java b/ca/spottedleaf/dataconverter/util/Int2IntArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6596de3d9ebae583c252aa061f0cfdf8778ea1a5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/Int2IntArraySortedMap.java +@@ -0,0 +1,77 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++import it.unimi.dsi.fastutil.ints.Int2IntFunction; ++ ++import java.util.Arrays; ++ ++public class Int2IntArraySortedMap { ++ ++ protected int[] key; ++ protected int[] val; ++ protected int size; ++ ++ public Int2IntArraySortedMap() { ++ this.key = new int[8]; ++ this.val = new int[8]; ++ } ++ ++ public int put(final int key, final int value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final int current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return 0; ++ } ++ ++ public int computeIfAbsent(final int key, final Int2IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public int get(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return 0; ++ } ++ return this.val[index]; ++ } ++ ++ public int getFloor(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? 0 : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/Int2ObjectArraySortedMap.java b/ca/spottedleaf/dataconverter/util/Int2ObjectArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..de9d632489609136c712a9adaee941fd38fad440 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/Int2ObjectArraySortedMap.java +@@ -0,0 +1,74 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++import java.util.Arrays; ++import java.util.function.IntFunction; ++ ++public class Int2ObjectArraySortedMap { ++ ++ protected int[] key; ++ protected V[] val; ++ protected int size; ++ ++ public Int2ObjectArraySortedMap() { ++ this.key = new int[8]; ++ this.val = (V[])new Object[8]; ++ } ++ ++ public V put(final int key, final V value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final V current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return null; ++ } ++ ++ public V computeIfAbsent(final int key, final IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public V get(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return null; ++ } ++ return this.val[index]; ++ } ++ ++ public V getFloor(final int key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1); ++ return this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/IntegerUtil.java b/ca/spottedleaf/dataconverter/util/IntegerUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..4bbf38c812feeb30d2aa5f3fcf482bfcbed79d05 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/IntegerUtil.java +@@ -0,0 +1,239 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++public final class IntegerUtil { ++ public static final int HIGH_BIT_U32 = Integer.MIN_VALUE; ++ public static final long HIGH_BIT_U64 = Long.MIN_VALUE; ++ ++ public static int ceilLog2(final int value) { ++ return Integer.SIZE - Integer.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros ++ } ++ ++ public static long ceilLog2(final long value) { ++ return Long.SIZE - Long.numberOfLeadingZeros(value - 1); // see doc of numberOfLeadingZeros ++ } ++ ++ public static int floorLog2(final int value) { ++ // xor is optimized subtract for 2^n -1 ++ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) ++ return (Integer.SIZE - 1) ^ Integer.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros ++ } ++ ++ public static int floorLog2(final long value) { ++ // xor is optimized subtract for 2^n -1 ++ // note that (2^n -1) - k = (2^n -1) ^ k for k <= (2^n - 1) ++ return (Long.SIZE - 1) ^ Long.numberOfLeadingZeros(value); // see doc of numberOfLeadingZeros ++ } ++ ++ public static int roundCeilLog2(final int value) { ++ // optimized variant of 1 << (32 - leading(val - 1)) ++ // given ++ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) ++ // 1 << (32 - leading(val - 1)) = HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) ++ // HIGH_BIT_32 >>> (31 - (32 - leading(val - 1))) ++ // HIGH_BIT_32 >>> (31 - 32 + leading(val - 1)) ++ // HIGH_BIT_32 >>> (-1 + leading(val - 1)) ++ return HIGH_BIT_U32 >>> (Integer.numberOfLeadingZeros(value - 1) - 1); ++ } ++ ++ public static long roundCeilLog2(final long value) { ++ // see logic documented above ++ return HIGH_BIT_U64 >>> (Long.numberOfLeadingZeros(value - 1) - 1); ++ } ++ ++ public static int roundFloorLog2(final int value) { ++ // optimized variant of 1 << (31 - leading(val)) ++ // given ++ // 1 << n = HIGH_BIT_32 >>> (31 - n) for n [0, 32) ++ // 1 << (31 - leading(val)) = HIGH_BIT_32 >> (31 - (31 - leading(val))) ++ // HIGH_BIT_32 >> (31 - (31 - leading(val))) ++ // HIGH_BIT_32 >> (31 - 31 + leading(val)) ++ return HIGH_BIT_U32 >>> Integer.numberOfLeadingZeros(value); ++ } ++ ++ public static long roundFloorLog2(final long value) { ++ // see logic documented above ++ return HIGH_BIT_U64 >>> Long.numberOfLeadingZeros(value); ++ } ++ ++ public static boolean isPowerOfTwo(final int n) { ++ // 2^n has one bit ++ // note: this rets true for 0 still ++ return IntegerUtil.getTrailingBit(n) == n; ++ } ++ ++ public static boolean isPowerOfTwo(final long n) { ++ // 2^n has one bit ++ // note: this rets true for 0 still ++ return IntegerUtil.getTrailingBit(n) == n; ++ } ++ ++ public static int getTrailingBit(final int n) { ++ return -n & n; ++ } ++ ++ public static long getTrailingBit(final long n) { ++ return -n & n; ++ } ++ ++ public static int trailingZeros(final int n) { ++ return Integer.numberOfTrailingZeros(n); ++ } ++ ++ public static int trailingZeros(final long n) { ++ return Long.numberOfTrailingZeros(n); ++ } ++ ++ // from hacker's delight (signed division magic value) ++ public static int getDivisorMultiple(final long numbers) { ++ return (int)(numbers >>> 32); ++ } ++ ++ // from hacker's delight (signed division magic value) ++ public static int getDivisorShift(final long numbers) { ++ return (int)numbers; ++ } ++ ++ public static long getDivisorNumbers(final int d) { ++ final int ad = branchlessAbs(d); ++ ++ if (ad < 2) { ++ throw new IllegalArgumentException("|number| must be in [2, 2^31 -1], not: " + d); ++ } ++ ++ final int two31 = 0x80000000; ++ final long mask = 0xFFFFFFFFL; // mask for enforcing unsigned behaviour ++ ++ /* ++ Signed usage: ++ int number; ++ long magic = getDivisorNumbers(div); ++ long mul = magic >>> 32; ++ int sign = number >> 31; ++ int result = (int)(((long)number * mul) >>> magic) - sign; ++ */ ++ /* ++ Unsigned usage: ++ int number; ++ long magic = getDivisorNumbers(div); ++ long mul = magic >>> 32; ++ int result = (int)(((long)number * mul) >>> magic); ++ */ ++ ++ int p = 31; ++ ++ // all these variables are UNSIGNED! ++ int t = two31 + (d >>> 31); ++ int anc = t - 1 - (int)((t & mask)%ad); ++ int q1 = (int)((two31 & mask)/(anc & mask)); ++ int r1 = two31 - q1*anc; ++ int q2 = (int)((two31 & mask)/(ad & mask)); ++ int r2 = two31 - q2*ad; ++ int delta; ++ ++ do { ++ p = p + 1; ++ q1 = 2*q1; // Update q1 = 2**p/|nc|. ++ r1 = 2*r1; // Update r1 = rem(2**p, |nc|). ++ if ((r1 & mask) >= (anc & mask)) {// (Must be an unsigned comparison here) ++ q1 = q1 + 1; ++ r1 = r1 - anc; ++ } ++ q2 = 2*q2; // Update q2 = 2**p/|d|. ++ r2 = 2*r2; // Update r2 = rem(2**p, |d|). ++ if ((r2 & mask) >= (ad & mask)) {// (Must be an unsigned comparison here) ++ q2 = q2 + 1; ++ r2 = r2 - ad; ++ } ++ delta = ad - r2; ++ } while ((q1 & mask) < (delta & mask) || (q1 == delta && r1 == 0)); ++ ++ int magicNum = q2 + 1; ++ if (d < 0) { ++ magicNum = -magicNum; ++ } ++ int shift = p; ++ return ((long)magicNum << 32) | shift; ++ } ++ ++ public static int branchlessAbs(final int val) { ++ // -n = -1 ^ n + 1 ++ final int mask = val >> (Integer.SIZE - 1); // -1 if < 0, 0 if >= 0 ++ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 ++ } ++ ++ public static long branchlessAbs(final long val) { ++ // -n = -1 ^ n + 1 ++ final long mask = val >> (Long.SIZE - 1); // -1 if < 0, 0 if >= 0 ++ return (mask ^ val) - mask; // if val < 0, then (0 ^ val) - 0 else (-1 ^ val) + 1 ++ } ++ ++ //https://github.com/skeeto/hash-prospector for hash functions ++ ++ //score = ~590.47984224483832 ++ public static int hash0(int x) { ++ x *= 0x36935555; ++ x ^= x >>> 16; ++ return x; ++ } ++ ++ //score = ~310.01596637036749 ++ public static int hash1(int x) { ++ x ^= x >>> 15; ++ x *= 0x356aaaad; ++ x ^= x >>> 17; ++ return x; ++ } ++ ++ public static int hash2(int x) { ++ x ^= x >>> 16; ++ x *= 0x7feb352d; ++ x ^= x >>> 15; ++ x *= 0x846ca68b; ++ x ^= x >>> 16; ++ return x; ++ } ++ ++ public static int hash3(int x) { ++ x ^= x >>> 17; ++ x *= 0xed5ad4bb; ++ x ^= x >>> 11; ++ x *= 0xac4c1b51; ++ x ^= x >>> 15; ++ x *= 0x31848bab; ++ x ^= x >>> 14; ++ return x; ++ } ++ ++ //score = ~365.79959673201887 ++ public static long hash1(long x) { ++ x ^= x >>> 27; ++ x *= 0xb24924b71d2d354bL; ++ x ^= x >>> 28; ++ return x; ++ } ++ ++ //h2 hash ++ public static long hash2(long x) { ++ x ^= x >>> 32; ++ x *= 0xd6e8feb86659fd93L; ++ x ^= x >>> 32; ++ x *= 0xd6e8feb86659fd93L; ++ x ^= x >>> 32; ++ return x; ++ } ++ ++ public static long hash3(long x) { ++ x ^= x >>> 45; ++ x *= 0xc161abe5704b6c79L; ++ x ^= x >>> 41; ++ x *= 0xe3e5389aedbc90f7L; ++ x ^= x >>> 56; ++ x *= 0x1f9aba75a52db073L; ++ x ^= x >>> 53; ++ return x; ++ } ++ ++ private IntegerUtil() { ++ throw new RuntimeException(); ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/Long2IntArraySortedMap.java b/ca/spottedleaf/dataconverter/util/Long2IntArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..94705bb141b550589faa9a0408402d8636c61907 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/Long2IntArraySortedMap.java +@@ -0,0 +1,76 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++import it.unimi.dsi.fastutil.longs.Long2IntFunction; ++import java.util.Arrays; ++ ++public class Long2IntArraySortedMap { ++ ++ protected long[] key; ++ protected int[] val; ++ protected int size; ++ ++ public Long2IntArraySortedMap() { ++ this.key = new long[8]; ++ this.val = new int[8]; ++ } ++ ++ public int put(final long key, final int value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final int current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return 0; ++ } ++ ++ public int computeIfAbsent(final long key, final Long2IntFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public int get(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return 0; ++ } ++ return this.val[index]; ++ } ++ ++ public int getFloor(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? 0 : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/Long2ObjectArraySortedMap.java b/ca/spottedleaf/dataconverter/util/Long2ObjectArraySortedMap.java +new file mode 100644 +index 0000000000000000000000000000000000000000..6f634c8825589a23f46ad7b54354475c9a95bd1b +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/Long2ObjectArraySortedMap.java +@@ -0,0 +1,76 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++import java.util.Arrays; ++import java.util.function.LongFunction; ++ ++public class Long2ObjectArraySortedMap { ++ ++ protected long[] key; ++ protected V[] val; ++ protected int size; ++ ++ public Long2ObjectArraySortedMap() { ++ this.key = new long[8]; ++ this.val = (V[])new Object[8]; ++ } ++ ++ public V put(final long key, final V value) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ final V current = this.val[index]; ++ this.val[index] = value; ++ return current; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ this.val[insert] = value; ++ ++ return null; ++ } ++ ++ public V computeIfAbsent(final long key, final LongFunction producer) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index >= 0) { ++ return this.val[index]; ++ } ++ final int insert = -(index + 1); ++ // shift entries down ++ if (this.size >= this.val.length) { ++ this.key = Arrays.copyOf(this.key, this.key.length * 2); ++ this.val = Arrays.copyOf(this.val, this.val.length * 2); ++ } ++ System.arraycopy(this.key, insert, this.key, insert + 1, this.size - insert); ++ System.arraycopy(this.val, insert, this.val, insert + 1, this.size - insert); ++ ++this.size; ++ ++ this.key[insert] = key; ++ ++ return this.val[insert] = producer.apply(key); ++ } ++ ++ public V get(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ return null; ++ } ++ return this.val[index]; ++ } ++ ++ public V getFloor(final long key) { ++ final int index = Arrays.binarySearch(this.key, 0, this.size, key); ++ if (index < 0) { ++ final int insert = -(index + 1) - 1; ++ return insert < 0 ? null : this.val[insert]; ++ } ++ return this.val[index]; ++ } ++} +diff --git a/ca/spottedleaf/dataconverter/util/NamespaceUtil.java b/ca/spottedleaf/dataconverter/util/NamespaceUtil.java +new file mode 100644 +index 0000000000000000000000000000000000000000..b028017b9c44821a8a313a04e0b10f5d0610edd5 +--- /dev/null ++++ b/ca/spottedleaf/dataconverter/util/NamespaceUtil.java +@@ -0,0 +1,39 @@ ++package ca.spottedleaf.dataconverter.util; ++ ++import ca.spottedleaf.dataconverter.types.MapType; ++import net.minecraft.resources.ResourceLocation; ++ ++public final class NamespaceUtil { ++ ++ private NamespaceUtil() {} ++ ++ public static void enforceForPath(final MapType data, final String path) { ++ if (data == null) { ++ return; ++ } ++ ++ final String id = data.getString(path); ++ if (id != null) { ++ final String replace = NamespaceUtil.correctNamespaceOrNull(id); ++ if (replace != null) { ++ data.setString(path, replace); ++ } ++ } ++ } ++ ++ public static String correctNamespace(final String value) { ++ if (value == null) { ++ return null; ++ } ++ final ResourceLocation resourceLocation = ResourceLocation.tryParse(value); ++ return resourceLocation != null ? resourceLocation.toString() : value; ++ } ++ ++ public static String correctNamespaceOrNull(final String value) { ++ if (value == null) { ++ return null; ++ } ++ final String correct = correctNamespace(value); ++ return correct.equals(value) ? null : correct; ++ } ++} +diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java +index 0ced5a8990b9fa2bdda90eac0a1c7ab27effe0e9..3b97e8d90327d6fcb4c4149a1107f79ee8d33918 100644 +--- a/ca/spottedleaf/moonrise/paper/PaperHooks.java ++++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java +@@ -211,6 +211,43 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo + @Override + public CompoundTag convertNBT(final DSL.TypeReference type, final DataFixer dataFixer, final CompoundTag nbt, + final int fromVersion, final int toVersion) { ++ // Paper start - optimise data conversion ++ if (type == net.minecraft.util.datafix.fixes.References.PLAYER) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.PLAYER, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.STRUCTURE) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.STRUCTURE, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.POI_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ENTITY_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ITEM_STACK) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ITEM_STACK, nbt, fromVersion, toVersion ++ ); ++ } ++ if (type == net.minecraft.util.datafix.fixes.References.ENTITY || type == net.minecraft.util.datafix.fixes.References.ENTITY_TREE) { ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag( ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY, nbt, fromVersion, toVersion ++ ); ++ } ++ // Paper end - optimise data conversion + return (CompoundTag)dataFixer.update( + type, new Dynamic<>(NbtOps.INSTANCE, nbt), fromVersion, toVersion + ).getValue(); +diff --git a/net/minecraft/data/structures/StructureUpdater.java b/net/minecraft/data/structures/StructureUpdater.java +index 6536dc08c80170f5679acedd65cd2b9f6ad3fb3a..294cd15a796ad25823c8ccf98fbfae46ddac2c26 100644 +--- a/net/minecraft/data/structures/StructureUpdater.java ++++ b/net/minecraft/data/structures/StructureUpdater.java +@@ -27,7 +27,7 @@ public class StructureUpdater implements SnbtToNbt.Filter { + LOGGER.warn("SNBT Too old, do not forget to update: {} < {}: {}", dataVersion, 4420, structureLocationPath); + } + +- CompoundTag compoundTag = DataFixTypes.STRUCTURE.updateToCurrentVersion(DataFixers.getDataFixer(), tag, dataVersion); ++ CompoundTag compoundTag = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.STRUCTURE, tag, dataVersion, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); // Paper + structureTemplate.load(BuiltInRegistries.BLOCK, compoundTag); + return structureTemplate.save(new CompoundTag()); + } +diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java +index 794a01ee70a2a30d91550f5265f774ba73828cf9..c716521fb1497dc8a22d827ddb50fc1cc21a05f4 100644 +--- a/net/minecraft/server/MinecraftServer.java ++++ b/net/minecraft/server/MinecraftServer.java +@@ -305,6 +305,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop S spin(Function threadFunction) { ++ ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.init(); // Paper - rewrite data converter system + AtomicReference atomicReference = new AtomicReference<>(); + Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> atomicReference.get().runServer(), "Server thread"); + thread.setUncaughtExceptionHandler((thread1, exception) -> LOGGER.error("Uncaught exception in server thread", exception)); +diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java +index 8c1417c659ea0e079e99b9bfa79e1cf6ba9b712b..a8a32edea080f32fd25c9e009d4efa416a51a4cf 100644 +--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java ++++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java +@@ -54,7 +54,7 @@ public class ChunkStorage implements AutoCloseable { + } else { + try { + // CraftBukkit start +- if (version < 1466) { ++ if (false && version < 1466) { // Paper - no longer needed, data converter system / DFU handles it now + CompoundTag level = chunkData.getCompoundOrEmpty("Level"); + if (level.getBooleanOr("TerrainPopulated", false) && !level.getBooleanOr("LightPopulated", false)) { + // Light is purged updating to 1.14+. We need to set light populated to true so the converter recognizes the chunk as being "full" +@@ -63,7 +63,7 @@ public class ChunkStorage implements AutoCloseable { + } + // CraftBukkit end + if (version < 1493) { +- chunkData = DataFixTypes.CHUNK.update(this.fixerUpper, chunkData, version, 1493); ++ chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter + if (chunkData.getCompound("Level").flatMap(compoundTag -> compoundTag.getBoolean("hasLegacyStructureData")).orElse(false)) { + LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage); + chunkData = legacyStructureHandler.updateFromLegacy(chunkData); +@@ -80,7 +80,7 @@ public class ChunkStorage implements AutoCloseable { + // Spigot end + + injectDatafixingContext(chunkData, levelKey, chunkGeneratorKey); +- chunkData = DataFixTypes.CHUNK.updateToCurrentVersion(this.fixerUpper, chunkData, Math.max(1493, version)); ++ chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, Math.max(1493, version), ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); // Paper - replace chunk converter + // Spigot start + if (stopBelowZero) { + chunkData.putString("Status", net.minecraft.core.registries.BuiltInRegistries.CHUNK_STATUS.getKey(net.minecraft.world.level.chunk.status.ChunkStatus.SPAWN).toString()); +diff --git a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java +index 6be673172548c1382c7402ec4e1ec6ef51f702d3..18750f1ea3101b6c0ab0b8e33c304eb7fa1ed04d 100644 +--- a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java ++++ b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java +@@ -32,13 +32,30 @@ public class SimpleRegionStorage implements AutoCloseable { + return this.worker.store(chunkPos, data); + } + ++ // Paper start - rewrite data conversion system ++ private ca.spottedleaf.dataconverter.minecraft.datatypes.MCDataType getDataConverterType() { ++ if (this.dataFixType == DataFixTypes.ENTITY_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.ENTITY_CHUNK; ++ } else if (this.dataFixType == DataFixTypes.POI_CHUNK) { ++ return ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.POI_CHUNK; ++ } else { ++ throw new UnsupportedOperationException("For " + this.dataFixType.name()); ++ } ++ } ++ // Paper end - rewrite data conversion system ++ + public CompoundTag upgradeChunkTag(CompoundTag tag, int version) { +- int dataVersion = NbtUtils.getDataVersion(tag, version); +- return this.dataFixType.updateToCurrentVersion(this.fixerUpper, tag, dataVersion); ++ // Paper start - rewrite data conversion system ++ final int dataVer = NbtUtils.getDataVersion(tag, version); ++ return ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(this.getDataConverterType(), tag, dataVer, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); ++ // Paper end - rewrite data conversion system + } + + public Dynamic upgradeChunkTag(Dynamic tag, int version) { +- return this.dataFixType.updateToCurrentVersion(this.fixerUpper, tag, version); ++ // Paper start - rewrite data conversion system ++ final CompoundTag converted = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(this.getDataConverterType(), (CompoundTag)tag.getValue(), version, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); ++ return new Dynamic<>(tag.getOps(), converted); ++ // Paper end - rewrite data conversion system + } + + public CompletableFuture synchronize(boolean flushStorage) { +diff --git a/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/net/minecraft/world/level/levelgen/structure/StructureCheck.java +index 6a5451440751ad017324e3fec8cfd8efb118511b..4a3a05335e21008eb349e9ab221b54234d9ac200 100644 +--- a/net/minecraft/world/level/levelgen/structure/StructureCheck.java ++++ b/net/minecraft/world/level/levelgen/structure/StructureCheck.java +@@ -152,7 +152,7 @@ public class StructureCheck { + + CompoundTag compoundTag1; + try { +- compoundTag1 = DataFixTypes.CHUNK.updateToCurrentVersion(this.fixerUpper, compoundTag, version); ++ compoundTag1 = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, compoundTag, version, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); // Paper - replace chunk converter + } catch (Exception var12) { + LOGGER.warn("Failed to partially datafix chunk {}", chunkPos, var12); + return StructureCheckResult.CHUNK_LOAD_NEEDED; +diff --git a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java +index 7bb5a1102524cfe850859482346b1dd2af2d8868..c748e9b29173bed20f14de11d52e719b19d3469e 100644 +--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java ++++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplateManager.java +@@ -243,7 +243,7 @@ public class StructureTemplateManager { + public StructureTemplate readStructure(CompoundTag nbt) { + StructureTemplate structureTemplate = new StructureTemplate(); + int dataVersion = NbtUtils.getDataVersion(nbt, 500); +- structureTemplate.load(this.blockLookup, DataFixTypes.STRUCTURE.updateToCurrentVersion(this.fixerUpper, nbt, dataVersion)); ++ structureTemplate.load(this.blockLookup, ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.STRUCTURE, nbt, dataVersion, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion())); // Paper - rewrite data conversion system + return structureTemplate; + } + +diff --git a/net/minecraft/world/level/storage/LevelStorageSource.java b/net/minecraft/world/level/storage/LevelStorageSource.java +index d0512d2e9b241fbea2cb8248c750aa55c41fbb9d..3b40822ea6ec9783fe3cb8eaba069a8d626d8382 100644 +--- a/net/minecraft/world/level/storage/LevelStorageSource.java ++++ b/net/minecraft/world/level/storage/LevelStorageSource.java +@@ -227,7 +227,7 @@ public class LevelStorageSource { + CompoundTag compoundOrEmpty = levelDataTagRaw.getCompoundOrEmpty("Data"); + int dataVersion = NbtUtils.getDataVersion(compoundOrEmpty, -1); + Dynamic dynamic = DataFixTypes.LEVEL.updateToCurrentVersion(dataFixer, new Dynamic<>(NbtOps.INSTANCE, compoundOrEmpty), dataVersion); +- dynamic = dynamic.update("Player", dynamic1 -> DataFixTypes.PLAYER.updateToCurrentVersion(dataFixer, dynamic1, dataVersion)); ++ dynamic = dynamic.update("Player", dynamic1 -> new Dynamic(dynamic1.getOps(), ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.PLAYER, (net.minecraft.nbt.CompoundTag)dynamic1.getValue(), dataVersion, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()))); // Paper - replace data conversion system + return dynamic.update("WorldGenSettings", dynamic1 -> DataFixTypes.WORLD_GEN_SETTINGS.updateToCurrentVersion(dataFixer, dynamic1, dataVersion)); + } + +diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java +index 232a561be430d0be7964eb15a873f8dc5ac1bcd8..fe44d8d17d2622b3d6021c11579af85ef96737bb 100644 +--- a/net/minecraft/world/level/storage/PlayerDataStorage.java ++++ b/net/minecraft/world/level/storage/PlayerDataStorage.java +@@ -117,7 +117,7 @@ public class PlayerDataStorage { + + return optional.or(() -> this.load(name, uuid, ".dat_old")).map(compoundTag -> { // CraftBukkit + int dataVersion = NbtUtils.getDataVersion(compoundTag, -1); +- compoundTag = DataFixTypes.PLAYER.updateToCurrentVersion(this.fixerUpper, compoundTag, dataVersion); ++ compoundTag = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.PLAYER, compoundTag, dataVersion, ca.spottedleaf.dataconverter.minecraft.util.Version.getCurrentVersion()); // Paper - rewrite data conversion system + return compoundTag; // CraftBukkit - handled above + }); + } diff --git a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch similarity index 98% rename from paper-server/patches/features/0015-Moonrise-optimisation-patches.patch rename to paper-server/patches/features/0016-Moonrise-optimisation-patches.patch index 6959dec065..b7b43ba59b 100644 --- a/paper-server/patches/features/0015-Moonrise-optimisation-patches.patch +++ b/paper-server/patches/features/0016-Moonrise-optimisation-patches.patch @@ -297,7 +297,7 @@ index 0000000000000000000000000000000000000000..1b8193587814225c2ef2c5d9e667436e + } +} diff --git a/ca/spottedleaf/moonrise/paper/PaperHooks.java b/ca/spottedleaf/moonrise/paper/PaperHooks.java -index 729eb5d052465e4093e9d8c5d4fe8463b2efaca6..b9b774a3ca600cee3d0e967063ea2f72c7ab184f 100644 +index 6f65564f6a6e99d6549de9a23a031b1f4a8a9798..cba09766b9e0c47573aa562872cbe4cfbda4e99a 100644 --- a/ca/spottedleaf/moonrise/paper/PaperHooks.java +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java @@ -13,6 +13,7 @@ import net.minecraft.server.level.ChunkHolder; @@ -308,28 +308,26 @@ index 729eb5d052465e4093e9d8c5d4fe8463b2efaca6..b9b774a3ca600cee3d0e967063ea2f72 import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.boss.EnderDragonPart; import net.minecraft.world.level.BlockGetter; -@@ -231,11 +232,16 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo +@@ -150,7 +151,7 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo + @Override + public long[] getCounterTypesUncached(final net.minecraft.server.level.TicketType type) { +- return new long[0]; ++ return type == TicketType.FORCED ? new long[] { ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType.COUNTER_TYPE_FORCED } : it.unimi.dsi.fastutil.longs.LongArrays.EMPTY_ARRAY; // Paper - rewrite chunk system + } + + @Override +@@ -276,7 +277,7 @@ public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHo @Override public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { -- net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); -+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities(), chunk.getPos()); // Paper - rewrite chunk system - add ChunkPos param + try (final net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) { +- net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, net.minecraft.world.level.storage.TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities())); ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, net.minecraft.world.level.storage.TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities()), chunk.getPos()); // Paper - rewrite chunk system - add ChunkPos param + } } - @Override - public int modifyEntityTrackingRange(final Entity entity, final int currentRange) { - return org.spigotmc.TrackingRange.getEntityTrackingRange(entity, currentRange); - } --} -\ No newline at end of file -+ -+ @Override -+ public long[] getCounterTypesUncached(final TicketType type) { -+ return type == TicketType.FORCED ? new long[] { ca.spottedleaf.moonrise.patches.chunk_system.ticket.ChunkSystemTicketType.COUNTER_TYPE_FORCED } : it.unimi.dsi.fastutil.longs.LongArrays.EMPTY_ARRAY; -+ } -+} diff --git a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java -index 6cfc2bc8d5816304c42d9f23396ec9e65c27bdde..975a2e4ea1f84e81fa3526395b43cb8157a06243 100644 +index ce81e9f4f1e80be3b4f0cbdd95609990f9006534..975a2e4ea1f84e81fa3526395b43cb8157a06243 100644 --- a/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java +++ b/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java @@ -1,38 +1,24 @@ @@ -667,7 +665,7 @@ index 6cfc2bc8d5816304c42d9f23396ec9e65c27bdde..975a2e4ea1f84e81fa3526395b43cb81 @Override public int getViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); +- final ServerLevel level = player.level(); - if (level == null) { - return Bukkit.getViewDistance(); - } @@ -677,7 +675,7 @@ index 6cfc2bc8d5816304c42d9f23396ec9e65c27bdde..975a2e4ea1f84e81fa3526395b43cb81 @Override public int getTickViewDistance(final ServerPlayer player) { -- final ServerLevel level = player.serverLevel(); +- final ServerLevel level = player.level(); - if (level == null) { - return Bukkit.getSimulationDistance(); - } @@ -1007,7 +1005,7 @@ index 0000000000000000000000000000000000000000..866f38eb0f379ffbe2888023a7d1c290 +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java b/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java new file mode 100644 -index 0000000000000000000000000000000000000000..f3f5a3f04283a130b4e48e6b78732758335629e7 +index 0000000000000000000000000000000000000000..02d596647ab78afb056eefe14ffa0ef2f27867f6 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/ChunkSystemConverters.java @@ -0,0 +1,38 @@ @@ -1028,7 +1026,7 @@ index 0000000000000000000000000000000000000000..f3f5a3f04283a130b4e48e6b78732758 + private static final int DEFAULT_ENTITY_CHUNK_DATA_VERSION = -1; + + private static int getCurrentVersion() { -+ return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); ++ return SharedConstants.getCurrentVersion().dataVersion().version(); + } + + private static int getDataVersion(final CompoundTag data, final int dfl) { @@ -1051,15 +1049,16 @@ index 0000000000000000000000000000000000000000..f3f5a3f04283a130b4e48e6b78732758 +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java b/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java new file mode 100644 -index 0000000000000000000000000000000000000000..c7da23900228aab3a5673eb5adfada5091140319 +index 0000000000000000000000000000000000000000..1d2498e33b9cd5a22cb348a213be3d75281b6d24 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/entity/ChunkSystemEntity.java -@@ -0,0 +1,44 @@ +@@ -0,0 +1,45 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.entity; + +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.world.entity.Entity; ++import net.minecraft.world.entity.animal.HappyGhast; +import net.minecraft.world.entity.monster.Shulker; +import net.minecraft.world.entity.vehicle.AbstractMinecart; +import net.minecraft.world.entity.vehicle.Boat; @@ -1070,7 +1069,7 @@ index 0000000000000000000000000000000000000000..c7da23900228aab3a5673eb5adfada50 + + // for mods to override + public default boolean moonrise$isHardCollidingUncached() { -+ return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || ((Entity)this).canBeCollidedWith(); ++ return this instanceof Boat || this instanceof AbstractMinecart || this instanceof Shulker || this instanceof HappyGhast || ((Entity)this).canBeCollidedWith(null); + } + + public FullChunkStatus moonrise$getChunkStatus(); @@ -3299,10 +3298,10 @@ index 0000000000000000000000000000000000000000..59cbbf65c9df5c680b803f6dd6436a35 +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java new file mode 100644 -index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cdc7efdf56 +index 0000000000000000000000000000000000000000..c380487a97f626163e1f13d87231d64ce2ea4b24 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -0,0 +1,569 @@ +@@ -0,0 +1,591 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.level.entity; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -3310,6 +3309,7 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd +import ca.spottedleaf.moonrise.patches.chunk_system.level.chunk.ChunkData; +import ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity; +import com.google.common.collect.ImmutableList; ++import com.mojang.logging.LogUtils; +import it.unimi.dsi.fastutil.objects.Reference2ObjectMap; +import it.unimi.dsi.fastutil.objects.Reference2ObjectOpenHashMap; +import net.minecraft.nbt.CompoundTag; @@ -3319,6 +3319,7 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd +import net.minecraft.server.level.FullChunkStatus; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.util.Mth; ++import net.minecraft.util.ProblemReporter; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.entity.EntityType; @@ -3326,9 +3327,14 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd +import net.minecraft.world.entity.boss.enderdragon.EnderDragon; +import net.minecraft.world.level.ChunkPos; +import net.minecraft.world.level.Level; ++import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.chunk.storage.EntityStorage; +import net.minecraft.world.level.entity.Visibility; ++import net.minecraft.world.level.storage.TagValueInput; ++import net.minecraft.world.level.storage.TagValueOutput; ++import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.phys.AABB; ++import org.slf4j.Logger; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; @@ -3337,6 +3343,8 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd + +public final class ChunkEntitySlices { + ++ private static final Logger LOGGER = LogUtils.getLogger(); ++ + public final int minSection; + public final int maxSection; + public final int chunkX; @@ -3379,9 +3387,12 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd + this.chunkData = chunkData; + } + -+ public static List readEntities(final ServerLevel world, final CompoundTag compoundTag) { -+ // TODO check this and below on update for format changes -+ return EntityType.loadEntitiesRecursive(compoundTag.getListOrEmpty("Entities"), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList()); ++ public static List readEntities(final ServerLevel world, final ChunkPos pos, final CompoundTag compoundTag) { ++ try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(pos), LOGGER)) { ++ ValueInput valueinput = TagValueInput.create(scopedCollector, world.registryAccess(), compoundTag); ++ // TODO check this and below on update for format changes ++ return EntityType.loadEntitiesRecursive(valueinput.childrenListOrEmpty("Entities"), world, EntitySpawnReason.LOAD).collect(ImmutableList.toImmutableList()); ++ } + } + + // Paper start - rewrite chunk system @@ -3409,12 +3420,22 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd + } + + final ListTag entitiesTag = new ListTag(); -+ for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { -+ CompoundTag compoundTag = new CompoundTag(); -+ if (entity.save(compoundTag)) { -+ entitiesTag.add(compoundTag); ++ try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(chunkPos), LOGGER)) { ++ for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { ++ final TagValueOutput savedEntity = TagValueOutput.createWithContext( ++ scopedCollector.forChild(entity.problemPath()), entity.registryAccess() ++ ); ++ ++ try { ++ if (entity.save(savedEntity)) { ++ entitiesTag.add(savedEntity.buildResult()); ++ } ++ } catch (final Exception ex) { ++ LOGGER.error("Entity type " + entity.getType() + " failed to serialize", ex); ++ } + } + } ++ + final CompoundTag ret = NbtUtils.addCurrentDataVersion(new CompoundTag()); + ret.put("Entities", entitiesTag); + ret.store("Position", ChunkPos.CODEC, chunkPos); @@ -5303,7 +5324,7 @@ index 0000000000000000000000000000000000000000..89b956b8fdf1a0d862a843104511005e +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java new file mode 100644 -index 0000000000000000000000000000000000000000..8b5eedee7b5876c0981520ec1548f70a935a501f +index 0000000000000000000000000000000000000000..5adbeecd61ab80fd86546f22f0867f27af5a7662 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/poi/PoiChunk.java @@ -0,0 +1,204 @@ @@ -5428,7 +5449,7 @@ index 0000000000000000000000000000000000000000..8b5eedee7b5876c0981520ec1548f70a + final CompoundTag sections = new CompoundTag(); + ret.put("Sections", sections); + -+ ret.putInt("DataVersion", SharedConstants.getCurrentVersion().getDataVersion().getVersion()); ++ ret.putInt("DataVersion", SharedConstants.getCurrentVersion().dataVersion().version()); + + final ServerLevel world = this.world; + final int chunkX = this.chunkX; @@ -5553,7 +5574,7 @@ index 0000000000000000000000000000000000000000..003a857e70ead858e8437e3c1bfaf22f +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java new file mode 100644 -index 0000000000000000000000000000000000000000..02a9ef1694c796584c29430d27f0a09047368835 +index 0000000000000000000000000000000000000000..f3bac0906d8a1c5dea7b0dee13c5cd6fdbbcae49 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/player/RegionizedPlayerChunkLoader.java @@ -0,0 +1,1089 @@ @@ -5706,7 +5727,7 @@ index 0000000000000000000000000000000000000000..02a9ef1694c796584c29430d27f0a090 + } + + public static int getAPITickViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader(); + if (data == null) { + return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPITickDistance(); @@ -5715,7 +5736,7 @@ index 0000000000000000000000000000000000000000..02a9ef1694c796584c29430d27f0a090 + } + + public static int getAPIViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader(); + if (data == null) { + return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPIViewDistance(); @@ -5725,7 +5746,7 @@ index 0000000000000000000000000000000000000000..02a9ef1694c796584c29430d27f0a090 + } + + public static int getAPISendViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + final PlayerChunkLoaderData data = ((ChunkSystemServerPlayer)player).moonrise$getChunkLoader(); + if (data == null) { + return ((ChunkSystemServerLevel)level).moonrise$getPlayerChunkLoader().getAPISendViewDistance(); @@ -9408,10 +9429,10 @@ index 0000000000000000000000000000000000000000..8f8268924ac92fca5df8a11e08031fa8 +} diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java new file mode 100644 -index 0000000000000000000000000000000000000000..e4a5fa25ed368fc4662c30934da2963ef446d782 +index 0000000000000000000000000000000000000000..2cc0e7c72d2b2e562452138f2b41fd1dcaf0570a --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/chunk_system/scheduling/NewChunkHolder.java -@@ -0,0 +1,1997 @@ +@@ -0,0 +1,1999 @@ +package ca.spottedleaf.moonrise.patches.chunk_system.scheduling; + +import ca.spottedleaf.concurrentutil.completable.CallbackCompletable; @@ -9531,9 +9552,11 @@ index 0000000000000000000000000000000000000000..e4a5fa25ed368fc4662c30934da2963e + + if (!transientChunk) { + if (entityChunk != null) { -+ final List entities = ChunkEntitySlices.readEntities(this.world, entityChunk); ++ final ChunkPos pos = new ChunkPos(this.chunkX, this.chunkZ); + -+ ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, new ChunkPos(this.chunkX, this.chunkZ)); ++ final List entities = ChunkEntitySlices.readEntities(this.world, pos, entityChunk); ++ ++ ((ChunkSystemServerLevel)this.world).moonrise$getEntityLookup().addEntityChunkEntities(entities, pos); + } + } + @@ -16353,7 +16376,7 @@ index 0000000000000000000000000000000000000000..1414f25ef770b0fe73ea618a450ade2f +} diff --git a/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java new file mode 100644 -index 0000000000000000000000000000000000000000..a97a2a8492f3858e3b622d26768b4d819c9b47a7 +index 0000000000000000000000000000000000000000..01cd38bba2deb6cf65c82b4e4ec352a2998fd339 --- /dev/null +++ b/ca/spottedleaf/moonrise/patches/collisions/CollisionUtil.java @@ -0,0 +1,2185 @@ @@ -18450,7 +18473,7 @@ index 0000000000000000000000000000000000000000..a97a2a8492f3858e3b622d26768b4d81 + continue; + } + -+ if ((entity == null && otherEntity.canBeCollidedWith()) || (entity != null && entity.canCollideWith(otherEntity))) { ++ if ((entity == null && otherEntity.canBeCollidedWith(entity)) || (entity != null && entity.canCollideWith(otherEntity))) { + if (checkOnly) { + return true; + } else { @@ -22963,7 +22986,7 @@ index 0000000000000000000000000000000000000000..f1f72a051083b61273202cb4e67ecb11 + private SaveUtil() {} +} diff --git a/io/papermc/paper/FeatureHooks.java b/io/papermc/paper/FeatureHooks.java -index 329e9562e9c2b25228b04c21ff7353d2d8d6e5f6..52b981a05ad5aabb7c85dc1e0f1d2b835163bb87 100644 +index 0a80ab83ca69b8b51fb1bb8c12ee6fcf439a3ac4..a42a773503ca0e0dc36dd44440b3eda670a6811b 100644 --- a/io/papermc/paper/FeatureHooks.java +++ b/io/papermc/paper/FeatureHooks.java @@ -1,6 +1,9 @@ @@ -23004,7 +23027,7 @@ index 329e9562e9c2b25228b04c21ff7353d2d8d6e5f6..52b981a05ad5aabb7c85dc1e0f1d2b83 + // Paper start - rewrite chunk system + final LongOpenHashSet rawChunkKeys = player.moonrise$getChunkLoader().getSentChunksRaw(); + final ObjectSet chunks = new ObjectOpenHashSet<>(rawChunkKeys.size()); - final World world = player.serverLevel().getWorld(); + final World world = player.level().getWorld(); - player.getChunkTrackingView().forEach(pos -> { - final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey); - chunks.add(chunk); @@ -23710,10 +23733,10 @@ index 2028c2a1613b36629dab2c8e36689af329596f09..63fd7b45750430b565d599337d3112cb + // Paper end - optimise collisions } diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java -index a70fc668e1ab7c069bb6ea1500667074ef3f2f91..761e583a56b1c4a605b0cbb04b61c4df60b8b9bb 100644 +index 5bc77b86acf26c2d66f16bdfb30342b998509f77..4715a60760c2c9079313db9016000bfb5c65e070 100644 --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -50,6 +50,19 @@ public class MappedRegistry implements WritableRegistry { +@@ -57,6 +57,19 @@ public class MappedRegistry implements WritableRegistry { return this.getTags(); } @@ -23733,7 +23756,7 @@ index a70fc668e1ab7c069bb6ea1500667074ef3f2f91..761e583a56b1c4a605b0cbb04b61c4df public MappedRegistry(ResourceKey> key, Lifecycle registryLifecycle) { this(key, registryLifecycle, false); } -@@ -115,6 +128,7 @@ public class MappedRegistry implements WritableRegistry { +@@ -122,6 +135,7 @@ public class MappedRegistry implements WritableRegistry { this.registrationInfos.put(key, registrationInfo); this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle()); this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API @@ -23742,10 +23765,10 @@ index a70fc668e1ab7c069bb6ea1500667074ef3f2f91..761e583a56b1c4a605b0cbb04b61c4df } } diff --git a/net/minecraft/server/Main.java b/net/minecraft/server/Main.java -index 58be6e1d1607a3af5e28f851718b82321f2feb25..9c9b601a3f903bebb0dd1bda0e24745587229727 100644 +index 46de98a6bbbae48c4837e1e588ba198a363d2dde..fd3553bdc1c3cdbf6aa3dc00e0a4987f8eaa4fb8 100644 --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -324,6 +324,7 @@ public class Main { +@@ -325,6 +325,7 @@ public class Main { levelStorageAccess.saveDataTag(frozen, worldData); */ @@ -23754,10 +23777,10 @@ index 58be6e1d1607a3af5e28f851718b82321f2feb25..9c9b601a3f903bebb0dd1bda0e247455 thread1 -> { DedicatedServer dedicatedServer1 = new DedicatedServer( diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 91df2a420eeab1bab508b95f0029fae7adb51c58..094ef7f54ad71795a2d8c2a8d03a32bef6ff2164 100644 +index c716521fb1497dc8a22d827ddb50fc1cc21a05f4..80442494db670fec34df310390ea787fb963eef4 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -172,7 +172,7 @@ import net.minecraft.world.phys.Vec2; +@@ -173,7 +173,7 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.slf4j.Logger; @@ -23766,7 +23789,7 @@ index 91df2a420eeab1bab508b95f0029fae7adb51c58..094ef7f54ad71795a2d8c2a8d03a32be private static MinecraftServer SERVER; // Paper public static final Logger LOGGER = LogUtils.getLogger(); public static final net.kyori.adventure.text.logger.slf4j.ComponentLogger COMPONENT_LOGGER = net.kyori.adventure.text.logger.slf4j.ComponentLogger.logger(LOGGER.getName()); // Paper -@@ -318,6 +318,77 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop false : this::haveTime); @@ -23938,7 +23961,7 @@ index 91df2a420eeab1bab508b95f0029fae7adb51c58..094ef7f54ad71795a2d8c2a8d03a32be this.tickFrame.end(); profilerFiller.popPush("nextTickWait"); this.mayHaveDelayedTasks = true; -@@ -1337,6 +1424,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop list = this.mountedOrDismounted(passengers).map(Entity::getUUID).toList(); diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8813846a6 100644 +index 49008b4cbaead8a66a93d2b0d4b50b335a6c3eed..f9c96bbdc54e68b9216b7f8662bfae03012d2866 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -166,7 +166,7 @@ import net.minecraft.world.phys.shapes.VoxelShape; - import net.minecraft.world.ticks.LevelTicks; +@@ -168,7 +168,7 @@ import net.minecraft.world.ticks.LevelTicks; + import net.minecraft.world.waypoints.WaypointTransmitter; import org.slf4j.Logger; -public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLevel { @@ -26830,16 +26853,16 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 public static final BlockPos END_SPAWN_POINT = new BlockPos(100, 50, 0); public static final IntProvider RAIN_DELAY = UniformInt.of(12000, 180000); public static final IntProvider RAIN_DURATION = UniformInt.of(12000, 24000); -@@ -181,7 +181,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type +@@ -184,7 +184,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe private int lastSpawnChunkRadius; final EntityTickList entityTickList = new EntityTickList(); + private final ServerWaypointManager waypointManager; - public final PersistentEntitySectionManager entityManager; + // Paper - rewrite chunk system private final GameEventDispatcher gameEventDispatcher; public boolean noSave; private final SleepStatus sleepStatus; -@@ -253,12 +253,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -256,12 +256,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final void loadChunksForMoveAsync(AABB axisalignedbb, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { @@ -26853,7 +26876,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 int minBlockX = Mth.floor(axisalignedbb.minX - 1.0E-7D) - 3; int minBlockZ = Mth.floor(axisalignedbb.minZ - 1.0E-7D) - 3; -@@ -277,30 +272,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -280,30 +275,159 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final void loadChunks(int minChunkX, int minChunkZ, int maxChunkX, int maxChunkZ, ca.spottedleaf.concurrentutil.util.Priority priority, java.util.function.Consumer> onLoad) { @@ -27028,7 +27051,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } } } -@@ -314,16 +438,128 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -317,16 +441,128 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } } @@ -27164,7 +27187,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 public ServerLevel( MinecraftServer server, -@@ -371,18 +607,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -374,18 +610,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe // CraftBukkit end boolean flag = server.forceSynchronousWrites(); DataFixer fixerUpper = server.getFixerUpper(); @@ -27184,7 +27207,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 this.chunkSource = new ServerChunkCache( this, levelStorageAccess, -@@ -394,7 +619,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -397,7 +622,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.spigotConfig.simulationDistance, // Spigot flag, progressListener, @@ -27193,10 +27216,10 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 () -> server.overworld().getDataStorage() ); this.chunkSource.getGeneratorState().ensureStructuresGenerated(); -@@ -430,6 +655,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe - this.sleepStatus = new SleepStatus(); +@@ -434,6 +659,20 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.gameEventDispatcher = new GameEventDispatcher(this); this.randomSequences = Objects.requireNonNullElseGet(randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.TYPE)); + this.waypointManager = new ServerWaypointManager(); + // Paper start - rewrite chunk system + this.moonrise$setEntityLookup(new ca.spottedleaf.moonrise.patches.chunk_system.level.entity.server.ServerEntityLookup((ServerLevel)(Object)this, ((ServerLevel)(Object)this).new EntityCallbacks())); + this.chunkTaskScheduler = new ca.spottedleaf.moonrise.patches.chunk_system.scheduling.ChunkTaskScheduler((ServerLevel)(Object)this); @@ -27214,7 +27237,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit } -@@ -553,8 +792,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -557,8 +796,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe profilerFiller.push("checkDespawn"); entity.checkDespawn(); profilerFiller.pop(); @@ -27224,7 +27247,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 Entity vehicle = entity.getVehicle(); if (vehicle != null) { if (!vehicle.isRemoved() && vehicle.hasPassenger(entity)) { -@@ -577,13 +815,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -581,13 +819,16 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } profilerFiller.push("entityManagement"); @@ -27243,7 +27266,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } protected void tickTime() { -@@ -614,7 +855,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -618,7 +859,60 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.players.stream().filter(LivingEntity::isSleeping).collect(Collectors.toList()).forEach(player -> player.stopSleepInBed(false, false)); } @@ -27304,7 +27327,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 ChunkPos pos = chunk.getPos(); int minBlockX = pos.getMinBlockX(); int minBlockZ = pos.getMinBlockZ(); -@@ -623,7 +917,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -627,7 +921,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (!this.paperConfig().environment.disableIceAndSnow) { // Paper - Option to disable ice and snow for (int i = 0; i < randomTickSpeed; i++) { @@ -27313,7 +27336,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 this.tickPrecipitation(this.getBlockRandomPos(minBlockX, 0, minBlockZ, 15)); } } -@@ -631,33 +925,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -635,33 +929,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe profilerFiller.popPush("tickBlocks"); if (randomTickSpeed > 0) { @@ -27348,7 +27371,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } profilerFiller.pop(); -@@ -948,6 +1216,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -956,6 +1224,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (fluidState.is(fluid)) { fluidState.tick(this, pos, blockState); } @@ -27361,7 +27384,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } private void tickBlock(BlockPos pos, Block block) { -@@ -955,6 +1229,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -963,6 +1237,12 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe if (blockState.is(block)) { blockState.tick(this, pos, this.random); } @@ -27374,7 +27397,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } // Paper start - log detailed entity tick information -@@ -1037,6 +1317,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1059,6 +1339,11 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) { @@ -27386,7 +27409,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 ServerChunkCache chunkSource = this.getChunkSource(); if (!skipSave) { org.bukkit.Bukkit.getPluginManager().callEvent(new org.bukkit.event.world.WorldSaveEvent(this.getWorld())); // CraftBukkit -@@ -1049,13 +1334,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1071,13 +1356,18 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe progress.progressStage(Component.translatable("menu.savingChunks")); } @@ -27410,7 +27433,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 // CraftBukkit start - moved from MinecraftServer#saveAllChunks ServerLevel serverLevel1 = this; -@@ -1186,7 +1476,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1208,7 +1498,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe this.removePlayerImmediately((ServerPlayer)entity, Entity.RemovalReason.DISCARDED); } @@ -27419,7 +27442,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } // CraftBukkit start -@@ -1217,7 +1507,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1239,7 +1529,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } // CraftBukkit end @@ -27428,7 +27451,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } } -@@ -1228,7 +1518,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1250,7 +1540,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public boolean tryAddFreshEntityWithPassengers(Entity entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) { // CraftBukkit end @@ -27437,7 +27460,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 return false; } else { this.addFreshEntityWithPassengers(entity, reason); // CraftBukkit -@@ -1962,7 +2252,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -1984,7 +2274,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } } @@ -27446,7 +27469,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 bufferedWriter.write(String.format(Locale.ROOT, "block_entity_tickers: %d\n", this.blockEntityTickers.size())); bufferedWriter.write(String.format(Locale.ROOT, "block_ticks: %d\n", this.getBlockTicks().count())); bufferedWriter.write(String.format(Locale.ROOT, "fluid_ticks: %d\n", this.getFluidTicks().count())); -@@ -1980,13 +2270,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2002,13 +2292,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe Path path1 = path.resolve("chunks.csv"); try (Writer bufferedWriter2 = Files.newBufferedWriter(path1)) { @@ -27462,7 +27485,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } Path path3 = path.resolve("entities.csv"); -@@ -2083,8 +2373,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2105,8 +2395,8 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe Locale.ROOT, "players: %s, entities: %s [%s], block_entities: %d [%s], block_ticks: %d, fluid_ticks: %d, chunk_source: %s", this.players.size(), @@ -27473,7 +27496,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 this.blockEntityTickers.size(), getTypeCount(this.blockEntityTickers, TickingBlockEntity::getType), this.getBlockTicks().count(), -@@ -2116,15 +2406,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2138,15 +2428,25 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public LevelEntityGetter getEntities() { org.spigotmc.AsyncCatcher.catchOp("Chunk getEntities call"); // Spigot @@ -27502,7 +27525,16 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } public void startTickingChunk(LevelChunk chunk) { -@@ -2142,28 +2442,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2166,7 +2466,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe + this.chunkSource.addTicketWithRadius(TicketType.UNKNOWN, chunkPos, i); + list.forEach(chunkPos1 -> this.getChunk(chunkPos1.x, chunkPos1.z)); + this.server.managedBlock(() -> { +- this.entityManager.processPendingLoads(); ++ //this.entityManager.processPendingLoads(); // Paper - rewrite chunk system + + for (ChunkPos chunkPos1 : list) { + if (!this.areEntitiesLoaded(chunkPos1.toLong())) { +@@ -2181,28 +2481,38 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public void close() throws IOException { super.close(); @@ -27547,7 +27579,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } public boolean anyPlayerCloseEnoughForSpawning(BlockPos pos) { -@@ -2175,7 +2485,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2214,7 +2524,10 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe } public boolean canSpawnEntitiesInChunk(ChunkPos chunkPos) { @@ -27559,7 +27591,7 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } @Override -@@ -2230,7 +2543,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2269,7 +2582,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashReportCategory = super.fillReportDetails(report); @@ -27569,10 +27601,10 @@ index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8 } diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 57af8cd7629fa14176c6e7a29956617ec9506999..63fecebe6048b0d3372ea84ac74dc74744de3273 100644 +index 69dbff3f62e3a9ba7090156380f842bb44deebf8..c0b74d408340101bc3aac4cb4b7232c5cc78b08a 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -186,7 +186,7 @@ import net.minecraft.world.scores.Team; +@@ -193,7 +193,7 @@ import net.minecraft.world.scores.Team; import net.minecraft.world.scores.criteria.ObjectiveCriteria; import org.slf4j.Logger; @@ -27581,7 +27613,7 @@ index 57af8cd7629fa14176c6e7a29956617ec9506999..63fecebe6048b0d3372ea84ac74dc747 private static final Logger LOGGER = LogUtils.getLogger(); private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_XZ = 32; private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10; -@@ -415,6 +415,36 @@ public class ServerPlayer extends Player { +@@ -426,6 +426,36 @@ public class ServerPlayer extends Player { public @Nullable String clientBrandName = null; // Paper - Brand support public @Nullable org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event @@ -27616,7 +27648,7 @@ index 57af8cd7629fa14176c6e7a29956617ec9506999..63fecebe6048b0d3372ea84ac74dc747 + // Paper end - rewrite chunk system + public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { - super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile); + super(level, gameProfile); this.textFilter = server.createTextFilterForPlayer(this); diff --git a/net/minecraft/server/level/ThreadedLevelLightEngine.java b/net/minecraft/server/level/ThreadedLevelLightEngine.java index 11a264ef2f43c2b00741397c9c9ea5393afad6ab..216c2294f59a9d53613ac249ea63adeaa8a8efa4 100644 @@ -28206,10 +28238,10 @@ index b30f56fbc1fd17259a1d05dc9155fffcab292ca1..11fed81a4696ba18440e755c3b8a5ca3 this.generatingStep = generatingStep; this.cache = cache; diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java -index eda176c96bcf3d67650722ffce33863edfbdea9e..a7a07ebe6ceed99fa768b6834e350fe2f51a6950 100644 +index 891d3e13057c6034c59a78e594935c433921de04..a3aa852b04e6deccccf995cfc57f95fa79860c04 100644 --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -1332,7 +1332,7 @@ public abstract class PlayerList { +@@ -1328,7 +1328,7 @@ public abstract class PlayerList { public void setViewDistance(int viewDistance) { this.viewDistance = viewDistance; @@ -28218,7 +28250,7 @@ index eda176c96bcf3d67650722ffce33863edfbdea9e..a7a07ebe6ceed99fa768b6834e350fe2 for (ServerLevel serverLevel : this.server.getAllLevels()) { if (serverLevel != null) { -@@ -1343,7 +1343,7 @@ public abstract class PlayerList { +@@ -1339,7 +1339,7 @@ public abstract class PlayerList { public void setSimulationDistance(int simulationDistance) { this.simulationDistance = simulationDistance; @@ -28601,19 +28633,19 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896 + // Paper end - block counting } diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java -index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed30ad0868 100644 +index bd962b2a0f381ddc1c7251162531bdecf3c2706b..9344cdbad8415f6ff4d592d3f13390e85477a10d 100644 --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -140,7 +140,7 @@ import net.minecraft.world.scores.ScoreHolder; - import net.minecraft.world.scores.Team; +@@ -147,7 +147,7 @@ import net.minecraft.world.waypoints.WaypointTransmitter; import org.jetbrains.annotations.Contract; + import org.slf4j.Logger; -public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter { +public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter, ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity, ca.spottedleaf.moonrise.patches.entity_tracker.EntityTrackerEntity { // Paper - rewrite chunk system // Paper - optimise entity tracker // CraftBukkit start - private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); private static final int CURRENT_LEVEL = 2; -@@ -151,7 +151,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo +@@ -157,7 +157,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess // Paper start - Share random for entities to make them more random public static RandomSource SHARED_RANDOM = new RandomRandomSource(); @@ -28632,7 +28664,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed private boolean locked = false; @Override -@@ -164,61 +174,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -170,61 +180,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } } @@ -28695,8 +28727,8 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed } // Paper end - Share random for entities to make them more random public @Nullable org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason; // Paper - Entity#getEntitySpawnReason -@@ -409,6 +365,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess - this.movementThisTick.clear(); +@@ -426,6 +382,156 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess + return this.dimensions.makeBoundingBox(x, y, z); } // Paper end + // Paper start - rewrite chunk system @@ -28852,7 +28884,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed public Entity(EntityType entityType, Level level) { this.type = entityType; -@@ -1349,35 +1455,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -1378,35 +1484,77 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return distance; } @@ -28954,7 +28986,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed } private static float[] collectCandidateStepUpHeights(AABB box, List colliders, float deltaY, float maxUpStep) { -@@ -2620,21 +2768,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -2680,21 +2828,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public boolean isInWall() { @@ -29076,7 +29108,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed } public InteractionResult interact(Player player, InteractionHand hand) { -@@ -4082,15 +4319,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4291,15 +4528,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public Iterable getIndirectPassengers() { @@ -29102,7 +29134,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed } public int countPlayerPassengers() { -@@ -4233,77 +4472,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4442,77 +4681,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess return Mth.lerp(partialTick, this.yRotO, this.yRot); } @@ -29293,7 +29325,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed public boolean touchingUnloadedChunk() { AABB aabb = this.getBoundingBox().inflate(1.0); -@@ -4458,6 +4756,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4667,6 +4965,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess } public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { @@ -29309,7 +29341,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed if (!checkPosition(this, x, y, z)) { return; } -@@ -4591,6 +4898,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4823,6 +5130,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess @Override public final void setRemoved(Entity.RemovalReason removalReason, @Nullable org.bukkit.event.entity.EntityRemoveEvent.Cause cause) { // CraftBukkit - add Bukkit remove cause @@ -29322,7 +29354,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers if (this.removalReason == null) { -@@ -4601,7 +4914,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4833,7 +5146,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess this.stopRiding(); } @@ -29331,7 +29363,7 @@ index bcac0c25acb8c5176c2ca6bffbae118d83fb63f7..4057431072cd1ca159b25576969908ed this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); // Paper start - Folia schedulers -@@ -4635,7 +4948,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess +@@ -4867,7 +5180,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess public boolean shouldBeSaved() { return (this.removalReason == null || this.removalReason.shouldSave()) && !this.isPassenger() @@ -29580,10 +29612,10 @@ index b766b4281aecb3b96e2c263664d81da3425e3653..c3bcb494afe464207e805f8c40b03c70 this(setDirty, true, ImmutableList.of()); } diff --git a/net/minecraft/world/entity/decoration/ArmorStand.java b/net/minecraft/world/entity/decoration/ArmorStand.java -index f5ce8151bb1bae9be638ced7f74899d452d517e1..5248f3c22abb608d7d7b338f169f13bfbf4cd2d6 100644 +index 1dfc7950d9623457d8c3d4a8f13ed8f3fe918382..46369e554be8c72e6fc2e6d58374dbfc77d94879 100644 --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -245,7 +245,7 @@ public class ArmorStand extends LivingEntity { +@@ -203,7 +203,7 @@ public class ArmorStand extends LivingEntity { @Override protected void pushEntities() { if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper - Option to prevent armor stands from doing entity lookups @@ -29606,7 +29638,7 @@ index 9f34fc4278860dd7bcfa1fd79b15e588b0cc3973..a7ebd624652cb6f0edc735bf6b9760e7 public ClipContext(Vec3 from, Vec3 to, ClipContext.Block block, ClipContext.Fluid fluid, Entity entity) { diff --git a/net/minecraft/world/level/EntityGetter.java b/net/minecraft/world/level/EntityGetter.java -index 300f3ed58109219d97846082941b860585f66fed..892a7c1eb1b321ca6d5ca709142e7feae1220815 100644 +index 300f3ed58109219d97846082941b860585f66fed..9175a7e4e6076626cb46144c5858c2f2474f1858 100644 --- a/net/minecraft/world/level/EntityGetter.java +++ b/net/minecraft/world/level/EntityGetter.java @@ -15,7 +15,7 @@ import net.minecraft.world.phys.shapes.BooleanOp; @@ -29718,7 +29750,7 @@ index 300f3ed58109219d97846082941b860585f66fed..892a7c1eb1b321ca6d5ca709142e7fea + continue; + } + -+ if ((entity == null && otherEntity.canBeCollidedWith()) || (entity != null && entity.canCollideWith(otherEntity))) { ++ if ((entity == null && otherEntity.canBeCollidedWith(entity)) || (entity != null && entity.canCollideWith(otherEntity))) { + ret.add(Shapes.create(otherEntity.getBoundingBox())); } } @@ -29729,7 +29761,7 @@ index 300f3ed58109219d97846082941b860585f66fed..892a7c1eb1b321ca6d5ca709142e7fea // Paper start - Affects Spawning API diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d9d2473e2 100644 +index 1eb8cb187d33510a4e99d229e721a2e7db4012ad..f286dd9996590e5d448ca809c34b6f640203e274 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java @@ -81,6 +81,7 @@ import net.minecraft.world.level.storage.LevelData; @@ -30465,7 +30497,7 @@ index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d } // Paper end - Option to prevent armor stands from doing entity lookups -@@ -994,7 +1642,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -987,7 +1635,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl if (this.isOutsideBuildHeight(pos)) { return null; } else { @@ -30474,7 +30506,7 @@ index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d ? null : this.getChunkAt(pos).getBlockEntity(pos, LevelChunk.EntityCreationType.IMMEDIATE); } -@@ -1087,22 +1735,16 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -1080,22 +1728,16 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl public List getEntities(@Nullable Entity entity, AABB boundingBox, Predicate predicate) { Profiler.get().incrementCounter("getEntities"); List list = Lists.newArrayList(); @@ -30505,7 +30537,7 @@ index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d } @Override -@@ -1116,33 +1758,94 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -1109,33 +1751,94 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl this.getEntities(entityTypeTest, bounds, predicate, output, Integer.MAX_VALUE); } @@ -30645,7 +30677,7 @@ index c59f2c0634e3ebb11b8f6bc09020f951cb602f9b..0842fd6488c8b27d98c4344e1244996b ChunkAccess getChunk(int x, int z, ChunkStatus chunkStatus, boolean requireChunk); diff --git a/net/minecraft/world/level/ServerExplosion.java b/net/minecraft/world/level/ServerExplosion.java -index 01083cf32b4b0bd57d1b0ac83eb4e43d9d90fa98..ec4b63a574e7ff2c807c283c9f4b402229864e51 100644 +index 8afaded394fcbf5d7ad4c51ea49642ce93cd5198..e5ccfb8cbfafed7bb0a1d888b5bc98a923e46e59 100644 --- a/net/minecraft/world/level/ServerExplosion.java +++ b/net/minecraft/world/level/ServerExplosion.java @@ -60,6 +60,249 @@ public class ServerExplosion implements Explosion { @@ -31077,7 +31109,7 @@ index 01083cf32b4b0bd57d1b0ac83eb4e43d9d90fa98..ec4b63a574e7ff2c807c283c9f4b4022 } private static void addOrAppendStack(List stackCollectors, ItemStack stack, BlockPos pos) { -@@ -462,12 +759,12 @@ public class ServerExplosion implements Explosion { +@@ -461,12 +758,12 @@ public class ServerExplosion implements Explosion { // Paper start - Optimize explosions private float getBlockDensity(Vec3 vec3d, Entity entity) { if (!this.level.paperConfig().environment.optimizeExplosions) { @@ -31093,10 +31125,10 @@ index 01083cf32b4b0bd57d1b0ac83eb4e43d9d90fa98..ec4b63a574e7ff2c807c283c9f4b4022 } diff --git a/net/minecraft/world/level/TicketStorage.java b/net/minecraft/world/level/TicketStorage.java -index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72c6d67ebd 100644 +index ac9d453df4bfa3cc50f1909e0d425e5ba98e6d75..669d347d90de6b083d56e995c7e3b022b54dd838 100644 --- a/net/minecraft/world/level/TicketStorage.java +++ b/net/minecraft/world/level/TicketStorage.java -@@ -27,7 +27,7 @@ import net.minecraft.world.level.saveddata.SavedData; +@@ -29,7 +29,7 @@ import net.minecraft.world.level.saveddata.SavedData; import net.minecraft.world.level.saveddata.SavedDataType; import org.slf4j.Logger; @@ -31105,7 +31137,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 private static final int INITIAL_TICKET_LIST_CAPACITY = 4; private static final Logger LOGGER = LogUtils.getLogger(); private static final Codec> TICKET_ENTRY = Codec.mapPair(ChunkPos.CODEC.fieldOf("chunk_pos"), Ticket.CODEC).codec(); -@@ -36,18 +36,32 @@ public class TicketStorage extends SavedData { +@@ -38,18 +38,32 @@ public class TicketStorage extends SavedData { .apply(instance, TicketStorage::fromPacked) ); public static final SavedDataType TYPE = new SavedDataType<>("chunks", TicketStorage::new, CODEC, DataFixTypes.SAVED_DATA_FORCED_CHUNKS); @@ -31142,7 +31174,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } public TicketStorage() { -@@ -76,8 +90,32 @@ public class TicketStorage extends SavedData { +@@ -78,8 +92,32 @@ public class TicketStorage extends SavedData { return list; } @@ -31176,7 +31208,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 forEachTicket(action, this.deactivatedTickets); } -@@ -102,23 +140,26 @@ public class TicketStorage extends SavedData { +@@ -104,23 +142,26 @@ public class TicketStorage extends SavedData { } public void setLoadingChunkUpdatedListener(@Nullable TicketStorage.ChunkUpdated loadingChunkUpdatedListener) { @@ -31208,7 +31240,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } public void addTicketWithRadius(TicketType ticketType, ChunkPos chunkPos, int radius) { -@@ -131,33 +172,14 @@ public class TicketStorage extends SavedData { +@@ -133,33 +174,14 @@ public class TicketStorage extends SavedData { } public boolean addTicket(long chunkPos, Ticket ticket) { @@ -31248,7 +31280,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } private static boolean isTicketSameTypeAndLevel(Ticket first, Ticket second) { -@@ -204,49 +226,20 @@ public class TicketStorage extends SavedData { +@@ -206,49 +228,20 @@ public class TicketStorage extends SavedData { } public boolean removeTicket(long chunkPos, Ticket ticket) { @@ -31307,38 +31339,44 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } public String getTicketDebugString(long chunkPos, boolean requireSimulation) { -@@ -256,89 +249,20 @@ public class TicketStorage extends SavedData { +@@ -258,96 +251,20 @@ public class TicketStorage extends SavedData { } - public void purgeStaleTickets() { -- this.removeTicketIf(ticket -> { -- ticket.decreaseTicksLeft(); -- return ticket.isTimedOut(); + public void purgeStaleTickets(ChunkMap chunkMap) { +- this.removeTicketIf((_long, ticket) -> { +- ChunkHolder updatingChunkIfPresent = chunkMap.getUpdatingChunkIfPresent(_long); +- boolean flag = updatingChunkIfPresent != null && !updatingChunkIfPresent.isReadyForSaving() && ticket.getType().doesSimulate(); +- if (flag) { +- return false; +- } else { +- ticket.decreaseTicksLeft(); +- return ticket.isTimedOut(); +- } - }, null); + ((ca.spottedleaf.moonrise.patches.chunk_system.level.ChunkSystemServerLevel)this.chunkMap.level).moonrise$getChunkTaskScheduler().chunkHolderManager.tick(); // Paper - rewrite chunk system this.setDirty(); } public void deactivateTicketsOnClosing() { -- this.removeTicketIf(ticket -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets); -+ // Paper - rewrite chunk system - } - - public void removeTicketIf(Predicate predicate, @Nullable Long2ObjectOpenHashMap> tickets) { +- this.removeTicketIf((_long, ticket) -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets); +- } +- +- public void removeTicketIf(BiPredicate biPredicate, @Nullable Long2ObjectOpenHashMap> map) { - ObjectIterator>> objectIterator = this.tickets.long2ObjectEntrySet().fastIterator(); - boolean flag = false; - - while (objectIterator.hasNext()) { - Entry> entry = objectIterator.next(); - Iterator iterator = entry.getValue().iterator(); +- long longKey = entry.getLongKey(); - boolean flag1 = false; - boolean flag2 = false; - - while (iterator.hasNext()) { - Ticket ticket = iterator.next(); -- if (predicate.test(ticket)) { -- if (tickets != null) { -- List list = tickets.computeIfAbsent(entry.getLongKey(), chunkPos -> new ObjectArrayList<>(entry.getValue().size())); +- if (biPredicate.test(longKey, ticket)) { +- if (map != null) { +- List list = map.computeIfAbsent(longKey, chunkPos -> new ObjectArrayList<>(entry.getValue().size())); - list.add(ticket); - } - @@ -31359,11 +31397,11 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 - - if (flag2 || flag1) { - if (flag2 && this.loadingChunkUpdatedListener != null) { -- this.loadingChunkUpdatedListener.update(entry.getLongKey(), getTicketLevelAt(entry.getValue(), false), false); +- this.loadingChunkUpdatedListener.update(longKey, getTicketLevelAt(entry.getValue(), false), false); - } - - if (flag1 && this.simulationChunkUpdatedListener != null) { -- this.simulationChunkUpdatedListener.update(entry.getLongKey(), getTicketLevelAt(entry.getValue(), true), false); +- this.simulationChunkUpdatedListener.update(longKey, getTicketLevelAt(entry.getValue(), true), false); - } - - this.setDirty(); @@ -31372,10 +31410,13 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 - } - } - } -- ++ // Paper - rewrite chunk system ++ } + - if (flag) { - this.updateForcedChunks(); - } ++ public void removeTicketIf(Predicate predicate, @Nullable Long2ObjectOpenHashMap> tickets) { + throw new UnsupportedOperationException(); // Paper - rewrite chunk system } @@ -31401,7 +31442,7 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } public boolean updateChunkForced(ChunkPos chunkPos, boolean add) { -@@ -347,22 +271,20 @@ public class TicketStorage extends SavedData { +@@ -356,22 +273,20 @@ public class TicketStorage extends SavedData { } public LongSet getForceLoadedChunks() { @@ -31435,11 +31476,11 @@ index 03c6e64fc98a42475467b3d42a9af250777c853f..b072dee51b5c189986b1d940b90ffd72 } @FunctionalInterface -@@ -381,7 +303,7 @@ public class TicketStorage extends SavedData { +@@ -390,7 +305,7 @@ public class TicketStorage extends SavedData { } public void removeAllPluginRegionTickets(TicketType ticketType, int ticketLevel, org.bukkit.plugin.Plugin ticketIdentifier) { -- removeTicketIf(ticket -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null); +- removeTicketIf((chunkKey, ticket) -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null); + this.chunkMap.level.moonrise$getChunkTaskScheduler().chunkHolderManager.removeAllTicketsFor(ticketType, ticketLevel, ticketIdentifier); // Paper - rewrite chunk system } // Paper end @@ -31485,7 +31526,7 @@ index 8d98cba3830dc5dfb5cae9a6f5fedfffee0d2cd8..73962e79a0f3d892e3155443a1b84508 public interface NoiseBiomeSource { diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java -index 95bd1139401d49ddf443a64faca8cd30ca3b1a1d..ae3e6e31171b1bcfba1ae51a0941b52dda270acd 100644 +index 96e8dfb1ff24954656470925a1fc6280fe5e09d9..be6f37f91569c659c609e5e8d38671ca86f8cd95 100644 --- a/net/minecraft/world/level/block/Block.java +++ b/net/minecraft/world/level/block/Block.java @@ -305,7 +305,7 @@ public class Block extends BlockBehaviour implements ItemLike { @@ -31977,10 +32018,10 @@ index 92350434746f06bbf4a161c6bc42602de7b45220..1c24f38d21da1be9740512981f219924 public Property.Value value(T value) { diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java -index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d369dc0f01 100644 +index d1ae452f0aa96c36afe8b7ecddd3e06b06165878..182c14b660f8860bed627eed4e01fd4002153e9a 100644 --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick; +@@ -58,7 +58,7 @@ import net.minecraft.world.ticks.SavedTick; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -31989,7 +32030,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 public static final int NO_FILLED_SECTION = -1; private static final Logger LOGGER = LogUtils.getLogger(); private static final LongSet EMPTY_REFERENCE_SET = new LongOpenHashSet(); -@@ -75,7 +75,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -76,7 +76,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @Nullable protected BlendingData blendingData; public final Map heightmaps = Maps.newEnumMap(Heightmap.Types.class); @@ -31998,7 +32039,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 private final Map structureStarts = Maps.newHashMap(); private final Map structuresRefences = Maps.newHashMap(); protected final Map pendingBlockEntities = Maps.newHashMap(); -@@ -88,6 +88,57 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -89,6 +89,57 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh // CraftBukkit end public final Registry biomeRegistry; // CraftBukkit @@ -32056,7 +32097,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 public ChunkAccess( ChunkPos chunkPos, UpgradeData upgradeData, -@@ -105,7 +156,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -106,7 +157,7 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh this.inhabitedTime = inhabitedTime; this.postProcessing = new ShortList[levelHeightAccessor.getSectionsCount()]; this.blendingData = blendingData; @@ -32065,7 +32106,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 if (sections != null) { if (this.sections.length == sections.length) { System.arraycopy(sections, 0, this.sections, 0, this.sections.length); -@@ -116,6 +167,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -117,6 +168,16 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh this.replaceMissingSections(biomeRegistry, this.sections); // Paper - Anti-Xray - make it a non-static method this.biomeRegistry = biomeRegistry; // CraftBukkit @@ -32082,7 +32123,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 } private void replaceMissingSections(Registry biomeRegistry, LevelChunkSection[] sections) { // Paper - Anti-Xray - make it a non-static method -@@ -448,18 +509,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -445,18 +506,22 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh @Override public Holder getNoiseBiome(int x, int y, int z) { @@ -32116,7 +32157,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 } // CraftBukkit start public void setBiome(int x, int y, int z, Holder biome) { -@@ -509,12 +574,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh +@@ -506,12 +571,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh } public void initializeLightSources() { @@ -32130,7 +32171,7 @@ index 97231db28146df56c727c9765f36277634d59a64..3b7f0d5fe40bdda65ab859a0c22bf0d3 + return null; // Paper - rewrite chunk system } - public record PackedTicks(List> blocks, List> fluids) { + public static ProblemReporter.PathElement problemPath(ChunkPos pos) { diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java index 842f633a1e74ec9e405922bb40469c5d04d8f6e7..857aa6e29b57a0a8eea4d7c14971b9dde59bb0d0 100644 --- a/net/minecraft/world/level/chunk/ChunkGenerator.java @@ -32154,7 +32195,7 @@ index 842f633a1e74ec9e405922bb40469c5d04d8f6e7..857aa6e29b57a0a8eea4d7c14971b9dd if (startForStructure != null && startForStructure.isValid() && (!skipKnownStructures || tryAddReference(structureManager, startForStructure))) { return Pair.of(placement.getLocatePos(startForStructure.getChunkPos()), holder); diff --git a/net/minecraft/world/level/chunk/EmptyLevelChunk.java b/net/minecraft/world/level/chunk/EmptyLevelChunk.java -index d4016e0db6a370f2d1ed8ccae4f11aa85f63d56f..796ca48de2e9b87801646c7e404ef27025e915c7 100644 +index 0de3316ee56116b9fbabb7970b8e6dd7520229cf..b7cf517a87c7c03cf53cc91697157ee087af1cf7 100644 --- a/net/minecraft/world/level/chunk/EmptyLevelChunk.java +++ b/net/minecraft/world/level/chunk/EmptyLevelChunk.java @@ -13,7 +13,7 @@ import net.minecraft.world.level.block.state.BlockState; @@ -32295,10 +32336,10 @@ index 2ccb56f5befc1a93172e6ab81f93c785222ca6fb..d1331b580b3d27c77244b22a4ad15e71 @Override public BlockEntity getBlockEntity(BlockPos pos) { diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java -index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb8747fb8376 100644 +index 6f19586b4a39541c0fb895a18a0a4fd9b5da504c..75578e6ed7233a03d9b6cd3c6d3997f1c6148392 100644 --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -53,7 +53,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; +@@ -55,7 +55,7 @@ import net.minecraft.world.ticks.LevelChunkTicks; import net.minecraft.world.ticks.TickContainerAccess; import org.slf4j.Logger; @@ -32307,7 +32348,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 static final Logger LOGGER = LogUtils.getLogger(); private static final TickingBlockEntity NULL_TICKER = new TickingBlockEntity() { @Override -@@ -94,6 +94,39 @@ public class LevelChunk extends ChunkAccess { +@@ -96,6 +96,39 @@ public class LevelChunk extends ChunkAccess { // Paper start boolean loadedTicketLevel; // Paper end @@ -32347,7 +32388,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 public LevelChunk(Level level, ChunkPos pos) { this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null); -@@ -123,6 +156,14 @@ public class LevelChunk extends ChunkAccess { +@@ -125,6 +158,14 @@ public class LevelChunk extends ChunkAccess { this.postLoad = postLoad; this.blockTicks = blockTicks; this.fluidTicks = fluidTicks; @@ -32362,7 +32403,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 } public LevelChunk(ServerLevel level, ProtoChunk chunk, @Nullable LevelChunk.PostLoadProcessor postLoad) { -@@ -160,13 +201,19 @@ public class LevelChunk extends ChunkAccess { +@@ -162,13 +203,19 @@ public class LevelChunk extends ChunkAccess { } } @@ -32383,7 +32424,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 } public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) { -@@ -338,7 +385,7 @@ public class LevelChunk extends ChunkAccess { +@@ -340,7 +387,7 @@ public class LevelChunk extends ChunkAccess { if (LightEngine.hasDifferentLightProperties(blockState, state)) { ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("updateSkyLightSources"); @@ -32392,7 +32433,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 profilerFiller.popPush("queueCheckLight"); this.level.getChunkSource().getLightEngine().checkBlock(pos); profilerFiller.pop(); -@@ -581,11 +628,12 @@ public class LevelChunk extends ChunkAccess { +@@ -584,11 +631,12 @@ public class LevelChunk extends ChunkAccess { // CraftBukkit start public void loadCallback() { @@ -32406,7 +32447,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 if (server != null) { /* * If it's a new world, the first few chunks are generated inside -@@ -594,6 +642,7 @@ public class LevelChunk extends ChunkAccess { +@@ -597,6 +645,7 @@ public class LevelChunk extends ChunkAccess { */ org.bukkit.Chunk bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(bukkitChunk, this.needsDecoration)); @@ -32414,7 +32455,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 if (this.needsDecoration) { this.needsDecoration = false; -@@ -620,13 +669,15 @@ public class LevelChunk extends ChunkAccess { +@@ -623,13 +672,15 @@ public class LevelChunk extends ChunkAccess { } public void unloadCallback() { @@ -32432,7 +32473,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 // Paper start this.loadedTicketLevel = false; // Paper end -@@ -634,8 +685,31 @@ public class LevelChunk extends ChunkAccess { +@@ -637,8 +688,31 @@ public class LevelChunk extends ChunkAccess { @Override public boolean isUnsaved() { @@ -32465,7 +32506,7 @@ index 08e2442f6965cc6eaab67bdf9340a5152c08db2a..5d3fc807221392d378fec283bfdefb87 // CraftBukkit end public boolean isEmpty() { -@@ -710,6 +784,7 @@ public class LevelChunk extends ChunkAccess { +@@ -716,6 +790,7 @@ public class LevelChunk extends ChunkAccess { this.pendingBlockEntities.clear(); this.upgradeData.upgrade(this); @@ -32731,10 +32772,10 @@ index b4b973e453a093dcc04a6b7257883aa0065e2a89..a80b2e9dceea423180a9c390d1970317 boolean maybeHas(Predicate filter); diff --git a/net/minecraft/world/level/chunk/PalettedContainer.java b/net/minecraft/world/level/chunk/PalettedContainer.java -index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02f926bba0 100644 +index 9b0f17841230640f532ac33bb86e6585e88b5a57..a251ba67644cd02a0b00d7c8b0e2c64aa5e26291 100644 --- a/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -29,7 +29,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -28,7 +28,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer private final PaletteResize dummyPaletteResize = (bits, objectAdded) -> 0; public final IdMap registry; private final T @org.jetbrains.annotations.Nullable [] presetValues; // Paper - Anti-Xray - Add preset values @@ -32743,7 +32784,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 private final PalettedContainer.Strategy strategy; //private final ThreadingDetector threadingDetector = new ThreadingDetector("PalettedContainer"); // Paper - unused -@@ -75,6 +75,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -74,6 +74,33 @@ public class PalettedContainer implements PaletteResize, PalettedContainer ); } @@ -32777,7 +32818,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 // Paper start - Anti-Xray - Add preset values @Deprecated @io.papermc.paper.annotation.DoNotUse public PalettedContainer(IdMap registry, PalettedContainer.Strategy strategy, PalettedContainer.Configuration configuration, BitStorage storage, List values) { -@@ -109,6 +136,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -108,6 +135,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } } // Paper end @@ -32785,7 +32826,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } // Paper start - Anti-Xray - Add preset values -@@ -118,6 +146,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -117,6 +145,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = registry; this.strategy = strategy; this.data = data; @@ -32793,7 +32834,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } private PalettedContainer(PalettedContainer other, T @org.jetbrains.annotations.Nullable [] presetValues) { // Paper - Anti-Xray - Add preset values -@@ -139,6 +168,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -138,6 +167,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.registry = registry; this.data = this.createOrReuseData(null, 0); this.data.palette.idFor(palette); @@ -32801,7 +32842,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } private PalettedContainer.Data createOrReuseData(@Nullable PalettedContainer.Data data, int id) { -@@ -163,6 +193,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -162,6 +192,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer this.data = data1; // Paper start - Anti-Xray this.addPresetValues(); @@ -32809,7 +32850,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 return objectAdded == null ? -1 : data1.palette.idFor(objectAdded); } private void addPresetValues() { -@@ -192,9 +223,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -191,9 +222,12 @@ public class PalettedContainer implements PaletteResize, PalettedContainer } private T getAndSet(int index, T state) { @@ -32825,7 +32866,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } public synchronized void set(int x, int y, int z, T state) { // Paper - synchronize -@@ -217,9 +251,11 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -216,9 +250,11 @@ public class PalettedContainer implements PaletteResize, PalettedContainer return this.get(this.strategy.getIndex(x, y, z)); } @@ -32840,7 +32881,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } @Override -@@ -240,6 +276,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -239,6 +275,7 @@ public class PalettedContainer implements PaletteResize, PalettedContainer buffer.readFixedSizeLongArray(data.storage.getRaw()); this.data = data; this.addPresetValues(); // Paper - Anti-Xray - Add preset values (inefficient, but this isn't used by the server) @@ -32848,7 +32889,7 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 } finally { this.release(); } -@@ -390,7 +427,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer +@@ -389,7 +426,44 @@ public class PalettedContainer implements PaletteResize, PalettedContainer void accept(T state, int count); } @@ -32895,10 +32936,10 @@ index 1491401ec94038450ea5eeb589fc33a336a3ae55..7da7ce0fd19896593e63edc88b492c02 for (int i = 0; i < bitStorage.getSize(); i++) { T object = palette.valueFor(bitStorage.get(i)); diff --git a/net/minecraft/world/level/chunk/ProtoChunk.java b/net/minecraft/world/level/chunk/ProtoChunk.java -index 991263ac68d0fb2eeeda28c283ca6f80d5a10af3..13837d5508c34de3ccc49caac0d6c0ba7010d88a 100644 +index ea3a70a2c2e79ca898f0d3d5c7a8bce732150780..aa085d8a78a3fb40a214e4b152ab04d9a409f76f 100644 --- a/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -152,7 +152,7 @@ public class ProtoChunk extends ChunkAccess { +@@ -157,7 +157,7 @@ public class ProtoChunk extends ChunkAccess { } if (LightEngine.hasDifferentLightProperties(blockState, state)) { @@ -33059,28 +33100,28 @@ index f2aa944dedf917f01d669a703a9b9f4f35af78c2..116efc09663cac3b0f4b8c157e93201e this.chunkType = chunkType; this.heightmapsAfter = heightmapsAfter; diff --git a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -index dc9c612b245275900ae43f7a45e7be755853207c..8129d8a6807b6e770b65ba42441817af09521468 100644 +index ad1f1f46b347918b90e13094daaca1041cc0c3aa..c937fc1a80e47a694f5c052774f3aee45f0283e6 100644 --- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -182,7 +182,7 @@ public class ChunkStatusTasks { - if (protoChunk instanceof ImposterProtoChunk imposterProtoChunk) { - wrapped = imposterProtoChunk.getWrapped(); +@@ -189,7 +189,7 @@ public class ChunkStatusTasks { } else { -- wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities())); -+ wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> postLoadProtoChunk(serverLevel, protoChunk.getEntities(), protoChunk.getPos())); // Paper - rewrite chunk system + wrapped = new LevelChunk(serverLevel, protoChunk, chunk1 -> { + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) { +- postLoadProtoChunk(serverLevel, TagValueInput.create(scopedCollector, serverLevel.registryAccess(), protoChunk.getEntities())); ++ postLoadProtoChunk(serverLevel, TagValueInput.create(scopedCollector, serverLevel.registryAccess(), protoChunk.getEntities()), protoChunk.getPos()); // Paper - rewrite chunk system + } + }); generationChunkHolder.replaceProtoChunk(new ImposterProtoChunk(wrapped, false)); - } - -@@ -196,7 +196,7 @@ public class ChunkStatusTasks { +@@ -205,7 +205,7 @@ public class ChunkStatusTasks { }, worldGenContext.mainThreadExecutor()); } -- public static void postLoadProtoChunk(ServerLevel level, List entityTags) { -+ public static void postLoadProtoChunk(ServerLevel level, List entityTags, ChunkPos pos) { // Paper - rewrite chunk system - add ChunkPos param - if (!entityTags.isEmpty()) { +- public static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input) { ++ public static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input, ChunkPos pos) { // Paper - rewrite chunk system - add ChunkPos param + if (!input.isEmpty()) { // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities - level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD).filter((entity) -> { -@@ -208,7 +208,7 @@ public class ChunkStatusTasks { + level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD).filter((entity) -> { +@@ -217,7 +217,7 @@ public class ChunkStatusTasks { } checkDupeUUID(level, entity); // Paper - duplicate uuid resolving return !needsRemoval; @@ -33205,7 +33246,7 @@ index 7a4d299d2ce36982204e30de9278ddfd5b37c3df..b8348976e80578d9eff64eea68c04c60 private final ChunkStatus status; @Nullable diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java -index 273ba0bdcf2588ea12ecae03b6a566da24a34e2c..258a6b82b10bce1aecc42ddb61cb6732645c1ea0 100644 +index a8a32edea080f32fd25c9e009d4efa416a51a4cf..f6de972541fb2ed6d65aab06d61f5dcd0bfa1616 100644 --- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java +++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java @@ -22,20 +22,30 @@ import net.minecraft.world.level.chunk.ChunkGenerator; @@ -33244,7 +33285,7 @@ index 273ba0bdcf2588ea12ecae03b6a566da24a34e2c..258a6b82b10bce1aecc42ddb61cb6732 // CraftBukkit start @@ -66,7 +76,9 @@ public class ChunkStorage implements AutoCloseable { - chunkData = DataFixTypes.CHUNK.update(this.fixerUpper, chunkData, version, 1493); + chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter if (chunkData.getCompound("Level").flatMap(compoundTag -> compoundTag.getBoolean("hasLegacyStructureData")).orElse(false)) { LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage); + synchronized (legacyStructureHandler) { // Paper - rewrite chunk system @@ -33743,7 +33784,7 @@ index 763879cdc389fc4d80135b38aa96a5bec448ae9e..50bbd8c778bfa9fc9ce93ed09a6fe4dc public RegionStorageInfo info() { diff --git a/net/minecraft/world/level/chunk/storage/SectionStorage.java b/net/minecraft/world/level/chunk/storage/SectionStorage.java -index 7dc1ffffd9d0fec54dbc254c154ee85ee750174d..778bd73a938c94ecb85ca0f8b686ff4e1baee040 100644 +index 1686b499570518c01fcbcceee1f88025a535dbea..964dfe6c84ca947ec7165aff821588ad8513d467 100644 --- a/net/minecraft/world/level/chunk/storage/SectionStorage.java +++ b/net/minecraft/world/level/chunk/storage/SectionStorage.java @@ -40,10 +40,10 @@ import net.minecraft.world.level.ChunkPos; @@ -33883,10 +33924,10 @@ index 7dc1ffffd9d0fec54dbc254c154ee85ee750174d..778bd73a938c94ecb85ca0f8b686ff4e record PackedChunk(Int2ObjectMap sectionsByY, boolean versionChanged) { diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f064e36c3b 100644 +index 15417fab103feec3c1f7d5bd5b332e89d3ace3f5..2e6263d8b466e0f61bc72eb818044734b7d0ee6d 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -149,7 +149,7 @@ public record SerializableChunkData( +@@ -151,7 +151,7 @@ public record SerializableChunkData( UpgradeData upgradeData = tag.getCompound("UpgradeData") .map(compoundTag1 -> new UpgradeData(compoundTag1, levelHeightAccessor)) .orElse(UpgradeData.EMPTY); @@ -33895,7 +33936,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 BlendingData.Packed packed = tag.read("blending_data", BlendingData.Packed.CODEC).orElse(null); BelowZeroRetrogen belowZeroRetrogen = tag.read("below_zero_retrogen", BelowZeroRetrogen.CODEC).orElse(null); long[] longs = tag.getLongArray("carving_mask").orElse(null); -@@ -187,7 +187,7 @@ public record SerializableChunkData( +@@ -189,7 +189,7 @@ public record SerializableChunkData( for (int i2 = 0; i2 < listOrEmpty2.size(); i2++) { Optional compound = listOrEmpty2.getCompound(i2); if (!compound.isEmpty()) { @@ -33904,7 +33945,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 int byteOr = compoundTag.getByteOr("Y", (byte)0); LevelChunkSection levelChunkSection; if (byteOr >= levelHeightAccessor.getMinSectionY() && byteOr <= levelHeightAccessor.getMaxSectionY()) { -@@ -222,7 +222,17 @@ public record SerializableChunkData( +@@ -224,7 +224,17 @@ public record SerializableChunkData( DataLayer dataLayer = compoundTag.getByteArray("BlockLight").map(DataLayer::new).orElse(null); DataLayer dataLayer1 = compoundTag.getByteArray("SkyLight").map(DataLayer::new).orElse(null); @@ -33923,7 +33964,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 } } -@@ -250,6 +260,59 @@ public record SerializableChunkData( +@@ -252,6 +262,59 @@ public record SerializableChunkData( } } @@ -33983,7 +34024,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 public ProtoChunk read(ServerLevel level, PoiManager poiManager, RegionStorageInfo regionStorageInfo, ChunkPos pos) { if (!Objects.equals(pos, this.chunkPos)) { LOGGER.error("Chunk file at {} is in the wrong location; relocating. (Expected {}, got {})", pos, pos, this.chunkPos); -@@ -268,7 +331,7 @@ public record SerializableChunkData( +@@ -270,7 +333,7 @@ public record SerializableChunkData( SectionPos sectionPos = SectionPos.of(pos, sectionData.y); if (sectionData.chunkSection != null) { levelChunkSections[level.getSectionIndexFromSectionY(sectionData.y)] = sectionData.chunkSection; @@ -33992,7 +34033,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 } boolean flag1 = sectionData.blockLight != null; -@@ -350,7 +413,7 @@ public record SerializableChunkData( +@@ -352,7 +415,7 @@ public record SerializableChunkData( } if (chunkType == ChunkType.LEVELCHUNK) { @@ -34001,7 +34042,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 } else { ProtoChunk protoChunk1 = (ProtoChunk)chunkAccess; -@@ -366,7 +429,7 @@ public record SerializableChunkData( +@@ -368,7 +431,7 @@ public record SerializableChunkData( protoChunk1.setCarvingMask(new CarvingMask(this.carvingMask, chunkAccess.getMinY())); } @@ -34010,7 +34051,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 } } -@@ -394,22 +457,48 @@ public record SerializableChunkData( +@@ -396,22 +459,48 @@ public record SerializableChunkData( throw new IllegalArgumentException("Chunk can't be serialized: " + chunk); } else { ChunkPos pos = chunk.getPos(); @@ -34070,7 +34111,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 List list1 = new ArrayList<>(chunk.getBlockEntitiesPos().size()); -@@ -495,7 +584,7 @@ public record SerializableChunkData( +@@ -497,7 +586,7 @@ public record SerializableChunkData( Codec>> codec = makeBiomeCodec(this.biomeRegistry); for (SerializableChunkData.SectionData sectionData : this.sectionData) { @@ -34079,7 +34120,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 LevelChunkSection levelChunkSection = sectionData.chunkSection; if (levelChunkSection != null) { compoundTag1.store("block_states", BLOCK_STATE_CODEC, levelChunkSection.getStates()); -@@ -510,6 +599,19 @@ public record SerializableChunkData( +@@ -512,6 +601,19 @@ public record SerializableChunkData( compoundTag1.putByteArray("SkyLight", sectionData.skyLight.getData()); } @@ -34099,7 +34140,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 if (!compoundTag1.isEmpty()) { compoundTag1.putByte("Y", (byte)sectionData.y); listTag.add(compoundTag1); -@@ -544,6 +646,14 @@ public record SerializableChunkData( +@@ -546,6 +648,14 @@ public record SerializableChunkData( compoundTag.put("ChunkBukkitValues", this.persistentDataContainer); } // CraftBukkit end @@ -34114,7 +34155,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 return compoundTag; } -@@ -681,6 +791,66 @@ public record SerializableChunkData( +@@ -691,6 +801,66 @@ public record SerializableChunkData( } } @@ -34183,7 +34224,7 @@ index 58bc96235f0149ea868da3bc3d20472f96d5f6ec..03d1527073cf827fc3e191915fe5f7f0 } } diff --git a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java -index 6be673172548c1382c7402ec4e1ec6ef51f702d3..1d8c151c00ef1192792584b50fe15e102ef46d60 100644 +index 18750f1ea3101b6c0ab0b8e33c304eb7fa1ed04d..bf708ff89ea1f2c7279e48c41c4f44abc77ceebb 100644 --- a/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java +++ b/net/minecraft/world/level/chunk/storage/SimpleRegionStorage.java @@ -14,7 +14,7 @@ import net.minecraft.util.datafix.DataFixTypes; @@ -34309,7 +34350,7 @@ index 6d61739574155f89511b9adcaf1174841bdc7da7..65728ef17e63d71833677fdcbd5bb907 private ChunkAccess doFill(Blender blender, StructureManager structureManager, RandomState random, ChunkAccess chunk, int minCellY, int cellCountY) { diff --git a/net/minecraft/world/level/levelgen/structure/StructureCheck.java b/net/minecraft/world/level/levelgen/structure/StructureCheck.java -index 6a5451440751ad017324e3fec8cfd8efb118511b..48fce0845fb023d6286dac144c285b048d778564 100644 +index 4a3a05335e21008eb349e9ab221b54234d9ac200..7779a2f83f51465bde476776470bd77712f6be0d 100644 --- a/net/minecraft/world/level/levelgen/structure/StructureCheck.java +++ b/net/minecraft/world/level/levelgen/structure/StructureCheck.java @@ -48,8 +48,13 @@ public class StructureCheck { @@ -34840,10 +34881,10 @@ index 9dda7d19f3f6ca9b402ebe0e4b042ff859b5dcbd..0a5ae623a636923f3bbd3c01974497f3 @Nullable diff --git a/net/minecraft/world/phys/AABB.java b/net/minecraft/world/phys/AABB.java -index f6accdae9fa6c7bd02db92e113eb96fdd2e19d9b..c22acc8889fbb3c9ee698624189c195ee4b5eefb 100644 +index b0398510268e8f2acc9187b19a86af166c60861c..84f3073444ae9e11e5d11224d6af6474ced925e2 100644 --- a/net/minecraft/world/phys/AABB.java +++ b/net/minecraft/world/phys/AABB.java -@@ -315,7 +315,7 @@ public class AABB { +@@ -319,7 +319,7 @@ public class AABB { } @Nullable diff --git a/paper-server/patches/features/0016-Fix-entity-tracker-desync-when-new-players-are-added.patch b/paper-server/patches/features/0017-Fix-entity-tracker-desync-when-new-players-are-added.patch similarity index 87% rename from paper-server/patches/features/0016-Fix-entity-tracker-desync-when-new-players-are-added.patch rename to paper-server/patches/features/0017-Fix-entity-tracker-desync-when-new-players-are-added.patch index 4a6adb3c0a..78def5e8d4 100644 --- a/paper-server/patches/features/0016-Fix-entity-tracker-desync-when-new-players-are-added.patch +++ b/paper-server/patches/features/0017-Fix-entity-tracker-desync-when-new-players-are-added.patch @@ -48,7 +48,7 @@ index db31989ebe3d7021cfd2311439e9a00f819b0841..1373977b339405ef59bb3ea03d195285 serverEntity.getLastSentYRot(), entity.getType(), diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index 1463c31ba980ab0eb2174e3e891d1423a505e9dc..886340232b58afd59caa6df29e211589a7781070 100644 +index 61692c07dfb75ca0c19f603aafc96c0817861107..56a1d081a28e8b38384cfca732b103462693e322 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -1278,6 +1278,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -60,7 +60,7 @@ index 1463c31ba980ab0eb2174e3e891d1423a505e9dc..886340232b58afd59caa6df29e211589 } else if (this.seenBy.remove(player.connection)) { this.serverEntity.removePairing(player); diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java -index a1ae77b70f69852d9e4332bf1cb3409c33b21de0..b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954 100644 +index 3d5a8163a7dd78a195b77c4aaebdee2dc3dee64b..e96d4dee14c05f2fa329bfb1588ec795d4e3d730 100644 --- a/net/minecraft/server/level/ServerEntity.java +++ b/net/minecraft/server/level/ServerEntity.java @@ -103,6 +103,13 @@ public class ServerEntity { @@ -90,12 +90,12 @@ index a1ae77b70f69852d9e4332bf1cb3409c33b21de0..b118e91f1e0b5a8b8c0b2a4a32faabc5 long l1 = this.positionCodec.encodeY(vec3); long l2 = this.positionCodec.encodeZ(vec3); boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L; -- if (flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) { -+ if (this.forceStateResync || flag5 || this.teleportDelay > 400 || this.wasRiding || this.wasOnGround != this.entity.onGround()) { // Paper - fix desync when a player is added to the tracker - this.wasOnGround = this.entity.onGround(); - this.teleportDelay = 0; - packet = ClientboundEntityPositionSyncPacket.of(this.entity); -@@ -241,6 +248,7 @@ public class ServerEntity { +- if (this.entity.getRequiresPrecisePosition() ++ if (this.forceStateResync || this.entity.getRequiresPrecisePosition() // Paper - fix desync when a player is added to the tracker + || flag5 + || this.teleportDelay > 400 + || this.wasRiding +@@ -245,6 +252,7 @@ public class ServerEntity { } this.entity.hasImpulse = false; diff --git a/paper-server/patches/features/0017-Eigencraft-redstone-implementation.patch b/paper-server/patches/features/0018-Eigencraft-redstone-implementation.patch similarity index 100% rename from paper-server/patches/features/0017-Eigencraft-redstone-implementation.patch rename to paper-server/patches/features/0018-Eigencraft-redstone-implementation.patch diff --git a/paper-server/patches/features/0018-Add-Alternate-Current-redstone-implementation.patch b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch similarity index 99% rename from paper-server/patches/features/0018-Add-Alternate-Current-redstone-implementation.patch rename to paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch index c505fb79b8..fe1796186f 100644 --- a/paper-server/patches/features/0018-Add-Alternate-Current-redstone-implementation.patch +++ b/paper-server/patches/features/0019-Add-Alternate-Current-redstone-implementation.patch @@ -2326,10 +2326,10 @@ index 0000000000000000000000000000000000000000..298076a0db4e6ee6e4775ac43bf749d9 + } +} diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java -index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac2c7c3b6e 100644 +index f9c96bbdc54e68b9216b7f8662bfae03012d2866..34b7769663e235b93c6388ab0c92c00f0297e42f 100644 --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -210,6 +210,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -213,6 +213,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe public final java.util.UUID uuid; public boolean hasPhysicsEvent = true; // Paper - BlockPhysicsEvent public boolean hasEntityMoveEvent; // Paper - Add EntityMoveEvent @@ -2337,7 +2337,7 @@ index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac @Override public @Nullable LevelChunk getChunkIfLoaded(int x, int z) { -@@ -2552,6 +2553,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe +@@ -2591,6 +2592,13 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe return this.chunkSource.getGenerator().getSeaLevel(); } @@ -2352,10 +2352,10 @@ index 8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee..32db2b9e375c12cbf7abab69cc01e8ac @Override public void onCreated(Entity entity) { diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java -index eb4d03cfdb34243901cfba832d35559d5be9e876..013ed7dbe2309f562f63e66203179a90566e8115 100644 +index f286dd9996590e5d448ca809c34b6f640203e274..c41df4b1fff1f65532256e835dc30fadbb4f8c8b 100644 --- a/net/minecraft/world/level/Level.java +++ b/net/minecraft/world/level/Level.java -@@ -2096,6 +2096,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl +@@ -2093,6 +2093,17 @@ public abstract class Level implements LevelAccessor, UUIDLookup, AutoCl return 0; } diff --git a/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch b/paper-server/patches/features/0020-Improve-exact-choice-recipe-ingredients.patch similarity index 99% rename from paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch rename to paper-server/patches/features/0020-Improve-exact-choice-recipe-ingredients.patch index 733a8ab4db..d78ceed249 100644 --- a/paper-server/patches/features/0019-Improve-exact-choice-recipe-ingredients.patch +++ b/paper-server/patches/features/0020-Improve-exact-choice-recipe-ingredients.patch @@ -204,10 +204,10 @@ index 6d3e3ec045d5b15a435f7217369968b33e082724..b7a3758af337270737041f84d10eb437 int i = this.inventory.findSlotMatchingCraftingIngredient(item, item1); if (i == -1) { diff --git a/net/minecraft/world/entity/player/Inventory.java b/net/minecraft/world/entity/player/Inventory.java -index e25e0bd410f8822cb9a1118b39a786f44aabef7b..d9cb4f0ed0c4f63362c837aeef3c4194911455c9 100644 +index 46408ccee787b45e7957c12bfe426cb391f6e173..a6bb436dc80daf6901dc027a6011ead4b3ed27e2 100644 --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -234,12 +234,12 @@ public class Inventory implements Container, Nameable { +@@ -251,12 +251,12 @@ public class Inventory implements Container, Nameable { return !stack.isDamaged() && !stack.isEnchanted() && !stack.has(DataComponents.CUSTOM_NAME); } diff --git a/paper-server/patches/features/0021-Entity-load-save-limit-per-chunk.patch b/paper-server/patches/features/0021-Entity-load-save-limit-per-chunk.patch deleted file mode 100644 index 85d8aa9cf2..0000000000 --- a/paper-server/patches/features/0021-Entity-load-save-limit-per-chunk.patch +++ /dev/null @@ -1,81 +0,0 @@ -From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 -From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> -Date: Wed, 18 Nov 2020 20:52:25 -0800 -Subject: [PATCH] Entity load/save limit per chunk - -Adds a config option to limit the number of entities saved and loaded -to a chunk. The default values of -1 disable the limit. Although -defaults are only included for certain entites, this allows setting -limits for any entity type. - -diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -index 1c82dcd38f789707e15e8cbec72ef9cdc7efdf56..ba20e87d2105ce53cdaf4049de2388d05fcd1b56 100644 ---- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java -@@ -104,7 +104,18 @@ public final class ChunkEntitySlices { - } - - final ListTag entitiesTag = new ListTag(); -+ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { -+ // Paper start - Entity load/save limit per chunk -+ final EntityType entityType = entity.getType(); -+ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); -+ if (saveLimit > -1) { -+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { -+ continue; -+ } -+ savedEntityCounts.merge(entityType, 1, Integer::sum); -+ } -+ // Paper end - Entity load/save limit per chunk - CompoundTag compoundTag = new CompoundTag(); - if (entity.save(compoundTag)) { - entitiesTag.add(compoundTag); -diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java -index 4c57990c94721dd0973477669e1dadfab5f16404..8af02ed823da098a5592ef195c9fe8ed8f245b53 100644 ---- a/net/minecraft/world/entity/EntityType.java -+++ b/net/minecraft/world/entity/EntityType.java -@@ -1430,9 +1430,20 @@ public class EntityType implements FeatureElement, EntityTypeT - } - - public static Stream loadEntitiesRecursive(List entityTags, Level level, EntitySpawnReason spawnReason) { -+ final java.util.Map, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - return entityTags.stream() - .flatMap(tag -> tag.asCompound().stream()) - .mapMulti((compoundTag, consumer) -> loadEntityRecursive(compoundTag, level, spawnReason, entity -> { -+ // Paper start - Entity load/save limit per chunk -+ final EntityType entityType = entity.getType(); -+ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); -+ if (saveLimit > -1) { -+ if (loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { -+ return null; -+ } -+ loadedEntityCounts.merge(entityType, 1, Integer::sum); -+ } -+ // Paper end - Entity load/save limit per chunk - consumer.accept(entity); - return entity; - })); -diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java -index bcc2a4081fac07c4579c3aabfe4353743f8cd876..f9fb1380be9cbe960127c208c65c19f770e50b6d 100644 ---- a/net/minecraft/world/level/chunk/storage/EntityStorage.java -+++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java -@@ -87,7 +87,18 @@ public class EntityStorage implements EntityPersistentStorage { - } - } else { - ListTag listTag = new ListTag(); -+ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk - entities.getEntities().forEach(entity -> { -+ // Paper start - Entity load/save limit per chunk -+ final EntityType entityType = entity.getType(); -+ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); -+ if (saveLimit > -1) { -+ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { -+ return; -+ } -+ savedEntityCounts.merge(entityType, 1, Integer::sum); -+ } -+ // Paper end - Entity load/save limit per chunk - CompoundTag compoundTag1 = new CompoundTag(); - if (entity.save(compoundTag1)) { - listTag.add(compoundTag1); diff --git a/paper-server/patches/features/0020-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch b/paper-server/patches/features/0021-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch similarity index 100% rename from paper-server/patches/features/0020-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch rename to paper-server/patches/features/0021-Only-write-chunk-data-to-disk-if-it-serializes-witho.patch diff --git a/paper-server/patches/features/0022-Entity-load-save-limit-per-chunk.patch b/paper-server/patches/features/0022-Entity-load-save-limit-per-chunk.patch new file mode 100644 index 0000000000..90dcdaabd4 --- /dev/null +++ b/paper-server/patches/features/0022-Entity-load-save-limit-per-chunk.patch @@ -0,0 +1,80 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Jason Penilla <11360596+jpenilla@users.noreply.github.com> +Date: Wed, 18 Nov 2020 20:52:25 -0800 +Subject: [PATCH] Entity load/save limit per chunk + +Adds a config option to limit the number of entities saved and loaded +to a chunk. The default values of -1 disable the limit. Although +defaults are only included for certain entites, this allows setting +limits for any entity type. + +diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +index c380487a97f626163e1f13d87231d64ce2ea4b24..b2bcfb3557a0326fd7ec1059f95d6da4568dfd80 100644 +--- a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java ++++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/ChunkEntitySlices.java +@@ -116,8 +116,19 @@ public final class ChunkEntitySlices { + } + + final ListTag entitiesTag = new ListTag(); ++ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk + try (final ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(chunkPos), LOGGER)) { + for (final Entity entity : PlatformHooks.get().modifySavedEntities(world, chunkPos.x, chunkPos.z, entities)) { ++ // Paper start - Entity load/save limit per chunk ++ final EntityType entityType = entity.getType(); ++ final int saveLimit = world.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); ++ if (saveLimit > -1) { ++ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { ++ continue; ++ } ++ savedEntityCounts.merge(entityType, 1, Integer::sum); ++ } ++ // Paper end - Entity load/save limit per chunk + final TagValueOutput savedEntity = TagValueOutput.createWithContext( + scopedCollector.forChild(entity.problemPath()), entity.registryAccess() + ); +diff --git a/net/minecraft/world/entity/EntityType.java b/net/minecraft/world/entity/EntityType.java +index 98586dfc562cf6909df0f4bfa1c19e35b3172abe..f92adee1c187561d3790a5a5c8c81f5e1543ed97 100644 +--- a/net/minecraft/world/entity/EntityType.java ++++ b/net/minecraft/world/entity/EntityType.java +@@ -1448,7 +1448,18 @@ public class EntityType implements FeatureElement, EntityTypeT + } + + public static Stream loadEntitiesRecursive(ValueInput.ValueInputList input, Level level, EntitySpawnReason spawnReason) { ++ final java.util.Map, Integer> loadedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk + return input.stream().mapMulti((valueInput, consumer) -> loadEntityRecursive(valueInput, level, spawnReason, entity -> { ++ // Paper start - Entity load/save limit per chunk ++ final EntityType entityType = entity.getType(); ++ final int saveLimit = level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); ++ if (saveLimit > -1) { ++ if (loadedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { ++ return null; ++ } ++ loadedEntityCounts.merge(entityType, 1, Integer::sum); ++ } ++ // Paper end - Entity load/save limit per chunk + consumer.accept(entity); + return entity; + })); +diff --git a/net/minecraft/world/level/chunk/storage/EntityStorage.java b/net/minecraft/world/level/chunk/storage/EntityStorage.java +index bf45cce4db77966d44d7a8d97673bb6631a6adaf..f1f8575a4b37114ced3cdb1d2ea33a36a2db44fd 100644 +--- a/net/minecraft/world/level/chunk/storage/EntityStorage.java ++++ b/net/minecraft/world/level/chunk/storage/EntityStorage.java +@@ -95,7 +95,18 @@ public class EntityStorage implements EntityPersistentStorage { + } else { + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(ChunkAccess.problemPath(pos), LOGGER)) { + ListTag listTag = new ListTag(); ++ final java.util.Map, Integer> savedEntityCounts = new java.util.HashMap<>(); // Paper - Entity load/save limit per chunk + entities.getEntities().forEach(entity -> { ++ // Paper start - Entity load/save limit per chunk ++ final EntityType entityType = entity.getType(); ++ final int saveLimit = this.level.paperConfig().chunks.entityPerChunkSaveLimit.getOrDefault(entityType, -1); ++ if (saveLimit > -1) { ++ if (savedEntityCounts.getOrDefault(entityType, 0) >= saveLimit) { ++ return; ++ } ++ savedEntityCounts.merge(entityType, 1, Integer::sum); ++ } ++ // Paper end - Entity load/save limit per chunk + TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector.forChild(entity.problemPath()), entity.registryAccess()); + if (entity.save(tagValueOutput)) { + CompoundTag compoundTag1 = tagValueOutput.buildResult(); diff --git a/paper-server/patches/features/0022-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch b/paper-server/patches/features/0023-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch similarity index 99% rename from paper-server/patches/features/0022-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch rename to paper-server/patches/features/0023-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch index e526626af1..c24795f73f 100644 --- a/paper-server/patches/features/0022-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch +++ b/paper-server/patches/features/0023-Attempt-to-recalculate-regionfile-header-if-it-is-co.patch @@ -778,10 +778,10 @@ index 1649119f45d970a9bf1683d676c47ecfc18ad047..cc544f3199cd6af29e50362923d06517 public static final RegionFileVersion VERSION_GZIP = register( new RegionFileVersion( diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -index 03d1527073cf827fc3e191915fe5f7f064e36c3b..749096358fccbd5d1d13801092255c51096eb001 100644 +index 2e6263d8b466e0f61bc72eb818044734b7d0ee6d..e04d3479383cd480cf35ed7ac3c82e7f6fb69e28 100644 --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -122,6 +122,18 @@ public record SerializableChunkData( +@@ -124,6 +124,18 @@ public record SerializableChunkData( } } // Paper end - guard against serializing mismatching coordinates @@ -799,8 +799,8 @@ index 03d1527073cf827fc3e191915fe5f7f064e36c3b..749096358fccbd5d1d13801092255c51 + // Paper end - Attempt to recalculate regionfile header if it is corrupt // Paper start - Do not let the server load chunks from newer versions - private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); -@@ -571,7 +583,7 @@ public record SerializableChunkData( + private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().version(); +@@ -573,7 +585,7 @@ public record SerializableChunkData( compoundTag.putInt("xPos", this.chunkPos.x); compoundTag.putInt("yPos", this.minSectionY); compoundTag.putInt("zPos", this.chunkPos.z); diff --git a/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch b/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch similarity index 89% rename from paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch rename to paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch index ae7d01be8e..197e61f563 100644 --- a/paper-server/patches/features/0023-Incremental-chunk-and-player-saving.patch +++ b/paper-server/patches/features/0024-Incremental-chunk-and-player-saving.patch @@ -5,10 +5,10 @@ Subject: [PATCH] Incremental chunk and player saving diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921da8671e87 100644 +index 80442494db670fec34df310390ea787fb963eef4..2dd512565ab901bf853f34b384155902b0fe8120 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements AutoCloseable, ca.spottedleaf.moonr diff --git a/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch b/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch similarity index 97% rename from paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch rename to paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch index b521f05eb7..93df896305 100644 --- a/paper-server/patches/features/0025-Optional-per-player-mob-spawns.patch +++ b/paper-server/patches/features/0026-Optional-per-player-mob-spawns.patch @@ -5,7 +5,7 @@ Subject: [PATCH] Optional per player mob spawns diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index 886340232b58afd59caa6df29e211589a7781070..4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957 100644 +index 86ba02916c4a1c1311eeca5b1fb10a46626ba9ab..b40b94c49dc0997654aca0a1a0dffe482cd14eac 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -243,11 +243,29 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -43,7 +43,7 @@ index 886340232b58afd59caa6df29e211589a7781070..4f4bcc4bbfcc9b191d12d667b8fc1e64 protected ChunkGenerator generator() { return this.worldGenContext.generator(); diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378eca2cf650b 100644 +index 8e9988130d9b912e5b858cd7792bdcefdeb66ada..25d74f866546362a17505b5d4abf85382c0df20c 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -541,9 +541,18 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -78,10 +78,10 @@ index 5d63bf024cbcbd2f627c64fee77553c9a512bd15..f863377a807b672f49f7140688f378ec profiler.popPush("tickSpawningChunks"); diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index 4b2801749328f250ce5735fbe7f6941a6bede01a..af04fcdba1e57b4eac678235b56ad3e1c70169b7 100644 +index b70929df38389d789dad46c0a6d94f6c08aa7eba..e96bb37bb7a7340a7ee33046820652ecd4accc53 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -395,6 +395,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -406,6 +406,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public boolean queueHealthUpdatePacket; public @Nullable net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket; // Paper end - cancellable death event diff --git a/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch b/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch similarity index 93% rename from paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch rename to paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch index 0f67c9da6d..7a941a9142 100644 --- a/paper-server/patches/features/0026-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch +++ b/paper-server/patches/features/0027-Improve-cancelling-PreCreatureSpawnEvent-with-per-pl.patch @@ -6,7 +6,7 @@ Subject: [PATCH] Improve cancelling PreCreatureSpawnEvent with per player mob diff --git a/net/minecraft/server/level/ChunkMap.java b/net/minecraft/server/level/ChunkMap.java -index 4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957..0d8aefe8c886eaa4c33cbab53b0ad1c016f0531f 100644 +index b40b94c49dc0997654aca0a1a0dffe482cd14eac..b72000ce6bdcb97b787bfab79236f60bdb4aa2ee 100644 --- a/net/minecraft/server/level/ChunkMap.java +++ b/net/minecraft/server/level/ChunkMap.java @@ -262,8 +262,25 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider @@ -37,7 +37,7 @@ index 4f4bcc4bbfcc9b191d12d667b8fc1e644a9d5957..0d8aefe8c886eaa4c33cbab53b0ad1c0 // Paper end - Optional per player mob spawns diff --git a/net/minecraft/server/level/ServerChunkCache.java b/net/minecraft/server/level/ServerChunkCache.java -index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d77584d8cc 100644 +index 25d74f866546362a17505b5d4abf85382c0df20c..7d78d270b7a076f595301acd9b3c6275e804496e 100644 --- a/net/minecraft/server/level/ServerChunkCache.java +++ b/net/minecraft/server/level/ServerChunkCache.java @@ -546,7 +546,17 @@ public class ServerChunkCache extends ChunkSource implements ca.spottedleaf.moon @@ -60,10 +60,10 @@ index f863377a807b672f49f7140688f378eca2cf650b..59e8a5e1b35c81883c9b1ca00c6e55d7 spawnState = NaturalSpawner.createState(naturalSpawnChunkCount, this.level.getAllEntities(), this::getFullChunk, null, true); } else { diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java -index af04fcdba1e57b4eac678235b56ad3e1c70169b7..3781d9cc174b7aecacb9b9855d52c7b1ff05835c 100644 +index e96bb37bb7a7340a7ee33046820652ecd4accc53..53f038e1b5e7a13a08a0c925c8bd3f8a40868195 100644 --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -399,6 +399,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc +@@ -410,6 +410,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc public static final int MOBCATEGORY_TOTAL_ENUMS = net.minecraft.world.entity.MobCategory.values().length; public final int[] mobCounts = new int[MOBCATEGORY_TOTAL_ENUMS]; // Paper end - Optional per player mob spawns diff --git a/paper-server/patches/features/0027-Optimize-Hoppers.patch b/paper-server/patches/features/0028-Optimize-Hoppers.patch similarity index 97% rename from paper-server/patches/features/0027-Optimize-Hoppers.patch rename to paper-server/patches/features/0028-Optimize-Hoppers.patch index 6cf9616f88..96481082bc 100644 --- a/paper-server/patches/features/0027-Optimize-Hoppers.patch +++ b/paper-server/patches/features/0028-Optimize-Hoppers.patch @@ -48,10 +48,10 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf + } +} diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java -index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df6188de3a0e9 100644 +index 2dd512565ab901bf853f34b384155902b0fe8120..d6dcb6d146d89a8fb96e7c669e5deb802223abd6 100644 --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop 0; // Paper - BlockPhysicsEvent serverLevel.hasEntityMoveEvent = io.papermc.paper.event.entity.EntityMoveEvent.getHandlerList().getRegisteredListeners().length > 0; // Paper - Add EntityMoveEvent serverLevel.updateLagCompensationTick(); // Paper - lag compensation @@ -60,10 +60,10 @@ index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df618 /* Drop global time updates if (this.tickCount % 20 == 0) { diff --git a/net/minecraft/world/item/ItemStack.java b/net/minecraft/world/item/ItemStack.java -index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064f78eefa0 100644 +index fc91f7f5ca01f1afe6ceb21f12d1a6ec6f5b68f9..cf283389d9263ba29720bf296a778be9eaf308a7 100644 --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -831,10 +831,16 @@ public final class ItemStack implements DataComponentHolder { +@@ -811,10 +811,16 @@ public final class ItemStack implements DataComponentHolder { } public ItemStack copy() { @@ -83,10 +83,10 @@ index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064 return itemStack; } diff --git a/net/minecraft/world/level/block/entity/BlockEntity.java b/net/minecraft/world/level/block/entity/BlockEntity.java -index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81aa9d34c48 100644 +index 275646a9f99f3c46bc81a23143c1960f2a6300b1..5986825d6a381eeb445dd424dd127864aa703163 100644 --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -33,6 +33,7 @@ import net.minecraft.world.level.block.state.BlockState; +@@ -35,6 +35,7 @@ import net.minecraft.world.level.storage.ValueOutput; import org.slf4j.Logger; public abstract class BlockEntity { @@ -94,7 +94,7 @@ index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81a // CraftBukkit start - data containers private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry(); public final org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer; -@@ -202,6 +203,7 @@ public abstract class BlockEntity { +@@ -227,6 +228,7 @@ public abstract class BlockEntity { public void setChanged() { if (this.level != null) { @@ -103,7 +103,7 @@ index 7783ff94e5183737d01c75c521b70b4fbd8c34a6..a1075c26d55cc01219acd94d0138f81a } } diff --git a/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/net/minecraft/world/level/block/entity/HopperBlockEntity.java -index 9a03934dd4d96184f37b9ff5661eb7bd76150464..15d4f60942c0cc612c1468b4c0fda886867a67cb 100644 +index 94d68fbb3d152b2fd43f989b728c5efabbf3c22c..800b7e78ae989868ed0b9e060c80dcd002759412 100644 --- a/net/minecraft/world/level/block/entity/HopperBlockEntity.java +++ b/net/minecraft/world/level/block/entity/HopperBlockEntity.java @@ -143,18 +143,56 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen @@ -669,7 +669,7 @@ index 9a03934dd4d96184f37b9ff5661eb7bd76150464..15d4f60942c0cc612c1468b4c0fda886 @Override diff --git a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java -index 1c98d003907feb16de8f26377fceedf728afe7fb..eed5f8f912544b79c8ed54dcdc5eeacb6dcfaccd 100644 +index d2cd30ed072a3d75c32b49a72920a9c26ce29922..dc59465d63e36bd50a48a8ea4197424556736552 100644 --- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -54,7 +54,7 @@ public abstract class RandomizableContainerBlockEntity extends BaseContainerBloc diff --git a/paper-server/patches/features/0028-Flush-regionfiles-on-save-configuration-option.patch b/paper-server/patches/features/0029-Flush-regionfiles-on-save-configuration-option.patch similarity index 94% rename from paper-server/patches/features/0028-Flush-regionfiles-on-save-configuration-option.patch rename to paper-server/patches/features/0029-Flush-regionfiles-on-save-configuration-option.patch index d7b455d7eb..7f331c737b 100644 --- a/paper-server/patches/features/0028-Flush-regionfiles-on-save-configuration-option.patch +++ b/paper-server/patches/features/0029-Flush-regionfiles-on-save-configuration-option.patch @@ -14,7 +14,7 @@ timestamp so that fs watchers can detect when RegionFiles are modified. diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java -index 1acea58838f057ab87efd103cbecb6f5aeaef393..98fbc5c8044bd945d64569f13412a6e7e49a4e7f 100644 +index 09320f243a54f855b29d3833089b096975ca0075..709df35246fb328cda21679b53d44d9f96206cb3 100644 --- a/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java +++ b/ca/spottedleaf/moonrise/patches/chunk_system/io/MoonriseRegionFileIO.java @@ -1258,6 +1258,14 @@ public final class MoonriseRegionFileIO { diff --git a/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch b/paper-server/patches/features/0030-Optimise-collision-checking-in-player-move-packet-ha.patch similarity index 71% rename from paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch rename to paper-server/patches/features/0030-Optimise-collision-checking-in-player-move-packet-ha.patch index b00faac56b..73a0f055bd 100644 --- a/paper-server/patches/features/0029-Optimise-collision-checking-in-player-move-packet-ha.patch +++ b/paper-server/patches/features/0030-Optimise-collision-checking-in-player-move-packet-ha.patch @@ -6,53 +6,43 @@ Subject: [PATCH] Optimise collision checking in player move packet handling Move collision logic to just the hasNewCollision call instead of getCubes + hasNewCollision diff --git a/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a195b8302 100644 +index c9a0df5e5617e62703787942d067883ea537618b..aeb43902a09ef9c1b137964065780be3e87648f4 100644 --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -555,7 +555,7 @@ public class ServerGamePacketListenerImpl - return; - } - -- boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625)); -+ final AABB oldBox = rootVehicle.getBoundingBox(); // Paper - copy from player movement packet - d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above - d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above - d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above -@@ -565,6 +565,7 @@ public class ServerGamePacketListenerImpl +@@ -592,6 +592,7 @@ public class ServerGamePacketListenerImpl } rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5)); + final boolean didCollide = toX != rootVehicle.getX() || toY != rootVehicle.getY() || toZ != rootVehicle.getZ(); // Paper - needed here as the difference in Y can be reset - also note: this is only a guess at whether collisions took place, floating point errors can make this true when it shouldn't be... - double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost + double verticalDelta = d4; d3 = d - rootVehicle.getX(); d4 = d1 - rootVehicle.getY(); -@@ -576,14 +577,22 @@ public class ServerGamePacketListenerImpl +@@ -603,12 +604,21 @@ public class ServerGamePacketListenerImpl d7 = d3 * d3 + d4 * d4 + d5 * d5; - boolean flag2 = false; + boolean flag1 = false; if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot -- flag2 = true; -+ flag2 = true; // Paper - diff on change, this should be moved wrongly +- flag1 = true; ++ flag1 = true; // Paper - diff on change, this should be moved wrongly LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7)); } - rootVehicle.absSnapTo(d, d1, d2, f, f1); - this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit -- boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625)); -- if (flag && (flag2 || !flag3)) { +- if (flag1 && serverLevel.noCollision(rootVehicle, boundingBox) +- || this.isEntityCollidingWithAnythingNew(serverLevel, rootVehicle, boundingBox, d, d1, d2)) { + // Paper start - optimise out extra getCubes -+ boolean teleportBack = flag2; // violating this is always a fail ++ boolean teleportBack = flag1; + if (!teleportBack) { + // note: only call after setLocation, or else getBoundingBox is wrong + final AABB newBox = rootVehicle.getBoundingBox(); -+ if (didCollide || !oldBox.equals(newBox)) { -+ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, oldBox, newBox); ++ if (didCollide || !boundingBox.equals(newBox)) { ++ teleportBack = this.hasNewCollision(serverLevel, rootVehicle, boundingBox, newBox); + } // else: no collision at all detected, why do we care? + } -+ if (teleportBack) { // Paper end - optimise out extra getCubes ++ if (teleportBack) { ++ // Paper end - optimise out extra getCubes rootVehicle.absSnapTo(x, y, z, f, f1); - this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle)); -@@ -661,9 +670,32 @@ public class ServerGamePacketListenerImpl + rootVehicle.removeLatestMovementRecording(); +@@ -687,9 +697,32 @@ public class ServerGamePacketListenerImpl } private boolean noBlocksAround(Entity entity) { @@ -88,7 +78,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a } @Override -@@ -1432,7 +1464,7 @@ public class ServerGamePacketListenerImpl +@@ -1465,7 +1498,7 @@ public class ServerGamePacketListenerImpl } } @@ -97,7 +87,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a d3 = d - this.lastGoodX; // Paper - diff on change, used for checking large move vectors above d4 = d1 - this.lastGoodY; // Paper - diff on change, used for checking large move vectors above d5 = d2 - this.lastGoodZ; // Paper - diff on change, used for checking large move vectors above -@@ -1471,6 +1503,7 @@ public class ServerGamePacketListenerImpl +@@ -1504,6 +1537,7 @@ public class ServerGamePacketListenerImpl boolean flag1 = this.player.verticalCollisionBelow; this.player.move(MoverType.PLAYER, new Vec3(d3, d4, d5)); this.player.onGround = packet.isOnGround(); // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move @@ -105,26 +95,26 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a // Paper start - prevent position desync if (this.awaitingPositionFromClient != null) { return; // ... thanks Mojang for letting move calls teleport across dimensions. -@@ -1503,7 +1536,17 @@ public class ServerGamePacketListenerImpl +@@ -1536,7 +1570,17 @@ public class ServerGamePacketListenerImpl } // Paper start - Add fail move event -- boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)); +- boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || (!movedWrongly || !serverLevel.noCollision(this.player, boundingBox)) && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2); + // Paper start - optimise out extra getCubes -+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && movedWrongly; ++ boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || !movedWrongly; + this.player.absSnapTo(d, d1, d2, f, f1); // prevent desync by tping to the set position, dropped for unknown reasons by mojang -+ if (!this.player.noPhysics && !this.player.isSleeping() && !teleportBack) { ++ if (!this.player.noPhysics && !this.player.isSleeping() && allowMovement) { + final AABB newBox = this.player.getBoundingBox(); + if (didCollide || !boundingBox.equals(newBox)) { + // note: only call after setLocation, or else getBoundingBox is wrong -+ teleportBack = this.hasNewCollision(serverLevel, this.player, boundingBox, newBox); ++ allowMovement = !this.hasNewCollision(serverLevel, this.player, boundingBox, newBox); + } // else: no collision at all detected, why do we care? + } + // Paper end - optimise out extra getCubes - if (teleportBack) { + if (!allowMovement) { io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, toX, toY, toZ, toYaw, toPitch, false); -@@ -1640,7 +1683,7 @@ public class ServerGamePacketListenerImpl +@@ -1672,7 +1716,7 @@ public class ServerGamePacketListenerImpl private boolean updateAwaitingTeleport() { if (this.awaitingPositionFromClient != null) { @@ -133,7 +123,7 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a this.awaitingTeleportTime = this.tickCount; this.teleport( this.awaitingPositionFromClient.x, -@@ -1659,6 +1702,33 @@ public class ServerGamePacketListenerImpl +@@ -1691,6 +1735,33 @@ public class ServerGamePacketListenerImpl } } @@ -164,6 +154,6 @@ index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a + return false; + } + // Paper end - optimise out extra getCubes - private boolean isPlayerCollidingWithAnythingNew(LevelReader level, AABB box, double x, double y, double z) { - AABB aabb = this.player.getBoundingBox().move(x - this.player.getX(), y - this.player.getY(), z - this.player.getZ()); - Iterable collisions = level.getCollisions(this.player, aabb.deflate(1.0E-5F)); + private boolean isEntityCollidingWithAnythingNew(LevelReader levelReader, Entity entity, AABB aabb, double d, double d1, double d2) { + AABB aabb1 = entity.getBoundingBox().move(d - entity.getX(), d1 - entity.getY(), d2 - entity.getZ()); + Iterable preMoveCollisions = levelReader.getPreMoveCollisions(entity, aabb1.deflate(1.0E-5F), aabb.getBottomCenter()); diff --git a/paper-server/patches/features/0031-DataConverter-Fixes.patch b/paper-server/patches/features/0031-DataConverter-Fixes.patch new file mode 100644 index 0000000000..78f9a419ad --- /dev/null +++ b/paper-server/patches/features/0031-DataConverter-Fixes.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com> +Date: Sat, 7 Jun 2025 15:05:05 -0400 +Subject: [PATCH] DataConverter Fixes + + +diff --git a/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java +index d2877c20f389d0131e1dd208b464f590671e5d82..27bdc70d861ca39487ad16cb3afb89d604b462c8 100644 +--- a/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java ++++ b/ca/spottedleaf/dataconverter/minecraft/versions/V4307.java +@@ -87,10 +87,10 @@ public final class V4307 { + + @Override + public MapType convert(final MapType root, final long sourceVersion, final long toVersion) { +- final Set hiddenComponents = new LinkedHashSet<>(); +- +- unwrapBlockPredicates(root, "minecraft:can_break", hiddenComponents); ++ // Don't use a linked hash set, and ensure that it is added in the same (undefined) order as the vanilla datafixer ++ final Set hiddenComponents = new java.util.HashSet<>(); + unwrapBlockPredicates(root, "minecraft:can_place_on", hiddenComponents); ++ unwrapBlockPredicates(root, "minecraft:can_break", hiddenComponents); + + updateComponent(root, "minecraft:trim", hiddenComponents); + updateComponent(root, "minecraft:unbreakable", hiddenComponents); diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch index d736409b62..2701d3e9a7 100644 --- a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch +++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/PaperHooks.java.patch @@ -1,6 +1,6 @@ --- /dev/null +++ b/ca/spottedleaf/moonrise/paper/PaperHooks.java -@@ -1,0 +_,241 @@ +@@ -1,0 +_,250 @@ +package ca.spottedleaf.moonrise.paper; + +import ca.spottedleaf.moonrise.common.PlatformHooks; @@ -33,6 +33,8 @@ + +public final class PaperHooks extends BaseChunkSystemHooks implements PlatformHooks { + ++ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); ++ + @Override + public String getBrand() { + return "Paper"; @@ -150,6 +152,11 @@ + } + + @Override ++ public long[] getCounterTypesUncached(final net.minecraft.server.level.TicketType type) { ++ return new long[0]; ++ } ++ ++ @Override + public boolean configFixMC224294() { + return true; + } @@ -234,7 +241,9 @@ + + @Override + public void postLoadProtoChunk(final ServerLevel world, final ProtoChunk chunk) { -+ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, chunk.getEntities()); ++ try (final net.minecraft.util.ProblemReporter.ScopedCollector scopedCollector = new net.minecraft.util.ProblemReporter.ScopedCollector(chunk.problemPath(), LOGGER)) { ++ net.minecraft.world.level.chunk.status.ChunkStatusTasks.postLoadProtoChunk(world, net.minecraft.world.level.storage.TagValueInput.create(scopedCollector, world.registryAccess(), chunk.getEntities())); ++ } + } + + @Override diff --git a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch index 3f95b375a8..71b326b986 100644 --- a/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch +++ b/paper-server/patches/sources/ca/spottedleaf/moonrise/paper/util/BaseChunkSystemHooks.java.patch @@ -300,7 +300,7 @@ + + @Override + public int getViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + if (level == null) { + return Bukkit.getViewDistance(); + } @@ -309,7 +309,7 @@ + + @Override + public int getTickViewDistance(final ServerPlayer player) { -+ final ServerLevel level = player.serverLevel(); ++ final ServerLevel level = player.level(); + if (level == null) { + return Bukkit.getSimulationDistance(); + } diff --git a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch index 1254bdfc94..13c5dc9238 100644 --- a/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch +++ b/paper-server/patches/sources/com/mojang/brigadier/tree/CommandNode.java.patch @@ -10,7 +10,7 @@ private final RedirectModifier modifier; private final boolean forks; private Command command; -+ public CommandNode clientNode; // Paper - Brigadier API ++ public CommandNode clientNode; // Paper - Brigadier API + public CommandNode unwrappedCached = null; // Paper - Brigadier Command API + public CommandNode wrappedCached = null; // Paper - Brigadier Command API + public io.papermc.paper.command.brigadier.APICommandMeta apiCommandMeta; // Paper - Brigadier Command API @@ -24,25 +24,6 @@ protected CommandNode(final Command command, final Predicate requirement, final CommandNode redirect, final RedirectModifier modifier, final boolean forks) { this.command = command; -@@ -61,7 +_,17 @@ - return modifier; - } - -- public boolean canUse(final S source) { -+ // CraftBukkit start -+ public synchronized boolean canUse(final S source) { -+ if (source instanceof final net.minecraft.commands.CommandSourceStack css) { -+ try { -+ css.currentCommand.put(Thread.currentThread(), this); // Paper - Thread Safe Vanilla Command permission checking -+ return this.requirement.test(source); -+ } finally { -+ css.currentCommand.remove(Thread.currentThread()); // Paper - Thread Safe Vanilla Command permission checking -+ } -+ } -+ // CraftBukkit end - return requirement.test(source); - } - @@ -151,6 +_,12 @@ protected abstract String getSortedKey(); diff --git a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch index cdbc56fdd1..bfc7cf4e96 100644 --- a/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch +++ b/paper-server/patches/sources/io/papermc/paper/FeatureHooks.java.patch @@ -64,7 +64,7 @@ + + public static Set getSentChunks(final ServerPlayer player) { + final ObjectSet chunks = new ObjectOpenHashSet<>(); -+ final World world = player.serverLevel().getWorld(); ++ final World world = player.level().getWorld(); + player.getChunkTrackingView().forEach(pos -> { + final org.bukkit.Chunk chunk = world.getChunkAt(pos.longKey); + chunks.add(chunk); diff --git a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch index b008af84c3..ebf5edef1b 100644 --- a/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/CommandSourceStack.java.patch @@ -1,24 +1,23 @@ --- a/net/minecraft/commands/CommandSourceStack.java +++ b/net/minecraft/commands/CommandSourceStack.java -@@ -45,7 +_,7 @@ +@@ -47,7 +_,7 @@ import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; --public class CommandSourceStack implements ExecutionCommandSource, SharedSuggestionProvider { -+public class CommandSourceStack implements ExecutionCommandSource, SharedSuggestionProvider, io.papermc.paper.command.brigadier.PaperCommandSourceStack { // Paper - Brigadier API +-public class CommandSourceStack implements ExecutionCommandSource, PermissionSource, SharedSuggestionProvider { ++public class CommandSourceStack implements ExecutionCommandSource, PermissionSource, SharedSuggestionProvider, io.papermc.paper.command.brigadier.PaperCommandSourceStack { // Paper - Brigadier API public static final SimpleCommandExceptionType ERROR_NOT_PLAYER = new SimpleCommandExceptionType(Component.translatable("permissions.requires.player")); public static final SimpleCommandExceptionType ERROR_NOT_ENTITY = new SimpleCommandExceptionType(Component.translatable("permissions.requires.entity")); public final CommandSource source; -@@ -63,6 +_,8 @@ +@@ -65,6 +_,7 @@ private final Vec2 rotation; private final CommandSigningContext signingContext; private final TaskChainer chatMessageChainer; -+ public java.util.Map currentCommand = new java.util.concurrent.ConcurrentHashMap<>(); // CraftBukkit // Paper - Thread Safe Vanilla Command permission checking + public boolean bypassSelectorPermissions = false; // Paper - add bypass for selector permissions public CommandSourceStack( CommandSource source, -@@ -188,6 +_,30 @@ +@@ -190,6 +_,30 @@ ); } @@ -49,19 +48,7 @@ public CommandSourceStack withRotation(Vec2 rotation) { return this.rotation.equals(rotation) ? this -@@ -391,9 +_,44 @@ - - @Override - public boolean hasPermission(int level) { -+ // CraftBukkit start -+ // Paper start - Thread Safe Vanilla Command permission checking -+ com.mojang.brigadier.tree.CommandNode currentCommand = this.currentCommand.get(Thread.currentThread()); -+ if (currentCommand != null) { -+ return this.hasPermission(level, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand)); -+ // Paper end - Thread Safe Vanilla Command permission checking -+ } -+ // CraftBukkit end -+ +@@ -396,6 +_,32 @@ return this.permissionLevel >= level; } @@ -94,7 +81,7 @@ public Vec3 getPosition() { return this.worldPosition; } -@@ -498,20 +_,25 @@ +@@ -500,20 +_,25 @@ Component component = Component.translatable("chat.type.admin", this.getDisplayName(), message).withStyle(ChatFormatting.GRAY, ChatFormatting.ITALIC); if (this.server.getGameRules().getBoolean(GameRules.RULE_SENDCOMMANDFEEDBACK)) { for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) { @@ -123,7 +110,7 @@ } } -@@ -522,7 +_,7 @@ +@@ -524,7 +_,7 @@ @Override public Collection getOnlinePlayerNames() { @@ -132,7 +119,7 @@ } @Override -@@ -597,4 +_,16 @@ +@@ -604,4 +_,16 @@ public boolean isSilent() { return this.silent; } diff --git a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch index 24a2b69e5a..a3538d58eb 100644 --- a/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/Commands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/commands/Commands.java +++ b/net/minecraft/commands/Commands.java -@@ -150,6 +_,11 @@ +@@ -176,6 +_,11 @@ private final CommandDispatcher dispatcher = new CommandDispatcher<>(); public Commands(Commands.CommandSelection selection, CommandBuildContext context) { @@ -12,7 +12,7 @@ AdvancementCommands.register(this.dispatcher); AttributeCommand.register(this.dispatcher, context); ExecuteCommand.register(this.dispatcher, context); -@@ -251,6 +_,40 @@ +@@ -280,6 +_,42 @@ PublishCommand.register(this.dispatcher); } @@ -20,6 +20,8 @@ + for (final CommandNode node : this.dispatcher.getRoot().getChildren()) { + if (node.getRequirement() == com.mojang.brigadier.builder.ArgumentBuilder.defaultRequirement()) { + node.requirement = stack -> stack.source == CommandSource.NULL || stack.getBukkitSender().hasPermission(org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(node)); ++ } else if (node.getRequirement() instanceof net.minecraft.commands.PermissionSource.Check check) { ++ check.vanillaNode().set(node); + } + } + // Paper end - Vanilla command permission fixes @@ -53,7 +55,7 @@ this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer()); } -@@ -260,15 +_,58 @@ +@@ -289,9 +_,41 @@ return new ParseResults<>(commandContextBuilder, parseResults.getReader(), parseResults.getExceptions()); } @@ -89,12 +91,16 @@ + } + + public void performPrefixedCommand(CommandSourceStack source, String command, String label) { - command = command.startsWith("/") ? command.substring(1) : command; + command = trimOptionalPrefix(command); - this.performCommand(this.dispatcher.parse(command, source), command); + this.performCommand(this.dispatcher.parse(command, source), command, label); + // CraftBukkit end } + public static String trimOptionalPrefix(String command) { +@@ -299,9 +_,20 @@ + } + public void performCommand(ParseResults parseResults, String command) { + // CraftBukkit start + this.performCommand(parseResults, command, command); @@ -114,7 +120,7 @@ try { if (contextChain != null) { -@@ -280,9 +_,10 @@ +@@ -313,9 +_,10 @@ ); } } catch (Exception var12) { @@ -127,7 +133,7 @@ StackTraceElement[] stackTrace = var12.getStackTrace(); for (int i = 0; i < Math.min(stackTrace.length, 3); i++) { -@@ -308,18 +_,22 @@ +@@ -341,18 +_,22 @@ } @Nullable @@ -153,7 +159,7 @@ if (min > 10) { mutableComponent.append(CommonComponents.ELLIPSIS); } -@@ -331,7 +_,17 @@ +@@ -364,7 +_,17 @@ } mutableComponent.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC)); @@ -172,13 +178,13 @@ } return null; -@@ -359,26 +_,121 @@ +@@ -392,17 +_,110 @@ } public void sendCommands(ServerPlayer player) { + // Paper start - Send empty commands if tab completion is disabled + if (org.spigotmc.SpigotConfig.tabComplete < 0) { -+ player.connection.send(new ClientboundCommandsPacket(new RootCommandNode<>())); ++ player.connection.send(new ClientboundCommandsPacket(new RootCommandNode<>(), COMMAND_NODE_INSPECTOR)); + return; + } + // Paper end - Send empty commands if tab completion is disabled @@ -203,11 +209,11 @@ + + private void sendAsync(ServerPlayer player, java.util.Collection> dispatcherRootChildren) { + // Paper end - Perf: Async command map building - Map, CommandNode> map = Maps.newHashMap(); - RootCommandNode rootCommandNode = new RootCommandNode<>(); + Map, CommandNode> map = new HashMap<>(); + RootCommandNode rootCommandNode = new RootCommandNode<>(); map.put(this.dispatcher.getRoot(), rootCommandNode); -- this.fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map); -+ this.fillUsableCommands(dispatcherRootChildren, rootCommandNode, player.createCommandSourceStack(), map); // Paper - Perf: Async command map building; pass copy of children +- fillUsableCommands(this.dispatcher.getRoot(), rootCommandNode, player.createCommandSourceStack(), map); ++ fillUsableCommands(dispatcherRootChildren, rootCommandNode, player.createCommandSourceStack(), map); // Paper - Perf: Async command map building; pass copy of children + + java.util.Collection bukkit = new java.util.LinkedHashSet<>(); + for (CommandNode node : rootCommandNode.getChildren()) { @@ -216,11 +222,11 @@ + // Paper start - Perf: Async command map building + new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, false).callEvent(); // Paper - Brigadier API + net.minecraft.server.MinecraftServer.getServer().execute(() -> { -+ runSync(player, bukkit, rootCommandNode); ++ runSync(player, bukkit, rootCommandNode); + }); + } + -+ private void runSync(ServerPlayer player, java.util.Collection bukkit, RootCommandNode rootCommandNode) { ++ private void runSync(ServerPlayer player, java.util.Collection bukkit, RootCommandNode rootCommandNode) { + // Paper end - Perf: Async command map building + new com.destroystokyo.paper.event.brigadier.AsyncPlayerSendCommandsEvent(player.getBukkitEntity(), (RootCommandNode) rootCommandNode, true).callEvent(); // Paper - Brigadier API + org.bukkit.event.player.PlayerCommandSendEvent event = new org.bukkit.event.player.PlayerCommandSendEvent(player.getBukkitEntity(), new java.util.LinkedHashSet<>(bukkit)); @@ -233,28 +239,21 @@ + } + } + // CraftBukkit end -+ - player.connection.send(new ClientboundCommandsPacket(rootCommandNode)); + player.connection.send(new ClientboundCommandsPacket(rootCommandNode, COMMAND_NODE_INSPECTOR)); } - private void fillUsableCommands( -- CommandNode rootCommandSource, -+ java.util.Collection> children, // Paper - Perf: Async command map building; pass copy of children - CommandNode rootSuggestion, - CommandSourceStack source, - Map, CommandNode> commandNodeToSuggestionNode - ) { -- for (CommandNode commandNode : rootCommandSource.getChildren()) { -+ for (CommandNode commandNode : children) { // Paper - Perf: Async command map building; pass copy of children +- private static void fillUsableCommands(CommandNode root, CommandNode current, S source, Map, CommandNode> output) { +- for (CommandNode commandNode : root.getChildren()) { ++ private static void fillUsableCommands(java.util.Collection> children, CommandNode current, S source, Map, CommandNode> output) { // Paper - Perf: Async command map building; pass copy of children ++ for (CommandNode commandNode : children) { // Paper - Perf: Async command map building; pass copy of children + // Paper start - Brigadier API + if (commandNode.clientNode != null) { + commandNode = commandNode.clientNode; + } + // Paper end - Brigadier API + if (!org.spigotmc.SpigotConfig.sendNamespaced && commandNode.getName().contains(":")) continue; // Spigot -+ if (commandNode.wrappedCached != null && commandNode.wrappedCached.apiCommandMeta != null && commandNode.wrappedCached.apiCommandMeta.serverSideOnly()) continue; // Paper if (commandNode.canUse(source)) { - ArgumentBuilder argumentBuilder = (ArgumentBuilder) commandNode.createBuilder(); + ArgumentBuilder argumentBuilder = commandNode.createBuilder(); + // Paper start + /* + Because of how commands can be yeeted right left and center due to bad bukkit practices @@ -271,41 +270,34 @@ + - Do this :) + */ + // Is there an invalid command redirect? -+ if (argumentBuilder.getRedirect() != null && commandNodeToSuggestionNode.get(argumentBuilder.getRedirect()) == null) { ++ if (argumentBuilder.getRedirect() != null && output.get(argumentBuilder.getRedirect()) == null) { + // Create the argument builder with the same values as the specified node, but with a different literal and populated children + -+ final CommandNode redirect = argumentBuilder.getRedirect(); ++ final CommandNode redirect = argumentBuilder.getRedirect(); + // Diff copied from LiteralCommand#createBuilder -+ final com.mojang.brigadier.builder.LiteralArgumentBuilder builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName()); ++ final com.mojang.brigadier.builder.LiteralArgumentBuilder builder = com.mojang.brigadier.builder.LiteralArgumentBuilder.literal(commandNode.getName()); + builder.requires(redirect.getRequirement()); + // builder.forward(redirect.getRedirect(), redirect.getRedirectModifier(), redirect.isFork()); We don't want to migrate the forward, since it's invalid. + if (redirect.getCommand() != null) { + builder.executes(redirect.getCommand()); + } + // Diff copied from LiteralCommand#createBuilder -+ for (final CommandNode child : redirect.getChildren()) { ++ for (final CommandNode child : redirect.getChildren()) { + builder.then(child); + } + + argumentBuilder = builder; + } + // Paper end - argumentBuilder.requires(suggestions -> true); -- if (argumentBuilder.getCommand() != null) { -- argumentBuilder.executes(commandContext -> 0); -- } -+ // Paper - don't replace Command instance on suggestion node -+ // we want the exact command instance to be used for equality checks -+ // when assigning serialization ids to each command node - - if (argumentBuilder instanceof RequiredArgumentBuilder requiredArgumentBuilder - && requiredArgumentBuilder.getSuggestionsProvider() != null) { -@@ -393,7 +_,7 @@ - commandNodeToSuggestionNode.put(commandNode, commandNode1); - rootSuggestion.addChild(commandNode1); + if (argumentBuilder.getRedirect() != null) { + argumentBuilder.redirect(output.get(argumentBuilder.getRedirect())); + } +@@ -411,7 +_,7 @@ + output.put(commandNode, commandNode1); + current.addChild(commandNode1); if (!commandNode.getChildren().isEmpty()) { -- this.fillUsableCommands(commandNode, commandNode1, source, commandNodeToSuggestionNode); -+ this.fillUsableCommands(commandNode.getChildren(), commandNode1, source, commandNodeToSuggestionNode); // Paper - Perf: Async command map building; pass copy of children +- fillUsableCommands(commandNode, commandNode1, source, output); ++ fillUsableCommands(commandNode.getChildren(), commandNode1, source, output); // Paper - Perf: Async command map building; pass copy of children } } } diff --git a/paper-server/patches/sources/net/minecraft/commands/PermissionSource.java.patch b/paper-server/patches/sources/net/minecraft/commands/PermissionSource.java.patch new file mode 100644 index 0000000000..d71a268e02 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/commands/PermissionSource.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/commands/PermissionSource.java ++++ b/net/minecraft/commands/PermissionSource.java +@@ -9,9 +_,20 @@ + return this.hasPermission(2); + } + +- public record Check(@Override int requiredLevel) implements PermissionCheck { ++ public record Check(@Override int requiredLevel, java.util.concurrent.atomic.AtomicReference> vanillaNode) implements PermissionCheck { // Paper ++ // Paper start - Vanilla Command permission checking ++ public Check(int requiredLevel) { ++ this(requiredLevel, new java.util.concurrent.atomic.AtomicReference<>()); ++ } ++ // Paper end - Vanilla Command permission checking + @Override + public boolean test(T source) { ++ // Paper start - Vanilla Command permission checking ++ com.mojang.brigadier.tree.CommandNode currentCommand = vanillaNode.get(); ++ if (currentCommand != null && source instanceof CommandSourceStack commandSourceStack) { ++ return commandSourceStack.hasPermission(this.requiredLevel, org.bukkit.craftbukkit.command.VanillaCommandWrapper.getPermission(currentCommand)); ++ } ++ // Paper end - Vanilla Command permission checking + return source.hasPermission(this.requiredLevel); + } + } diff --git a/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch b/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch index d39db32c3a..4a154e157e 100644 --- a/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/arguments/EntityArgument.java.patch @@ -16,7 +16,7 @@ if (entitySelector.getMaxResults() > 1 && this.single) { if (this.playersOnly) { reader.setCursor(0); -@@ -129,7 +_,12 @@ +@@ -129,7 +_,13 @@ if (context.getSource() instanceof SharedSuggestionProvider sharedSuggestionProvider) { StringReader stringReader = new StringReader(builder.getInput()); stringReader.setCursor(builder.getStart()); @@ -24,7 +24,8 @@ + // Paper start - Fix EntityArgument permissions + final boolean permission = sharedSuggestionProvider instanceof CommandSourceStack stack + ? stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector") -+ : sharedSuggestionProvider.hasPermission(2); ++ // Only CommandSourceStack implements SharedSuggestionProvider. If *somehow* anything else ends up here, try to query its permission level, otherwise yield false. ++ : (sharedSuggestionProvider instanceof final net.minecraft.commands.PermissionSource permissionSource && permissionSource.hasPermission(2)); + EntitySelectorParser entitySelectorParser = new EntitySelectorParser(stringReader, permission); + // Paper end - Fix EntityArgument permissions diff --git a/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch b/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch index c89791f903..533e1c872d 100644 --- a/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelector.java.patch @@ -4,7 +4,7 @@ } private void checkPermissions(CommandSourceStack source) throws CommandSyntaxException { -- if (this.usesSelector && !source.hasPermission(2)) { +- if (this.usesSelector && !source.allowsSelectors()) { + if (!source.bypassSelectorPermissions && (this.usesSelector && !source.hasPermission(2, "minecraft.command.selector"))) { // CraftBukkit // Paper - add bypass for selector perms throw EntityArgument.ERROR_SELECTORS_NOT_ALLOWED.create(); } diff --git a/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch b/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch index 7274630b68..7afec03c54 100644 --- a/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch +++ b/paper-server/patches/sources/net/minecraft/commands/arguments/selector/EntitySelectorParser.java.patch @@ -9,7 +9,7 @@ + return stack.bypassSelectorPermissions || stack.hasPermission(2, "minecraft.command.selector"); + } + // Paper end - Fix EntityArgument permissions - return suggestionProvider instanceof SharedSuggestionProvider sharedSuggestionProvider && sharedSuggestionProvider.hasPermission(2); + return suggestionProvider instanceof PermissionSource permissionSource && permissionSource.allowsSelectors(); } @@ -198,8 +_,10 @@ diff --git a/paper-server/patches/sources/net/minecraft/core/HolderLookup.java.patch b/paper-server/patches/sources/net/minecraft/core/HolderLookup.java.patch new file mode 100644 index 0000000000..17edc3610c --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/core/HolderLookup.java.patch @@ -0,0 +1,40 @@ +--- a/net/minecraft/core/HolderLookup.java ++++ b/net/minecraft/core/HolderLookup.java +@@ -68,6 +_,9 @@ + } + + public interface RegistryLookup extends HolderLookup, HolderOwner { ++ ++ Optional getValueForCopying(ResourceKey resourceKey); // Paper - add method to get the value for pre-filling builders in the reg mod API ++ + ResourceKey> key(); + + Lifecycle registryLifecycle(); +@@ -80,6 +_,13 @@ + + default HolderLookup.RegistryLookup filterElements(final Predicate predicate) { + return new HolderLookup.RegistryLookup.Delegate() { ++ // Paper start - add getValueForCopying ++ @Override ++ public Optional getValueForCopying(final ResourceKey resourceKey) { ++ return this.parent().getValueForCopying(resourceKey).filter(predicate); ++ } ++ // Paper end - add getValueForCopying ++ + @Override + public HolderLookup.RegistryLookup parent() { + return RegistryLookup.this; +@@ -99,6 +_,13 @@ + + public interface Delegate extends HolderLookup.RegistryLookup { + HolderLookup.RegistryLookup parent(); ++ ++ // Paper start - add getValueForCopying ++ @Override ++ default Optional getValueForCopying(ResourceKey resourceKey) { ++ return this.parent().getValueForCopying(resourceKey); ++ } ++ // Paper end - add getValueForCopying + + @Override + default ResourceKey> key() { diff --git a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch index da03bc092e..941381d50b 100644 --- a/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/MappedRegistry.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/core/MappedRegistry.java +++ b/net/minecraft/core/MappedRegistry.java -@@ -32,17 +_,18 @@ +@@ -32,17 +_,25 @@ public class MappedRegistry implements WritableRegistry { private final ResourceKey> key; private final ObjectList> byId = new ObjectArrayList<>(256); @@ -20,7 +20,14 @@ private boolean frozen; @Nullable private Map> unregisteredIntrusiveHolders; -+ public final Map temporaryUnfrozenMap = new HashMap<>(); // Paper - support pre-filling in registry mod API ++ // Paper start - support pre-filling in registry mod API ++ private final Map temporaryUnfrozenMap = new HashMap<>(); ++ ++ @Override ++ public Optional getValueForCopying(final ResourceKey resourceKey) { ++ return this.frozen ? this.getOptional(resourceKey) : Optional.ofNullable(this.temporaryUnfrozenMap.get(resourceKey.location())); ++ } ++ // Paper end - support pre-filling in registry mod API @Override public Stream> listTags() { diff --git a/paper-server/patches/sources/net/minecraft/core/RegistrySetBuilder.java.patch b/paper-server/patches/sources/net/minecraft/core/RegistrySetBuilder.java.patch new file mode 100644 index 0000000000..150d368bed --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/core/RegistrySetBuilder.java.patch @@ -0,0 +1,30 @@ +--- a/net/minecraft/core/RegistrySetBuilder.java ++++ b/net/minecraft/core/RegistrySetBuilder.java +@@ -41,6 +_,13 @@ + final Map, Holder.Reference> elements + ) { + return new RegistrySetBuilder.EmptyTagRegistryLookup(owner) { ++ // Paper start - add getValueForCopying method ++ @Override ++ public Optional getValueForCopying(final ResourceKey resourceKey) { ++ return this.get(resourceKey).map(Holder.Reference::value); ++ } ++ // Paper end - add getValueForCopying method ++ + @Override + public ResourceKey> key() { + return registryKey; +@@ -121,6 +_,13 @@ + public Optional> lookup(ResourceKey> registryKey) { + return getEntry(registryKey).map(Entry::opsInfo); + } ++ ++ // Paper start - add method to get the value for pre-filling builders in the reg mod API ++ @Override ++ public HolderLookup.Provider lookupForValueCopyViaBuilders() { ++ throw new UnsupportedOperationException("Not implemented"); ++ } ++ // Paper end - add method to get the value for pre-filling builders in the reg mod API + }); + } + }; diff --git a/paper-server/patches/sources/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch b/paper-server/patches/sources/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch index 40242cb71f..4e793f4817 100644 --- a/paper-server/patches/sources/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/dispenser/ShearsDispenseItemBehavior.java.patch @@ -27,23 +27,27 @@ + // CraftBukkit end if (!serverLevel.isClientSide()) { BlockPos blockPos = blockSource.pos().relative(blockSource.state().getValue(DispenserBlock.FACING)); -- this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item)); -+ this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearLivingEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit +- this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearEntity(serverLevel, blockPos, item)); ++ this.setSuccess(tryShearBeehive(serverLevel, blockPos) || tryShearEntity(serverLevel, blockPos, item, bukkitBlock, craftItem)); // CraftBukkit if (this.isSuccess()) { item.hurtAndBreak(1, serverLevel, null, item1 -> {}); } -@@ -50,10 +_,18 @@ +@@ -50,14 +_,22 @@ return false; } -- private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack stack) { -+ private static boolean tryShearLivingEntity(ServerLevel level, BlockPos pos, ItemStack stack, org.bukkit.block.Block bukkitBlock, org.bukkit.craftbukkit.inventory.CraftItemStack craftItem) { // CraftBukkit - add args - for (LivingEntity livingEntity : level.getEntitiesOfClass(LivingEntity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) { - if (livingEntity instanceof Shearable shearable && shearable.readyForShearing()) { +- private static boolean tryShearEntity(ServerLevel level, BlockPos pos, ItemStack stack) { ++ private static boolean tryShearEntity(ServerLevel level, BlockPos pos, ItemStack stack, org.bukkit.block.Block bukkitBlock, org.bukkit.craftbukkit.inventory.CraftItemStack craftItem) { // CraftBukkit - add args + for (Entity entity : level.getEntitiesOfClass(Entity.class, new AABB(pos), EntitySelector.NO_SPECTATORS)) { + if (entity.shearOffAllLeashConnections(null)) { + return true; + } + + if (entity instanceof Shearable shearable && shearable.readyForShearing()) { - shearable.shear(level, SoundSource.BLOCKS, stack); + // CraftBukkit start + // Paper start - Add drops to shear events -+ org.bukkit.event.block.BlockShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockShearEntityEvent(livingEntity, bukkitBlock, craftItem, shearable.generateDefaultDrops(level, stack)); ++ org.bukkit.event.block.BlockShearEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockShearEntityEvent(entity, bukkitBlock, craftItem, shearable.generateDefaultDrops(level, stack)); + if (event.isCancelled()) { + // Paper end - Add drops to shear events + continue; diff --git a/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch b/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch index 82d6614036..f31d3aaaaa 100644 --- a/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch +++ b/paper-server/patches/sources/net/minecraft/core/registries/BuiltInRegistries.java.patch @@ -1,32 +1,26 @@ --- a/net/minecraft/core/registries/BuiltInRegistries.java +++ b/net/minecraft/core/registries/BuiltInRegistries.java -@@ -311,6 +_,17 @@ - ); +@@ -325,6 +_,11 @@ + public static final Registry> DIALOG_BODY_TYPE = registerSimple(Registries.DIALOG_BODY_TYPE, DialogBodyTypes::bootstrap); public static final Registry> TEST_FUNCTION = registerSimple(Registries.TEST_FUNCTION, BuiltinTestFunctions::bootstrap); public static final Registry> REGISTRY = WRITABLE_REGISTRY; + // Paper start - add built-in registry conversions -+ public static final io.papermc.paper.registry.data.util.Conversions BUILT_IN_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(new net.minecraft.resources.RegistryOps.RegistryInfoLookup() { -+ @Override -+ public java.util.Optional> lookup(final ResourceKey> registryRef) { -+ final Registry registry = net.minecraft.server.RegistryLayer.STATIC_ACCESS.lookupOrThrow(registryRef); -+ return java.util.Optional.of( -+ new net.minecraft.resources.RegistryOps.RegistryInfo<>(registry, registry, Lifecycle.experimental()) -+ ); -+ } -+ }); ++ public static final io.papermc.paper.registry.data.util.Conversions STATIC_ACCESS_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions( ++ new net.minecraft.resources.RegistryOps.HolderLookupAdapter(net.minecraft.server.RegistryLayer.STATIC_ACCESS) ++ ); + // Paper end - add built-in registry conversions private static Registry registerSimple(ResourceKey> key, BuiltInRegistries.RegistryBootstrap bootstrap) { return internalRegister(key, new MappedRegistry<>(key, Lifecycle.stable(), false), bootstrap); -@@ -336,6 +_,7 @@ +@@ -350,6 +_,7 @@ ResourceKey> key, R registry, BuiltInRegistries.RegistryBootstrap bootstrap ) { Bootstrap.checkBootstrapCalled(() -> "registry " + key.location()); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry.key(), registry); // Paper - initialize API registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry); // Paper - initialize API registry ResourceLocation resourceLocation = key.location(); LOADERS.put(resourceLocation, () -> bootstrap.run(registry)); WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN); -@@ -343,16 +_,34 @@ +@@ -357,16 +_,34 @@ } public static void bootStrap() { @@ -61,11 +55,11 @@ }); } -@@ -361,6 +_,7 @@ +@@ -375,6 +_,7 @@ for (Registry registry : REGISTRY) { bindBootstrappedTagsToEmpty(registry); -+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), BUILT_IN_CONVERSIONS); // Paper ++ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), STATIC_ACCESS_CONVERSIONS); // Paper registry.freeze(); } } diff --git a/paper-server/patches/sources/net/minecraft/gametest/framework/GameTestMainUtil.java.patch b/paper-server/patches/sources/net/minecraft/gametest/framework/GameTestMainUtil.java.patch index 9026c81bf7..488330e439 100644 --- a/paper-server/patches/sources/net/minecraft/gametest/framework/GameTestMainUtil.java.patch +++ b/paper-server/patches/sources/net/minecraft/gametest/framework/GameTestMainUtil.java.patch @@ -8,4 +8,4 @@ + LevelStorageSource.LevelStorageAccess levelStorageAccess = LevelStorageSource.createDefault(Paths.get(string)).createAccess("gametestworld", net.minecraft.world.level.dimension.LevelStem.OVERWORLD); // Paper PackRepository packRepository = ServerPacksSource.createPackRepository(levelStorageAccess); MinecraftServer.spin( - thread -> GameTestServer.create(thread, levelStorageAccess, packRepository, optionalFromOption(optionSet, tests), optionSet.has(verify)) + thread -> { diff --git a/paper-server/patches/sources/net/minecraft/gametest/framework/StructureUtils.java.patch b/paper-server/patches/sources/net/minecraft/gametest/framework/StructureUtils.java.patch index 4c113b07fb..2cdf7b03ff 100644 --- a/paper-server/patches/sources/net/minecraft/gametest/framework/StructureUtils.java.patch +++ b/paper-server/patches/sources/net/minecraft/gametest/framework/StructureUtils.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/gametest/framework/StructureUtils.java +++ b/net/minecraft/gametest/framework/StructureUtils.java -@@ -86,7 +_,7 @@ +@@ -87,7 +_,7 @@ level.clearBlockEvents(boundingBox1); AABB aabb = AABB.of(boundingBox1); List entitiesOfClass = level.getEntitiesOfClass(Entity.class, aabb, entity -> !(entity instanceof Player)); diff --git a/paper-server/patches/sources/net/minecraft/nbt/CompoundTag.java.patch b/paper-server/patches/sources/net/minecraft/nbt/CompoundTag.java.patch index 26f53ef9e0..644f58a4e0 100644 --- a/paper-server/patches/sources/net/minecraft/nbt/CompoundTag.java.patch +++ b/paper-server/patches/sources/net/minecraft/nbt/CompoundTag.java.patch @@ -23,7 +23,7 @@ @Override public CompoundTag copy() { - HashMap map = new HashMap<>(); -- this.tags.forEach((string, tag) -> map.put(string, tag.copy())); +- this.tags.forEach((key, value) -> map.put(key, value.copy())); - return new CompoundTag(map); + // Paper start - Reduce memory footprint of CompoundTag + it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap ret = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(this.tags.size(), 0.8f); diff --git a/paper-server/patches/sources/net/minecraft/network/Connection.java.patch b/paper-server/patches/sources/net/minecraft/network/Connection.java.patch index f34c32dc5a..773b494465 100644 --- a/paper-server/patches/sources/net/minecraft/network/Connection.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/Connection.java.patch @@ -192,7 +192,7 @@ } catch (RejectedExecutionException var6) { this.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown")); } catch (ClassCastException var7) { -@@ -385,10 +_,30 @@ +@@ -373,10 +_,30 @@ } } @@ -223,7 +223,7 @@ } if (!this.isConnected() && !this.disconnectionHandled) { -@@ -396,7 +_,7 @@ +@@ -384,7 +_,7 @@ } if (this.channel != null) { @@ -232,7 +232,7 @@ } if (this.tickCount++ % 20 == 0) { -@@ -432,12 +_,13 @@ +@@ -420,12 +_,13 @@ } public void disconnect(DisconnectionDetails disconnectionDetails) { @@ -247,7 +247,7 @@ this.disconnectionDetails = disconnectionDetails; } } -@@ -584,6 +_,13 @@ +@@ -572,6 +_,13 @@ } } @@ -261,7 +261,7 @@ public void setupCompression(int threshold, boolean validateDecompressed) { if (threshold >= 0) { if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder compressionDecoder) { -@@ -597,6 +_,7 @@ +@@ -585,6 +_,7 @@ } else { this.channel.pipeline().addAfter("prepender", "compress", new CompressionEncoder(threshold)); } @@ -269,7 +269,7 @@ } else { if (this.channel.pipeline().get("decompress") instanceof CompressionDecoder) { this.channel.pipeline().remove("decompress"); -@@ -605,6 +_,7 @@ +@@ -593,6 +_,7 @@ if (this.channel.pipeline().get("compress") instanceof CompressionEncoder) { this.channel.pipeline().remove("compress"); } @@ -277,7 +277,7 @@ } } -@@ -622,6 +_,26 @@ +@@ -610,6 +_,26 @@ ); packetListener1.onDisconnect(disconnectionDetails); } diff --git a/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch b/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch index dfcc706642..863e8114fe 100644 --- a/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/FriendlyByteBuf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/FriendlyByteBuf.java +++ b/net/minecraft/network/FriendlyByteBuf.java -@@ -70,14 +_,20 @@ +@@ -71,14 +_,20 @@ public class FriendlyByteBuf extends ByteBuf { public static final int DEFAULT_NBT_QUOTA = 2097152; private final ByteBuf source; @@ -21,7 +21,7 @@ this.source = source; } -@@ -106,8 +_,13 @@ +@@ -107,8 +_,13 @@ } public void writeJsonWithCodec(Codec codec, T value) { @@ -36,7 +36,7 @@ } public static IntFunction limitValue(IntFunction function, int limit) { -@@ -539,7 +_,7 @@ +@@ -556,7 +_,7 @@ try { NbtIo.writeAnyTag(nbt, new ByteBufOutputStream(buffer)); diff --git a/paper-server/patches/sources/net/minecraft/network/chat/Component.java.patch b/paper-server/patches/sources/net/minecraft/network/chat/Component.java.patch index 5df40c7c2d..50d0b20318 100644 --- a/paper-server/patches/sources/net/minecraft/network/chat/Component.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/chat/Component.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/chat/Component.java +++ b/net/minecraft/network/chat/Component.java -@@ -37,7 +_,19 @@ +@@ -23,7 +_,19 @@ import net.minecraft.util.FormattedCharSequence; import net.minecraft.world.level.ChunkPos; diff --git a/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch b/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch index 40d3315311..866e2dbfc0 100644 --- a/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/codec/ByteBufCodecs.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/network/codec/ByteBufCodecs.java +++ b/net/minecraft/network/codec/ByteBufCodecs.java -@@ -389,6 +_,48 @@ +@@ -435,6 +_,48 @@ }; } diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java.patch index 3ff4b6655b..ef54b04ade 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/game/ClientboundLevelChunkPacketData.java.patch @@ -9,7 +9,7 @@ throw new RuntimeException("Chunk Packet trying to allocate too much memory on read."); } else { this.buffer = new byte[varInt]; -@@ -151,6 +_,7 @@ +@@ -155,6 +_,7 @@ CompoundTag updateTag = blockEntity.getUpdateTag(blockEntity.getLevel().registryAccess()); BlockPos blockPos = blockEntity.getBlockPos(); int i = SectionPos.sectionRelative(blockPos.getX()) << 4 | SectionPos.sectionRelative(blockPos.getZ()); diff --git a/paper-server/patches/sources/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java.patch b/paper-server/patches/sources/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java.patch index 3bc9092eb9..e9de3c6940 100644 --- a/paper-server/patches/sources/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java.patch +++ b/paper-server/patches/sources/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java.patch @@ -1,21 +1,30 @@ --- a/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java +++ b/net/minecraft/network/protocol/login/ClientboundLoginDisconnectPacket.java -@@ -18,11 +_,16 @@ - } +@@ -14,8 +_,25 @@ - private ClientboundLoginDisconnectPacket(FriendlyByteBuf buffer) { -- this.reason = Component.Serializer.fromJsonLenient(buffer.readUtf(262144), RegistryAccess.EMPTY); -+ this.reason = Component.Serializer.fromJsonLenient(buffer.readUtf(FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH), RegistryAccess.EMPTY); // Paper - diff on change - } - - private void write(FriendlyByteBuf buffer) { -- buffer.writeUtf(Component.Serializer.toJson(this.reason, RegistryAccess.EMPTY)); -+ // Paper start - Adventure -+ // buffer.writeUtf(Component.Serializer.toJson(this.reason, RegistryAccess.EMPTY)); -+ // In the login phase, buffer.adventure$locale field is most likely null, but plugins may use internals to set it via the channel attribute -+ java.util.Locale bufLocale = buffer.adventure$locale; -+ buffer.writeJsonWithCodec(net.minecraft.network.chat.ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale), this.reason, FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH); -+ // Paper end - Adventure - } - - @Override + public record ClientboundLoginDisconnectPacket(Component reason) implements Packet { + private static final RegistryOps OPS = RegistryAccess.EMPTY.createSerializationContext(JsonOps.INSTANCE); +- public static final StreamCodec STREAM_CODEC = StreamCodec.composite( +- ByteBufCodecs.lenientJson(262144).apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.CODEC)), ++ // Paper start - localized codec ++ // In the login phase, buffer.adventure$locale field is most likely null, but plugins may use internals to set it via the channel attribute ++ public static final StreamCodec STREAM_CODEC = StreamCodec.composite( ++ new StreamCodec<>() { ++ ++ private static final net.minecraft.network.codec.StreamCodec LENIENT_JSON = ByteBufCodecs.lenientJson(net.minecraft.network.FriendlyByteBuf.MAX_COMPONENT_STRING_LENGTH); ++ @Override ++ public Component decode(final net.minecraft.network.FriendlyByteBuf buffer) { ++ java.util.Locale bufLocale = buffer.adventure$locale; ++ return LENIENT_JSON.apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale))).decode(buffer); ++ } ++ ++ @Override ++ public void encode(final net.minecraft.network.FriendlyByteBuf buffer, final Component value) { ++ java.util.Locale bufLocale = buffer.adventure$locale; ++ LENIENT_JSON.apply(ByteBufCodecs.fromCodec(OPS, ComponentSerialization.localizedCodec(bufLocale == null ? java.util.Locale.US : bufLocale))).encode(buffer, value); ++ } ++ }, ++ // Paper end - localized codec + ClientboundLoginDisconnectPacket::reason, + ClientboundLoginDisconnectPacket::new + ); diff --git a/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch b/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch index 5f037fe851..3f52e9a7fc 100644 --- a/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch +++ b/paper-server/patches/sources/net/minecraft/resources/RegistryDataLoader.java.patch @@ -1,6 +1,28 @@ --- a/net/minecraft/resources/RegistryDataLoader.java +++ b/net/minecraft/resources/RegistryDataLoader.java -@@ -271,13 +_,14 @@ +@@ -206,11 +_,21 @@ + final Map>, RegistryOps.RegistryInfo> map = new HashMap<>(); + registryLookups.forEach(registryLookup -> map.put(registryLookup.key(), createInfoForContextRegistry((HolderLookup.RegistryLookup)registryLookup))); + loaders.forEach(loader -> map.put(loader.registry.key(), createInfoForNewRegistry(loader.registry))); ++ // this creates a HolderLookup.Provider to be used exclusively to obtain real instances of values to pre-populate builders ++ // for the Registry Modification API. This concatenates the context registry lookups and the empty registries about to be filled. ++ final HolderLookup.Provider providerForBuilders = HolderLookup.Provider.create(java.util.stream.Stream.concat(registryLookups.stream(), loaders.stream().map(Loader::registry))); // Paper - add method to get the value for pre-filling builders in the reg mod API + return new RegistryOps.RegistryInfoLookup() { + @Override + public Optional> lookup(ResourceKey> registryKey) { + return Optional.ofNullable((RegistryOps.RegistryInfo)map.get(registryKey)); + } ++ ++ // Paper start - add method to get the value for pre-filling builders in the reg mod API ++ @Override ++ public HolderLookup.Provider lookupForValueCopyViaBuilders() { ++ return providerForBuilders; ++ } ++ // Paper end - add method to get the value for pre-filling builders in the reg mod API + }; + } + +@@ -274,13 +_,14 @@ RegistryOps ops, ResourceKey resourceKey, Resource resource, @@ -9,7 +31,7 @@ + io.papermc.paper.registry.data.util.Conversions conversions // Paper - pass conversions ) throws IOException { try (Reader reader = resource.openAsReader()) { - JsonElement jsonElement = JsonParser.parseReader(reader); + JsonElement jsonElement = StrictJsonParser.parse(reader); DataResult dataResult = codec.parse(ops, jsonElement); E orThrow = dataResult.getOrThrow(); - registry.register(resourceKey, orThrow, registrationInfo); @@ -17,7 +39,7 @@ } } -@@ -291,6 +_,7 @@ +@@ -294,6 +_,7 @@ FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key()); RegistryOps registryOps = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup); @@ -25,7 +47,7 @@ for (Entry entry : fileToIdConverter.listMatchingResources(resourceManager).entrySet()) { ResourceLocation resourceLocation = entry.getKey(); ResourceKey resourceKey = ResourceKey.create(registry.key(), fileToIdConverter.fileToId(resourceLocation)); -@@ -298,7 +_,7 @@ +@@ -301,7 +_,7 @@ RegistrationInfo registrationInfo = REGISTRATION_INFO_CACHE.apply(resource.knownPackInfo()); try { @@ -34,7 +56,7 @@ } catch (Exception var14) { loadingErrors.put( resourceKey, -@@ -307,7 +_,9 @@ +@@ -310,7 +_,9 @@ } } @@ -45,7 +67,7 @@ } static void loadContentsFromNetwork( -@@ -324,6 +_,7 @@ +@@ -327,6 +_,7 @@ RegistryOps registryOps1 = RegistryOps.create(JsonOps.INSTANCE, registryInfoLookup); FileToIdConverter fileToIdConverter = FileToIdConverter.registry(registry.key()); @@ -53,7 +75,7 @@ for (RegistrySynchronization.PackedRegistryEntry packedRegistryEntry : networkedRegistryData.elements) { ResourceKey resourceKey = ResourceKey.create(registry.key(), packedRegistryEntry.id()); Optional optional = packedRegistryEntry.data(); -@@ -342,7 +_,7 @@ +@@ -345,7 +_,7 @@ try { Resource resourceOrThrow = resourceProvider.getResourceOrThrow(resourceLocation); @@ -62,11 +84,11 @@ } catch (Exception var17) { loadingErrors.put(resourceKey, new IllegalStateException("Failed to parse local data", var17)); } -@@ -384,6 +_,7 @@ +@@ -387,6 +_,7 @@ RegistryDataLoader.Loader create(Lifecycle registryLifecycle, Map, Exception> loadingErrors) { WritableRegistry writableRegistry = new MappedRegistry<>(this.key, registryLifecycle); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(this.key, writableRegistry); // Paper - initialize API registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(writableRegistry); // Paper - initialize API registry return new RegistryDataLoader.Loader<>(this, writableRegistry, loadingErrors); } diff --git a/paper-server/patches/sources/net/minecraft/resources/RegistryOps.java.patch b/paper-server/patches/sources/net/minecraft/resources/RegistryOps.java.patch new file mode 100644 index 0000000000..93b5b31807 --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/resources/RegistryOps.java.patch @@ -0,0 +1,24 @@ +--- a/net/minecraft/resources/RegistryOps.java ++++ b/net/minecraft/resources/RegistryOps.java +@@ -117,6 +_,13 @@ + public int hashCode() { + return this.lookupProvider.hashCode(); + } ++ ++ // Paper start - add method to get the value for pre-filling builders in the reg mod API ++ @Override ++ public HolderLookup.Provider lookupForValueCopyViaBuilders() { ++ return this.lookupProvider; ++ } ++ // Paper end - add method to get the value for pre-filling builders in the reg mod API + } + + public record RegistryInfo(HolderOwner owner, HolderGetter getter, Lifecycle elementsLifecycle) { +@@ -127,5 +_,7 @@ + + public interface RegistryInfoLookup { + Optional> lookup(ResourceKey> registryKey); ++ ++ HolderLookup.Provider lookupForValueCopyViaBuilders(); // Paper - add method to get the value for pre-filling builders in the reg mod API + } + } diff --git a/paper-server/patches/sources/net/minecraft/server/Main.java.patch b/paper-server/patches/sources/net/minecraft/server/Main.java.patch index 3ee6c7ea3b..1e32c74c86 100644 --- a/paper-server/patches/sources/net/minecraft/server/Main.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/Main.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/Main.java +++ b/net/minecraft/server/Main.java -@@ -67,8 +_,10 @@ +@@ -68,8 +_,10 @@ reason = "System.out needed before bootstrap" ) @DontObfuscate @@ -12,7 +12,7 @@ OptionParser optionParser = new OptionParser(); OptionSpec optionSpec = optionParser.accepts("nogui"); OptionSpec optionSpec1 = optionParser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits"); -@@ -93,41 +_,94 @@ +@@ -94,41 +_,94 @@ optionParser.printHelpOn(System.err); return; } @@ -116,7 +116,7 @@ Dynamic dataTag; if (levelStorageAccess.hasWorldData()) { LevelSummary summary; -@@ -169,12 +_,33 @@ +@@ -170,12 +_,33 @@ } Dynamic dynamic = dataTag; @@ -141,7 +141,7 @@ + "pack_format": %d + } + } -+ """.formatted(SharedConstants.getCurrentVersion().getPackVersion(net.minecraft.server.packs.PackType.SERVER_DATA)) ++ """.formatted(SharedConstants.getCurrentVersion().packVersion(net.minecraft.server.packs.PackType.SERVER_DATA)) + ); + } catch (java.io.IOException ex) { + throw new RuntimeException("Could not initialize Bukkit datapack", ex); @@ -151,7 +151,7 @@ WorldStem worldStem; try { -@@ -183,6 +_,7 @@ +@@ -184,6 +_,7 @@ executor -> WorldLoader.load( initConfig, context -> { @@ -159,7 +159,7 @@ Registry registry = context.datapackDimensions().lookupOrThrow(Registries.LEVEL_STEM); if (dynamic != null) { LevelDataAndDimensions levelDataAndDimensions = LevelStorageSource.getLevelDataAndDimensions( -@@ -196,7 +_,7 @@ +@@ -197,7 +_,7 @@ LevelSettings levelSettings; WorldOptions worldOptions; WorldDimensions worldDimensions; @@ -168,7 +168,7 @@ levelSettings = MinecraftServer.DEMO_SETTINGS; worldOptions = WorldOptions.DEMO_OPTIONS; worldDimensions = WorldPresets.createNormalWorldDimensions(context.datapackWorldgen()); -@@ -211,7 +_,7 @@ +@@ -212,7 +_,7 @@ new GameRules(context.dataConfiguration().enabledFeatures()), context.dataConfiguration() ); @@ -177,7 +177,7 @@ worldDimensions = properties.createDimensions(context.datapackWorldgen()); } -@@ -237,6 +_,7 @@ +@@ -238,6 +_,7 @@ return; } @@ -185,7 +185,7 @@ RegistryAccess.Frozen frozen = worldStem.registries().compositeAccess(); WorldData worldData = worldStem.worldData(); boolean hasOptionSpec1 = optionSet.has(optionSpec6); -@@ -245,9 +_,13 @@ +@@ -246,9 +_,13 @@ } levelStorageAccess.saveDataTag(frozen, worldData); @@ -199,7 +199,7 @@ thread1, levelStorageAccess, packRepository, -@@ -257,17 +_,34 @@ +@@ -258,18 +_,36 @@ services, LoggerChunkProgressListener::createFromGameruleRadius ); @@ -221,14 +221,16 @@ if (flag && !GraphicsEnvironment.isHeadless()) { dedicatedServer1.showGui(); } - ++ // Paper start + if (optionSet.has("port")) { + int port = (Integer) optionSet.valueOf("port"); + if (port > 0) { + dedicatedServer1.setPort(port); + } + } -+ ++ // Paper end + + GameTestTicker.SINGLETON.startTicking(); return dedicatedServer1; } ); @@ -236,7 +238,7 @@ Thread thread = new Thread("Server Shutdown Thread") { @Override public void run() { -@@ -276,6 +_,7 @@ +@@ -278,6 +_,7 @@ }; thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)); Runtime.getRuntime().addShutdownHook(thread); @@ -244,7 +246,7 @@ } catch (Exception var42) { LOGGER.error(LogUtils.FATAL_MARKER, "Failed to start the minecraft server", (Throwable)var42); } -@@ -317,7 +_,7 @@ +@@ -319,7 +_,7 @@ RegistryAccess registryAccess, boolean recreateRegionFiles ) { diff --git a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch index f7c930147a..fd6b978268 100644 --- a/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/MinecraftServer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/MinecraftServer.java +++ b/net/minecraft/server/MinecraftServer.java -@@ -173,11 +_,13 @@ +@@ -174,11 +_,13 @@ import org.slf4j.Logger; public abstract class MinecraftServer extends ReentrantBlockableEventLoop implements ServerInfo, ChunkIOErrorReporter, CommandSource { @@ -15,7 +15,7 @@ private static final int OVERLOADED_TICKS_THRESHOLD = 20; private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeUtil.NANOSECONDS_PER_SECOND; private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100; -@@ -217,6 +_,7 @@ +@@ -218,6 +_,7 @@ private Map, ServerLevel> levels = Maps.newLinkedHashMap(); private PlayerList playerList; private volatile boolean running = true; @@ -23,7 +23,7 @@ private boolean stopped; private int tickCount; private int ticksUntilAutosave = 6000; -@@ -225,11 +_,15 @@ +@@ -226,11 +_,15 @@ private boolean preventProxyConnections; private boolean pvp; private boolean allowFlight; @@ -41,7 +41,7 @@ @Nullable private KeyPair keyPair; @Nullable -@@ -270,10 +_,37 @@ +@@ -271,10 +_,37 @@ private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector(); private final DiscontinuousFrame tickFrame; @@ -80,7 +80,7 @@ if (Runtime.getRuntime().availableProcessors() > 4) { thread.setPriority(8); } -@@ -285,6 +_,10 @@ +@@ -286,6 +_,10 @@ } public MinecraftServer( @@ -91,7 +91,7 @@ Thread serverThread, LevelStorageSource.LevelStorageAccess storageSource, PackRepository packRepository, -@@ -295,9 +_,10 @@ +@@ -296,9 +_,10 @@ ChunkProgressListenerFactory progressListenerFactory ) { super("Server"); @@ -103,7 +103,7 @@ throw new IllegalStateException("Missing Overworld dimension data"); } else { this.proxy = proxy; -@@ -308,7 +_,7 @@ +@@ -309,7 +_,7 @@ services.profileCache().setExecutor(this); } @@ -112,7 +112,7 @@ this.tickRateManager = new ServerTickRateManager(this); this.progressListenerFactory = progressListenerFactory; this.storageSource = storageSource; -@@ -327,6 +_,38 @@ +@@ -328,6 +_,38 @@ this.fuelValues = FuelValues.vanillaBurnTimes(this.registries.compositeAccess(), this.worldData.enabledFeatures()); this.tickFrame = TracyClient.createDiscontinuousFrame("Server Tick"); } @@ -151,7 +151,7 @@ } private void readScoreboard(DimensionDataStorage dataStorage) { -@@ -335,18 +_,13 @@ +@@ -336,18 +_,13 @@ protected abstract boolean initServer() throws IOException; @@ -172,7 +172,7 @@ if (profiledDuration != null) { profiledDuration.finish(true); } -@@ -363,25 +_,265 @@ +@@ -364,25 +_,265 @@ protected void forceDifficulty() { } @@ -457,7 +457,7 @@ if (!serverLevelData.isInitialized()) { try { setInitialSpawn(serverLevel, serverLevelData, worldOptions.generateBonusChest(), isDebugWorld); -@@ -402,47 +_,30 @@ +@@ -403,47 +_,30 @@ serverLevelData.setInitialized(true); } @@ -522,7 +522,7 @@ int spawnHeight = chunkSource.getGenerator().getSpawnHeight(level); if (spawnHeight < level.getMinY()) { BlockPos worldPosition = chunkPos.getWorldPosition(); -@@ -494,36 +_,48 @@ +@@ -495,36 +_,48 @@ serverLevelData.setGameType(GameType.SPECTATOR); } @@ -582,7 +582,7 @@ } public GameType getDefaultGameType() { -@@ -552,11 +_,14 @@ +@@ -553,11 +_,14 @@ flag = true; } @@ -597,7 +597,7 @@ if (flush) { for (ServerLevel serverLevel2 : this.getAllLevels()) { LOGGER.info("ThreadedAnvilChunkStorage ({}): All chunks are saved", serverLevel2.getChunkSource().chunkMap.getStorageName()); -@@ -586,18 +_,48 @@ +@@ -587,18 +_,48 @@ this.stopServer(); } @@ -647,7 +647,7 @@ } LOGGER.info("Saving worlds"); -@@ -639,6 +_,25 @@ +@@ -640,6 +_,25 @@ } catch (IOException var4) { LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), var4); } @@ -673,7 +673,7 @@ } public String getLocalIp() { -@@ -654,6 +_,14 @@ +@@ -655,6 +_,14 @@ } public void halt(boolean waitForServer) { @@ -688,7 +688,7 @@ this.running = false; if (waitForServer) { try { -@@ -664,6 +_,57 @@ +@@ -665,6 +_,57 @@ } } @@ -746,7 +746,7 @@ protected void runServer() { try { if (!this.initServer()) { -@@ -674,6 +_,35 @@ +@@ -675,6 +_,35 @@ this.statusIcon = this.loadStatusIcon().orElse(null); this.status = this.buildServerStatus(); @@ -782,7 +782,7 @@ while (this.running) { long l; if (!this.isPaused() && this.tickRateManager.isSprinting() && this.tickRateManager.checkShouldSprintThisTick()) { -@@ -686,11 +_,30 @@ +@@ -687,11 +_,30 @@ if (l1 > OVERLOADED_THRESHOLD_NANOS + 20L * l && this.nextTickTimeNanos - this.lastOverloadWarningNanos >= OVERLOADED_WARNING_INTERVAL_NANOS + 100L * l) { long l2 = l1 / l; @@ -813,7 +813,7 @@ boolean flag = l == 0L; if (this.debugCommandProfilerDelayStart) { -@@ -698,6 +_,8 @@ +@@ -699,6 +_,8 @@ this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount); } @@ -822,7 +822,7 @@ this.nextTickTimeNanos += l; try (Profiler.Scope scope = Profiler.use(this.createProfiler())) { -@@ -748,7 +_,7 @@ +@@ -749,7 +_,7 @@ this.services.profileCache().clearExecutor(); } @@ -831,7 +831,7 @@ } } } -@@ -800,7 +_,14 @@ +@@ -801,7 +_,14 @@ } private boolean haveTime() { @@ -847,7 +847,7 @@ } public static boolean throwIfFatalException() { -@@ -845,6 +_,12 @@ +@@ -846,6 +_,12 @@ @Override public TickTask wrapRunnable(Runnable runnable) { @@ -860,7 +860,7 @@ return new TickTask(this.tickCount, runnable); } -@@ -864,15 +_,16 @@ +@@ -865,15 +_,16 @@ if (super.pollTask()) { return true; } else { @@ -879,7 +879,7 @@ } } -@@ -920,26 +_,44 @@ +@@ -921,26 +_,44 @@ } public void tickServer(BooleanSupplier hasTimeLeft) { @@ -925,7 +925,7 @@ this.tickCount++; this.tickRateManager.tick(); this.tickChildren(hasTimeLeft); -@@ -949,11 +_,19 @@ +@@ -950,11 +_,19 @@ } this.ticksUntilAutosave--; @@ -946,7 +946,7 @@ profilerFiller.push("tallying"); long l = Util.getNanos() - nanos; int i1 = this.tickCount % 100; -@@ -961,12 +_,17 @@ +@@ -962,12 +_,17 @@ this.aggregatedTickTimesNanos += l; this.tickTimesNanos[i1] = l; this.smoothedTickTimeMillis = this.smoothedTickTimeMillis * 0.8F + (float)l / (float)TimeUtil.NANOSECONDS_PER_MILLISECOND * 0.19999999F; @@ -965,7 +965,7 @@ LOGGER.debug("Autosave started"); ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("save"); -@@ -1008,7 +_,7 @@ +@@ -1009,7 +_,7 @@ private ServerStatus buildServerStatus() { ServerStatus.Players players = this.buildPlayerStatus(); return new ServerStatus( @@ -974,7 +974,7 @@ Optional.of(players), Optional.of(ServerStatus.Version.current()), Optional.ofNullable(this.statusIcon), -@@ -1022,7 +_,7 @@ +@@ -1023,7 +_,7 @@ if (this.hidesOnlinePlayers()) { return new ServerStatus.Players(maxPlayers, players.size(), List.of()); } else { @@ -983,7 +983,7 @@ ObjectArrayList list = new ObjectArrayList<>(min); int randomInt = Mth.nextInt(this.random, 0, players.size() - min); -@@ -1039,17 +_,66 @@ +@@ -1040,17 +_,66 @@ protected void tickChildren(BooleanSupplier hasTimeLeft) { ProfilerFiller profilerFiller = Profiler.get(); this.getPlayerList().getPlayers().forEach(serverPlayer1 -> serverPlayer1.connection.suspendFlushing()); @@ -1050,7 +1050,7 @@ profilerFiller.push("tick"); -@@ -1063,7 +_,9 @@ +@@ -1064,7 +_,9 @@ profilerFiller.pop(); profilerFiller.pop(); @@ -1060,7 +1060,7 @@ profilerFiller.popPush("connection"); this.tickConnection(); -@@ -1141,6 +_,22 @@ +@@ -1142,6 +_,22 @@ return this.levels.get(dimension); } @@ -1083,7 +1083,7 @@ public Set> levelKeys() { return this.levels.keySet(); } -@@ -1170,7 +_,7 @@ +@@ -1171,7 +_,7 @@ @DontObfuscate public String getServerModName() { @@ -1092,7 +1092,7 @@ } public SystemReport fillSystemReport(SystemReport systemReport) { -@@ -1205,7 +_,7 @@ +@@ -1206,7 +_,7 @@ @Override public void sendSystemMessage(Component component) { @@ -1101,7 +1101,7 @@ } public KeyPair getKeyPair() { -@@ -1243,11 +_,14 @@ +@@ -1244,11 +_,14 @@ } } @@ -1121,7 +1121,7 @@ } } -@@ -1257,7 +_,7 @@ +@@ -1258,7 +_,7 @@ private void updateMobSpawningFlags() { for (ServerLevel serverLevel : this.getAllLevels()) { @@ -1130,7 +1130,7 @@ } } -@@ -1333,10 +_,20 @@ +@@ -1334,10 +_,20 @@ @Override public String getMotd() { @@ -1152,7 +1152,7 @@ this.motd = motd; } -@@ -1359,7 +_,7 @@ +@@ -1360,7 +_,7 @@ } public ServerConnectionListener getConnection() { @@ -1161,7 +1161,7 @@ } public boolean isReady() { -@@ -1445,7 +_,7 @@ +@@ -1446,7 +_,7 @@ @Override public void executeIfPossible(Runnable task) { if (this.isStopped()) { @@ -1170,7 +1170,7 @@ } else { super.executeIfPossible(task); } -@@ -1484,7 +_,14 @@ +@@ -1485,7 +_,14 @@ return this.functionManager; } @@ -1185,7 +1185,7 @@ CompletableFuture completableFuture = CompletableFuture.supplyAsync( () -> selectedIds.stream().map(this.packRepository::getPack).filter(Objects::nonNull).map(Pack::open).collect(ImmutableList.toImmutableList()), this -@@ -1492,7 +_,7 @@ +@@ -1493,7 +_,7 @@ .thenCompose( list -> { CloseableResourceManager closeableResourceManager = new MultiPackResourceManager(PackType.SERVER_DATA, list); @@ -1194,7 +1194,7 @@ return ReloadableServerResources.loadResources( closeableResourceManager, this.registries, -@@ -1513,20 +_,39 @@ +@@ -1514,20 +_,39 @@ ) .thenAcceptAsync( reloadableResources -> { @@ -1236,7 +1236,7 @@ }, this ); -@@ -1543,7 +_,7 @@ +@@ -1544,7 +_,7 @@ DataPackConfig dataPackConfig = initialDataConfig.dataPacks(); FeatureFlagSet featureFlagSet = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures(); FeatureFlagSet featureFlagSet1 = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures(); @@ -1245,7 +1245,7 @@ if (safeMode) { return configureRepositoryWithSelection(packRepository, List.of("vanilla"), featureFlagSet, false); } else { -@@ -1598,7 +_,7 @@ +@@ -1599,7 +_,7 @@ private static WorldDataConfiguration configureRepositoryWithSelection( PackRepository packRepository, Collection selectedPacks, FeatureFlagSet enabledFeatures, boolean safeMode ) { @@ -1254,7 +1254,7 @@ enableForcedFeaturePacks(packRepository, enabledFeatures); DataPackConfig selectedPacks1 = getSelectedPacks(packRepository, safeMode); FeatureFlagSet featureFlagSet = packRepository.getRequestedFeatureFlags().join(enabledFeatures); -@@ -1630,7 +_,7 @@ +@@ -1631,7 +_,7 @@ } } @@ -1263,7 +1263,7 @@ } } -@@ -1644,11 +_,12 @@ +@@ -1645,11 +_,12 @@ public void kickUnlistedPlayers(CommandSourceStack commandSource) { if (this.isEnforceWhitelist()) { PlayerList playerList = commandSource.getServer().getPlayerList(); @@ -1278,7 +1278,7 @@ } } } -@@ -1852,6 +_,17 @@ +@@ -1853,6 +_,17 @@ } } @@ -1296,7 +1296,7 @@ private ProfilerFiller createProfiler() { if (this.willStartRecordingMetrics) { this.metricsRecorder = ActiveMetricsRecorder.createStarted( -@@ -1973,16 +_,22 @@ +@@ -1974,16 +_,22 @@ } public void logChatMessage(Component content, ChatType.Bound boundChatType, @Nullable String header) { @@ -1323,7 +1323,7 @@ } public boolean logIPs() { -@@ -2115,4 +_,53 @@ +@@ -2120,4 +_,53 @@ }; } } diff --git a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch index 777791f770..42f13731ad 100644 --- a/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/PlayerAdvancements.java.patch @@ -17,7 +17,7 @@ public PlayerAdvancements(DataFixer dataFixer, PlayerList playerList, ServerAdvancementManager manager, Path playerSavePath, ServerPlayer player) { this.playerList = playerList; -@@ -128,6 +_,7 @@ +@@ -127,6 +_,7 @@ } public void save() { @@ -25,7 +25,7 @@ JsonElement jsonElement = this.codec.encodeStart(JsonOps.INSTANCE, this.asData()).getOrThrow(); try { -@@ -145,6 +_,7 @@ +@@ -144,6 +_,7 @@ data.forEach((path, progress) -> { AdvancementHolder advancementHolder = advancementManager.get(path); if (advancementHolder == null) { @@ -33,7 +33,7 @@ LOGGER.warn("Ignored advancement '{}' in progress file {} - it doesn't exist anymore?", path, this.playerSavePath); } else { this.startProgress(advancementHolder, progress); -@@ -169,14 +_,31 @@ +@@ -168,14 +_,31 @@ AdvancementProgress orStartProgress = this.getOrStartProgress(advancement); boolean isDone = orStartProgress.isDone(); if (orStartProgress.grantProgress(criterionKey)) { @@ -58,16 +58,16 @@ + // Paper end advancement.value().rewards().grant(this.player); advancement.value().display().ifPresent(displayInfo -> { -- if (displayInfo.shouldAnnounceChat() && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { +- if (displayInfo.shouldAnnounceChat() && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { - this.playerList.broadcastSystemMessage(displayInfo.getType().createAnnouncement(advancement, this.player), false); + // Paper start - Add Adventure message to PlayerAdvancementDoneEvent -+ if (event.message() != null && this.player.serverLevel().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { ++ if (event.message() != null && this.player.level().getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) { + this.playerList.broadcastSystemMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.message()), false); + // Paper end } }); } -@@ -247,7 +_,7 @@ +@@ -246,7 +_,7 @@ public void flushDirty(ServerPlayer player, boolean showAdvancements) { if (this.isFirstPacket || !this.rootsToUpdate.isEmpty() || !this.progressChanged.isEmpty()) { Map map = new HashMap<>(); diff --git a/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch b/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch index 4276054d2f..138e996818 100644 --- a/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/ReloadableServerRegistries.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/ReloadableServerRegistries.java +++ b/net/minecraft/server/ReloadableServerRegistries.java -@@ -48,8 +_,9 @@ +@@ -46,8 +_,9 @@ List> list = TagLoader.buildUpdatedLookups(registryAccess.getAccessForLoading(RegistryLayer.RELOADABLE), postponedTags); HolderLookup.Provider provider = HolderLookup.Provider.create(list.stream()); RegistryOps registryOps = provider.createSerializationContext(JsonOps.INSTANCE); @@ -11,7 +11,7 @@ .toList(); CompletableFuture>> completableFuture = Util.sequence(list1); return completableFuture.thenApplyAsync( -@@ -58,19 +_,20 @@ +@@ -56,19 +_,20 @@ } private static CompletableFuture> scheduleRegistryLoad( @@ -21,7 +21,7 @@ return CompletableFuture.supplyAsync( () -> { WritableRegistry writableRegistry = new MappedRegistry<>(lootDataType.registryKey(), Lifecycle.experimental()); -+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(lootDataType.registryKey(), writableRegistry); // Paper - register reloadable registry ++ io.papermc.paper.registry.PaperRegistryAccess.instance().registerReloadableRegistry(writableRegistry); // Paper - register reloadable registry Map map = new HashMap<>(); SimpleJsonResourceReloadListener.scanDirectory(resourceManager, lootDataType.registryKey(), ops, lootDataType.codec(), map); map.forEach( diff --git a/paper-server/patches/sources/net/minecraft/server/ServerScoreboard.java.patch b/paper-server/patches/sources/net/minecraft/server/ServerScoreboard.java.patch index 24e1381dd3..e96ff2b56a 100644 --- a/paper-server/patches/sources/net/minecraft/server/ServerScoreboard.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/ServerScoreboard.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/ServerScoreboard.java +++ b/net/minecraft/server/ServerScoreboard.java -@@ -43,9 +_,7 @@ +@@ -45,9 +_,7 @@ protected void onScoreChanged(ScoreHolder scoreHolder, Objective objective, Score score) { super.onScoreChanged(scoreHolder, objective, score); if (this.trackedObjectives.contains(objective)) { @@ -11,7 +11,7 @@ new ClientboundSetScorePacket( scoreHolder.getScoreboardName(), objective.getName(), -@@ -68,7 +_,7 @@ +@@ -70,7 +_,7 @@ @Override public void onPlayerRemoved(ScoreHolder scoreHolder) { super.onPlayerRemoved(scoreHolder); @@ -20,7 +20,7 @@ this.setDirty(); } -@@ -76,7 +_,7 @@ +@@ -78,7 +_,7 @@ public void onPlayerScoreRemoved(ScoreHolder scoreHolder, Objective objective) { super.onPlayerScoreRemoved(scoreHolder, objective); if (this.trackedObjectives.contains(objective)) { @@ -29,7 +29,7 @@ } this.setDirty(); -@@ -88,7 +_,7 @@ +@@ -90,7 +_,7 @@ super.setDisplayObjective(slot, objective); if (displayObjective != objective && displayObjective != null) { if (this.getObjectiveDisplaySlotCount(displayObjective) > 0) { @@ -38,7 +38,7 @@ } else { this.stopTrackingObjective(displayObjective); } -@@ -96,7 +_,7 @@ +@@ -98,7 +_,7 @@ if (objective != null) { if (this.trackedObjectives.contains(objective)) { @@ -47,27 +47,21 @@ } else { this.startTrackingObjective(objective); } -@@ -108,24 +_,50 @@ +@@ -110,9 +_,7 @@ @Override public boolean addPlayerToTeam(String playerName, PlayerTeam team) { if (super.addPlayerToTeam(playerName, team)) { - this.server - .getPlayerList() - .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, playerName, ClientboundSetPlayerTeamPacket.Action.ADD)); -- this.setDirty(); -- return true; -- } else { -- return false; -- } -- } + this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(team, playerName, ClientboundSetPlayerTeamPacket.Action.ADD)); // CraftBukkit -+ this.setDirty(); -+ return true; -+ } else { -+ return false; -+ } -+ } -+ + this.updatePlayerWaypoint(playerName); + this.setDirty(); + return true; +@@ -121,16 +_,44 @@ + } + } + + // Paper start - Multiple Entries with Scoreboards + public boolean addPlayersToTeam(java.util.Collection players, PlayerTeam team) { + boolean anyAdded = false; @@ -86,19 +80,18 @@ + } + } + // Paper end - Multiple Entries with Scoreboards - ++ @Override public void removePlayerFromTeam(String username, PlayerTeam playerTeam) { super.removePlayerFromTeam(username, playerTeam); - this.server - .getPlayerList() - .broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE)); -- this.setDirty(); -- } + this.broadcastAll(ClientboundSetPlayerTeamPacket.createPlayerPacket(playerTeam, username, ClientboundSetPlayerTeamPacket.Action.REMOVE)); // CraftBukkit -+ this.setDirty(); -+ } -+ + this.updatePlayerWaypoint(username); + this.setDirty(); + } + + // Paper start - Multiple Entries with Scoreboards + public void removePlayersFromTeam(java.util.Collection players, PlayerTeam team) { + for (String playerName : players) { @@ -109,10 +102,11 @@ + this.setDirty(); + } + // Paper end - Multiple Entries with Scoreboards - ++ @Override public void onObjectiveAdded(Objective objective) { -@@ -137,7 +_,7 @@ + super.onObjectiveAdded(objective); +@@ -141,7 +_,7 @@ public void onObjectiveChanged(Objective objective) { super.onObjectiveChanged(objective); if (this.trackedObjectives.contains(objective)) { @@ -121,7 +115,7 @@ } this.setDirty(); -@@ -156,21 +_,21 @@ +@@ -160,14 +_,14 @@ @Override public void onTeamAdded(PlayerTeam playerTeam) { super.onTeamAdded(playerTeam); @@ -135,18 +129,19 @@ super.onTeamChanged(playerTeam); - this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false)); + this.broadcastAll(ClientboundSetPlayerTeamPacket.createAddOrModifyPacket(playerTeam, false)); // CraftBukkit + this.updateTeamWaypoints(playerTeam); this.setDirty(); } - +@@ -175,7 +_,7 @@ @Override public void onTeamRemoved(PlayerTeam playerTeam) { super.onTeamRemoved(playerTeam); - this.server.getPlayerList().broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam)); + this.broadcastAll(ClientboundSetPlayerTeamPacket.createRemovePacket(playerTeam)); // CraftBukkit + this.updateTeamWaypoints(playerTeam); this.setDirty(); } - -@@ -213,6 +_,7 @@ +@@ -219,6 +_,7 @@ List> startTrackingPackets = this.getStartTrackingPackets(objective); for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) { @@ -154,7 +149,7 @@ for (Packet packet : startTrackingPackets) { serverPlayer.connection.send(packet); } -@@ -238,6 +_,7 @@ +@@ -244,6 +_,7 @@ List> stopTrackingPackets = this.getStopTrackingPackets(objective); for (ServerPlayer serverPlayer : this.server.getPlayerList().getPlayers()) { @@ -162,11 +157,10 @@ for (Packet packet : stopTrackingPackets) { serverPlayer.connection.send(packet); } -@@ -269,6 +_,16 @@ - scoreboardSaveData.loadFrom(data); - return scoreboardSaveData; +@@ -295,4 +_,13 @@ + .forEach(serverPlayer -> serverLevel.getWaypointManager().remakeConnections(serverPlayer)); + } } -+ + // CraftBukkit start - Send to players + private void broadcastAll(Packet packet) { + for (ServerPlayer serverPlayer : this.server.getPlayerList().players) { @@ -176,6 +170,4 @@ + } + } + // CraftBukkit end - - public static enum Method { - CHANGE, + } diff --git a/paper-server/patches/sources/net/minecraft/server/commands/BanPlayerCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/BanPlayerCommands.java.patch index 9c2282ee36..f2d0852ac0 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/BanPlayerCommands.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/BanPlayerCommands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/BanPlayerCommands.java +++ b/net/minecraft/server/commands/BanPlayerCommands.java -@@ -55,7 +_,7 @@ +@@ -57,7 +_,7 @@ ); ServerPlayer player = source.getServer().getPlayerList().getPlayer(gameProfile.getId()); if (player != null) { diff --git a/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch index 8f0c19b86d..bd2915738b 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/DeOpCommands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/DeOpCommands.java +++ b/net/minecraft/server/commands/DeOpCommands.java -@@ -35,7 +_,7 @@ +@@ -39,7 +_,7 @@ if (playerList.isOp(gameProfile)) { playerList.deop(gameProfile); i++; diff --git a/paper-server/patches/sources/net/minecraft/server/commands/EffectCommands.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/EffectCommands.java.patch index b634208b16..23d1fde806 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/EffectCommands.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/EffectCommands.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/EffectCommands.java +++ b/net/minecraft/server/commands/EffectCommands.java -@@ -180,7 +_,7 @@ +@@ -182,7 +_,7 @@ for (Entity entity : targets) { if (entity instanceof LivingEntity) { MobEffectInstance mobEffectInstance = new MobEffectInstance(effect, i1, amplifier, false, showParticles); @@ -9,7 +9,7 @@ i++; } } -@@ -210,7 +_,7 @@ +@@ -212,7 +_,7 @@ int i = 0; for (Entity entity : targets) { @@ -18,7 +18,7 @@ i++; } } -@@ -235,7 +_,7 @@ +@@ -237,7 +_,7 @@ int i = 0; for (Entity entity : targets) { diff --git a/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch index 51e5a4909d..43f871bab2 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/GameModeCommand.java.patch @@ -1,18 +1,20 @@ --- a/net/minecraft/server/commands/GameModeCommand.java +++ b/net/minecraft/server/commands/GameModeCommand.java -@@ -54,9 +_,14 @@ - int i = 0; +@@ -69,9 +_,16 @@ + } - for (ServerPlayer serverPlayer : players) { -- if (serverPlayer.setGameMode(gameType)) { -+ // Paper start - Expand PlayerGameModeChangeEvent -+ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty()); -+ if (event != null && !event.isCancelled()) { - logGamemodeChange(source.getSource(), serverPlayer, gameType); - i++; -+ } else if (event != null && event.cancelMessage() != null) { -+ source.getSource().sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true); -+ // Paper end - Expand PlayerGameModeChangeEvent - } + private static boolean setGameMode(CommandSourceStack source, ServerPlayer player, GameType gameMode) { +- if (player.setGameMode(gameMode)) { ++ // Paper start ++ org.bukkit.event.player.PlayerGameModeChangeEvent event = player.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty()); ++ if (event != null && !event.isCancelled()) { ++ // Paper end + logGamemodeChange(source, player, gameMode); + return true; ++ } else if (event != null && event.cancelMessage() != null) { ++ source.sendSuccess(() -> io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true); ++ return false; ++ // Paper end - Expand PlayerGameModeChangeEvent + } else { + return false; } - diff --git a/paper-server/patches/sources/net/minecraft/server/commands/GiveCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/GiveCommand.java.patch index 3d787b6dda..451a7265d2 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/GiveCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/GiveCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/GiveCommand.java +++ b/net/minecraft/server/commands/GiveCommand.java -@@ -51,6 +_,7 @@ +@@ -54,6 +_,7 @@ private static int giveItem(CommandSourceStack source, ItemInput item, Collection targets, int count) throws CommandSyntaxException { ItemStack itemStack = item.createItemStack(1, false); @@ -8,25 +8,7 @@ int maxStackSize = itemStack.getMaxStackSize(); int i = maxStackSize * 100; if (count > i) { -@@ -66,7 +_,7 @@ - ItemStack itemStack1 = item.createItemStack(min, false); - boolean flag = serverPlayer.getInventory().add(itemStack1); - if (flag && itemStack1.isEmpty()) { -- ItemEntity itemEntity = serverPlayer.drop(itemStack, false); -+ ItemEntity itemEntity = serverPlayer.drop(itemStack, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command - if (itemEntity != null) { - itemEntity.makeFakeItem(); - } -@@ -84,7 +_,7 @@ - ); - serverPlayer.containerMenu.broadcastChanges(); - } else { -- ItemEntity itemEntity = serverPlayer.drop(itemStack1, false); -+ ItemEntity itemEntity = serverPlayer.drop(itemStack1, false, false, false, null); // Paper - do not fire PlayerDropItemEvent for /give command - if (itemEntity != null) { - itemEntity.setNoPickUpDelay(); - itemEntity.setTarget(serverPlayer.getUUID()); -@@ -95,11 +_,11 @@ +@@ -98,11 +_,11 @@ if (targets.size() == 1) { source.sendSuccess( diff --git a/paper-server/patches/sources/net/minecraft/server/commands/KickCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/KickCommand.java.patch index f76fe82415..1570889475 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/KickCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/KickCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/KickCommand.java +++ b/net/minecraft/server/commands/KickCommand.java -@@ -48,7 +_,7 @@ +@@ -50,7 +_,7 @@ for (ServerPlayer serverPlayer : players) { if (!source.getServer().isSingleplayerOwner(serverPlayer.getGameProfile())) { diff --git a/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch index 455b4cb074..697228612e 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/LocateCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/LocateCommand.java +++ b/net/minecraft/server/commands/LocateCommand.java -@@ -202,6 +_,6 @@ +@@ -199,6 +_,6 @@ private static float dist(int x1, int z1, int x2, int z2) { int i = x2 - x1; int i1 = z2 - z1; diff --git a/paper-server/patches/sources/net/minecraft/server/commands/ReloadCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/ReloadCommand.java.patch index cfcc1b2b54..da6d6d1877 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/ReloadCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/ReloadCommand.java.patch @@ -34,4 +34,4 @@ + // CraftBukkit end public static void register(CommandDispatcher dispatcher) { - dispatcher.register(Commands.literal("reload").requires(source -> source.hasPermission(2)).executes(context -> { + dispatcher.register(Commands.literal("reload").requires(Commands.hasPermission(2)).executes(commandContext -> { diff --git a/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch index 3e36919047..1a405cea64 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/RideCommand.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/server/commands/RideCommand.java +++ b/net/minecraft/server/commands/RideCommand.java -@@ -58,7 +_,7 @@ +@@ -60,7 +_,7 @@ Entity vehicle1 = target.getVehicle(); if (vehicle1 != null) { throw ERROR_ALREADY_RIDING.create(target.getDisplayName(), vehicle1.getDisplayName()); - } else if (vehicle.getType() == EntityType.PLAYER) { + } else if (vehicle.getType() == EntityType.PLAYER && !io.papermc.paper.configuration.GlobalConfiguration.get().commands.rideCommandAllowPlayerAsVehicle) { // Paper - allow player as vehicle throw ERROR_MOUNTING_PLAYER.create(); - } else if (target.getSelfAndPassengers().anyMatch(passenger -> passenger == vehicle)) { + } else if (target.getSelfAndPassengers().anyMatch(entity -> entity == vehicle)) { throw ERROR_MOUNTING_LOOP.create(); diff --git a/paper-server/patches/sources/net/minecraft/server/commands/WorldBorderCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/WorldBorderCommand.java.patch index 26d5ded309..f6d040619b 100644 --- a/paper-server/patches/sources/net/minecraft/server/commands/WorldBorderCommand.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/commands/WorldBorderCommand.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/commands/WorldBorderCommand.java +++ b/net/minecraft/server/commands/WorldBorderCommand.java -@@ -135,7 +_,7 @@ +@@ -136,7 +_,7 @@ } private static int setDamageBuffer(CommandSourceStack source, float distance) throws CommandSyntaxException { @@ -9,7 +9,7 @@ if (worldBorder.getDamageSafeZone() == distance) { throw ERROR_SAME_DAMAGE_BUFFER.create(); } else { -@@ -146,7 +_,7 @@ +@@ -147,7 +_,7 @@ } private static int setDamageAmount(CommandSourceStack source, float damagePerBlock) throws CommandSyntaxException { @@ -18,7 +18,7 @@ if (worldBorder.getDamagePerBlock() == damagePerBlock) { throw ERROR_SAME_DAMAGE_AMOUNT.create(); } else { -@@ -159,7 +_,7 @@ +@@ -160,7 +_,7 @@ } private static int setWarningTime(CommandSourceStack source, int time) throws CommandSyntaxException { @@ -27,7 +27,7 @@ if (worldBorder.getWarningTime() == time) { throw ERROR_SAME_WARNING_TIME.create(); } else { -@@ -170,7 +_,7 @@ +@@ -171,7 +_,7 @@ } private static int setWarningDistance(CommandSourceStack source, int distance) throws CommandSyntaxException { @@ -36,7 +36,7 @@ if (worldBorder.getWarningBlocks() == distance) { throw ERROR_SAME_WARNING_DISTANCE.create(); } else { -@@ -181,13 +_,13 @@ +@@ -182,13 +_,13 @@ } private static int getSize(CommandSourceStack source) { @@ -52,7 +52,7 @@ if (worldBorder.getCenterX() == pos.x && worldBorder.getCenterZ() == pos.y) { throw ERROR_SAME_CENTER.create(); } else if (!(Math.abs(pos.x) > 2.9999984E7) && !(Math.abs(pos.y) > 2.9999984E7)) { -@@ -205,7 +_,7 @@ +@@ -206,7 +_,7 @@ } private static int setSize(CommandSourceStack source, double newSize, long time) throws CommandSyntaxException { diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch index 24a45b3776..9e68c7056d 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -70,7 +70,7 @@ thread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)); - thread.start(); + // thread.start(); // Paper - Enhance console tab completions for brigadier commands; moved down - LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().getName()); + LOGGER.info("Starting minecraft server version {}", SharedConstants.getCurrentVersion().name()); if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) { LOGGER.warn("To start the server with more ram, launch it as \"java -Xmx1024M -Xms1024M -jar minecraft_server.jar\""); } diff --git a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch index 9e44f8227b..f1a573d66d 100644 --- a/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/dedicated/DedicatedServerProperties.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/dedicated/DedicatedServerProperties.java +++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java -@@ -45,6 +_,7 @@ +@@ -47,6 +_,7 @@ static final Logger LOGGER = LogUtils.getLogger(); private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$"); private static final Splitter COMMA_SPLITTER = Splitter.on(',').trimResults(); @@ -8,7 +8,7 @@ public final boolean onlineMode = this.get("online-mode", true); public final boolean preventProxyConnections = this.get("prevent-proxy-connections", false); public final String serverIp = this.get("server-ip", ""); -@@ -85,7 +_,7 @@ +@@ -87,7 +_,7 @@ public final boolean broadcastRconToOps = this.get("broadcast-rcon-to-ops", true); public final boolean broadcastConsoleToOps = this.get("broadcast-console-to-ops", true); public final int maxWorldSize = this.get("max-world-size", property -> Mth.clamp(property, 1, 29999984), 29999984); @@ -17,7 +17,7 @@ public final String regionFileComression = this.get("region-file-compression", "deflate"); public final boolean enableJmxMonitoring = this.get("enable-jmx-monitoring", false); public final boolean enableStatus = this.get("enable-status", true); -@@ -99,13 +_,16 @@ +@@ -101,13 +_,16 @@ public final Settings.MutableValue whiteList = this.getMutable("white-list", false); public final boolean enforceSecureProfile = this.get("enforce-secure-profile", true); public final boolean logIPs = this.get("log-ips", true); @@ -37,7 +37,7 @@ String string = this.get("level-seed", ""); boolean flag = this.get("generate-structures", true); long l = WorldOptions.parseSeed(string).orElse(WorldOptions.randomSeed()); -@@ -126,15 +_,21 @@ +@@ -128,15 +_,21 @@ this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())), this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled())) ); diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch index 299330b837..1bd602d6fb 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerChunkCache.java.patch @@ -5,7 +5,7 @@ @VisibleForDebug private NaturalSpawner.SpawnState lastSpawnState; + // Paper start -+ private final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); ++ public final ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable fullChunks = new ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable<>(); + public int getFullChunksCount() { + return this.fullChunks.size(); + } @@ -146,7 +146,7 @@ + ProfilerFiller gameprofilerfiller = Profiler.get(); + + gameprofilerfiller.push("purge"); -+ this.ticketStorage.purgeStaleTickets(); ++ this.ticketStorage.purgeStaleTickets(this.chunkMap); + this.runDistanceManagerUpdates(); + gameprofilerfiller.popPush("unload"); + this.chunkMap.tick(() -> true); @@ -161,7 +161,7 @@ profilerFiller.push("purge"); - if (this.level.tickRateManager().runsNormally() || !tickChunks) { + if (this.level.tickRateManager().runsNormally() || !tickChunks || this.level.spigotConfig.unloadFrozenChunks) { // Spigot - this.ticketStorage.purgeStaleTickets(); + this.ticketStorage.purgeStaleTickets(this.chunkMap); } @@ -388,12 +_,20 @@ @@ -188,7 +188,7 @@ } else { filteredSpawningCategories = List.of(); } -@@ -544,8 +_,13 @@ +@@ -547,8 +_,13 @@ @Override public void setSpawnSettings(boolean spawnSettings) { @@ -203,7 +203,7 @@ } public String getChunkDebugData(ChunkPos chunkPos) { -@@ -618,12 +_,18 @@ +@@ -621,12 +_,18 @@ @Override public boolean pollTask() { diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch index 2254ee134a..d28acac7d5 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerEntity.java.patch @@ -70,7 +70,7 @@ Packet packet = null; boolean flag2 = flag1 || this.tickCount % 60 == 0; boolean flag3 = false; -@@ -223,6 +_,25 @@ +@@ -227,6 +_,25 @@ this.tickCount++; if (this.entity.hurtMarked) { @@ -96,7 +96,7 @@ this.entity.hurtMarked = false; this.broadcastAndSend(new ClientboundSetEntityMotionPacket(this.entity)); } -@@ -280,7 +_,10 @@ +@@ -284,7 +_,10 @@ public void sendPairingData(ServerPlayer player, Consumer> consumer) { if (this.entity.isRemoved()) { @@ -108,11 +108,10 @@ } Packet addEntityPacket = this.entity.getAddEntityPacket(this); -@@ -292,6 +_,12 @@ - boolean flag = this.trackDelta; - if (this.entity instanceof LivingEntity) { - Collection syncableAttributes = ((LivingEntity)this.entity).getAttributes().getSyncableAttributes(); -+ +@@ -295,6 +_,11 @@ + + if (this.entity instanceof LivingEntity livingEntity) { + Collection syncableAttributes = livingEntity.getAttributes().getSyncableAttributes(); + // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health + if (this.entity.getId() == player.getId()) { + ((ServerPlayer) this.entity).getBukkitEntity().injectScaledMaxHealth(syncableAttributes, false); @@ -121,7 +120,7 @@ if (!syncableAttributes.isEmpty()) { consumer.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), syncableAttributes)); } -@@ -316,8 +_,9 @@ +@@ -311,8 +_,9 @@ } if (!list.isEmpty()) { @@ -132,7 +131,7 @@ } if (!this.entity.getPassengers().isEmpty()) { -@@ -364,6 +_,11 @@ +@@ -359,6 +_,11 @@ if (this.entity instanceof LivingEntity) { Set attributesToSync = ((LivingEntity)this.entity).getAttributes().getAttributesToSync(); if (!attributesToSync.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 25f605cfb3..9727927366 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/level/ServerLevel.java +++ b/net/minecraft/server/level/ServerLevel.java -@@ -178,7 +_,7 @@ +@@ -180,7 +_,7 @@ final List players = Lists.newArrayList(); public final ServerChunkCache chunkSource; private final MinecraftServer server; @@ -8,8 +8,8 @@ + public final net.minecraft.world.level.storage.PrimaryLevelData serverLevelData; // CraftBukkit - type private int lastSpawnChunkRadius; final EntityTickList entityTickList = new EntityTickList(); - public final PersistentEntitySectionManager entityManager; -@@ -205,11 +_,131 @@ + private final ServerWaypointManager waypointManager; +@@ -208,11 +_,131 @@ private final boolean tickTime; private final RandomSequences randomSequences; @@ -142,7 +142,7 @@ ResourceKey dimension, LevelStem levelStem, ChunkProgressListener progressListener, -@@ -217,14 +_,38 @@ +@@ -220,14 +_,38 @@ long biomeZoomSeed, List customSpawners, boolean tickTime, @@ -183,7 +183,7 @@ boolean flag = server.forceSynchronousWrites(); DataFixer fixerUpper = server.getFixerUpper(); EntityPersistentStorage entityPersistentStorage = new EntityStorage( -@@ -246,8 +_,8 @@ +@@ -249,8 +_,8 @@ server.getStructureManager(), dispatcher, chunkGenerator, @@ -194,7 +194,7 @@ flag, progressListener, this.entityManager::updateChunkStatus, -@@ -268,7 +_,7 @@ +@@ -271,7 +_,7 @@ this.chunkSource.chunkScanner(), this.registryAccess(), server.getStructureManager(), @@ -203,7 +203,7 @@ chunkGenerator, this.chunkSource.randomState(), this, -@@ -276,9 +_,9 @@ +@@ -279,9 +_,9 @@ seed, fixerUpper ); @@ -216,10 +216,10 @@ } else { this.dragonFight = null; } -@@ -286,7 +_,15 @@ - this.sleepStatus = new SleepStatus(); +@@ -290,7 +_,15 @@ this.gameEventDispatcher = new GameEventDispatcher(this); this.randomSequences = Objects.requireNonNullElseGet(randomSequences, () -> this.getDataStorage().computeIfAbsent(RandomSequences.TYPE)); + this.waypointManager = new ServerWaypointManager(); - } + this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit + } @@ -233,7 +233,7 @@ @Deprecated @VisibleForTesting -@@ -298,8 +_,8 @@ +@@ -302,8 +_,8 @@ this.serverLevelData.setClearWeatherTime(clearTime); this.serverLevelData.setRainTime(weatherTime); this.serverLevelData.setThunderTime(weatherTime); @@ -244,7 +244,7 @@ } @Override -@@ -326,12 +_,25 @@ +@@ -330,12 +_,25 @@ int _int = this.getGameRules().getInt(GameRules.RULE_PLAYERS_SLEEPING_PERCENTAGE); if (this.sleepStatus.areEnoughSleeping(_int) && this.sleepStatus.areEnoughDeepSleeping(_int, this.players)) { @@ -273,7 +273,7 @@ if (this.getGameRules().getBoolean(GameRules.RULE_WEATHER_CYCLE) && this.isRaining()) { this.resetWeatherCycle(); } -@@ -346,9 +_,9 @@ +@@ -350,9 +_,9 @@ if (!this.isDebug() && runsNormally) { long l = this.getGameTime(); profilerFiller.push("blockTicks"); @@ -285,7 +285,7 @@ profilerFiller.pop(); } -@@ -366,7 +_,7 @@ +@@ -370,7 +_,7 @@ this.handlingTick = false; profilerFiller.pop(); @@ -294,7 +294,7 @@ if (flag) { this.resetEmptyTime(); } -@@ -455,11 +_,13 @@ +@@ -459,11 +_,13 @@ ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("iceandsnow"); @@ -308,7 +308,7 @@ profilerFiller.popPush("tickBlocks"); if (randomTickSpeed > 0) { -@@ -502,12 +_,12 @@ +@@ -506,12 +_,12 @@ int minBlockZ = pos.getMinBlockZ(); ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("thunder"); @@ -323,7 +323,7 @@ && !this.getBlockState(blockPos.below()).is(Blocks.LIGHTNING_ROD); if (flag) { SkeletonHorse skeletonHorse = EntityType.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT); -@@ -515,7 +_,7 @@ +@@ -519,7 +_,7 @@ skeletonHorse.setTrap(true); skeletonHorse.setAge(0); skeletonHorse.setPos(blockPos.getX(), blockPos.getY(), blockPos.getZ()); @@ -332,7 +332,7 @@ } } -@@ -523,7 +_,7 @@ +@@ -527,7 +_,7 @@ if (lightningBolt != null) { lightningBolt.snapTo(Vec3.atBottomCenterOf(blockPos)); lightningBolt.setVisualOnly(flag); @@ -341,7 +341,7 @@ } } } -@@ -537,7 +_,7 @@ +@@ -541,7 +_,7 @@ BlockPos blockPos1 = heightmapPos.below(); Biome biome = this.getBiome(heightmapPos).value(); if (biome.shouldFreeze(this, blockPos1)) { @@ -350,7 +350,7 @@ } if (this.isRaining()) { -@@ -549,10 +_,10 @@ +@@ -553,10 +_,10 @@ if (layersValue < Math.min(_int, 8)) { BlockState blockState1 = blockState.setValue(SnowLayerBlock.LAYERS, layersValue + 1); Block.pushEntitiesUp(blockState, blockState1, this, heightmapPos); @@ -363,7 +363,7 @@ } } -@@ -577,6 +_,12 @@ +@@ -581,6 +_,12 @@ } protected BlockPos findLightningTargetAround(BlockPos pos) { @@ -376,7 +376,7 @@ BlockPos heightmapPos = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos); Optional optional = this.findLightningRod(heightmapPos); if (optional.isPresent()) { -@@ -584,11 +_,12 @@ +@@ -588,11 +_,12 @@ } else { AABB aabb = AABB.encapsulatingFullBlocks(heightmapPos, heightmapPos.atY(this.getMaxY() + 1)).inflate(3.0); List entitiesOfClass = this.getEntitiesOfClass( @@ -390,7 +390,7 @@ if (heightmapPos.getY() == this.getMinY() - 1) { heightmapPos = heightmapPos.above(2); } -@@ -675,8 +_,8 @@ +@@ -683,8 +_,8 @@ this.serverLevelData.setThunderTime(thunderTime); this.serverLevelData.setRainTime(rainTime); this.serverLevelData.setClearWeatherTime(clearWeatherTime); @@ -401,7 +401,7 @@ } this.oThunderLevel = this.thunderLevel; -@@ -697,6 +_,7 @@ +@@ -705,6 +_,7 @@ this.rainLevel = Mth.clamp(this.rainLevel, 0.0F, 1.0F); } @@ -409,7 +409,7 @@ if (this.oRainLevel != this.rainLevel) { this.server .getPlayerList() -@@ -719,14 +_,47 @@ +@@ -727,14 +_,47 @@ this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, this.rainLevel)); this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel)); } @@ -461,7 +461,7 @@ } public void resetEmptyTime() { -@@ -748,18 +_,46 @@ +@@ -756,18 +_,46 @@ } } @@ -508,7 +508,7 @@ } private void tickPassenger(Entity ridingEntity, Entity passengerEntity) { -@@ -768,10 +_,12 @@ +@@ -776,10 +_,12 @@ } else if (passengerEntity instanceof Player || this.entityTickList.contains(passengerEntity)) { passengerEntity.setOldPosAndRot(); passengerEntity.tickCount++; @@ -521,7 +521,7 @@ profilerFiller.pop(); for (Entity entity : passengerEntity.getPassengers()) { -@@ -788,6 +_,7 @@ +@@ -810,6 +_,7 @@ public void save(@Nullable ProgressListener progress, boolean flush, boolean skipSave) { ServerChunkCache chunkSource = this.getChunkSource(); if (!skipSave) { @@ -529,7 +529,7 @@ if (progress != null) { progress.progressStartNoAbort(Component.translatable("menu.savingLevel")); } -@@ -804,11 +_,19 @@ +@@ -826,11 +_,19 @@ this.entityManager.autoSave(); } } @@ -550,7 +550,7 @@ } DimensionDataStorage dataStorage = this.getChunkSource().getDataStorage(); -@@ -873,18 +_,40 @@ +@@ -895,18 +_,40 @@ @Override public boolean addFreshEntity(Entity entity) { @@ -594,7 +594,7 @@ } } -@@ -907,40 +_,119 @@ +@@ -929,40 +_,119 @@ this.entityManager.addNewEntity(player); } @@ -719,7 +719,7 @@ if (d * d + d1 * d1 + d2 * d2 < 1024.0) { serverPlayer.connection.send(new ClientboundBlockDestructionPacket(breakerId, pos, progress)); } -@@ -1015,7 +_,7 @@ +@@ -1037,7 +_,7 @@ pos.getX(), pos.getY(), pos.getZ(), @@ -728,7 +728,7 @@ this.dimension(), new ClientboundLevelEventPacket(type, pos, data, false) ); -@@ -1027,6 +_,11 @@ +@@ -1049,6 +_,11 @@ @Override public void gameEvent(Holder gameEvent, Vec3 pos, GameEvent.Context context) { @@ -740,7 +740,7 @@ this.gameEventDispatcher.post(gameEvent, pos, context); } -@@ -1039,17 +_,28 @@ +@@ -1061,17 +_,28 @@ this.getChunkSource().blockChanged(pos); this.pathTypesByPosCache.invalidate(pos); @@ -769,7 +769,7 @@ try { this.isUpdatingNavigations = true; -@@ -1061,15 +_,23 @@ +@@ -1083,15 +_,23 @@ this.isUpdatingNavigations = false; } } @@ -793,7 +793,7 @@ this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, block, null, orientation); } -@@ -1118,6 +_,42 @@ +@@ -1140,6 +_,42 @@ ParticleOptions largeExplosionParticles, Holder explosionSound ) { @@ -836,7 +836,7 @@ Explosion.BlockInteraction blockInteraction = switch (explosionInteraction) { case NONE -> Explosion.BlockInteraction.KEEP; case BLOCK -> this.getDestroyType(GameRules.RULE_BLOCK_EXPLOSION_DROP_DECAY); -@@ -1126,10 +_,17 @@ +@@ -1148,10 +_,17 @@ : Explosion.BlockInteraction.KEEP; case TNT -> this.getDestroyType(GameRules.RULE_TNT_EXPLOSION_DROP_DECAY); case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK; @@ -854,7 +854,7 @@ ParticleOptions particleOptions = serverExplosion.isSmall() ? smallExplosionParticles : largeExplosionParticles; for (ServerPlayer serverPlayer : this.players) { -@@ -1138,6 +_,8 @@ +@@ -1160,6 +_,8 @@ serverPlayer.connection.send(new ClientboundExplodePacket(vec3, optional, particleOptions, explosionSound)); } } @@ -863,7 +863,7 @@ } private Explosion.BlockInteraction getDestroyType(GameRules.Key decayGameRule) { -@@ -1208,7 +_,7 @@ +@@ -1230,7 +_,7 @@ public int sendParticles( T type, double posX, double posY, double posZ, int particleCount, double xOffset, double yOffset, double zOffset, double speed ) { @@ -872,7 +872,7 @@ } public int sendParticles( -@@ -1224,13 +_,49 @@ +@@ -1246,13 +_,49 @@ double zOffset, double speed ) { @@ -924,7 +924,7 @@ if (this.sendParticles(serverPlayer, overrideLimiter, posX, posY, posZ, clientboundLevelParticlesPacket)) { i++; } -@@ -1293,7 +_,7 @@ +@@ -1315,7 +_,7 @@ @Nullable public BlockPos findNearestMapStructure(TagKey structureTag, BlockPos pos, int radius, boolean skipExistingChunks) { @@ -933,7 +933,7 @@ return null; } else { Optional> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag); -@@ -1340,10 +_,36 @@ +@@ -1362,10 +_,36 @@ @Nullable @Override public MapItemSavedData getMapData(MapId mapId) { @@ -971,7 +971,7 @@ this.getServer().overworld().getDataStorage().set(MapItemSavedData.type(mapId), data); } -@@ -1355,17 +_,27 @@ +@@ -1377,17 +_,27 @@ BlockPos spawnPos = this.levelData.getSpawnPos(); float spawnAngle = this.levelData.getSpawnAngle(); if (!spawnPos.equals(pos) || spawnAngle != angle) { @@ -1001,7 +1001,7 @@ } this.lastSpawnChunkRadius = i; -@@ -1400,6 +_,11 @@ +@@ -1422,6 +_,11 @@ DebugPackets.sendPoiRemovedPacket(this, blockPos); })); optional1.ifPresent(holder -> this.getServer().execute(() -> { @@ -1013,7 +1013,7 @@ this.getPoiManager().add(blockPos, (Holder)holder); DebugPackets.sendPoiAddedPacket(this, blockPos); })); -@@ -1552,12 +_,12 @@ +@@ -1574,12 +_,12 @@ } public boolean isFlat() { @@ -1028,7 +1028,7 @@ } @Nullable -@@ -1608,6 +_,7 @@ +@@ -1630,6 +_,7 @@ @Override public LevelEntityGetter getEntities() { @@ -1036,7 +1036,7 @@ return this.entityManager.getEntityGetter(); } -@@ -1697,6 +_,28 @@ +@@ -1736,6 +_,28 @@ return this.serverLevelData.getGameRules(); } @@ -1065,15 +1065,15 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashReportCategory = super.fillReportDetails(report); -@@ -1712,6 +_,7 @@ - final class EntityCallbacks implements LevelCallback { - @Override - public void onCreated(Entity entity) { +@@ -1754,6 +_,7 @@ + if (entity instanceof WaypointTransmitter waypointTransmitter && waypointTransmitter.isTransmittingWaypoint()) { + ServerLevel.this.getWaypointManager().trackWaypoint(waypointTransmitter); + } + entity.setOldPosAndRot(); // Paper - update old pos / rot for new entities as it will default to Vec3.ZERO } @Override -@@ -1721,24 +_,32 @@ +@@ -1767,17 +_,24 @@ @Override public void onTickingStart(Entity entity) { @@ -1086,8 +1086,7 @@ ServerLevel.this.entityTickList.remove(entity); + // Paper start - Reset pearls when they stop being ticked + if (ServerLevel.this.paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && ServerLevel.this.paperConfig().misc.legacyEnderPearlBehavior && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) { -+ pearl.cachedOwner = null; -+ pearl.ownerUUID = null; ++ pearl.setOwner(null); + } + // Paper end - Reset pearls when they stop being ticked } @@ -1099,7 +1098,8 @@ + // ServerLevel.this.getChunkSource().addEntity(entity); // Paper - ignore and warn about illegal addEntity calls instead of crashing server; moved down below valid=true if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.add(serverPlayer); - ServerLevel.this.updateSleepingPlayerList(); + if (serverPlayer.isReceivingWaypoints()) { +@@ -1792,7 +_,7 @@ } if (entity instanceof Mob mob) { @@ -1108,7 +1108,7 @@ String string = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde( "onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration") -@@ -1755,10 +_,52 @@ +@@ -1809,10 +_,52 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::add); @@ -1161,7 +1161,7 @@ ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer serverPlayer) { ServerLevel.this.players.remove(serverPlayer); -@@ -1766,7 +_,7 @@ +@@ -1821,7 +_,7 @@ } if (entity instanceof Mob mob) { @@ -1170,7 +1170,7 @@ String string = "onTrackingStart called during navigation iteration"; Util.logAndPauseIfInIde( "onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration") -@@ -1783,6 +_,15 @@ +@@ -1838,6 +_,15 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove); @@ -1186,7 +1186,7 @@ } @Override -@@ -1790,4 +_,24 @@ +@@ -1845,4 +_,24 @@ entity.updateDynamicGameEventListener(DynamicGameEventListener::move); } } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch index 9470cf950a..4e9066f0c9 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayer.java.patch @@ -1,14 +1,6 @@ --- a/net/minecraft/server/level/ServerPlayer.java +++ b/net/minecraft/server/level/ServerPlayer.java -@@ -65,7 +_,6 @@ - import net.minecraft.network.protocol.game.ClientboundHurtAnimationPacket; - import net.minecraft.network.protocol.game.ClientboundMerchantOffersPacket; - import net.minecraft.network.protocol.game.ClientboundOpenBookPacket; --import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; - import net.minecraft.network.protocol.game.ClientboundOpenSignEditorPacket; - import net.minecraft.network.protocol.game.ClientboundPlayerAbilitiesPacket; - import net.minecraft.network.protocol.game.ClientboundPlayerCombatEndPacket; -@@ -235,7 +_,8 @@ +@@ -245,7 +_,8 @@ private int levitationStartTime; private boolean disconnected; private int requestedViewDistance = 2; @@ -18,7 +10,7 @@ @Nullable private Vec3 startingToFallPosition; @Nullable -@@ -281,6 +_,13 @@ +@@ -291,6 +_,13 @@ } } @@ -32,7 +24,7 @@ @Override public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) { ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack)); -@@ -316,6 +_,32 @@ +@@ -326,6 +_,32 @@ } } @@ -65,7 +57,7 @@ @Override public void dataChanged(AbstractContainerMenu containerMenu, int dataSlotIndex, int value) { } -@@ -344,9 +_,43 @@ +@@ -354,9 +_,43 @@ public void sendSystemMessage(Component component) { ServerPlayer.this.sendSystemMessage(component); } @@ -108,22 +100,20 @@ + public @Nullable org.bukkit.event.player.PlayerQuitEvent.QuitReason quitReason = null; // Paper - Add API for quit reason; there are a lot of changes to do if we change all methods leading to the event public ServerPlayer(MinecraftServer server, ServerLevel level, GameProfile gameProfile, ClientInformation clientInformation) { - super(level, level.getSharedSpawnPos(), level.getSharedSpawnAngle(), gameProfile); -@@ -356,16 +_,22 @@ + super(level, gameProfile); +@@ -366,15 +_,21 @@ this.server = server; this.stats = server.getPlayerList().getPlayerStats(this); this.advancements = server.getPlayerList().getPlayerAdvancements(this); -- this.snapTo(this.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); - this.updateOptions(clientInformation); -+ // this.snapTo(this.adjustSpawnLocation(level, level.getSharedSpawnPos()).getBottomCenter(), 0.0F, 0.0F); // Paper - Don't move existing players to world spawn + this.updateOptionsNoEvents(clientInformation); // Paper - don't call options events on login this.object = null; -+ + // CraftBukkit start + this.displayName = this.getScoreboardName(); + this.adventure$displayName = net.kyori.adventure.text.Component.text(this.getScoreboardName()); // Paper + this.bukkitPickUpLoot = true; + this.maxHealthCache = this.getMaxHealth(); ++ // CraftBukkit end } @Override @@ -135,22 +125,22 @@ int max = Math.max(0, this.server.getSpawnRadius(level)); int floor = Mth.floor(level.getWorldBorder().getDistanceToBorder(pos.getX(), pos.getZ())); if (floor < max) { -@@ -436,6 +_,7 @@ - this.enteredNetherPosition = compound.read("entered_nether_pos", Vec3.CODEC).orElse(null); - this.seenCredits = compound.getBooleanOr("seenCredits", false); - this.recipeBook.fromNbt(compound.getCompoundOrEmpty("recipeBook"), key -> this.server.getRecipeManager().byKey(key).isPresent()); -+ this.getBukkitEntity().readExtraData(compound); // CraftBukkit +@@ -446,6 +_,7 @@ + this.seenCredits = input.getBooleanOr("seenCredits", false); + input.read("recipeBook", ServerRecipeBook.Packed.CODEC) + .ifPresent(packed -> this.recipeBook.loadUntrusted(packed, key -> this.server.getRecipeManager().byKey(key).isPresent())); ++ this.getBukkitEntity().readExtraData(input); // CraftBukkit if (this.isSleeping()) { this.stopSleeping(); } -@@ -459,12 +_,24 @@ - compound.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall); - compound.storeNullable("raid_omen_position", BlockPos.CODEC, this.raidOmenPosition); - this.saveEnderPearls(compound); -+ this.getBukkitEntity().setExtraData(compound); // CraftBukkit +@@ -469,12 +_,24 @@ + output.putBoolean("spawn_extra_particles_on_fall", this.spawnExtraParticlesOnFall); + output.storeNullable("raid_omen_position", BlockPos.CODEC, this.raidOmenPosition); + this.saveEnderPearls(output); ++ this.getBukkitEntity().setExtraData(output); // CraftBukkit } - private void saveParentVehicle(CompoundTag tag) { + private void saveParentVehicle(ValueOutput output) { Entity rootVehicle = this.getRootVehicle(); Entity vehicle = this.getVehicle(); - if (vehicle != null && rootVehicle != this && rootVehicle.hasExactlyOnePlayerPassenger()) { @@ -166,19 +156,19 @@ + } + if (persistVehicle && vehicle != null && rootVehicle != this && rootVehicle.hasExactlyOnePlayerPassenger() && !rootVehicle.isRemoved()) { // Paper - Ensure valid vehicle status + // CraftBukkit end - CompoundTag compoundTag = new CompoundTag(); - CompoundTag compoundTag1 = new CompoundTag(); - rootVehicle.save(compoundTag1); -@@ -479,7 +_,7 @@ - if (!compound.isEmpty()) { - ServerLevel serverLevel = this.serverLevel(); + ValueOutput valueOutput = output.child("RootVehicle"); + valueOutput.store("Attach", UUIDUtil.CODEC, vehicle.getUUID()); + rootVehicle.save(valueOutput.child("Entity")); +@@ -486,7 +_,7 @@ + if (!optional.isEmpty()) { + ServerLevel serverLevel = this.level(); Entity entity = EntityType.loadEntityRecursive( -- compound.get().getCompoundOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2) ? null : entity2 -+ compound.get().getCompoundOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2 // Paper - Entity#getEntitySpawnReason +- optional.get().childOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2) ? null : entity2 ++ optional.get().childOrEmpty("Entity"), serverLevel, EntitySpawnReason.LOAD, entity2 -> !serverLevel.addWithUUID(entity2, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.MOUNT) ? null : entity2 // Paper - Entity#getEntitySpawnReason ); if (entity != null) { - UUID uuid = compound.get().read("Attach", UUIDUtil.CODEC).orElse(null); -@@ -496,10 +_,10 @@ + UUID uuid = optional.get().read("Attach", UUIDUtil.CODEC).orElse(null); +@@ -503,10 +_,10 @@ if (!this.isPassenger()) { LOGGER.warn("Couldn't reattach entity to player"); @@ -191,15 +181,15 @@ } } } -@@ -511,6 +_,7 @@ - ListTag listTag = new ListTag(); +@@ -518,6 +_,7 @@ + ValueOutput.ValueOutputList valueOutputList = output.childrenList("ender_pearls"); for (ThrownEnderpearl thrownEnderpearl : this.enderPearls) { + if (thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) continue; // Paper - Allow using old ender pearl behavior if (thrownEnderpearl.isRemoved()) { LOGGER.warn("Trying to save removed ender pearl, skipping"); } else { -@@ -546,6 +_,16 @@ +@@ -550,6 +_,16 @@ } } @@ -216,7 +206,7 @@ public void setExperiencePoints(int experiencePoints) { float f = this.getXpNeededForNextLevel(); float f1 = (f - 1.0F) / f; -@@ -603,6 +_,11 @@ +@@ -607,6 +_,11 @@ @Override public void tick() { @@ -228,7 +218,7 @@ this.tickClientLoadTimeout(); this.gameMode.tick(); this.wardenSpawnTracker.tick(); -@@ -610,9 +_,14 @@ +@@ -614,9 +_,14 @@ this.invulnerableTime--; } @@ -246,7 +236,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -662,7 +_,7 @@ +@@ -675,7 +_,7 @@ public void doTick() { try { @@ -255,7 +245,7 @@ super.tick(); } -@@ -676,7 +_,7 @@ +@@ -689,7 +_,7 @@ if (this.getHealth() != this.lastSentHealth || this.lastSentFood != this.foodData.getFoodLevel() || this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) { @@ -264,7 +254,7 @@ this.lastSentHealth = this.getHealth(); this.lastSentFood = this.foodData.getFoodLevel(); this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F; -@@ -707,6 +_,12 @@ +@@ -720,6 +_,12 @@ this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil((float)this.lastRecordedExperience)); } @@ -277,7 +267,7 @@ if (this.experienceLevel != this.lastRecordedLevel) { this.lastRecordedLevel = this.experienceLevel; this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil((float)this.lastRecordedLevel)); -@@ -720,6 +_,21 @@ +@@ -733,6 +_,21 @@ if (this.tickCount % 20 == 0) { CriteriaTriggers.LOCATION.trigger(this); } @@ -299,8 +289,8 @@ } catch (Throwable var4) { CrashReport crashReport = CrashReport.forThrowable(var4, "Ticking player"); CrashReportCategory crashReportCategory = crashReport.addCategory("Player being ticked"); -@@ -744,7 +_,7 @@ - if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) { +@@ -757,7 +_,7 @@ + if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.level().getGameRules().getBoolean(GameRules.RULE_NATURAL_REGENERATION)) { if (this.tickCount % 20 == 0) { if (this.getHealth() < this.getMaxHealth()) { - this.heal(1.0F); @@ -308,7 +298,7 @@ } float saturationLevel = this.foodData.getSaturationLevel(); -@@ -793,15 +_,36 @@ +@@ -806,15 +_,36 @@ } private void updateScoreForCriteria(ObjectiveCriteria criteria, int points) { @@ -318,7 +308,7 @@ - @Override - public void die(DamageSource cause) { - this.gameEvent(GameEvent.ENTITY_DIE); -- boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); +- boolean _boolean = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); - if (_boolean) { - Component deathMessage = this.getCombatTracker().getDeathMessage(); + this.level().getCraftServer().getScoreboardManager().forAllObjectives(criteria, this, score -> score.set(points)); // CraftBukkit - Use our scores instead @@ -354,7 +344,7 @@ this.connection .send( new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage), -@@ -818,6 +_,65 @@ +@@ -831,6 +_,65 @@ } ) ); @@ -366,13 +356,13 @@ + @Override + public void die(DamageSource cause) { + // this.gameEvent(GameEvent.ENTITY_DIE); // Paper - move below event cancellation check -+ boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); final boolean showDeathMessage = _boolean; // Paper - OBFHELPER ++ boolean _boolean = this.level().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES); final boolean showDeathMessage = _boolean; // Paper - OBFHELPER + // CraftBukkit start - fire PlayerDeathEvent + if (this.isRemoved()) { + return; + } + List loot = new java.util.ArrayList<>(this.getInventory().getContainerSize()); // Paper - Restore vanilla drops behavior -+ boolean keepInventory = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); ++ boolean keepInventory = this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || this.isSpectator(); + if (!keepInventory) { + for (ItemStack item : this.getInventory().getContents()) { + if (!item.isEmpty() && !EnchantmentHelper.has(item, net.minecraft.world.item.enchantment.EnchantmentEffectComponents.PREVENT_EQUIPMENT_DROP)) { @@ -380,9 +370,9 @@ + } + } + } -+ if (this.shouldDropLoot() && this.serverLevel().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false ++ if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - fix player loottables running when mob loot gamerule is false + // SPIGOT-5071: manually add player loot tables (SPIGOT-5195 - ignores keepInventory rule) -+ this.dropFromLootTable(this.serverLevel(), cause, this.lastHurtByPlayerMemoryTime > 0); ++ this.dropFromLootTable(this.level(), cause, this.lastHurtByPlayerMemoryTime > 0); + // Paper - Restore vanilla drops behaviour; custom death loot is a noop on server player, remove. + loot.addAll(this.drops); + this.drops.clear(); // SPIGOT-5188: make sure to clear @@ -420,7 +410,7 @@ Team team = this.getTeam(); if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) { this.server.getPlayerList().broadcastSystemMessage(deathMessage, false); -@@ -827,7 +_,7 @@ +@@ -840,7 +_,7 @@ this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, deathMessage); } } else { @@ -429,14 +419,14 @@ } this.removeEntitiesOnShoulder(); -@@ -835,11 +_,35 @@ +@@ -848,11 +_,35 @@ this.tellNeutralMobsThatIDied(); } - if (!this.isSpectator()) { -- this.dropAllDeathLoot(this.serverLevel(), cause); +- this.dropAllDeathLoot(this.level(), cause); + // SPIGOT-5478 must be called manually now -+ if (event.shouldDropExperience()) this.dropExperience(this.serverLevel(), cause.getEntity()); // Paper - tie to event ++ if (event.shouldDropExperience()) this.dropExperience(this.level(), cause.getEntity()); // Paper - tie to event + // we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. + if (!event.getKeepInventory()) { + // Paper start - PlayerDeathEvent#getItemsToKeep @@ -468,7 +458,7 @@ LivingEntity killCredit = this.getKillCredit(); if (killCredit != null) { this.awardStat(Stats.ENTITY_KILLED_BY.get(killCredit.getType())); -@@ -872,10 +_,10 @@ +@@ -885,10 +_,10 @@ public void awardKillScore(Entity entity, DamageSource damageSource) { if (entity != this) { super.awardKillScore(entity, damageSource); @@ -481,7 +471,7 @@ } else { this.awardStat(Stats.MOB_KILLS); } -@@ -891,7 +_,7 @@ +@@ -904,7 +_,7 @@ if (playersTeam != null) { int id = playersTeam.getColor().getId(); if (id >= 0 && id < crtieria.length) { @@ -490,7 +480,7 @@ } } } -@@ -902,9 +_,20 @@ +@@ -915,9 +_,20 @@ return false; } else { Entity entity = damageSource.getEntity(); @@ -513,7 +503,7 @@ } } -@@ -914,23 +_,77 @@ +@@ -927,23 +_,77 @@ } private boolean isPvpAllowed() { @@ -596,8 +586,8 @@ + // CraftBukkit end } - public static Optional findRespawnAndUseSpawnBlock( -@@ -947,10 +_,10 @@ + public boolean isReceivingWaypoints() { +@@ -978,10 +_,10 @@ level.setBlock(blockPos, blockState.setValue(RespawnAnchorBlock.CHARGE, blockState.getValue(RespawnAnchorBlock.CHARGE) - 1), 3); } @@ -610,7 +600,7 @@ } else if (!flag) { return Optional.empty(); } else { -@@ -958,7 +_,7 @@ +@@ -989,7 +_,7 @@ BlockState blockState1 = level.getBlockState(blockPos.above()); boolean isPossibleToRespawnInThis1 = blockState1.getBlock().isPossibleToRespawnInThis(blockState1); return isPossibleToRespawnInThis && isPossibleToRespawnInThis1 @@ -619,7 +609,7 @@ : Optional.empty(); } } -@@ -976,6 +_,7 @@ +@@ -1007,6 +_,7 @@ @Nullable @Override public ServerPlayer teleport(TeleportTransition teleportTransition) { @@ -627,10 +617,10 @@ if (this.isRemoved()) { return null; } else { -@@ -985,17 +_,52 @@ +@@ -1016,17 +_,52 @@ ServerLevel level = teleportTransition.newLevel(); - ServerLevel serverLevel = this.serverLevel(); + ServerLevel serverLevel = this.level(); - ResourceKey resourceKey = serverLevel.dimension(); + // CraftBukkit start + ResourceKey resourceKey = serverLevel.getTypeKey(); @@ -640,8 +630,8 @@ + org.bukkit.Location exit = org.bukkit.craftbukkit.util.CraftLocation.toBukkit(absolutePosition.position(), level.getWorld(), absolutePosition.yRot(), absolutePosition.xRot()); + org.bukkit.event.player.PlayerTeleportEvent tpEvent = new org.bukkit.event.player.PlayerTeleportEvent(this.getBukkitEntity(), enter, exit.clone(), teleportTransition.cause()); + // Paper start - gateway-specific teleport event -+ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.serverLevel().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { -+ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit.clone(), new org.bukkit.craftbukkit.block.CraftEndGateway(this.serverLevel().getWorld(), theEndGatewayBlockEntity)); ++ if (this.portalProcess != null && this.portalProcess.isSamePortal(((net.minecraft.world.level.block.EndGatewayBlock) net.minecraft.world.level.block.Blocks.END_GATEWAY)) && this.level().getBlockEntity(this.portalProcess.getEntryPosition()) instanceof net.minecraft.world.level.block.entity.TheEndGatewayBlockEntity theEndGatewayBlockEntity) { ++ tpEvent = new com.destroystokyo.paper.event.player.PlayerTeleportEndGatewayEvent(this.getBukkitEntity(), enter, exit.clone(), new org.bukkit.craftbukkit.block.CraftEndGateway(this.level().getWorld(), theEndGatewayBlockEntity)); + } + // Paper end - gateway-specific teleport event + org.bukkit.Bukkit.getServer().getPluginManager().callEvent(tpEvent); @@ -683,7 +673,7 @@ this.isChangingDimension = true; LevelData levelData = level.getLevelData(); this.connection.send(new ClientboundRespawnPacket(this.createCommonSpawnInfo(level), (byte)3)); -@@ -1004,16 +_,30 @@ +@@ -1035,16 +_,30 @@ playerList.sendPlayerPermissionLevel(this); serverLevel.removePlayerImmediately(this, Entity.RemovalReason.CHANGED_DIMENSION); this.unsetRemoved(); @@ -716,12 +706,10 @@ this.connection.resetPosition(); level.addDuringTeleport(this); profilerFiller.pop(); -@@ -1027,10 +_,39 @@ - this.lastSentExp = -1; +@@ -1059,10 +_,37 @@ this.lastSentHealth = -1.0F; this.lastSentFood = -1; -+ -+ + this.teleportSpectators(teleportTransition, serverLevel); + // CraftBukkit start + org.bukkit.event.player.PlayerChangedWorldEvent changeEvent = new org.bukkit.event.player.PlayerChangedWorldEvent(this.getBukkitEntity(), serverLevel.getWorld()); + this.level().getCraftServer().getPluginManager().callEvent(changeEvent); @@ -756,7 +744,7 @@ @Override public void forceSetRotation(float yRot, float xRot) { -@@ -1040,12 +_,26 @@ +@@ -1072,12 +_,26 @@ public void triggerDimensionChangeTriggers(ServerLevel level) { ResourceKey resourceKey = level.dimension(); ResourceKey resourceKey1 = this.level().dimension(); @@ -786,7 +774,7 @@ this.enteredNetherPosition = null; } } -@@ -1061,19 +_,18 @@ +@@ -1093,19 +_,18 @@ this.containerMenu.broadcastChanges(); } @@ -810,7 +798,7 @@ if (this.level().isBrightOutside()) { return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW); } else { -@@ -1092,7 +_,34 @@ +@@ -1124,7 +_,34 @@ } } @@ -846,7 +834,7 @@ this.awardStat(Stats.SLEEP_IN_BED); CriteriaTriggers.SLEPT_IN_BED.trigger(this); }); -@@ -1128,21 +_,29 @@ +@@ -1160,21 +_,29 @@ @Override public void stopSleepInBed(boolean wakeImmediately, boolean updateLevelForSleepingPlayers) { @@ -859,7 +847,7 @@ + } + // CraftBukkit end if (this.isSleeping()) { - this.serverLevel().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2)); + this.level().getChunkSource().broadcastAndSend(this, new ClientboundAnimatePacket(this, 2)); } super.stopSleepInBed(wakeImmediately, updateLevelForSleepingPlayers); @@ -879,8 +867,8 @@ } @Override -@@ -1185,8 +_,9 @@ - this.connection.send(new ClientboundOpenSignEditorPacket(signEntity.getBlockPos(), isFrontText)); +@@ -1222,8 +_,9 @@ + this.connection.send(new ClientboundShowDialogPacket(dialog)); } - public void nextContainerCounter() { @@ -890,7 +878,7 @@ } @Override -@@ -1194,12 +_,39 @@ +@@ -1231,12 +_,39 @@ if (menu == null) { return OptionalInt.empty(); } else { @@ -931,7 +919,7 @@ if (abstractContainerMenu == null) { if (this.isSpectator()) { this.displayClientMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED), true); -@@ -1207,10 +_,14 @@ +@@ -1244,10 +_,14 @@ return OptionalInt.empty(); } else { @@ -948,7 +936,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -1223,14 +_,25 @@ +@@ -1260,14 +_,25 @@ @Override public void openHorseInventory(AbstractHorse horse, Container inventory) { @@ -977,7 +965,7 @@ this.initMenu(this.containerMenu); } -@@ -1252,10 +_,30 @@ +@@ -1289,10 +_,30 @@ @Override public void closeContainer() { @@ -1008,7 +996,7 @@ @Override public void doCloseContainer() { this.containerMenu.removed(this); -@@ -1278,19 +_,19 @@ +@@ -1315,19 +_,19 @@ int rounded = Math.round((float)Math.sqrt(dx * dx + dy * dy + dz * dz) * 100.0F); if (rounded > 0) { this.awardStat(Stats.SWIM_ONE_CM, rounded); @@ -1031,7 +1019,7 @@ } } else if (this.onClimbable()) { if (dy > 0.0) { -@@ -1301,13 +_,13 @@ +@@ -1338,13 +_,13 @@ if (rounded > 0) { if (this.isSprinting()) { this.awardStat(Stats.SPRINT_ONE_CM, rounded); @@ -1048,7 +1036,7 @@ } } } else if (this.isFallFlying()) { -@@ -1347,13 +_,13 @@ +@@ -1386,13 +_,13 @@ @Override public void awardStat(Stat stat, int amount) { this.stats.increment(this, stat, amount); @@ -1064,7 +1052,7 @@ } @Override -@@ -1384,9 +_,9 @@ +@@ -1423,9 +_,9 @@ super.jumpFromGround(); this.awardStat(Stats.JUMP); if (this.isSprinting()) { @@ -1076,7 +1064,7 @@ } } -@@ -1399,6 +_,13 @@ +@@ -1438,6 +_,13 @@ public void disconnect() { this.disconnected = true; this.ejectPassengers(); @@ -1090,7 +1078,7 @@ if (this.isSleeping()) { this.stopSleepInBed(true, false); } -@@ -1410,6 +_,7 @@ +@@ -1449,6 +_,7 @@ public void resetSentInfo() { this.lastSentHealth = -1.0E8F; @@ -1098,7 +1086,7 @@ } @Override -@@ -1444,12 +_,12 @@ +@@ -1483,12 +_,12 @@ this.onUpdateAbilities(); if (keepEverything) { this.getAttributes().assignBaseValues(that.getAttributes()); @@ -1113,16 +1101,16 @@ } this.getInventory().replaceWith(that.getInventory()); -@@ -1460,7 +_,7 @@ +@@ -1499,7 +_,7 @@ this.portalProcess = that.portalProcess; } else { this.getAttributes().assignBaseValues(that.getAttributes()); - this.setHealth(this.getMaxHealth()); + // this.setHealth(this.getMaxHealth()); // CraftBukkit - if (this.serverLevel().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || that.isSpectator()) { + if (this.level().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) || that.isSpectator()) { this.getInventory().replaceWith(that.getInventory()); this.experienceLevel = that.experienceLevel; -@@ -1476,7 +_,7 @@ +@@ -1515,7 +_,7 @@ this.lastSentExp = -1; this.lastSentHealth = -1.0F; this.lastSentFood = -1; @@ -1131,7 +1119,7 @@ this.seenCredits = that.seenCredits; this.enteredNetherPosition = that.enteredNetherPosition; this.chunkTrackingView = that.chunkTrackingView; -@@ -1529,7 +_,7 @@ +@@ -1568,7 +_,7 @@ } @Override @@ -1140,7 +1128,7 @@ if (this.isSleeping()) { this.stopSleepInBed(true, true); } -@@ -1538,7 +_,7 @@ +@@ -1577,7 +_,7 @@ this.setCamera(this); } @@ -1149,7 +1137,7 @@ if (flag) { this.setYHeadRot(relativeMovements.contains(Relative.Y_ROT) ? this.getYHeadRot() + yaw : yaw); } -@@ -1575,9 +_,17 @@ +@@ -1615,9 +_,17 @@ } public boolean setGameMode(GameType gameMode) { @@ -1169,7 +1157,7 @@ } else { this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, gameMode.getId())); if (gameMode == GameType.SPECTATOR) { -@@ -1593,7 +_,7 @@ +@@ -1633,7 +_,7 @@ this.onUpdateAbilities(); this.updateEffectVisibility(); @@ -1178,7 +1166,7 @@ } } -@@ -1649,8 +_,13 @@ +@@ -1689,8 +_,13 @@ } public void sendChatMessage(OutgoingChatMessage message, boolean filtered, ChatType.Bound boundType) { @@ -1193,7 +1181,7 @@ } } -@@ -1661,7 +_,42 @@ +@@ -1701,7 +_,42 @@ } public void updateOptions(ClientInformation clientInformation) { @@ -1236,7 +1224,7 @@ this.requestedViewDistance = clientInformation.viewDistance(); this.chatVisibility = clientInformation.chatVisibility(); this.canChatColor = clientInformation.chatColors(); -@@ -1747,8 +_,23 @@ +@@ -1787,8 +_,23 @@ Entity camera = this.getCamera(); this.camera = (Entity)(entityToSpectate == null ? this : entityToSpectate); if (camera != this.camera) { @@ -1261,7 +1249,7 @@ } if (entityToSpectate != null) { -@@ -1782,11 +_,11 @@ +@@ -1822,11 +_,11 @@ @Nullable public Component getTabListDisplayName() { @@ -1275,7 +1263,7 @@ } @Override -@@ -1817,11 +_,56 @@ +@@ -1857,11 +_,56 @@ } public void setRespawnPosition(@Nullable ServerPlayer.RespawnConfig respawnConfig, boolean displayInChat) { @@ -1334,7 +1322,7 @@ } public SectionPos getLastSectionPos() { -@@ -1851,16 +_,23 @@ +@@ -1891,16 +_,23 @@ } @Override @@ -1362,24 +1350,24 @@ return itemEntity; } -@@ -1888,6 +_,16 @@ +@@ -1928,6 +_,16 @@ } - public void loadGameTypes(@Nullable CompoundTag tag) { + public void loadGameTypes(@Nullable ValueInput input) { + // Paper start - Expand PlayerGameModeChangeEvent -+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(tag, "playerGameType")) { ++ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != readPlayerMode(input, "playerGameType")) { + if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) { + this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE); + } else { -+ this.gameMode.setGameModeForPlayer(readPlayerMode(tag,"playerGameType"), readPlayerMode(tag, "previousPlayerGameType")); ++ this.gameMode.setGameModeForPlayer(readPlayerMode(input, "playerGameType"), readPlayerMode(input, "previousPlayerGameType")); + } + return; + } + // Paper end - Expand PlayerGameModeChangeEvent this.gameMode - .setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(tag, "playerGameType")), readPlayerMode(tag, "previousPlayerGameType")); + .setGameModeForPlayer(this.calculateGameModeForNewPlayer(readPlayerMode(input, "playerGameType")), readPlayerMode(input, "previousPlayerGameType")); } -@@ -1989,8 +_,14 @@ +@@ -2029,8 +_,14 @@ @Override public void removeVehicle() { @@ -1395,7 +1383,7 @@ if (vehicle instanceof LivingEntity livingEntity) { for (MobEffectInstance mobEffectInstance : livingEntity.getActiveEffects()) { this.connection.send(new ClientboundRemoveMobEffectPacket(vehicle.getId(), mobEffectInstance.getEffect())); -@@ -2089,7 +_,7 @@ +@@ -2129,7 +_,7 @@ } public static long placeEnderPearlTicket(ServerLevel level, ChunkPos pos) { @@ -1404,7 +1392,7 @@ return TicketType.ENDER_PEARL.timeout(); } -@@ -2113,9 +_,11 @@ +@@ -2153,9 +_,11 @@ } } @@ -1419,7 +1407,7 @@ } private static float calculateLookAtYaw(Vec3 position, BlockPos towardsPos) { -@@ -2123,4 +_,143 @@ +@@ -2163,4 +_,143 @@ return (float)Mth.wrapDegrees(Mth.atan2(vec3.z, vec3.x) * 180.0F / (float)Math.PI - 90.0); } } diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch index 0236b0722d..71a1bbae1b 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerPlayerGameMode.java.patch @@ -9,7 +9,7 @@ public ServerPlayerGameMode(ServerPlayer player) { this.player = player; - this.level = player.serverLevel(); + this.level = player.level(); } + @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper @@ -40,8 +40,8 @@ + // CraftBukkit end + this.setGameModeForPlayer(gameModeForPlayer, this.gameModeForPlayer); // Paper - Fix MC-259571 this.player.onUpdateAbilities(); - this.player - .server + this.level + .getServer() .getPlayerList() - .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player)); + .broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_GAME_MODE, this.player), this.player); // CraftBukkit diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch index 422fcb9bf7..da18c6208f 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerCommonPacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java +++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java -@@ -27,30 +_,67 @@ +@@ -29,30 +_,67 @@ import net.minecraft.util.profiling.Profiler; import org.slf4j.Logger; @@ -73,7 +73,7 @@ private void close() { if (!this.closed) { -@@ -61,6 +_,12 @@ +@@ -63,6 +_,12 @@ @Override public void onDisconnect(DisconnectionDetails details) { @@ -86,7 +86,7 @@ if (this.isSingleplayerOwner()) { LOGGER.info("Stopping singleplayer server as player logged out"); this.server.halt(false); -@@ -80,7 +_,7 @@ +@@ -82,7 +_,7 @@ this.latency = (this.latency * 3 + i) / 4; this.keepAlivePending = false; } else if (!this.isSingleplayerOwner()) { @@ -95,7 +95,7 @@ } } -@@ -88,30 +_,123 @@ +@@ -90,9 +_,73 @@ public void handlePong(ServerboundPongPacket packet) { } @@ -114,7 +114,7 @@ + return; + } + -+ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); ++ PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + + final net.minecraft.resources.ResourceLocation identifier = packet.payload().type().id(); + final byte[] data = discardedPayload.data(); @@ -169,7 +169,8 @@ + // Paper end @Override - public void handleResourcePackResponse(ServerboundResourcePackPacket packet) { + public void handleCustomClickAction(ServerboundCustomClickActionPacket packet) { +@@ -105,21 +_,50 @@ PacketUtils.ensureRunningOnSameThread(packet, this, this.server); if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) { LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().getName(), packet.id()); @@ -225,7 +226,7 @@ } else if (this.checkIfClosed(millis)) { this.keepAlivePending = true; this.keepAliveTime = millis; -@@ -126,7 +_,7 @@ +@@ -134,7 +_,7 @@ private boolean checkIfClosed(long time) { if (this.closed) { if (time - this.closedListenerTime >= 15000L) { @@ -234,10 +235,10 @@ } return false; -@@ -149,6 +_,13 @@ +@@ -157,6 +_,13 @@ } - public void send(Packet packet, @Nullable PacketSendListener listener) { + public void send(Packet packet, @Nullable ChannelFutureListener channelFutureListener) { + // CraftBukkit start + if (packet == null || this.processedDisconnect) { // Spigot + return; @@ -248,7 +249,7 @@ if (packet.isTerminal()) { this.close(); } -@@ -165,19 +_,115 @@ +@@ -173,19 +_,115 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch index 2ff7ea70fa..12373ae87d 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerConfigurationPacketListenerImpl.java.patch @@ -46,7 +46,7 @@ } @Override -@@ -139,16 +_,21 @@ +@@ -139,16 +_,22 @@ return; } @@ -57,9 +57,10 @@ return; } -- ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation); -+ ServerPlayer playerForLogin = playerList.getPlayerForLogin(this.gameProfile, this.clientInformation, this.player); // CraftBukkit - playerList.placeNewPlayer(this.connection, playerForLogin, this.createCookie(this.clientInformation)); +- ServerPlayer serverPlayer = new ServerPlayer(this.server, this.server.overworld(), this.gameProfile, this.clientInformation); ++ ServerPlayer serverPlayer = this.player; // Paper ++ this.player.updateOptions(this.clientInformation); // Paper - Of course, we reuse the player + playerList.placeNewPlayer(this.connection, serverPlayer, this.createCookie(this.clientInformation)); } catch (Exception var5) { LOGGER.error("Couldn't place player in world", (Throwable)var5); + // Paper start - Debugging diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch index 4ae0a3e926..efbca9819e 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerGamePacketListenerImpl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java +++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java -@@ -204,6 +_,39 @@ +@@ -208,6 +_,38 @@ import net.minecraft.world.phys.shapes.VoxelShape; import org.slf4j.Logger; @@ -33,14 +33,13 @@ +import org.bukkit.event.player.PlayerSwapHandItemsEvent; +import org.bukkit.event.player.PlayerTeleportEvent; +import org.bukkit.event.player.PlayerToggleFlightEvent; -+import org.bukkit.event.player.PlayerToggleSneakEvent; +import org.bukkit.event.player.PlayerToggleSprintEvent; +// CraftBukkit end + public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl implements GameProtocols.Context, -@@ -222,7 +_,9 @@ +@@ -226,7 +_,9 @@ private int tickCount; private int ackBlockChangesUpTo = -1; private final TickThrottler chatSpamThrottler = new TickThrottler(20, 200); @@ -50,7 +49,7 @@ private double firstGoodX; private double firstGoodY; private double firstGoodZ; -@@ -248,23 +_,42 @@ +@@ -252,23 +_,42 @@ private int receivedMovePacketCount; private int knownMovePacketCount; private boolean receivedMovementThisTick; @@ -95,7 +94,7 @@ } @Override -@@ -284,8 +_,8 @@ +@@ -288,8 +_,8 @@ this.knownMovePacketCount = this.receivedMovePacketCount; if (this.clientIsFloating && !this.player.isSleeping() && !this.player.isPassenger() && !this.player.isDeadOrDying()) { if (++this.aboveGroundTickCount > this.getMaximumFlyingTicks(this.player)) { @@ -106,7 +105,7 @@ return; } } else { -@@ -303,8 +_,8 @@ +@@ -307,8 +_,8 @@ this.vehicleLastGoodZ = this.lastVehicle.getZ(); if (this.clientVehicleIsFloating && this.lastVehicle.getControllingPassenger() == this.player) { if (++this.aboveGroundVehicleTickCount > this.getMaximumFlyingTicks(this.lastVehicle)) { @@ -117,7 +116,7 @@ return; } } else { -@@ -320,11 +_,20 @@ +@@ -324,11 +_,20 @@ this.keepConnectionAlive(); this.chatSpamThrottler.tick(); this.dropSpamThrottler.tick(); @@ -141,22 +140,49 @@ } private int getMaximumFlyingTicks(Entity entity) { -@@ -384,6 +_,12 @@ +@@ -388,11 +_,37 @@ @Override public void handlePlayerInput(ServerboundPlayerInputPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + // CraftBukkit start + if (!packet.input().equals(this.player.getLastClientInput())) { + PlayerInputEvent event = new PlayerInputEvent(this.player.getBukkitEntity(), new org.bukkit.craftbukkit.CraftInput(packet.input())); + this.cserver.getPluginManager().callEvent(event); + } + // CraftBukkit end ++ // Paper start - PlayerToggleSneakEvent ++ net.minecraft.world.entity.player.Input lastInput = this.player.getLastClientInput(); ++ boolean shiftKeyDown = packet.input().shift(); ++ if (lastInput.shift() != packet.input().shift()) { ++ // Has sneak changed ++ org.bukkit.event.player.PlayerToggleSneakEvent event = new org.bukkit.event.player.PlayerToggleSneakEvent(this.getCraftPlayer(), packet.input().shift()); ++ this.cserver.getPluginManager().callEvent(event); ++ ++ // Technically the player input and the flag is desynced, but this is previous behavior.. so should be fine? ++ if (event.isCancelled()) { ++ shiftKeyDown = this.player.isShiftKeyDown(); ++ } ++ } ++ // Paper end - PlayerToggleSneakEvent this.player.setLastClientInput(packet.input()); + if (this.player.hasClientLoaded()) { + this.player.resetLastActionTime(); +- this.player.setShiftKeyDown(packet.input().shift()); +- } ++ this.player.setShiftKeyDown(shiftKeyDown); // Paper ++ } ++ // Paper start - Add option to make parrots stay ++ if (packet.input().shift() && this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) { ++ this.player.removeEntitiesOnShoulder(); ++ } ++ // Paper end - Add option to make parrots stay ++ } -@@ -403,17 +_,29 @@ + private static boolean containsInvalidValues(double x, double y, double z, float yRot, float xRot) { +@@ -411,17 +_,29 @@ public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (containsInvalidValues(packet.position().x(), packet.position().y(), packet.position().z(), packet.yRot(), packet.xRot())) { - this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement")); + this.disconnect(Component.translatable("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause @@ -168,7 +194,7 @@ + } + // Paper end - Don't allow vehicle movement from players while teleporting if (rootVehicle != this.player && rootVehicle.getControllingPassenger() == this.player && rootVehicle == this.lastVehicle) { - ServerLevel serverLevel = this.player.serverLevel(); + ServerLevel serverLevel = this.player.level(); + // CraftBukkit - store current player position + double prevX = this.player.getX(); + double prevY = this.player.getY(); @@ -188,7 +214,7 @@ float f = Mth.wrapDegrees(packet.yRot()); float f1 = Mth.wrapDegrees(packet.xRot()); double d3 = d - this.vehicleFirstGoodX; -@@ -421,7 +_,52 @@ +@@ -429,7 +_,52 @@ double d5 = d2 - this.vehicleFirstGoodZ; double d6 = rootVehicle.getDeltaMovement().lengthSqr(); double d7 = d3 * d3 + d4 * d4 + d5 * d5; @@ -242,48 +268,34 @@ LOGGER.warn( "{} (vehicle of {}) moved too quickly! {},{},{}", rootVehicle.getName().getString(), this.player.getName().getString(), d3, d4, d5 ); -@@ -430,15 +_,16 @@ +@@ -438,9 +_,9 @@ } - boolean flag = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625)); + AABB boundingBox = rootVehicle.getBoundingBox(); - d3 = d - this.vehicleLastGoodX; - d4 = d1 - this.vehicleLastGoodY; - d5 = d2 - this.vehicleLastGoodZ; + d3 = d - this.vehicleLastGoodX; // Paper - diff on change, used for checking large move vectors above + d4 = d1 - this.vehicleLastGoodY; // Paper - diff on change, used for checking large move vectors above + d5 = d2 - this.vehicleLastGoodZ; // Paper - diff on change, used for checking large move vectors above - boolean flag1 = rootVehicle.verticalCollisionBelow; + boolean flag = rootVehicle.verticalCollisionBelow; if (rootVehicle instanceof LivingEntity livingEntity && livingEntity.onClimbable()) { livingEntity.resetFallDistance(); - } - - rootVehicle.move(MoverType.PLAYER, new Vec3(d3, d4, d5)); -+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost - d3 = d - rootVehicle.getX(); - d4 = d1 - rootVehicle.getY(); - if (d4 > -0.5 || d4 < 0.5) { -@@ -448,27 +_,80 @@ +@@ -457,7 +_,7 @@ d5 = d2 - rootVehicle.getZ(); d7 = d3 * d3 + d4 * d4 + d5 * d5; - boolean flag2 = false; + boolean flag1 = false; - if (d7 > 0.0625) { + if (d7 > org.spigotmc.SpigotConfig.movedWronglyThreshold) { // Spigot - flag2 = true; + flag1 = true; LOGGER.warn("{} (vehicle of {}) moved wrongly! {}", rootVehicle.getName().getString(), this.player.getName().getString(), Math.sqrt(d7)); } +@@ -471,6 +_,57 @@ + } rootVehicle.absSnapTo(d, d1, d2, f, f1); -+ this.player.absSnapTo(d, d1, d2, this.player.getYRot(), this.player.getXRot()); // CraftBukkit - boolean flag3 = serverLevel.noCollision(rootVehicle, rootVehicle.getBoundingBox().deflate(0.0625)); - if (flag && (flag2 || !flag3)) { - rootVehicle.absSnapTo(x, y, z, f, f1); -+ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // CraftBukkit - this.send(ClientboundMoveVehiclePacket.fromEntity(rootVehicle)); - rootVehicle.removeLatestMovementRecordingBatch(); - return; - } - -+ // CraftBukkit start - fire PlayerMoveEvent ++ // CraftBukkit start - fire PlayerMoveEvent TODO: this should be removed. ++ this.player.absSnapTo(x, y, z, this.player.getYRot(), this.player.getXRot()); // Paper - TODO: This breaks alot of stuff + org.bukkit.entity.Player player = this.getCraftPlayer(); + if (!this.hasMoved) { + this.lastPosX = prevX; @@ -333,20 +345,11 @@ + } + } + // CraftBukkit end -+ - this.player.serverLevel().getChunkSource().move(this.player); + this.player.level().getChunkSource().move(this.player); Vec3 vec3 = new Vec3(rootVehicle.getX() - x, rootVehicle.getY() - y, rootVehicle.getZ() - z); this.handlePlayerKnownMovement(vec3); - rootVehicle.setOnGroundWithMovement(packet.onGround(), vec3); - rootVehicle.doCheckFallDamage(vec3.x, vec3.y, vec3.z, packet.onGround()); - this.player.checkMovementStatistics(vec3.x, vec3.y, vec3.z); -- this.clientVehicleIsFloating = d4 >= -0.03125 -+ this.clientVehicleIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix - && !flag1 - && !this.server.isFlightAllowed() - && !rootVehicle.isNoGravity() -@@ -491,12 +_,12 @@ - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); +@@ -501,12 +_,12 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (packet.getId() == this.awaitingTeleport) { if (this.awaitingPositionFromClient == null) { - this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement")); @@ -360,17 +363,17 @@ this.awaitingPositionFromClient.x, this.awaitingPositionFromClient.y, this.awaitingPositionFromClient.z, -@@ -508,12 +_,20 @@ +@@ -518,12 +_,20 @@ this.lastGoodZ = this.awaitingPositionFromClient.z; this.player.hasChangedDimension(); this.awaitingPositionFromClient = null; -+ this.player.serverLevel().getChunkSource().move(this.player); // CraftBukkit ++ this.player.level().getChunkSource().move(this.player); // CraftBukkit } } @Override public void handleAcceptPlayerLoad(ServerboundPlayerLoadedPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + // Paper start - PlayerLoadedWorldEvent + if (this.player.hasClientLoaded()) { + return; @@ -381,15 +384,15 @@ this.player.setClientLoaded(true); } -@@ -535,6 +_,7 @@ +@@ -545,6 +_,7 @@ @Override public void handleRecipeBookChangeSettingsPacket(ServerboundRecipeBookChangeSettingsPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + CraftEventFactory.callRecipeBookSettingsEvent(this.player, packet.getBookType(), packet.isOpen(), packet.isFiltering()); // CraftBukkit this.player.getRecipeBook().setBookSetting(packet.getBookType(), packet.isOpen(), packet.isFiltering()); } -@@ -550,25 +_,110 @@ +@@ -560,25 +_,110 @@ } } @@ -400,8 +403,8 @@ + @Override public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) { -- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); -+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - AsyncTabCompleteEvent; run this async +- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); ++ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); // Paper - AsyncTabCompleteEvent; run this async + // CraftBukkit start + if (!this.tabSpamThrottler.isIncrementAndUnderThreshold() && !this.server.getPlayerList().isOp(this.player.getGameProfile()) && !this.server.isSingleplayerOwner(this.player.getGameProfile())) { // Paper - configurable tab spam limits + this.disconnectAsync(Component.translatable("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - Kick event cause // Paper - add proper async disconnect @@ -505,8 +508,8 @@ } ); } -@@ -578,7 +_,7 @@ - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); +@@ -588,7 +_,7 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); - } else if (!this.player.canUseGameMasterBlocks()) { @@ -514,8 +517,8 @@ this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); } else { BaseCommandBlock baseCommandBlock = null; -@@ -633,7 +_,7 @@ - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); +@@ -643,7 +_,7 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (!this.server.isCommandBlockEnabled()) { this.player.sendSystemMessage(Component.translatable("advMode.notEnabled")); - } else if (!this.player.canUseGameMasterBlocks()) { @@ -523,7 +526,7 @@ this.player.sendSystemMessage(Component.translatable("advMode.notAllowed")); } else { BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level()); -@@ -661,11 +_,11 @@ +@@ -671,11 +_,11 @@ boolean flag = this.player.hasInfiniteMaterials() && packet.includeData(); ItemStack cloneItemStack = blockState.getCloneItemStack(serverLevel, blockPos, flag); if (!cloneItemStack.isEmpty()) { @@ -537,7 +540,7 @@ } } } -@@ -689,27 +_,40 @@ +@@ -702,27 +_,40 @@ if (entityOrPart != null && this.player.canInteractWithEntity(entityOrPart, 3.0)) { ItemStack pickResult = entityOrPart.getPickResult(); if (pickResult != null && !pickResult.isEmpty()) { @@ -578,14 +581,14 @@ + inventory.addAndPickItem(stack, event.getTargetSlot()); // Paper - Add PlayerPickItemEvent } - this.player.connection.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot())); + this.send(new ClientboundSetHeldSlotPacket(inventory.getSelectedSlot())); this.player.inventoryMenu.broadcastChanges(); + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. } } -@@ -887,6 +_,13 @@ - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); +@@ -900,6 +_,13 @@ + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); int item = packet.getItem(); if (this.player.containerMenu instanceof MerchantMenu merchantMenu) { + // CraftBukkit start @@ -598,7 +601,7 @@ if (!merchantMenu.stillValid(this.player)) { LOGGER.debug("Player {} interacted with invalid menu {}", this.player, merchantMenu); return; -@@ -899,6 +_,51 @@ +@@ -912,6 +_,51 @@ @Override public void handleEditBook(ServerboundEditBookPacket packet) { @@ -650,7 +653,7 @@ int slot = packet.slot(); if (Inventory.isHotbarSlot(slot) || slot == 40) { List list = Lists.newArrayList(); -@@ -913,10 +_,14 @@ +@@ -926,10 +_,14 @@ } private void updateBookContents(List pages, int index) { @@ -666,7 +669,7 @@ } } -@@ -930,7 +_,8 @@ +@@ -943,7 +_,8 @@ DataComponents.WRITTEN_BOOK_CONTENT, new WrittenBookContent(this.filterableFromOutgoing(title), this.player.getName().getString(), 0, list, true) ); @@ -676,14 +679,14 @@ } } -@@ -974,27 +_,35 @@ +@@ -991,27 +_,35 @@ public void handleMovePlayer(ServerboundMovePlayerPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (containsInvalidValues(packet.getX(0.0), packet.getY(0.0), packet.getZ(0.0), packet.getYRot(0.0F), packet.getXRot(0.0F))) { - this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement")); + this.disconnect(Component.translatable("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause } else { - ServerLevel serverLevel = this.player.serverLevel(); + ServerLevel serverLevel = this.player.level(); - if (!this.player.wonGame) { + if (!this.player.wonGame && !this.player.isImmobile()) { // CraftBukkit if (this.tickCount == 0) { @@ -706,7 +709,7 @@ + double d2 = clampHorizontal(packet.getZ(this.player.getZ())); final double toZ = d2; // Paper - OBFHELPER if (this.player.isPassenger()) { this.player.absSnapTo(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); - this.player.serverLevel().getChunkSource().move(this.player); + this.player.level().getChunkSource().move(this.player); + this.allowedPlayerTicks = 20; // CraftBukkit } else { + // CraftBukkit - Make sure the move is valid but then reset it for plugins to modify @@ -719,7 +722,7 @@ double x = this.player.getX(); double y = this.player.getY(); double z = this.player.getZ(); -@@ -1003,6 +_,16 @@ +@@ -1020,6 +_,16 @@ double d5 = d2 - this.firstGoodZ; double d6 = this.player.getDeltaMovement().lengthSqr(); double d7 = d3 * d3 + d4 * d4 + d5 * d5; @@ -736,7 +739,7 @@ if (this.player.isSleeping()) { if (d7 > 1.0) { this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), f, f1); -@@ -1012,36 +_,109 @@ +@@ -1029,36 +_,108 @@ if (serverLevel.tickRateManager().runsNormally()) { this.receivedMovePacketCount++; int i = this.receivedMovePacketCount - this.knownMovePacketCount; @@ -853,11 +856,10 @@ + return; // ... thanks Mojang for letting move calls teleport across dimensions. + } + // Paper end - prevent position desync -+ double verticalDelta = d4; // Paper - Decompile fix: lvt reassignment lost + double verticalDelta = d4; d3 = d - this.player.getX(); d4 = d1 - this.player.getY(); - if (d4 > -0.5 || d4 < 0.5) { -@@ -1050,23 +_,104 @@ +@@ -1068,20 +_,100 @@ d5 = d2 - this.player.getZ(); d7 = d3 * d3 + d4 * d4 + d5 * d5; @@ -883,20 +885,20 @@ - if (this.player.noPhysics - || this.player.isSleeping() - || (!flag2 || !serverLevel.noCollision(this.player, boundingBox)) -- && !this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)) { +- && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2)) { + } // Paper + } + + // Paper start - Add fail move event -+ boolean teleportBack = !this.player.noPhysics && !this.player.isSleeping() && (movedWrongly && serverLevel.noCollision(this.player, boundingBox) || this.isPlayerCollidingWithAnythingNew(serverLevel, boundingBox, d, d1, d2)); -+ if (teleportBack) { ++ boolean allowMovement = this.player.noPhysics || this.player.isSleeping() || (!movedWrongly || !serverLevel.noCollision(this.player, boundingBox)) && !this.isEntityCollidingWithAnythingNew(serverLevel, this.player, boundingBox, d, d1, d2); ++ if (!allowMovement) { + io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK, + toX, toY, toZ, toYaw, toPitch, false); + if (event.isAllowed()) { -+ teleportBack = false; ++ allowMovement = true; + } + } -+ if (!teleportBack) { ++ if (allowMovement) { + // Paper end - Add fail move event + // CraftBukkit start - fire PlayerMoveEvent + // Reset to old location first @@ -911,7 +913,6 @@ + this.lastPitch = prevPitch; + this.hasMoved = true; + } -+ + Location from = new Location(player.getWorld(), this.lastPosX, this.lastPosY, this.lastPosZ, this.lastYaw, this.lastPitch); // Get the Players previous Event location. + Location to = player.getLocation().clone(); // Start off the To location as the Players current location. + @@ -964,24 +965,20 @@ + return; + } + } -+ // CraftBukkit end ++ // Paper end this.player.absSnapTo(d, d1, d2, f, f1); boolean isAutoSpinAttack = this.player.isAutoSpinAttack(); -- this.clientIsFloating = d4 >= -0.03125 -+ this.clientIsFloating = verticalDelta >= -0.03125 // Paper - Decompile fix - && !flag1 - && !this.player.isSpectator() - && !this.server.isFlightAllowed() -@@ -1098,7 +_,7 @@ + this.clientIsFloating = verticalDelta >= -0.03125 +@@ -1116,7 +_,7 @@ this.lastGoodY = this.player.getY(); this.lastGoodZ = this.player.getZ(); } else { - this.teleport(x, y, z, f, f1); + this.internalTeleport(x, y, z, f, f1); // CraftBukkit - SPIGOT-1807: Don't call teleport event, when the client thinks the player is falling, because the chunks are not loaded on the client yet. this.player.doCheckFallDamage(this.player.getX() - x, this.player.getY() - y, this.player.getZ() - z, packet.isOnGround()); - this.player.removeLatestMovementRecordingBatch(); + this.player.removeLatestMovementRecording(); } -@@ -1134,6 +_,7 @@ +@@ -1152,6 +_,7 @@ this.player.getXRot() ); } @@ -989,7 +986,7 @@ return true; } else { -@@ -1157,10 +_,77 @@ +@@ -1175,10 +_,77 @@ } public void teleport(double x, double y, double z, float yaw, float pitch) { @@ -1068,7 +1065,7 @@ this.awaitingTeleportTime = this.tickCount; if (++this.awaitingTeleport == Integer.MAX_VALUE) { this.awaitingTeleport = 0; -@@ -1168,12 +_,20 @@ +@@ -1186,12 +_,20 @@ this.player.teleportSetPosition(posMoveRotation, relatives); this.awaitingPositionFromClient = this.player.position(); @@ -1079,17 +1076,17 @@ + this.lastYaw = this.player.getYRot(); + this.lastPitch = this.player.getXRot(); + // CraftBukkit end - this.player.connection.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives)); + this.send(ClientboundPlayerPositionPacket.of(this.awaitingTeleport, posMoveRotation, relatives)); } @Override public void handlePlayerAction(ServerboundPlayerActionPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit if (this.player.hasClientLoaded()) { BlockPos pos = packet.getPos(); this.player.resetLastActionTime(); -@@ -1182,32 +_,95 @@ +@@ -1200,32 +_,95 @@ case SWAP_ITEM_WITH_OFFHAND: if (!this.player.isSpectator()) { ItemStack itemInHand = this.player.getItemInHand(InteractionHand.OFF_HAND); @@ -1167,7 +1164,7 @@ + this.player.gameMode.captureSentBlockEntities = true; + // Paper end - Send block entities after destroy prediction this.player.gameMode.handleBlockBreakAction(pos, action, packet.getDirection(), this.player.level().getMaxY(), packet.getSequence()); - this.player.connection.ackBlockChangesUpTo(packet.getSequence()); + this.ackBlockChangesUpTo(packet.getSequence()); + // Paper start - Send block entities after destroy prediction + this.player.gameMode.captureSentBlockEntities = false; + // If a block entity was modified speedup the block change ack to avoid the block entity @@ -1188,7 +1185,7 @@ return; default: throw new IllegalArgumentException("Invalid player action"); -@@ -1224,9 +_,31 @@ +@@ -1242,9 +_,31 @@ } } @@ -1214,13 +1211,13 @@ + @Override public void handleUseItemOn(ServerboundUseItemOnPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit + if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit if (this.player.hasClientLoaded()) { - this.player.connection.ackBlockChangesUpTo(packet.getSequence()); - ServerLevel serverLevel = this.player.serverLevel(); -@@ -1235,6 +_,11 @@ + this.ackBlockChangesUpTo(packet.getSequence()); + ServerLevel serverLevel = this.player.level(); +@@ -1253,6 +_,11 @@ if (itemInHand.isItemEnabled(serverLevel.enabledFeatures())) { BlockHitResult hitResult = packet.getHitResult(); Vec3 location = hitResult.getLocation(); @@ -1232,7 +1229,7 @@ BlockPos blockPos = hitResult.getBlockPos(); if (this.player.canInteractWithBlock(blockPos, 1.0)) { Vec3 vec3 = location.subtract(Vec3.atCenterOf(blockPos)); -@@ -1244,7 +_,8 @@ +@@ -1262,7 +_,8 @@ this.player.resetLastActionTime(); int maxY = this.player.level().getMaxY(); if (blockPos.getY() <= maxY) { @@ -1242,7 +1239,7 @@ InteractionResult interactionResult = this.player.gameMode.useItemOn(this.player, serverLevel, itemInHand, hand, hitResult); if (interactionResult.consumesAction()) { CriteriaTriggers.ANY_BLOCK_USE.trigger(this.player, hitResult.getBlockPos(), itemInHand.copy()); -@@ -1257,10 +_,10 @@ +@@ -1275,10 +_,10 @@ Component component = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED); this.player.sendSystemMessage(component, true); } else if (interactionResult instanceof InteractionResult.Success success @@ -1255,10 +1252,10 @@ } else { Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED); this.player.sendSystemMessage(component1, true); -@@ -1268,13 +_,7 @@ +@@ -1286,13 +_,8 @@ - this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos)); - this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction))); + this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos)); + this.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction))); - } else { - LOGGER.warn( - "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.", @@ -1267,19 +1264,20 @@ - blockPos - ); + if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes. ++ // Paper - Remove unused warning } } } -@@ -1284,6 +_,8 @@ +@@ -1302,6 +_,8 @@ @Override public void handleUseItem(ServerboundUseItemPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit + if (!this.checkLimit(packet.timestamp)) return; // Spigot - check limit if (this.player.hasClientLoaded()) { this.ackBlockChangesUpTo(packet.getSequence()); - ServerLevel serverLevel = this.player.serverLevel(); -@@ -1297,6 +_,48 @@ + ServerLevel serverLevel = this.player.level(); +@@ -1315,6 +_,48 @@ this.player.absSnapRotationTo(f, f1); } @@ -1328,7 +1326,7 @@ if (this.player.gameMode.useItem(this.player, serverLevel, itemInHand, hand) instanceof InteractionResult.Success success && success.swingSource() == InteractionResult.SwingSource.SERVER) { this.player.swing(hand, true); -@@ -1312,7 +_,7 @@ +@@ -1330,7 +_,7 @@ for (ServerLevel serverLevel : this.server.getAllLevels()) { Entity entity = packet.getEntity(serverLevel); if (entity != null) { @@ -1337,7 +1335,7 @@ return; } } -@@ -1329,24 +_,54 @@ +@@ -1347,24 +_,54 @@ @Override public void onDisconnect(DisconnectionDetails details) { @@ -1395,10 +1393,10 @@ throw new IllegalArgumentException("Expected packet sequence nr >= 0"); } else { this.ackBlockChangesUpTo = Math.max(sequence, this.ackBlockChangesUpTo); -@@ -1356,20 +_,38 @@ +@@ -1374,20 +_,38 @@ @Override public void handleSetCarriedItem(ServerboundSetCarriedItemPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit if (packet.getSlot() >= 0 && packet.getSlot() < Inventory.getSelectionSize()) { + if (packet.getSlot() == this.player.getInventory().getSelectedSlot()) { return; } // Paper - don't fire itemheldevent when there wasn't a slot change @@ -1434,7 +1432,7 @@ Optional optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages()); if (!optional.isEmpty()) { this.tryHandleChat(packet.message(), () -> { -@@ -1381,25 +_,45 @@ +@@ -1399,25 +_,45 @@ return; } @@ -1487,7 +1485,7 @@ ParseResults parseResults = this.parseCommand(command); if (this.server.enforceSecureProfile() && SignableCommand.hasSignableArguments(parseResults)) { LOGGER.error( -@@ -1416,28 +_,57 @@ +@@ -1434,28 +_,57 @@ Optional optional = this.unpackAndApplyLastSeen(packet.lastSeenMessages()); if (!optional.isEmpty()) { this.tryHandleChat(packet.command(), () -> { @@ -1548,7 +1546,7 @@ } private void handleMessageDecodeFailure(SignedMessageChain.DecodeException exception) { -@@ -1501,14 +_,20 @@ +@@ -1519,14 +_,20 @@ return dispatcher.parse(command, this.player.createCommandSourceStack()); } @@ -1573,7 +1571,7 @@ } } -@@ -1520,7 +_,7 @@ +@@ -1538,7 +_,7 @@ var10000 = Optional.of(lastSeenMessages); } catch (LastSeenMessagesValidator.ValidationException var5) { LOGGER.error("Failed to validate message acknowledgements from {}: {}", this.player.getName().getString(), var5.getMessage()); @@ -1582,7 +1580,7 @@ return Optional.empty(); } -@@ -1538,22 +_,81 @@ +@@ -1556,22 +_,81 @@ return false; } @@ -1670,7 +1668,7 @@ } } -@@ -1564,7 +_,7 @@ +@@ -1582,7 +_,7 @@ this.lastSeenMessages.applyOffset(packet.offset()); } catch (LastSeenMessagesValidator.ValidationException var5) { LOGGER.error("Failed to validate message acknowledgement offset from {}: {}", this.player.getName().getString(), var5.getMessage()); @@ -1679,10 +1677,10 @@ } } } -@@ -1572,7 +_,40 @@ +@@ -1590,7 +_,40 @@ @Override public void handleAnimate(ServerboundSwingPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit this.player.resetLastActionTime(); + // CraftBukkit start - Raytrace to look for 'rogue armswings' @@ -1720,23 +1718,13 @@ this.player.swing(packet.getHand()); } -@@ -1580,10 +_,41 @@ +@@ -1598,6 +_,22 @@ public void handlePlayerCommand(ServerboundPlayerCommandPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); if (this.player.hasClientLoaded()) { + // CraftBukkit start + if (this.player.isRemoved()) return; + switch (packet.getAction()) { -+ case PRESS_SHIFT_KEY: -+ case RELEASE_SHIFT_KEY: { -+ PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getCraftPlayer(), packet.getAction() == ServerboundPlayerCommandPacket.Action.PRESS_SHIFT_KEY); -+ this.cserver.getPluginManager().callEvent(event); -+ -+ if (event.isCancelled()) { -+ return; -+ } -+ break; -+ } + case START_SPRINTING: + case STOP_SPRINTING: { + PlayerToggleSprintEvent event = new PlayerToggleSprintEvent(this.getCraftPlayer(), packet.getAction() == ServerboundPlayerCommandPacket.Action.START_SPRINTING); @@ -1752,17 +1740,8 @@ + this.player.resetLastActionTime(); switch (packet.getAction()) { - case PRESS_SHIFT_KEY: - this.player.setShiftKeyDown(true); -+ // Paper start - Add option to make parrots stay -+ if (this.player.level().paperConfig().entities.behavior.parrotsAreUnaffectedByPlayerMovement) { -+ this.player.removeEntitiesOnShoulder(); -+ } -+ // Paper end - Add option to make parrots stay - break; - case RELEASE_SHIFT_KEY: - this.player.setShiftKeyDown(false); -@@ -1630,6 +_,14 @@ + case START_SPRINTING: +@@ -1642,6 +_,14 @@ } public void sendPlayerChatMessage(PlayerChatMessage chatMessage, ChatType.Bound boundType) { @@ -1777,7 +1756,7 @@ this.send( new ClientboundPlayerChatPacket( this.nextChatIndex++, -@@ -1652,9 +_,11 @@ +@@ -1664,9 +_,11 @@ } if (i > 4096) { @@ -1790,7 +1769,7 @@ } public void sendDisguisedChatMessage(Component message, ChatType.Bound boundType) { -@@ -1665,6 +_,17 @@ +@@ -1677,6 +_,17 @@ return this.connection.getRemoteAddress(); } @@ -1808,13 +1787,13 @@ public void switchToConfig() { this.waitingForSwitchToConfig = true; this.removePlayerFromWorld(); -@@ -1680,9 +_,16 @@ +@@ -1692,9 +_,16 @@ @Override public void handleInteract(ServerboundInteractPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit if (this.player.hasClientLoaded()) { - final ServerLevel serverLevel = this.player.serverLevel(); + final ServerLevel serverLevel = this.player.level(); final Entity target = packet.getTarget(serverLevel); + // Spigot start + if (target == this.player && !this.player.isSpectator()) { @@ -1825,7 +1804,7 @@ this.player.resetLastActionTime(); this.player.setShiftKeyDown(packet.isUsingSecondaryAction()); if (target != null) { -@@ -1691,16 +_,58 @@ +@@ -1703,16 +_,58 @@ } AABB boundingBox = target.getBoundingBox(); @@ -1889,7 +1868,7 @@ ItemStack itemStack1 = success.wasItemInteraction() ? itemStack : ItemStack.EMPTY; CriteriaTriggers.PLAYER_INTERACTED_WITH_ENTITY.trigger(ServerGamePacketListenerImpl.this.player, itemStack1, target); if (success.swingSource() == InteractionResult.SwingSource.SERVER) { -@@ -1712,13 +_,13 @@ +@@ -1724,13 +_,13 @@ @Override public void onInteraction(InteractionHand hand) { @@ -1905,7 +1884,7 @@ ); } -@@ -1726,14 +_,19 @@ +@@ -1738,14 +_,19 @@ public void onAttack() { if (!(target instanceof ItemEntity) && !(target instanceof ExperienceOrb) @@ -1927,7 +1906,7 @@ ServerGamePacketListenerImpl.LOGGER .warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString()); } -@@ -1742,6 +_,27 @@ +@@ -1754,6 +_,27 @@ ); } } @@ -1955,7 +1934,7 @@ } } -@@ -1754,7 +_,7 @@ +@@ -1766,7 +_,7 @@ case PERFORM_RESPAWN: if (this.player.wonGame) { this.player.wonGame = false; @@ -1964,7 +1943,7 @@ this.resetPosition(); CriteriaTriggers.CHANGED_DIMENSION.trigger(this.player, Level.END, Level.OVERWORLD); } else { -@@ -1762,11 +_,11 @@ +@@ -1774,11 +_,11 @@ return; } @@ -1973,13 +1952,13 @@ this.resetPosition(); if (this.server.isHardcore()) { - this.player.setGameMode(GameType.SPECTATOR); -- this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server); +- this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.server); + this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper - Expand PlayerGameModeChangeEvent -+ this.player.serverLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.serverLevel()); // CraftBukkit - per-world ++ this.player.level().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS).set(false, this.player.level()); // CraftBukkit - per-world } } break; -@@ -1777,16 +_,28 @@ +@@ -1789,16 +_,27 @@ @Override public void handleContainerClose(ServerboundContainerClosePacket packet) { @@ -1989,17 +1968,16 @@ + + public void handleContainerClose(ServerboundContainerClosePacket packet, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) { + // Paper end - Inventory close reason - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + + if (this.player.isImmobile()) return; // CraftBukkit + CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper -+ this.player.doCloseContainer(); } @Override public void handleContainerClick(ServerboundContainerClickPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit this.player.resetLastActionTime(); - if (this.player.containerMenu.containerId == packet.containerId()) { @@ -2010,7 +1988,7 @@ this.player.containerMenu.sendAllDataToRemote(); } else if (!this.player.containerMenu.stillValid(this.player)) { LOGGER.debug("Player {} interacted with invalid menu {}", this.player, this.player.containerMenu); -@@ -1799,7 +_,340 @@ +@@ -1811,7 +_,340 @@ } else { boolean flag = packet.stateId() != this.player.containerMenu.getStateId(); this.player.containerMenu.suppressRemoteUpdates(); @@ -2352,7 +2330,7 @@ for (Entry entry : Int2ObjectMaps.fastIterable(packet.changedSlots())) { this.player.containerMenu.setRemoteSlotUnsafe(entry.getIntKey(), entry.getValue()); -@@ -1812,6 +_,7 @@ +@@ -1824,6 +_,7 @@ } else { this.player.containerMenu.broadcastChanges(); } @@ -2360,7 +2338,7 @@ } } } -@@ -1819,6 +_,14 @@ +@@ -1831,6 +_,14 @@ @Override public void handlePlaceRecipe(ServerboundPlaceRecipePacket packet) { @@ -2372,10 +2350,10 @@ + } + } + // Paper end - auto recipe limit - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); this.player.resetLastActionTime(); if (!this.player.isSpectator() && this.player.containerMenu.containerId == packet.containerId()) { -@@ -1835,9 +_,44 @@ +@@ -1847,9 +_,44 @@ return; } @@ -2414,22 +2392,22 @@ + } + RecipeBookMenu.PostPlaceAction postPlaceAction = recipeBookMenu.handlePlacement( -- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory() -+ makeAll, this.player.isCreative(), recipeHolder, this.player.serverLevel(), this.player.getInventory() +- packet.useMaxItems(), this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory() ++ makeAll, this.player.isCreative(), recipeHolder, this.player.level(), this.player.getInventory() ); + // CraftBukkit end if (postPlaceAction == RecipeBookMenu.PostPlaceAction.PLACE_GHOST_RECIPE) { - this.player - .connection -@@ -1853,6 +_,7 @@ + this.send(new ClientboundPlaceGhostRecipePacket(this.player.containerMenu.containerId, recipeFromDisplay.display().display())); + } +@@ -1863,6 +_,7 @@ @Override public void handleContainerButtonClick(ServerboundContainerButtonClickPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + if (this.player.isImmobile()) return; // CraftBukkit this.player.resetLastActionTime(); if (this.player.containerMenu.containerId == packet.containerId() && !this.player.isSpectator()) { if (!this.player.containerMenu.stillValid(this.player)) { -@@ -1862,6 +_,7 @@ +@@ -1872,6 +_,7 @@ if (flag) { this.player.containerMenu.broadcastChanges(); } @@ -2437,7 +2415,7 @@ } } } -@@ -1878,10 +_,48 @@ +@@ -1888,10 +_,48 @@ boolean flag1 = packet.slotNum() >= 1 && packet.slotNum() <= 45; boolean flag2 = itemStack.isEmpty() || itemStack.getCount() <= itemStack.getMaxStackSize(); @@ -2486,7 +2464,7 @@ } else if (flag && flag2) { if (this.dropSpamThrottler.isUnderThreshold()) { this.dropSpamThrottler.increment(); -@@ -1895,15 +_,38 @@ +@@ -1905,15 +_,38 @@ @Override public void handleSignUpdate(ServerboundSignUpdatePacket packet) { @@ -2510,7 +2488,7 @@ private void updateSignText(ServerboundSignUpdatePacket packet, List filteredText) { + if (this.player.isImmobile()) return; // CraftBukkit this.player.resetLastActionTime(); - ServerLevel serverLevel = this.player.serverLevel(); + ServerLevel serverLevel = this.player.level(); BlockPos pos = packet.getPos(); if (serverLevel.hasChunkAt(pos)) { + // Paper start - Add API for client-side signs @@ -2526,10 +2504,10 @@ if (!(serverLevel.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity)) { return; } -@@ -1915,14 +_,32 @@ +@@ -1925,14 +_,32 @@ @Override public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); - this.player.getAbilities().flying = packet.isFlying() && this.player.getAbilities().mayfly; + // CraftBukkit start + if (this.player.getAbilities().mayfly && this.player.getAbilities().flying != packet.isFlying()) { @@ -2546,7 +2524,7 @@ @Override public void handleClientInformation(ServerboundClientInformationPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + // Paper start - do not accept invalid information + if (packet.information().viewDistance() < 0) { + LOGGER.warn("Disconnecting {} for invalid view distance: {}", this.player.getScoreboardName(), packet.information().viewDistance()); @@ -2560,16 +2538,16 @@ if (this.player.isModelPartShown(PlayerModelPart.HAT) != isModelPartShown) { this.server.getPlayerList().broadcastAll(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.UPDATE_HAT, this.player)); } -@@ -1932,7 +_,7 @@ - public void handleChangeDifficulty(ServerboundChangeDifficultyPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); - if (this.player.hasPermissions(2) || this.isSingleplayerOwner()) { -- this.server.setDifficulty(packet.getDifficulty(), false); -+ // this.server.setDifficulty(packet.getDifficulty(), false); // Paper - per level difficulty; don't allow clients to change this +@@ -1948,7 +_,7 @@ + packet.difficulty().getDisplayName() + ); + } else { +- this.server.setDifficulty(packet.difficulty(), false); ++ // this.server.setDifficulty(packet.difficulty(), false); // Paper - per level difficulty; don't allow clients to change this } } -@@ -1952,7 +_,7 @@ +@@ -1982,7 +_,7 @@ ProfilePublicKey.Data data2 = data.profilePublicKey(); if (!Objects.equals(data1, data2)) { if (data1 != null && data2.expiresAt().isBefore(data1.expiresAt())) { @@ -2578,7 +2556,7 @@ } else { try { SignatureValidator profileKeySignatureValidator = this.server.getProfileKeySignatureValidator(); -@@ -1963,8 +_,8 @@ +@@ -1993,8 +_,8 @@ this.resetPlayerChatState(data.validate(this.player.getGameProfile(), profileKeySignatureValidator)); } catch (ProfilePublicKey.ValidationException var6) { @@ -2589,7 +2567,7 @@ } } } -@@ -1978,7 +_,7 @@ +@@ -2008,7 +_,7 @@ this.connection .setupInboundProtocol( ConfigurationProtocols.SERVERBOUND, @@ -2598,7 +2576,7 @@ ); } } -@@ -1997,27 +_,32 @@ +@@ -2027,27 +_,32 @@ private void resetPlayerChatState(RemoteChatSession chatSession) { this.chatSession = chatSession; @@ -2627,12 +2605,12 @@ @Override public void handleClientTickEnd(ServerboundClientTickEndPacket packet) { - PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); + PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level()); + this.tickEndEvent.callEvent(); // Paper - add client tick end event if (!this.receivedMovementThisTick) { this.player.setKnownMovement(Vec3.ZERO); } -@@ -2048,4 +_,17 @@ +@@ -2078,4 +_,17 @@ interface EntityInteraction { InteractionResult run(ServerPlayer player, Entity entity, InteractionHand hand); } diff --git a/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch b/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch index abd87f5543..222fc98fbc 100644 --- a/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java.patch @@ -73,16 +73,16 @@ + org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); + } + // Paper end - Connection throttle - if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) { + if (packet.protocolVersion() != SharedConstants.getCurrentVersion().protocolVersion()) { - Component component; - if (packet.protocolVersion() < 754) { -- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().getName()); +- component = Component.translatable("multiplayer.disconnect.outdated_client", SharedConstants.getCurrentVersion().name()); + net.kyori.adventure.text.Component adventureComponent; // Paper - Fix hex colors not working in some kick messages -+ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().getProtocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message -+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages ++ if (packet.protocolVersion() < SharedConstants.getCurrentVersion().protocolVersion()) { // Spigot - SPIGOT-7546: Handle version check correctly for outdated client message ++ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages } else { -- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().getName()); -+ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName())); // Spigot // Paper - Fix hex colors not working in some kick messages +- component = Component.translatable("multiplayer.disconnect.incompatible", SharedConstants.getCurrentVersion().name()); ++ adventureComponent = net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().name())); // Spigot // Paper - Fix hex colors not working in some kick messages } + Component component = io.papermc.paper.adventure.PaperAdventure.asVanilla(adventureComponent); // Paper - Fix hex colors not working in some kick messages diff --git a/paper-server/patches/sources/net/minecraft/server/packs/PathPackResources.java.patch b/paper-server/patches/sources/net/minecraft/server/packs/PathPackResources.java.patch index 7f7053b2b2..250f69b89d 100644 --- a/paper-server/patches/sources/net/minecraft/server/packs/PathPackResources.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/packs/PathPackResources.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/packs/PathPackResources.java +++ b/net/minecraft/server/packs/PathPackResources.java -@@ -103,6 +_,12 @@ +@@ -112,6 +_,12 @@ try (DirectoryStream directoryStream = Files.newDirectoryStream(path)) { for (Path path1 : directoryStream) { String string = path1.getFileName().toString(); diff --git a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch index 5309bf10a2..35cfaca434 100644 --- a/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/players/PlayerList.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java -@@ -112,14 +_,16 @@ +@@ -111,14 +_,16 @@ private static final int SEND_PLAYER_INFO_INTERVAL = 600; private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private final MinecraftServer server; @@ -20,7 +20,7 @@ public final PlayerDataStorage playerIo; private boolean doWhiteList; private final LayeredRegistryAccess registries; -@@ -130,14 +_,26 @@ +@@ -129,14 +_,26 @@ private static final boolean ALLOW_LOGOUTIVATOR = false; private int sendAllPlayerInfoIn; @@ -47,259 +47,262 @@ GameProfile gameProfile = player.getGameProfile(); GameProfileCache profileCache = this.server.getProfileCache(); String string; -@@ -150,30 +_,94 @@ +@@ -149,20 +_,66 @@ } - Optional optional = this.load(player); -- ResourceKey resourceKey = optional.>flatMap( -- compoundTag -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))).resultOrPartial(LOGGER::error) -+ // CraftBukkit start - Better rename detection -+ if (optional.isPresent()) { -+ string = optional.flatMap(t -> t.getCompound("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string); -+ } -+ // CraftBukkit end -+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found -+ ResourceKey resourceKey = null; // Paper -+ boolean[] invalidPlayerWorld = {false}; -+ bukkitData: if (optional.isPresent()) { -+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds -+ final org.bukkit.World bWorld; -+ final CompoundTag playerData = optional.get(); -+ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first. -+ final Optional worldUUIDMost = playerData.getLong("WorldUUIDMost"); -+ final Optional worldUUIDLeast = playerData.getLong("WorldUUIDLeast"); -+ final java.util.Optional worldName = playerData.getString("world"); -+ if (worldUUIDMost.isPresent() && worldUUIDLeast.isPresent()) { -+ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(worldUUIDMost.get(), worldUUIDLeast.get())); -+ } else if (worldName.isPresent()) { // Paper - legacy bukkit world name -+ bWorld = org.bukkit.Bukkit.getServer().getWorld(worldName.get()); -+ } else { -+ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), LOGGER)) { +- Optional optional1 = this.load(player, scopedCollector); +- ResourceKey resourceKey = optional1.>flatMap(valueInput -> valueInput.read("Dimension", Level.RESOURCE_KEY_CODEC)) +- .orElse(Level.OVERWORLD); ++ Optional optional1 = this.load(player, scopedCollector); final Optional loadedPlayerData = optional1; // Paper - OBFHELPER ++ // CraftBukkit start - Better rename detection ++ if (loadedPlayerData.isPresent()) { ++ string = loadedPlayerData.flatMap(t -> t.child("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string); + } -+ if (bWorld != null) { -+ resourceKey = ((org.bukkit.craftbukkit.CraftWorld) bWorld).getHandle().dimension(); -+ } else { -+ resourceKey = Level.OVERWORLD; -+ invalidPlayerWorld[0] = true; -+ } -+ } -+ if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data -+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers -+ resourceKey = optional.>flatMap( -+ compoundTag -> { -+ com.mojang.serialization.DataResult> dataResult = DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))); -+ final Optional> result = dataResult.resultOrPartial(LOGGER::error); -+ invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found -+ return result; -+ } - ) -- .orElse(Level.OVERWORLD); -+ .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed -+ } -+ // Paper end - ServerLevel level = this.server.getLevel(resourceKey); - ServerLevel serverLevel; - if (level == null) { - LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourceKey); - serverLevel = this.server.overworld(); -+ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found - } else { - serverLevel = level; - } - -+ // Paper start - Entity#getEntitySpawnReason -+ if (optional.isEmpty()) { -+ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login -+ // Paper start - reset to main world spawn if first spawn or invalid world -+ } -+ if (optional.isEmpty() || invalidPlayerWorld[0]) { -+ // Paper end - reset to main world spawn if first spawn or invalid world -+ player.snapTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored -+ } -+ // Paper end - Entity#getEntitySpawnReason - player.setServerLevel(serverLevel); - String loggableAddress = connection.getLoggableAddress(this.server.logIPs()); -- LOGGER.info( -- "{}[{}] logged in with entity id {} at ({}, {}, {})", -- player.getName().getString(), -- loggableAddress, -- player.getId(), -- player.getX(), -- player.getY(), -- player.getZ() -- ); -+ // Spigot start - spawn location event -+ org.bukkit.entity.Player spawnPlayer = player.getBukkitEntity(); -+ org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new org.spigotmc.event.player.PlayerSpawnLocationEvent(spawnPlayer, spawnPlayer.getLocation()); -+ this.cserver.getPluginManager().callEvent(ev); -+ -+ org.bukkit.Location loc = ev.getSpawnLocation(); -+ serverLevel = ((org.bukkit.craftbukkit.CraftWorld) loc.getWorld()).getHandle(); -+ -+ player.spawnIn(serverLevel); -+ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world) -+ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ()); -+ player.setRot(loc.getYaw(), loc.getPitch()); -+ // Paper end - set raw so we aren't fully joined to the world -+ // Spigot end -+ // LOGGER.info( // CraftBukkit - Moved message to after join -+ // "{}[{}] logged in with entity id {} at ({}, {}, {})", -+ // player.getName().getString(), -+ // loggableAddress, -+ // player.getId(), -+ // player.getX(), -+ // player.getY(), -+ // player.getZ() -+ // ); - LevelData levelData = serverLevel.getLevelData(); - player.loadGameTypes(optional.orElse(null)); - ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie); -@@ -191,8 +_,8 @@ - levelData.isHardcore(), - this.server.levelKeys(), - this.getMaxPlayers(), -- this.viewDistance, -- this.simulationDistance, -+ serverLevel.spigotConfig.viewDistance,// Spigot - view distance -+ serverLevel.spigotConfig.simulationDistance, - _boolean1, - !_boolean, - _boolean2, -@@ -200,6 +_,7 @@ - this.server.enforceSecureProfile() - ) - ); -+ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit - serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked())); - serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); - serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); -@@ -219,26 +_,119 @@ - mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string); - } - -- this.broadcastSystemMessage(mutableComponent.withStyle(ChatFormatting.YELLOW), false); -+ // CraftBukkit start -+ mutableComponent.withStyle(ChatFormatting.YELLOW); -+ Component joinMessage = mutableComponent; // Paper - Adventure - serverGamePacketListenerImpl.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); - ServerStatus status = this.server.getStatus(); - if (status != null && !cookie.transferred()) { - player.sendServerStatus(status); - } - -- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); -+ // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below - this.players.add(player); -+ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot - this.playersByUUID.put(player.getUUID(), player); -- this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); -- this.sendLevelInfo(player, serverLevel); -+ // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below -+ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks -+ player.supressTrackerForLogin = true; - serverLevel.addNewPlayer(player); -- this.server.getCustomBossEvents().onPlayerConnect(player); -- this.sendActivePlayerEffects(player); -+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player); -+ // Paper end - Fire PlayerJoinEvent when Player is actually ready - optional.ifPresent(compoundTag -> { - player.loadAndSpawnEnderPearls(compoundTag); - player.loadAndSpawnParentVehicle(compoundTag); - }); -+ // CraftBukkit start -+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity(); -+ -+ // Ensure that player inventory is populated with its viewer -+ player.containerMenu.transferTo(player.containerMenu, bukkitPlayer); -+ -+ org.bukkit.event.player.PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(bukkitPlayer, io.papermc.paper.adventure.PaperAdventure.asAdventure(mutableComponent)); // Paper - Adventure -+ this.cserver.getPluginManager().callEvent(playerJoinEvent); -+ -+ if (!player.connection.isAcceptingMessages()) { -+ return; -+ } -+ -+ final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); -+ -+ if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure -+ joinMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure -+ this.server.getPlayerList().broadcastSystemMessage(joinMessage, false); // Paper - Adventure -+ } -+ // CraftBukkit end -+ -+ // CraftBukkit start - sendAll above replaced with this loop -+ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player -+ -+ final List onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join -+ for (int i = 0; i < this.players.size(); ++i) { -+ ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); -+ -+ if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { -+ // Paper start - Add Listing API for Player -+ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) { -+ // Paper end - Add Listing API for Player -+ entityplayer1.connection.send(packet); -+ // Paper start - Add Listing API for Player ++ // CraftBukkit end ++ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found ++ ResourceKey resourceKey = null; // Paper ++ boolean[] invalidPlayerWorld = {false}; ++ bukkitData: if (loadedPlayerData.isPresent()) { ++ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds ++ final org.bukkit.World bWorld; ++ final ValueInput playerData = loadedPlayerData.get(); ++ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first. ++ final Optional worldUUIDMost = playerData.getLong("WorldUUIDMost"); ++ final Optional worldUUIDLeast = playerData.getLong("WorldUUIDLeast"); ++ final java.util.Optional worldName = playerData.getString("world"); ++ if (worldUUIDMost.isPresent() && worldUUIDLeast.isPresent()) { ++ bWorld = org.bukkit.Bukkit.getServer().getWorld(new UUID(worldUUIDMost.get(), worldUUIDLeast.get())); ++ } else if (worldName.isPresent()) { // Paper - legacy bukkit world name ++ bWorld = org.bukkit.Bukkit.getServer().getWorld(worldName.get()); + } else { -+ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false)); ++ break bukkitData; // if neither of the bukkit data points exist, proceed to the vanilla migration section + } -+ // Paper end - Add Listing API for Player ++ if (bWorld != null) { ++ resourceKey = ((org.bukkit.craftbukkit.CraftWorld) bWorld).getHandle().dimension(); ++ } else { ++ resourceKey = Level.OVERWORLD; ++ invalidPlayerWorld[0] = true; ++ } ++ } ++ if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data ++ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers ++ resourceKey = loadedPlayerData.>flatMap( ++ compoundTag -> { ++ Optional> result = compoundTag.read("Dimension", Level.RESOURCE_KEY_CODEC); ++ invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found ++ return result; ++ } ++ ) ++ .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed ++ } ++ // Paper end + ServerLevel level = this.server.getLevel(resourceKey); + ServerLevel serverLevel; + if (level == null) { + LOGGER.warn("Unknown respawn dimension {}, defaulting to overworld", resourceKey); + serverLevel = this.server.overworld(); ++ invalidPlayerWorld[0] = true; // Paper - reset to main world if no world with parsed value is found + } else { + serverLevel = level; + } + ++ // Paper start - Entity#getEntitySpawnReason ++ if (loadedPlayerData.isEmpty()) { ++ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login ++ } ++ // Paper end - Entity#getEntitySpawnReason + player.setServerLevel(serverLevel); +- if (optional1.isEmpty()) { ++ if (loadedPlayerData.isEmpty() || invalidPlayerWorld[0]) { // Paper - reset to main world spawn if first spawn or invalid world + player.snapTo( + player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F + ); +@@ -170,15 +_,29 @@ + + serverLevel.waitForChunkAndEntities(player.chunkPosition(), 1); + String loggableAddress = connection.getLoggableAddress(this.server.logIPs()); +- LOGGER.info( +- "{}[{}] logged in with entity id {} at ({}, {}, {})", +- player.getName().getString(), +- loggableAddress, +- player.getId(), +- player.getX(), +- player.getY(), +- player.getZ() +- ); ++ // Spigot start - spawn location event ++ org.bukkit.entity.Player spawnPlayer = player.getBukkitEntity(); ++ org.spigotmc.event.player.PlayerSpawnLocationEvent ev = new org.spigotmc.event.player.PlayerSpawnLocationEvent(spawnPlayer, spawnPlayer.getLocation()); ++ this.cserver.getPluginManager().callEvent(ev); ++ ++ org.bukkit.Location loc = ev.getSpawnLocation(); ++ serverLevel = ((org.bukkit.craftbukkit.CraftWorld) loc.getWorld()).getHandle(); ++ ++ player.spawnIn(serverLevel); ++ // Paper start - set raw so we aren't fully joined to the world (not added to chunk or world) ++ player.setPosRaw(loc.getX(), loc.getY(), loc.getZ()); ++ player.setRot(loc.getYaw(), loc.getPitch()); ++ // Paper end - set raw so we aren't fully joined to the world ++ // Spigot end ++ // LOGGER.info( // CraftBukkit - Moved message to after join ++ // "{}[{}] logged in with entity id {} at ({}, {}, {})", ++ // player.getName().getString(), ++ // loggableAddress, ++ // player.getId(), ++ // player.getX(), ++ // player.getY(), ++ // player.getZ() ++ // ); + LevelData levelData = serverLevel.getLevelData(); + player.loadGameTypes(optional1.orElse(null)); + ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie); +@@ -196,8 +_,8 @@ + levelData.isHardcore(), + this.server.levelKeys(), + this.getMaxPlayers(), +- this.viewDistance, +- this.simulationDistance, ++ serverLevel.spigotConfig.viewDistance, // Spigot - view distance ++ serverLevel.spigotConfig.simulationDistance, // Spigot - simulation distance + _boolean1, + !_boolean, + _boolean2, +@@ -205,6 +_,7 @@ + this.server.enforceSecureProfile() + ) + ); ++ player.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked())); + serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); + serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); +@@ -224,26 +_,119 @@ + mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string); + } + +- this.broadcastSystemMessage(mutableComponent.withStyle(ChatFormatting.YELLOW), false); ++ // CraftBukkit start ++ mutableComponent.withStyle(ChatFormatting.YELLOW); ++ Component joinMessage = mutableComponent; // Paper - Adventure + serverGamePacketListenerImpl.teleport(player.getX(), player.getY(), player.getZ(), player.getYRot(), player.getXRot()); + ServerStatus status = this.server.getStatus(); + if (status != null && !cookie.transferred()) { + player.sendServerStatus(status); + } + +- player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); ++ // player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(this.players)); // CraftBukkit - replaced with loop below + this.players.add(player); ++ this.playersByName.put(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT), player); // Spigot + this.playersByUUID.put(player.getUUID(), player); +- this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); +- this.sendLevelInfo(player, serverLevel); ++ // this.broadcastAll(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player))); // CraftBukkit - replaced with loop below ++ // Paper start - Fire PlayerJoinEvent when Player is actually ready; correctly register player BEFORE PlayerJoinEvent, so the entity is valid and doesn't require tick delay hacks ++ player.supressTrackerForLogin = true; + serverLevel.addNewPlayer(player); +- this.server.getCustomBossEvents().onPlayerConnect(player); +- this.sendActivePlayerEffects(player); ++ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player); ++ // Paper end - Fire PlayerJoinEvent when Player is actually ready + optional1.ifPresent(valueInput -> { + player.loadAndSpawnEnderPearls(valueInput); + player.loadAndSpawnParentVehicle(valueInput); + }); ++ // CraftBukkit start ++ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity(); ++ ++ // Ensure that player inventory is populated with its viewer ++ player.containerMenu.transferTo(player.containerMenu, bukkitPlayer); ++ ++ org.bukkit.event.player.PlayerJoinEvent playerJoinEvent = new org.bukkit.event.player.PlayerJoinEvent(bukkitPlayer, io.papermc.paper.adventure.PaperAdventure.asAdventure(mutableComponent)); // Paper - Adventure ++ this.cserver.getPluginManager().callEvent(playerJoinEvent); ++ ++ if (!player.connection.isAcceptingMessages()) { ++ return; + } + -+ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player -+ continue; ++ final net.kyori.adventure.text.Component jm = playerJoinEvent.joinMessage(); ++ ++ if (jm != null && !jm.equals(net.kyori.adventure.text.Component.empty())) { // Paper - Adventure ++ joinMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(jm); // Paper - Adventure ++ this.server.getPlayerList().broadcastSystemMessage(joinMessage, false); // Paper - Adventure ++ } ++ // CraftBukkit end ++ ++ // CraftBukkit start - sendAll above replaced with this loop ++ ClientboundPlayerInfoUpdatePacket packet = ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(player)); // Paper - Add Listing API for Player ++ ++ final List onlinePlayers = Lists.newArrayListWithExpectedSize(this.players.size() - 1); // Paper - Use single player info update packet on join ++ for (int i = 0; i < this.players.size(); ++i) { ++ ServerPlayer entityplayer1 = (ServerPlayer) this.players.get(i); ++ ++ if (entityplayer1.getBukkitEntity().canSee(bukkitPlayer)) { ++ // Paper start - Add Listing API for Player ++ if (entityplayer1.getBukkitEntity().isListed(bukkitPlayer)) { ++ // Paper end - Add Listing API for Player ++ entityplayer1.connection.send(packet); ++ // Paper start - Add Listing API for Player ++ } else { ++ entityplayer1.connection.send(ClientboundPlayerInfoUpdatePacket.createSinglePlayerInitializing(player, false)); ++ } ++ // Paper end - Add Listing API for Player ++ } ++ ++ if (entityplayer1 == player || !bukkitPlayer.canSee(entityplayer1.getBukkitEntity())) { // Paper - Use single player info update packet on join; Don't include joining player ++ continue; ++ } ++ ++ onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join ++ } ++ // Paper start - Use single player info update packet on join ++ if (!onlinePlayers.isEmpty()) { ++ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player ++ } ++ // Paper end - Use single player info update packet on join ++ player.sentListPacket = true; ++ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready ++ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now ++ // CraftBukkit end ++ ++ //player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE ++ ++ this.sendLevelInfo(player, serverLevel); ++ ++ // CraftBukkit start - Only add if the player wasn't moved in the event ++ if (player.level() == serverLevel && !serverLevel.players().contains(player)) { ++ serverLevel.addNewPlayer(player); ++ this.server.getCustomBossEvents().onPlayerConnect(player); + } + -+ onlinePlayers.add(entityplayer1); // Paper - Use single player info update packet on join -+ } -+ // Paper start - Use single player info update packet on join -+ if (!onlinePlayers.isEmpty()) { -+ player.connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(onlinePlayers, player)); // Paper - Add Listing API for Player -+ } -+ // Paper end - Use single player info update packet on join -+ player.sentListPacket = true; -+ player.supressTrackerForLogin = false; // Paper - Fire PlayerJoinEvent when Player is actually ready -+ ((ServerLevel)player.level()).getChunkSource().chunkMap.addEntity(player); // Paper - Fire PlayerJoinEvent when Player is actually ready; track entity now -+ // CraftBukkit end -+ -+ //player.refreshEntityData(player); // CraftBukkit - BungeeCord#2321, send complete data to self on spawn // Paper - THIS IS NOT NEEDED ANYMORE -+ -+ this.sendLevelInfo(player, serverLevel); -+ -+ // CraftBukkit start - Only add if the player wasn't moved in the event -+ if (player.level() == serverLevel && !serverLevel.players().contains(player)) { -+ serverLevel.addNewPlayer(player); -+ this.server.getCustomBossEvents().onPlayerConnect(player); -+ } -+ -+ serverLevel = player.serverLevel(); // CraftBukkit - Update in case join event changed it -+ // CraftBukkit end -+ this.sendActivePlayerEffects(player); -+ // Paper - move loading pearls / parent vehicle up - player.initInventoryMenu(); -+ // CraftBukkit - Moved from above, added world -+ // Paper start - Configurable player collision; Add to collideRule team if needed -+ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); -+ final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName); -+ if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { -+ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); -+ } -+ // Paper end - Configurable player collision -+ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), loggableAddress, player.getId(), serverLevel.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); -+ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead -+ if (player.isDeadOrDying()) { -+ net.minecraft.core.Holder plains = serverLevel.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME) ++ serverLevel = player.level(); // CraftBukkit - Update in case join event changed it ++ // CraftBukkit end ++ this.sendActivePlayerEffects(player); ++ // Paper - move loading pearls / parent vehicle up + player.initInventoryMenu(); ++ // CraftBukkit - Moved from above, added world ++ // Paper start - Configurable player collision; Add to collideRule team if needed ++ final net.minecraft.world.scores.Scoreboard scoreboard = this.getServer().getLevel(Level.OVERWORLD).getScoreboard(); ++ final PlayerTeam collideRuleTeam = scoreboard.getPlayerTeam(this.collideRuleTeamName); ++ if (this.collideRuleTeamName != null && collideRuleTeam != null && player.getTeam() == null) { ++ scoreboard.addPlayerToTeam(player.getScoreboardName(), collideRuleTeam); ++ } ++ // Paper end - Configurable player collision ++ PlayerList.LOGGER.info("{}[{}] logged in with entity id {} at ([{}]{}, {}, {})", player.getName().getString(), loggableAddress, player.getId(), serverLevel.serverLevelData.getLevelName(), player.getX(), player.getY(), player.getZ()); ++ // Paper start - Send empty chunk, so players aren't stuck in the world loading screen with our chunk system not sending chunks when dead ++ if (player.isDeadOrDying()) { ++ net.minecraft.core.Holder plains = serverLevel.registryAccess().lookupOrThrow(net.minecraft.core.registries.Registries.BIOME) + .getOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS); -+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( ++ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket( + new net.minecraft.world.level.chunk.EmptyLevelChunk(serverLevel, player.chunkPosition(), plains), + serverLevel.getLightEngine(), (java.util.BitSet)null, (java.util.BitSet) null) -+ ); -+ } -+ // Paper end - Send empty chunk ++ ); ++ } ++ // Paper end - Send empty chunk + } } - public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { -@@ -261,30 +_,31 @@ +@@ -267,30 +_,31 @@ } public void addWorldborderListener(ServerLevel level) { @@ -336,7 +339,7 @@ } @Override -@@ -312,56 +_,156 @@ +@@ -319,56 +_,156 @@ } protected void save(ServerPlayer player) { @@ -362,7 +365,7 @@ + } + public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) { + // Paper end - Fix kick event leave message not being sent - ServerLevel serverLevel = player.serverLevel(); + ServerLevel serverLevel = player.level(); player.awardStat(Stats.LEAVE_GAME); + // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it + // See SPIGOT-5799, SPIGOT-6145 @@ -423,7 +426,7 @@ + if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) { + thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause + } else { -+ thrownEnderpearl.cachedOwner = null; ++ thrownEnderpearl.setOwner(null); + } + // Paper end - Allow using old ender pearl behavior } @@ -495,7 +498,7 @@ + // depending on the outcome. + SocketAddress socketAddress = loginlistener.connection.getRemoteAddress(); + -+ ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, ClientInformation.createDefault()); ++ ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, net.minecraft.server.level.ClientInformation.createDefault()); + entity.transferCookieConnection = loginlistener; + org.bukkit.entity.Player player = entity.getBukkitEntity(); + org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); @@ -507,7 +510,7 @@ MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason()); if (userBanListEntry.getExpires() != null) { mutableComponent.append( -@@ -369,10 +_,12 @@ +@@ -376,10 +_,12 @@ ); } @@ -524,7 +527,7 @@ IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress); MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason()); if (ipBanListEntry.getExpires() != null) { -@@ -381,69 +_,131 @@ +@@ -388,65 +_,124 @@ ); } @@ -538,10 +541,6 @@ - } - } - -- public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation) { -- return new ServerPlayer(this.server, this.server.overworld(), gameProfile, clientInformation); -- } -- - public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile) { - UUID id = gameProfile.getId(); - Set set = Sets.newIdentityHashSet(); @@ -578,13 +577,6 @@ + return entity; + } + -+ // CraftBukkit start - added EntityPlayer -+ public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation, ServerPlayer player) { -+ player.updateOptions(clientInformation); -+ return player; -+ // CraftBukkit end -+ } -+ + public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile, ServerPlayer player) { // CraftBukkit - added ServerPlayer + // CraftBukkit start - Moved up + // UUID id = gameProfile.getId(); @@ -619,7 +611,7 @@ + player.stopRiding(); // CraftBukkit this.players.remove(player); + this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot - player.serverLevel().removePlayerImmediately(player, reason); + player.level().removePlayerImmediately(player, reason); - TeleportTransition teleportTransition = player.findRespawnPositionAndUseSpawnBlock(!keepInventory, TeleportTransition.DO_NOTHING); - ServerLevel level = teleportTransition.newLevel(); - ServerPlayer serverPlayer = new ServerPlayer(this.server, level, player.getGameProfile(), player.clientInformation()); @@ -686,7 +678,7 @@ } byte b = (byte)(keepInventory ? 1 : 0); - ServerLevel serverLevel = serverPlayer.serverLevel(); + ServerLevel serverLevel = serverPlayer.level(); LevelData levelData = serverLevel.getLevelData(); serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b)); - serverPlayer.connection.teleport(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ(), serverPlayer.getYRot(), serverPlayer.getXRot()); @@ -697,7 +689,7 @@ serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle())); serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked())); serverPlayer.connection -@@ -451,10 +_,13 @@ +@@ -454,10 +_,13 @@ this.sendActivePlayerEffects(serverPlayer); this.sendLevelInfo(serverPlayer, level); this.sendPlayerPermissionLevel(serverPlayer); @@ -715,7 +707,7 @@ serverPlayer.setHealth(serverPlayer.getHealth()); ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig(); if (!keepInventory && respawnConfig != null) { -@@ -477,8 +_,52 @@ +@@ -480,8 +_,52 @@ ) ); } @@ -768,7 +760,7 @@ return serverPlayer; } -@@ -488,24 +_,59 @@ +@@ -491,24 +_,59 @@ } public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) { @@ -831,7 +823,7 @@ public void broadcastAll(Packet packet) { for (ServerPlayer serverPlayer : this.players) { serverPlayer.connection.send(packet); -@@ -581,6 +_,12 @@ +@@ -584,6 +_,12 @@ } private void sendPlayerPermissionLevel(ServerPlayer player, int permLevel) { @@ -844,7 +836,7 @@ if (player.connection != null) { byte b; if (permLevel <= 0) { -@@ -594,11 +_,33 @@ +@@ -597,11 +_,33 @@ player.connection.send(new ClientboundEntityEventPacket(player, b)); } @@ -879,7 +871,7 @@ } public boolean isOp(GameProfile profile) { -@@ -609,21 +_,17 @@ +@@ -612,21 +_,17 @@ @Nullable public ServerPlayer getPlayerByName(String username) { @@ -907,7 +899,7 @@ if (serverPlayer != except && serverPlayer.level().dimension() == dimension) { double d = x - serverPlayer.getX(); double d1 = y - serverPlayer.getY(); -@@ -636,9 +_,11 @@ +@@ -639,9 +_,11 @@ } public void saveAll() { @@ -919,7 +911,7 @@ } public UserWhiteList getWhiteList() { -@@ -661,14 +_,18 @@ +@@ -664,14 +_,18 @@ } public void sendLevelInfo(ServerPlayer player, ServerLevel level) { @@ -942,7 +934,7 @@ } player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); -@@ -677,8 +_,21 @@ +@@ -680,8 +_,21 @@ public void sendAllPlayerInfo(ServerPlayer player) { player.inventoryMenu.sendAllDataToRemote(); @@ -957,15 +949,15 @@ + player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); + // CraftBukkit start - from GameRules -+ int i = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; ++ int i = player.level().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; + player.connection.send(new ClientboundEntityEventPacket(player, (byte) i)); -+ float immediateRespawn = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F; ++ float immediateRespawn = player.level().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F; + player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, immediateRespawn)); + // CraftBukkit end } public int getPlayerCount() { -@@ -694,6 +_,7 @@ +@@ -697,6 +_,7 @@ } public void setUsingWhiteList(boolean whitelistEnabled) { @@ -973,7 +965,7 @@ this.doWhiteList = whitelistEnabled; } -@@ -731,10 +_,35 @@ +@@ -734,10 +_,35 @@ } public void removeAll() { @@ -1013,7 +1005,7 @@ public void broadcastSystemMessage(Component message, boolean bypassHiddenChat) { this.broadcastSystemMessage(message, serverPlayer -> message, bypassHiddenChat); -@@ -756,20 +_,39 @@ +@@ -759,20 +_,39 @@ } public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound boundChatType) { @@ -1056,7 +1048,7 @@ flag1 |= flag2 && message.isFullyFiltered(); } -@@ -782,14 +_,21 @@ +@@ -785,14 +_,21 @@ return message.hasSignature() && !message.hasExpiredServer(Instant.now()); } @@ -1082,7 +1074,7 @@ Path path = file2.toPath(); if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { file2.renameTo(file1); -@@ -797,7 +_,7 @@ +@@ -800,7 +_,7 @@ } serverStatsCounter = new ServerStatsCounter(this.server, file1); @@ -1091,7 +1083,7 @@ } return serverStatsCounter; -@@ -805,11 +_,11 @@ +@@ -808,11 +_,11 @@ public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { UUID uuid = player.getUUID(); @@ -1105,7 +1097,7 @@ } playerAdvancements.setPlayer(player); -@@ -852,11 +_,34 @@ +@@ -855,11 +_,34 @@ } public void reloadResources() { diff --git a/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch b/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch index 852ce031dc..6150d2e711 100644 --- a/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch +++ b/paper-server/patches/sources/net/minecraft/stats/ServerRecipeBook.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/stats/ServerRecipeBook.java +++ b/net/minecraft/stats/ServerRecipeBook.java -@@ -66,7 +_,7 @@ +@@ -63,7 +_,7 @@ for (RecipeHolder recipeHolder : recipes) { ResourceKey> resourceKey = recipeHolder.id(); @@ -9,7 +9,7 @@ this.add(resourceKey); this.addHighlight(resourceKey); this.displayResolver -@@ -77,7 +_,7 @@ +@@ -74,7 +_,7 @@ } } @@ -18,7 +18,7 @@ player.connection.send(new ClientboundRecipeBookAddPacket(list, false)); } -@@ -95,7 +_,7 @@ +@@ -92,7 +_,7 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/stats/ServerStatsCounter.java.patch b/paper-server/patches/sources/net/minecraft/stats/ServerStatsCounter.java.patch index d52fd871f7..90505e9a2b 100644 --- a/paper-server/patches/sources/net/minecraft/stats/ServerStatsCounter.java.patch +++ b/paper-server/patches/sources/net/minecraft/stats/ServerStatsCounter.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/stats/ServerStatsCounter.java +++ b/net/minecraft/stats/ServerStatsCounter.java -@@ -70,9 +_,21 @@ +@@ -68,9 +_,21 @@ LOGGER.error("Couldn't parse statistics file {}", file, var5); } } @@ -22,7 +22,7 @@ try { FileUtils.writeStringToFile(this.file, this.toJson()); } catch (IOException var2) { -@@ -82,6 +_,8 @@ +@@ -80,6 +_,8 @@ @Override public void setValue(Player player, Stat stat, int i) { diff --git a/paper-server/patches/sources/net/minecraft/util/PlaceholderLookupProvider.java.patch b/paper-server/patches/sources/net/minecraft/util/PlaceholderLookupProvider.java.patch new file mode 100644 index 0000000000..8b6037975a --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/util/PlaceholderLookupProvider.java.patch @@ -0,0 +1,16 @@ +--- a/net/minecraft/util/PlaceholderLookupProvider.java ++++ b/net/minecraft/util/PlaceholderLookupProvider.java +@@ -52,6 +_,13 @@ + ) + ); + } ++ ++ // Paper start add method to get the value for pre-filling builders in the reg mod API ++ @Override ++ public HolderLookup.Provider lookupForValueCopyViaBuilders() { ++ return PlaceholderLookupProvider.this.context; ++ } ++ // Paper end - add method to get the value for pre-filling builders in the reg mod API + } + ); + } diff --git a/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch b/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch index 63b5de6882..25927503d6 100644 --- a/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch +++ b/paper-server/patches/sources/net/minecraft/util/datafix/DataFixers.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/util/datafix/DataFixers.java +++ b/net/minecraft/util/datafix/DataFixers.java -@@ -541,6 +_,24 @@ +@@ -515,6 +_,24 @@ Schema schema44 = builder.addSchema(1456, SAME_NAMESPACED); builder.addFixer(new EntityItemFrameDirectionFix(schema44, false)); Schema schema45 = builder.addSchema(1458, V1458::new); diff --git a/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch b/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch deleted file mode 100644 index 440f7e8512..0000000000 --- a/paper-server/patches/sources/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- a/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java -+++ b/net/minecraft/util/datafix/fixes/RaidRenamesDataFix.java -@@ -39,6 +_,6 @@ - .renameField("PostRaidTicks", "post_raid_ticks") - .renameField("TotalHealth", "total_health") - .renameField("NumGroups", "group_count") -- .renameField("Status", "status"); -+ .renameField("Status", "status").renameField("HeroesOfTheVillage", "heroes_of_the_village"); // Paper - Add missing rename - } - } diff --git a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch index 4e15d4eedd..169adf2ef1 100644 --- a/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/RandomizableContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/RandomizableContainer.java +++ b/net/minecraft/world/RandomizableContainer.java -@@ -26,7 +_,7 @@ +@@ -27,7 +_,7 @@ void setLootTable(@Nullable ResourceKey lootTable); @@ -9,25 +9,25 @@ this.setLootTable(lootTable); this.setLootTableSeed(seed); } -@@ -49,8 +_,9 @@ - default boolean tryLoadLootTable(CompoundTag tag) { - ResourceKey resourceKey = tag.read("LootTable", LootTable.KEY_CODEC).orElse(null); +@@ -50,8 +_,9 @@ + default boolean tryLoadLootTable(ValueInput input) { + ResourceKey resourceKey = input.read("LootTable", LootTable.KEY_CODEC).orElse(null); this.setLootTable(resourceKey); -+ if (this.lootableData() != null && resourceKey != null) this.lootableData().loadNbt(tag); // Paper - LootTable API - this.setLootTableSeed(tag.getLongOr("LootTableSeed", 0L)); ++ if (this.lootableData() != null && resourceKey != null) this.lootableData().loadNbt(input); // Paper - LootTable API + this.setLootTableSeed(input.getLongOr("LootTableSeed", 0L)); - return resourceKey != null; + return resourceKey != null && this.lootableData() == null; // Paper - only track the loot table if there is chance for replenish } - default boolean trySaveLootTable(CompoundTag tag) { -@@ -59,26 +_,42 @@ + default boolean trySaveLootTable(ValueOutput output) { +@@ -60,26 +_,42 @@ return false; } else { - tag.store("LootTable", LootTable.KEY_CODEC, lootTable); -+ if (this.lootableData() != null) this.lootableData().saveNbt(tag); // Paper - LootTable API + output.store("LootTable", LootTable.KEY_CODEC, lootTable); ++ if (this.lootableData() != null) this.lootableData().saveNbt(output); // Paper - LootTable API long lootTableSeed = this.getLootTableSeed(); if (lootTableSeed != 0L) { - tag.putLong("LootTableSeed", lootTableSeed); + output.putLong("LootTableSeed", lootTableSeed); } - return true; @@ -65,7 +65,7 @@ LootParams.Builder builder = new LootParams.Builder((ServerLevel)level).withParameter(LootContextParams.ORIGIN, Vec3.atCenterOf(blockPos)); if (player != null) { builder.withLuck(player.getLuck()).withParameter(LootContextParams.THIS_ENTITY, player); -@@ -87,4 +_,17 @@ +@@ -88,4 +_,17 @@ lootTable1.fill(this, builder.create(LootContextParamSets.CHEST), this.getLootTableSeed()); } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch index 9fc83b1d7b..1364e8e57f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/AgeableMob.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/AgeableMob.java +++ b/net/minecraft/world/entity/AgeableMob.java -@@ -22,6 +_,7 @@ +@@ -23,6 +_,7 @@ protected int age = 0; protected int forcedAge = 0; protected int forcedAgeTimer; @@ -8,40 +8,31 @@ protected AgeableMob(EntityType entityType, Level level) { super(entityType, level); -@@ -68,13 +_,15 @@ +@@ -69,6 +_,7 @@ } public void ageUp(int amount, boolean forced) { + if (this.ageLocked) return; // Paper - Honor ageLock int age = this.getAge(); -+ int previousAge = age; // Paper - Decompile fix: lvt reassignment lost + int previousAge = age; age += amount * 20; - if (age > 0) { - age = 0; - } - -- int i1 = age - age; -+ int i1 = age - previousAge; // Paper - Decompile fix - this.setAge(age); - if (forced) { - this.forcedAge += i1; -@@ -106,6 +_,7 @@ - super.addAdditionalSaveData(compound); - compound.putInt("Age", this.getAge()); - compound.putInt("ForcedAge", this.forcedAge); -+ compound.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit +@@ -108,6 +_,7 @@ + super.addAdditionalSaveData(output); + output.putInt("Age", this.getAge()); + output.putInt("ForcedAge", this.forcedAge); ++ output.putBoolean("AgeLocked", this.ageLocked); // CraftBukkit } @Override -@@ -113,6 +_,7 @@ - super.readAdditionalSaveData(compound); - this.setAge(compound.getIntOr("Age", 0)); - this.forcedAge = compound.getIntOr("ForcedAge", 0); -+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // CraftBukkit +@@ -115,6 +_,7 @@ + super.readAdditionalSaveData(input); + this.setAge(input.getIntOr("Age", 0)); + this.forcedAge = input.getIntOr("ForcedAge", 0); ++ this.ageLocked = input.getBooleanOr("AgeLocked", false); // CraftBukkit } @Override -@@ -127,7 +_,7 @@ +@@ -129,7 +_,7 @@ @Override public void aiStep() { super.aiStep(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch index 439fa947ca..dff1e208fb 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/AreaEffectCloud.java.patch @@ -1,24 +1,15 @@ --- a/net/minecraft/world/entity/AreaEffectCloud.java +++ b/net/minecraft/world/entity/AreaEffectCloud.java -@@ -59,7 +_,7 @@ - public float radiusOnUse = 0.0F; - public float radiusPerTick = 0.0F; - @Nullable -- private LivingEntity owner; -+ private net.minecraft.world.entity.LivingEntity owner; - @Nullable - public UUID ownerUUID; - -@@ -193,7 +_,7 @@ +@@ -191,7 +_,7 @@ private void serverTick(ServerLevel level) { - if (this.duration != -1 && this.tickCount >= this.waitTime + this.duration) { + if (this.duration != -1 && this.tickCount - this.waitTime >= this.duration) { - this.discard(); + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { boolean isWaiting = this.isWaiting(); boolean flag = this.tickCount < this.waitTime; -@@ -206,7 +_,7 @@ +@@ -204,7 +_,7 @@ if (this.radiusPerTick != 0.0F) { radius += this.radiusPerTick; if (radius < 0.5F) { @@ -27,7 +18,7 @@ return; } -@@ -222,6 +_,7 @@ +@@ -220,6 +_,7 @@ this.potionContents.forEachEffect(list::add, this.potionDurationScale); List entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, this.getBoundingBox()); if (!entitiesOfClass.isEmpty()) { @@ -35,7 +26,7 @@ for (LivingEntity livingEntity : entitiesOfClass) { if (!this.victims.containsKey(livingEntity) && livingEntity.isAffectedByPotions() -@@ -230,6 +_,17 @@ +@@ -228,6 +_,17 @@ double d1 = livingEntity.getZ() - this.getZ(); double d2 = d * d + d1 * d1; if (d2 <= radius * radius) { @@ -53,7 +44,7 @@ this.victims.put(livingEntity, this.tickCount + this.reapplicationDelay); for (MobEffectInstance mobEffectInstance : list) { -@@ -238,14 +_,14 @@ +@@ -236,14 +_,14 @@ .value() .applyInstantenousEffect(level, this, this.getOwner(), livingEntity, mobEffectInstance.getAmplifier(), 0.5); } else { @@ -70,7 +61,7 @@ return; } -@@ -255,7 +_,7 @@ +@@ -253,7 +_,7 @@ if (this.durationOnUse != 0 && this.duration != -1) { this.duration = this.duration + this.durationOnUse; if (this.duration <= 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ConversionType.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ConversionType.java.patch index 92bdec3973..479522aad4 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ConversionType.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ConversionType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ConversionType.java +++ b/net/minecraft/world/entity/ConversionType.java -@@ -21,7 +_,7 @@ +@@ -24,7 +_,7 @@ for (Entity entity : newMob.getPassengers()) { entity.stopRiding(); @@ -9,7 +9,7 @@ } firstPassenger.startRiding(newMob); -@@ -70,6 +_,7 @@ +@@ -73,6 +_,7 @@ if (leashHolder != null) { oldMob.dropLeash(); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch index 94d3d44302..4ecc74c7b4 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch @@ -1,15 +1,14 @@ --- a/net/minecraft/world/entity/Entity.java +++ b/net/minecraft/world/entity/Entity.java -@@ -141,6 +_,107 @@ - import org.jetbrains.annotations.Contract; +@@ -148,6 +_,106 @@ + import org.slf4j.Logger; public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder, DataComponentGetter { + // CraftBukkit start -+ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); + private static final int CURRENT_LEVEL = 2; + public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first snapTo -+ static boolean isLevelAtLeast(CompoundTag tag, int level) { -+ return tag.getIntOr("Bukkit.updateLevel", CURRENT_LEVEL) >= level; ++ static boolean isLevelAtLeast(ValueInput input, int level) { ++ return input.getIntOr("Bukkit.updateLevel", CURRENT_LEVEL) >= level; + } + + // Paper start - Share random for entities to make them more random @@ -105,19 +104,19 @@ + return this.bukkitEntity; + } + // Paper end - public static final String ID_TAG = "id"; - public static final String PASSENGERS_TAG = "Passengers"; - private static final String DATA_TAG = "data"; -@@ -203,7 +_,7 @@ + private static final Logger LOGGER = LogUtils.getLogger(); + public static final String TAG_ID = "id"; + public static final String TAG_UUID = "UUID"; +@@ -224,7 +_,7 @@ public double yOld; public double zOld; public boolean noPhysics; - public final RandomSource random = RandomSource.create(); + public final RandomSource random = SHARED_RANDOM; // Paper - Share random for entities to make them more random public int tickCount; - private int remainingFireTicks = -this.getFireImmuneTicks(); + private int remainingFireTicks; public boolean wasTouchingWater; -@@ -240,7 +_,7 @@ +@@ -261,7 +_,7 @@ protected UUID uuid = Mth.createInsecureUUID(this.random); protected String stringUUID = this.uuid.toString(); private boolean hasGlowingTag; @@ -126,7 +125,7 @@ private final double[] pistonDeltas = new double[]{0.0, 0.0, 0.0}; private long pistonDeltasGameTime; private EntityDimensions dimensions; -@@ -251,7 +_,7 @@ +@@ -272,7 +_,7 @@ private boolean onGroundNoBlocks = false; private float crystalSoundIntensity; private int lastCrystalSoundPlayTick; @@ -134,8 +133,8 @@ + public net.kyori.adventure.util.TriState visualFire = net.kyori.adventure.util.TriState.NOT_SET; // Paper - improve visual fire API @Nullable private BlockState inBlockState = null; - private final List> movementThisTick = new ObjectArrayList<>(); -@@ -259,6 +_,45 @@ + public static final int MAX_MOVEMENTS_HANDELED_PER_TICK = 100; +@@ -281,6 +_,41 @@ private final LongSet visitedBlocks = new LongOpenHashSet(); private final InsideBlockEffectApplier.StepBasedCollector insideEffectCollector = new InsideBlockEffectApplier.StepBasedCollector(); private CustomData customData = CustomData.EMPTY; @@ -173,15 +172,11 @@ + public final AABB getBoundingBoxAt(double x, double y, double z) { + return this.dimensions.makeBoundingBox(x, y, z); + } -+ // MC-296337 -+ protected void clearMovementsThisTick() { -+ this.movementThisTick.clear(); -+ } + // Paper end public Entity(EntityType entityType, Level level) { this.type = entityType; -@@ -280,6 +_,7 @@ +@@ -302,6 +_,7 @@ this.entityData = builder.build(); this.setPos(0.0, 0.0, 0.0); this.eyeHeight = this.dimensions.eyeHeight(); @@ -189,7 +184,7 @@ } public boolean isColliding(BlockPos pos, BlockState state) { -@@ -292,6 +_,12 @@ +@@ -314,6 +_,12 @@ return team != null && team.getColor().getColor() != null ? team.getColor().getColor() : 16777215; } @@ -202,7 +197,7 @@ public boolean isSpectator() { return false; } -@@ -332,7 +_,7 @@ +@@ -362,7 +_,7 @@ } public boolean addTag(String tag) { @@ -211,7 +206,7 @@ } public boolean removeTag(String tag) { -@@ -340,12 +_,18 @@ +@@ -370,12 +_,18 @@ } public void kill(ServerLevel level) { @@ -232,7 +227,7 @@ } protected abstract void defineSynchedData(SynchedEntityData.Builder builder); -@@ -354,6 +_,48 @@ +@@ -384,6 +_,48 @@ return this.entityData; } @@ -281,7 +276,7 @@ @Override public boolean equals(Object object) { return object instanceof Entity && ((Entity)object).id == this.id; -@@ -365,7 +_,13 @@ +@@ -395,7 +_,13 @@ } public void remove(Entity.RemovalReason reason) { @@ -296,7 +291,7 @@ } public void onClientRemoval() { -@@ -375,6 +_,15 @@ +@@ -405,6 +_,15 @@ } public void setPose(Pose pose) { @@ -312,7 +307,7 @@ this.entityData.set(DATA_POSE, pose); } -@@ -398,6 +_,32 @@ +@@ -428,6 +_,32 @@ } public void setRot(float yRot, float xRot) { @@ -345,7 +340,7 @@ this.setYRot(yRot % 360.0F); this.setXRot(xRot % 360.0F); } -@@ -407,8 +_,8 @@ +@@ -437,8 +_,8 @@ } public void setPos(double x, double y, double z) { @@ -356,7 +351,7 @@ } protected final AABB makeBoundingBox() { -@@ -438,12 +_,28 @@ +@@ -468,12 +_,28 @@ } public void tick() { @@ -385,7 +380,7 @@ this.inBlockState = null; if (this.isPassenger() && this.getVehicle().isRemoved()) { this.stopRiding(); -@@ -453,7 +_,7 @@ +@@ -483,7 +_,7 @@ this.boardingCooldown--; } @@ -394,7 +389,7 @@ if (this.canSpawnSprintParticle()) { this.spawnSprintParticle(); } -@@ -484,6 +_,10 @@ +@@ -511,6 +_,10 @@ if (this.isInLava()) { this.fallDistance *= 0.5; @@ -405,7 +400,7 @@ } this.checkBelowWorld(); -@@ -500,11 +_,16 @@ +@@ -527,11 +_,16 @@ } public void setSharedFlagOnFire(boolean isOnFire) { @@ -424,7 +419,7 @@ this.onBelowWorld(); } } -@@ -532,15 +_,41 @@ +@@ -559,15 +_,41 @@ } public void lavaIgnite() { @@ -468,7 +463,7 @@ && this.shouldPlayLavaHurtSound() && !this.isSilent()) { serverLevel.playSound( -@@ -555,6 +_,20 @@ +@@ -582,6 +_,20 @@ } public final void igniteForSeconds(float seconds) { @@ -489,7 +484,7 @@ this.igniteForTicks(Mth.floor(seconds * 20.0F)); } -@@ -579,7 +_,7 @@ +@@ -606,7 +_,7 @@ } protected void onBelowWorld() { @@ -498,7 +493,7 @@ } public boolean isFree(double x, double y, double z) { -@@ -635,7 +_,28 @@ +@@ -662,7 +_,28 @@ return this.onGround; } @@ -527,7 +522,7 @@ if (this.noPhysics) { this.setPos(this.getX() + movement.x, this.getY() + movement.y, this.getZ() + movement.z); } else { -@@ -721,6 +_,27 @@ +@@ -738,6 +_,27 @@ block.updateEntityMovementAfterFallOn(this.level(), this); } } @@ -555,7 +550,7 @@ if (!this.level().isClientSide() || this.isLocalInstanceAuthoritative()) { Entity.MovementEmission movementEmission = this.getMovementEmission(); -@@ -734,6 +_,13 @@ +@@ -751,6 +_,13 @@ profilerFiller.pop(); } } @@ -569,7 +564,7 @@ } private void applyMovementEmissionAndPlaySound(Entity.MovementEmission movementEmission, Vec3 movement, BlockPos pos, BlockState state) { -@@ -898,7 +_,7 @@ +@@ -932,7 +_,7 @@ } protected BlockPos getOnPos(float yOffset) { @@ -578,25 +573,25 @@ BlockPos blockPos = this.mainSupportingBlockPos.get(); if (!(yOffset > 1.0E-5F)) { return blockPos; -@@ -1104,7 +_,7 @@ - || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs()); - if (flag) { - try { -- stepBasedCollector.advanceStep(step); -+ stepBasedCollector.advanceStep(step, pos); // Paper - track position inside effect was triggered on - blockState.entityInside(this.level(), pos, this, stepBasedCollector); - this.onInsideBlock(blockState); - } catch (Throwable var14) { -@@ -1119,7 +_,7 @@ +@@ -1163,7 +_,7 @@ + || this.collidedWithShapeMovingFrom(vec3, vec31, entityInsideCollisionShape.move(new Vec3(pos)).toAabbs()); + if (flag) { + try { +- stepBasedCollector.advanceStep(index); ++ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on + blockState.entityInside(this.level(), pos, this, stepBasedCollector); + this.onInsideBlock(blockState); + } catch (Throwable var14) { +@@ -1178,7 +_,7 @@ - boolean flag1 = this.collidedWithFluid(blockState.getFluidState(), pos, vec3, vec31); - if (flag1) { -- stepBasedCollector.advanceStep(step); -+ stepBasedCollector.advanceStep(step, pos); // Paper - track position inside effect was triggered on - blockState.getFluidState().entityInside(this.level(), pos, this, stepBasedCollector); - } - } -@@ -1519,6 +_,7 @@ + boolean flag1 = this.collidedWithFluid(blockState.getFluidState(), pos, vec3, vec31); + if (flag1) { +- stepBasedCollector.advanceStep(index); ++ stepBasedCollector.advanceStep(index, pos); // Paper - track position inside effect was triggered on + blockState.getFluidState().entityInside(this.level(), pos, this, stepBasedCollector); + } + +@@ -1594,6 +_,7 @@ this.setXRot(Mth.clamp(xRot, -90.0F, 90.0F) % 360.0F); this.yRotO = this.getYRot(); this.xRotO = this.getXRot(); @@ -604,7 +599,7 @@ } public void absSnapTo(double x, double y, double z) { -@@ -1528,6 +_,7 @@ +@@ -1603,6 +_,7 @@ this.yo = y; this.zo = d1; this.setPos(d, y, d1); @@ -612,7 +607,7 @@ } public void snapTo(Vec3 pos) { -@@ -1547,11 +_,19 @@ +@@ -1622,11 +_,19 @@ } public void snapTo(double x, double y, double z, float yRot, float xRot) { @@ -632,7 +627,7 @@ } public final void setOldPosAndRot() { -@@ -1618,6 +_,7 @@ +@@ -1693,6 +_,7 @@ public void push(Entity entity) { if (!this.isPassengerOfSameVehicle(entity)) { if (!entity.noPhysics && !this.noPhysics) { @@ -640,7 +635,7 @@ double d = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); double max = Mth.absMax(d, d1); -@@ -1651,7 +_,21 @@ +@@ -1726,7 +_,21 @@ } public void push(double x, double y, double z) { @@ -663,7 +658,7 @@ this.hasImpulse = true; } -@@ -1758,8 +_,20 @@ +@@ -1833,8 +_,20 @@ } public boolean isPushable() { @@ -684,17 +679,17 @@ public void awardKillScore(Entity entity, DamageSource damageSource) { if (entity instanceof ServerPlayer) { -@@ -1786,15 +_,23 @@ +@@ -1861,15 +_,23 @@ } - public boolean saveAsPassenger(CompoundTag compound) { + public boolean saveAsPassenger(ValueOutput output) { - if (this.removalReason != null && !this.removalReason.shouldSave()) { + // CraftBukkit start - allow excluding certain data when saving + // Paper start - Raw entity serialization API -+ return this.saveAsPassenger(compound, true, false, false); ++ return this.saveAsPassenger(output, true, false, false); + } + -+ public boolean saveAsPassenger(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { ++ public boolean saveAsPassenger(ValueOutput output, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { + // Paper end - Raw entity serialization API + // CraftBukkit end + if (this.removalReason != null && !this.removalReason.shouldSave() && !forceSerialization) { // Paper - Raw entity serialization API @@ -706,35 +701,35 @@ + if ((!this.persist && !forceSerialization) || encodeId == null) { // CraftBukkit - persist flag // Paper - Raw entity serialization API return false; } else { - compound.putString("id", encodeId); -- this.saveWithoutId(compound); -+ this.saveWithoutId(compound, includeAll, includeNonSaveable, forceSerialization); // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API + output.putString("id", encodeId); +- this.saveWithoutId(output); ++ this.saveWithoutId(output , includeAll, includeNonSaveable, forceSerialization); // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API return true; } } -@@ -1805,14 +_,35 @@ +@@ -1880,14 +_,35 @@ } - public CompoundTag saveWithoutId(CompoundTag compound) { + public void saveWithoutId(ValueOutput output) { + // CraftBukkit start - allow excluding certain data when saving + // Paper start - Raw entity serialization API -+ return this.saveWithoutId(compound, true, false, false); ++ this.saveWithoutId(output, true, false, false); + } + -+ public CompoundTag saveWithoutId(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { ++ public void saveWithoutId(ValueOutput output, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) { + // Paper end - Raw entity serialization API + // CraftBukkit end try { + if (includeAll) { // CraftBukkit - selectively save position if (this.vehicle != null) { - compound.store("Pos", Vec3.CODEC, new Vec3(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); + output.store("Pos", Vec3.CODEC, new Vec3(this.vehicle.getX(), this.getY(), this.vehicle.getZ())); } else { - compound.store("Pos", Vec3.CODEC, this.position()); + output.store("Pos", Vec3.CODEC, this.position()); } + } // CraftBukkit + this.setDeltaMovement(io.papermc.paper.util.MCUtil.sanitizeNanInf(this.deltaMovement, 0D)); // Paper - remove NaN values before usage in saving - compound.store("Motion", Vec3.CODEC, this.getDeltaMovement()); + output.store("Motion", Vec3.CODEC, this.getDeltaMovement()); + // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero + // TODO: make sure this is the best way to address this. + if (Float.isNaN(this.yRot)) { @@ -745,121 +740,121 @@ + this.xRot = 0; + } + // CraftBukkit end - compound.store("Rotation", Vec2.CODEC, new Vec2(this.getYRot(), this.getXRot())); - compound.putDouble("fall_distance", this.fallDistance); - compound.putShort("Fire", (short)this.remainingFireTicks); -@@ -1820,7 +_,29 @@ - compound.putBoolean("OnGround", this.onGround()); - compound.putBoolean("Invulnerable", this.invulnerable); - compound.putInt("PortalCooldown", this.portalCooldown); -- compound.store("UUID", UUIDUtil.CODEC, this.getUUID()); + output.store("Rotation", Vec2.CODEC, new Vec2(this.getYRot(), this.getXRot())); + output.putDouble("fall_distance", this.fallDistance); + output.putShort("Fire", (short)this.remainingFireTicks); +@@ -1895,7 +_,29 @@ + output.putBoolean("OnGround", this.onGround()); + output.putBoolean("Invulnerable", this.invulnerable); + output.putInt("PortalCooldown", this.portalCooldown); + // CraftBukkit start - selectively save uuid and world + if (includeAll) { -+ compound.store("UUID", UUIDUtil.CODEC, this.getUUID()); -+ // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast -+ compound.putLong("WorldUUIDLeast", this.level.getWorld().getUID().getLeastSignificantBits()); -+ compound.putLong("WorldUUIDMost", this.level.getWorld().getUID().getMostSignificantBits()); + output.store("UUID", UUIDUtil.CODEC, this.getUUID()); ++ // PAIL: Check above UUID reads 1.8 properly, ie: UUIDMost / UUIDLeast ++ output.putLong("WorldUUIDLeast", this.level.getWorld().getUID().getLeastSignificantBits()); ++ output.putLong("WorldUUIDMost", this.level.getWorld().getUID().getMostSignificantBits()); + } -+ compound.putInt("Bukkit.updateLevel", Entity.CURRENT_LEVEL); ++ output.putInt("Bukkit.updateLevel", Entity.CURRENT_LEVEL); + if (!this.persist) { -+ compound.putBoolean("Bukkit.persist", this.persist); ++ output.putBoolean("Bukkit.persist", this.persist); + } + if (!this.visibleByDefault) { -+ compound.putBoolean("Bukkit.visibleByDefault", this.visibleByDefault); ++ output.putBoolean("Bukkit.visibleByDefault", this.visibleByDefault); + } + if (this.persistentInvisibility) { -+ compound.putBoolean("Bukkit.invisible", this.persistentInvisibility); ++ output.putBoolean("Bukkit.invisible", this.persistentInvisibility); + } + // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() + if (this.maxAirTicks != this.getDefaultMaxAirSupply()) { -+ compound.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); ++ output.putInt("Bukkit.MaxAirSupply", this.getMaxAirSupply()); + } -+ compound.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper ++ output.putInt("Spigot.ticksLived", this.totalEntityAge); // Paper + // CraftBukkit end - Component customName = this.getCustomName(); - if (customName != null) { - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); -@@ -1848,9 +_,12 @@ - compound.putInt("TicksFrozen", this.getTicksFrozen()); + output.storeNullable("CustomName", ComponentSerialization.CODEC, this.getCustomName()); + if (this.isCustomNameVisible()) { + output.putBoolean("CustomNameVisible", this.isCustomNameVisible()); +@@ -1918,9 +_,12 @@ + output.putInt("TicksFrozen", this.getTicksFrozen()); } - if (this.hasVisualFire) { -- compound.putBoolean("HasVisualFire", this.hasVisualFire); +- output.putBoolean("HasVisualFire", this.hasVisualFire); + // Paper start - improve visual fire API + if (this.visualFire.equals(net.kyori.adventure.util.TriState.TRUE)) { -+ compound.putBoolean("HasVisualFire", true); ++ output.putBoolean("HasVisualFire", true); } -+ compound.putString("Paper.FireOverride", visualFire.name()); ++ output.putString("Paper.FireOverride", visualFire.name()); + // Paper end if (!this.tags.isEmpty()) { - compound.store("Tags", TAG_LIST_CODEC, List.copyOf(this.tags)); -@@ -1860,13 +_,13 @@ - compound.store("data", CustomData.CODEC, this.customData); + output.store("Tags", TAG_LIST_CODEC, List.copyOf(this.tags)); +@@ -1930,13 +_,13 @@ + output.store("data", CustomData.CODEC, this.customData); } -- this.addAdditionalSaveData(compound); -+ this.addAdditionalSaveData(compound, includeAll); // CraftBukkit - pass on includeAll +- this.addAdditionalSaveData(output); ++ this.addAdditionalSaveData(output, includeAll); // CraftBukkit - pass on includeAll if (this.isVehicle()) { - ListTag listTag = new ListTag(); + ValueOutput.ValueOutputList valueOutputList = output.childrenList("Passengers"); for (Entity entity : this.getPassengers()) { - CompoundTag compoundTag = new CompoundTag(); -- if (entity.saveAsPassenger(compoundTag)) { -+ if (entity.saveAsPassenger(compoundTag, includeAll, includeNonSaveable, forceSerialization)) { // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API - listTag.add(compoundTag); + ValueOutput valueOutput = valueOutputList.addChild(); +- if (!entity.saveAsPassenger(valueOutput)) { ++ if (!entity.saveAsPassenger(valueOutput, includeAll, includeNonSaveable, forceSerialization)) { // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API + valueOutputList.discardLast(); } } -@@ -1876,6 +_,33 @@ +@@ -1945,6 +_,34 @@ + output.discard("Passengers"); } } - ++ + // CraftBukkit start - stores eventually existing bukkit values + if (this.bukkitEntity != null) { -+ this.bukkitEntity.storeBukkitValues(compound); ++ this.bukkitEntity.storeBukkitValues(output); + } + // CraftBukkit end + // Paper start + if (this.origin != null) { + UUID originWorld = this.originWorld != null ? this.originWorld : (this.level != null ? this.level.getWorld().getUID() : null); + if (originWorld != null) { -+ compound.store("Paper.OriginWorld", UUIDUtil.CODEC, originWorld); ++ output.store("Paper.OriginWorld", UUIDUtil.CODEC, originWorld); + } -+ compound.store("Paper.Origin", Vec3.CODEC, this.origin); ++ output.store("Paper.Origin", Vec3.CODEC, this.origin); + } + if (this.spawnReason != null) { -+ compound.putString("Paper.SpawnReason", this.spawnReason.name()); ++ output.putString("Paper.SpawnReason", this.spawnReason.name()); + } + // Save entity's from mob spawner status + if (this.spawnedViaMobSpawner) { -+ compound.putBoolean("Paper.FromMobSpawner", true); ++ output.putBoolean("Paper.FromMobSpawner", true); + } + if (this.fromNetherPortal) { -+ compound.putBoolean("Paper.FromNetherPortal", true); ++ output.putBoolean("Paper.FromNetherPortal", true); + } + if (this.freezeLocked) { -+ compound.putBoolean("Paper.FreezeLock", true); ++ output.putBoolean("Paper.FreezeLock", true); + } + // Paper end - return compound; - } catch (Throwable var8) { - CrashReport crashReport = CrashReport.forThrowable(var8, "Saving entity NBT"); -@@ -1888,7 +_,7 @@ - public void load(CompoundTag compound) { + } catch (Throwable var7) { + CrashReport crashReport = CrashReport.forThrowable(var7, "Saving entity NBT"); + CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being saved"); +@@ -1956,7 +_,7 @@ + public void load(ValueInput input) { try { - Vec3 vec3 = compound.read("Pos", Vec3.CODEC).orElse(Vec3.ZERO); -- Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); -+ Vec3 vec31 = compound.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); vec31 = io.papermc.paper.util.MCUtil.sanitizeNanInf(vec31, 0D); // Paper - avoid setting NaN values - Vec2 vec2 = compound.read("Rotation", Vec2.CODEC).orElse(Vec2.ZERO); + Vec3 vec3 = input.read("Pos", Vec3.CODEC).orElse(Vec3.ZERO); +- Vec3 vec31 = input.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); ++ Vec3 vec31 = input.read("Motion", Vec3.CODEC).orElse(Vec3.ZERO); vec31 = io.papermc.paper.util.MCUtil.sanitizeNanInf(vec31, 0D); // Paper - avoid setting NaN values + Vec2 vec2 = input.read("Rotation", Vec2.CODEC).orElse(Vec2.ZERO); this.setDeltaMovement(Math.abs(vec31.x) > 10.0 ? 0.0 : vec31.x, Math.abs(vec31.y) > 10.0 ? 0.0 : vec31.y, Math.abs(vec31.z) > 10.0 ? 0.0 : vec31.z); this.hasImpulse = true; -@@ -1921,7 +_,20 @@ - this.setNoGravity(compound.getBooleanOr("NoGravity", false)); - this.setGlowingTag(compound.getBooleanOr("Glowing", false)); - this.setTicksFrozen(compound.getIntOr("TicksFrozen", 0)); -- this.hasVisualFire = compound.getBooleanOr("HasVisualFire", false); +@@ -1988,7 +_,20 @@ + this.setNoGravity(input.getBooleanOr("NoGravity", false)); + this.setGlowingTag(input.getBooleanOr("Glowing", false)); + this.setTicksFrozen(input.getIntOr("TicksFrozen", 0)); +- this.hasVisualFire = input.getBooleanOr("HasVisualFire", false); + // Paper start - improve visual fire API -+ compound.getString("Paper.FireOverride").ifPresentOrElse( ++ input.getString("Paper.FireOverride").ifPresentOrElse( + override -> { + try { + this.visualFire = net.kyori.adventure.util.TriState.valueOf(override); @@ -867,68 +862,62 @@ + LOGGER.error("Unknown fire override {} for {}", override, this); + } + }, -+ () -> this.visualFire = compound.getBoolean("HasVisualFire") ++ () -> this.visualFire = input.read("HasVisualFire", Codec.BOOL) + .map(net.kyori.adventure.util.TriState::byBoolean) + .orElse(net.kyori.adventure.util.TriState.NOT_SET) + ); + // Paper end - this.customData = compound.read("data", CustomData.CODEC).orElse(CustomData.EMPTY); + this.customData = input.read("data", CustomData.CODEC).orElse(CustomData.EMPTY); this.tags.clear(); - compound.read("Tags", TAG_LIST_CODEC).ifPresent(this.tags::addAll); -@@ -1932,6 +_,67 @@ + input.read("Tags", TAG_LIST_CODEC).ifPresent(this.tags::addAll); +@@ -1999,6 +_,59 @@ } else { throw new IllegalStateException("Entity has invalid rotation"); } ++ + // CraftBukkit start + // Spigot start + if (this instanceof net.minecraft.world.entity.LivingEntity) { -+ this.totalEntityAge = compound.getIntOr("Spigot.ticksLived", 0); // Paper ++ this.totalEntityAge = input.getIntOr("Spigot.ticksLived", 0); // Paper + } + // Spigot end -+ this.persist = compound.getBooleanOr("Bukkit.persist", true); -+ this.visibleByDefault = compound.getBooleanOr("Bukkit.visibleByDefault", true); ++ this.persist = input.getBooleanOr("Bukkit.persist", true); ++ this.visibleByDefault = input.getBooleanOr("Bukkit.visibleByDefault", true); + // SPIGOT-6907: re-implement LivingEntity#setMaximumAir() -+ this.maxAirTicks = compound.getIntOr("Bukkit.MaxAirSupply",this.maxAirTicks); ++ this.maxAirTicks = input.getIntOr("Bukkit.MaxAirSupply",this.maxAirTicks); + // CraftBukkit end + + // CraftBukkit start + // Paper - move world parsing/loading to PlayerList#placeNewPlayer -+ this.getBukkitEntity().readBukkitValues(compound); -+ if (compound.contains("Bukkit.invisible")) { -+ boolean bukkitInvisible = compound.getBooleanOr("Bukkit.invisible", false); ++ this.getBukkitEntity().readBukkitValues(input); ++ input.read("Bukkit.invisible", Codec.BOOL).ifPresent(bukkitInvisible -> { + this.setInvisible(bukkitInvisible); + this.persistentInvisibility = bukkitInvisible; -+ } ++ }); + // CraftBukkit end + + // Paper start -+ Optional originVec = compound.read("Paper.Origin", Vec3.CODEC); ++ Optional originVec = input.read("Paper.Origin", Vec3.CODEC); + if (originVec.isPresent()) { -+ UUID originWorld = null; -+ if (compound.contains("Paper.OriginWorld")) { -+ originWorld = compound.read("Paper.OriginWorld", UUIDUtil.CODEC).orElse(null); -+ } else if (this.level != null) { -+ originWorld = this.level.getWorld().getUID(); -+ } -+ this.originWorld = originWorld; ++ this.originWorld = input.read("Paper.OriginWorld", UUIDUtil.CODEC) ++ .orElse(this.level != null ? this.level.getWorld().getUID() : null); + this.origin = originVec.get(); + } + -+ spawnedViaMobSpawner = compound.getBooleanOr("Paper.FromMobSpawner", false); // Restore entity's from mob spawner status -+ fromNetherPortal = compound.getBooleanOr("Paper.FromNetherPortal", false); -+ if (compound.contains("Paper.SpawnReason")) { -+ String spawnReasonName = compound.getString("Paper.SpawnReason").orElse(null); ++ spawnedViaMobSpawner = input.getBooleanOr("Paper.FromMobSpawner", false); // Restore entity's from mob spawner status ++ fromNetherPortal = input.getBooleanOr("Paper.FromNetherPortal", false); ++ input.getString("Paper.SpawnReason").ifPresent(spawnReasonName -> { + try { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.valueOf(spawnReasonName); + } catch (Exception ignored) { + LOGGER.error("Unknown SpawnReason " + spawnReasonName + " for " + this); + } -+ } ++ }); + if (spawnReason == null) { + if (spawnedViaMobSpawner) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; + } else if (this instanceof Mob && (this instanceof net.minecraft.world.entity.animal.Animal || this instanceof net.minecraft.world.entity.animal.AbstractFish) && !((Mob) this).removeWhenFarAway(0.0)) { -+ if (!compound.getBooleanOr("PersistenceRequired", false)) { ++ if (!input.getBooleanOr("PersistenceRequired", false)) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL; + } + } @@ -936,14 +925,12 @@ + if (spawnReason == null) { + spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; + } -+ if (compound.contains("Paper.FreezeLock")) { -+ freezeLocked = compound.getBooleanOr("Paper.FreezeLock", false); -+ } ++ freezeLocked = input.getBooleanOr("Paper.FreezeLock", false); + // Paper end - } catch (Throwable var8) { - CrashReport crashReport = CrashReport.forThrowable(var8, "Loading entity NBT"); + } catch (Throwable var7) { + CrashReport crashReport = CrashReport.forThrowable(var7, "Loading entity NBT"); CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded"); -@@ -1946,10 +_,21 @@ +@@ -2013,13 +_,24 @@ @Nullable public final String getEncodeId() { @@ -955,24 +942,26 @@ EntityType type = this.getType(); ResourceLocation key = EntityType.getKey(type); - return type.canSerialize() && key != null ? key.toString() : null; -- } -+ return (type.canSerialize() || includeNonSaveable) && key != null ? key.toString() : null; // Paper - Raw entity serialization API -+ } -+ ++ return (type.canSerialize() || includeNonSaveable) ? key.toString() : null; // Paper - Raw entity serialization API + } + + protected abstract void readAdditionalSaveData(ValueInput input); + + // CraftBukkit start - allow excluding certain data when saving -+ protected void addAdditionalSaveData(CompoundTag tag, boolean includeAll) { -+ this.addAdditionalSaveData(tag); ++ protected void addAdditionalSaveData(ValueOutput output, boolean includeAll) { ++ this.addAdditionalSaveData(output); + } + // CraftBukkit end - - protected abstract void readAdditionalSaveData(CompoundTag tag); - -@@ -1972,11 +_,63 @@ ++ + protected abstract void addAdditionalSaveData(ValueOutput output); @Nullable - public ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, float yOffset) { +@@ -2039,11 +_,63 @@ + + @Nullable + public ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, Vec3 offset) { + // Paper start - Restore vanilla drops behavior -+ return this.spawnAtLocation(level, stack, yOffset, null); ++ return this.spawnAtLocation(level, stack, offset, null); + } + + public record DefaultDrop(Item item, org.bukkit.inventory.ItemStack stack, @Nullable java.util.function.Consumer dropConsumer) { @@ -990,17 +979,17 @@ + } + + @Nullable -+ public ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, float yOffset, @Nullable java.util.function.Consumer delayedAddConsumer) { ++ public ItemEntity spawnAtLocation(ServerLevel level, ItemStack stack, Vec3 offset, @Nullable java.util.function.Consumer delayedAddConsumer) { + // Paper end - Restore vanilla drops behavior if (stack.isEmpty()) { return null; } else { -- ItemEntity itemEntity = new ItemEntity(level, this.getX(), this.getY() + yOffset, this.getZ(), stack); +- ItemEntity itemEntity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, stack); + // CraftBukkit start - Capture drops for death event + if (this instanceof net.minecraft.world.entity.LivingEntity && !this.forceDrops) { + // Paper start - Restore vanilla drops behavior + ((net.minecraft.world.entity.LivingEntity) this).drops.add(new net.minecraft.world.entity.Entity.DefaultDrop(stack, itemStack -> { -+ ItemEntity itemEntity = new ItemEntity(this.level, this.getX(), this.getY() + (double) yOffset, this.getZ(), itemStack); // stack is copied before consumer ++ ItemEntity itemEntity = new ItemEntity(this.level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, itemStack); // stack is copied before consumer + itemEntity.setDefaultPickUpDelay(); + this.level.addFreshEntity(itemEntity); + if (delayedAddConsumer != null) delayedAddConsumer.accept(itemEntity); @@ -1009,7 +998,7 @@ + return null; + } + // CraftBukkit end -+ ItemEntity itemEntity = new ItemEntity(level, this.getX(), this.getY() + yOffset, this.getZ(), stack.copy()); // Paper - copy so we can destroy original ++ ItemEntity itemEntity = new ItemEntity(level, this.getX() + offset.x, this.getY() + offset.y, this.getZ() + offset.z, stack.copy()); // Paper - copy so we can destroy original + stack.setCount(0); // Paper - destroy this item - if this ever leaks due to game bugs, ensure it doesn't dupe + itemEntity.setDefaultPickUpDelay(); @@ -1032,39 +1021,142 @@ level.addFreshEntity(itemEntity); return itemEntity; } -@@ -2008,7 +_,16 @@ - if (this.isAlive() && this instanceof Leashable leashable) { - if (leashable.getLeashHolder() == player) { - if (!this.level().isClientSide()) { -- if (player.hasInfiniteMaterials()) { -+ // CraftBukkit start - fire PlayerUnleashEntityEvent -+ // Paper start - Expand EntityUnleashEvent -+ org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(this, player, hand, !player.hasInfiniteMaterials()); -+ if (event.isCancelled()) { -+ // Paper end - Expand EntityUnleashEvent -+ ((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(this, leashable.getLeashHolder())); -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end -+ if (!event.isDropLeash()) { // Paper - Expand EntityUnleashEvent - leashable.removeLeash(); - } else { - leashable.dropLeash(); -@@ -2023,6 +_,13 @@ - ItemStack itemInHand = player.getItemInHand(hand); - if (itemInHand.is(Items.LEAD) && leashable.canHaveALeashAttachedToIt()) { - if (!this.level().isClientSide()) { -+ // CraftBukkit start - fire PlayerLeashEntityEvent -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) { -+ ((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(this, leashable.getLeashHolder())); -+ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync -+ return InteractionResult.PASS; -+ } -+ // CraftBukkit end - leashable.setLeashedTo(player, true); +@@ -2089,6 +_,15 @@ + + for (Leashable leashable1 : list) { + if (leashable1.canHaveALeashAttachedTo(this)) { ++ // Paper start - PlayerLeashEvent ++ final org.bukkit.event.entity.PlayerLeashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent( ++ leashable1, ++ this, ++ player, ++ hand ++ ); ++ if (event != null && event.isCancelled()) continue; // If the event was called and cancelled, skip this. ++ // Paper end - PlayerLeashEvent + leashable1.setLeashedTo(this, true); + flag = true; + } +@@ -2103,7 +_,7 @@ + } + + ItemStack itemInHand = player.getItemInHand(hand); +- if (itemInHand.is(Items.SHEARS) && this.shearOffAllLeashConnections(player)) { ++ if (itemInHand.is(Items.SHEARS) && this.shearOffAllLeashConnections(player, hand)) { // Paper - PlayerUnleashEntityEvent - pass used hand + itemInHand.hurtAndBreak(1, player, hand); + return InteractionResult.SUCCESS; + } else if (this instanceof Mob mob +@@ -2116,11 +_,13 @@ + if (this.isAlive() && this instanceof Leashable leashable2) { + if (leashable2.getLeashHolder() == player) { + if (!this.level().isClientSide()) { +- if (player.hasInfiniteMaterials()) { +- leashable2.removeLeash(); +- } else { +- leashable2.dropLeash(); ++ // Paper start - EntityUnleashEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( ++ leashable2, player, hand, !player.hasInfiniteMaterials(), true ++ )) { ++ return InteractionResult.PASS; + } ++ // Paper end - EntityUnleashEvent + + this.gameEvent(GameEvent.ENTITY_INTERACT, player); + this.playSound(SoundEvents.LEAD_UNTIED); +@@ -2133,9 +_,23 @@ + if (itemInHand1.is(Items.LEAD) && !(leashable2.getLeashHolder() instanceof Player)) { + if (!this.level().isClientSide() && leashable2.canHaveALeashAttachedTo(player)) { + if (leashable2.isLeashed()) { +- leashable2.dropLeash(); ++ // Paper start - EntityUnleashEvent ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( ++ leashable2, player, hand, true, true ++ )) { ++ return InteractionResult.PASS; ++ } ++ // Paper end - EntityUnleashEvent ++ // leashable2.dropLeash(); // Paper - EntityUnleashEvent - moved into handlePlayerUnleashEntityEvent + } + ++ // Paper start - EntityLeashEvent ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(this, player, player, hand).isCancelled()) { ++ ((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(this, leashable2.getLeashHolder())); ++ player.containerMenu.sendAllDataToRemote(); // Paper - Fix inventory desync ++ return InteractionResult.PASS; ++ } ++ // Paper end - EntityLeashEvent + leashable2.setLeashedTo(player, true); + this.playSound(SoundEvents.LEAD_TIED); + itemInHand1.shrink(1); +@@ -2150,7 +_,12 @@ + } + + public boolean shearOffAllLeashConnections(@Nullable Player player) { +- boolean flag = this.dropAllLeashConnections(player); ++ // Paper start - EntityUnleashEvent - overload ++ return this.shearOffAllLeashConnections(player, null); ++ } ++ public boolean shearOffAllLeashConnections(@Nullable Player player, @Nullable InteractionHand interactionHand) { ++ // Paper end - EntityUnleashEvent - overload ++ boolean flag = this.dropAllLeashConnections(player, interactionHand); // Paper - EntityUnleashEvent - overload + if (flag && this.level() instanceof ServerLevel serverLevel) { + serverLevel.playSound(null, this.blockPosition(), SoundEvents.SHEARS_SNIP, player != null ? player.getSoundSource() : this.getSoundSource()); + } +@@ -2159,15 +_,38 @@ + } + + public boolean dropAllLeashConnections(@Nullable Player player) { ++ // Paper start - EntityUnleashEvent - overload ++ return dropAllLeashConnections(player, null); ++ } ++ public boolean dropAllLeashConnections(@Nullable Player player, @Nullable InteractionHand interactionHand) { ++ // Paper start - EntityUnleashEvent - overload + List list = Leashable.leashableLeashedTo(this); +- boolean flag = !list.isEmpty(); ++ boolean flag = false; // Paper - EntityUnleashEvent - compute flag later, events might prevent unleashing all connected leashables. + if (this instanceof Leashable leashable && leashable.isLeashed()) { +- leashable.dropLeash(); +- flag = true; ++ // Paper start - EntityUnleashEvent ++ flag |= org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( ++ this, ++ player, ++ interactionHand, ++ true, ++ true ++ ); ++ // Paper end - EntityUnleashEvent ++ // leashable.dropLeash(); // Paper - EntityUnleashEvent - moved into handlePlayerUnleashEntityEvent ++ // flag = true; // Paper - EntityUnleashEvent - moved above + } + + for (Leashable leashable1 : list) { +- leashable1.dropLeash(); ++ // Paper start - EntityUnleashEvent ++ flag |= org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerUnleashEntityEvent( // Update flag here, if any entity was unleashed, set to true. ++ leashable1, ++ player, ++ interactionHand, ++ true, ++ true ++ ); ++ // leashable1.dropLeash(); // Paper - EntityUnleashEvent - moved into handlePlayerUnleashEntityEvent ++ // Paper end - EntityUnleashEvent + } + + if (flag) { +@@ -2191,7 +_,9 @@ + this.gameEvent(GameEvent.SHEAR, player); + this.playSound(equippable.shearingSound().value()); + if (this.level() instanceof ServerLevel serverLevel) { ++ this.forceDrops = true; // Paper + this.spawnAtLocation(serverLevel, itemBySlot, average); ++ this.forceDrops = false; // Paper + CriteriaTriggers.PLAYER_SHEARED_EQUIPMENT.trigger((ServerPlayer)player, itemBySlot, mob); } -@@ -2096,11 +_,11 @@ +@@ -2264,11 +_,11 @@ } public boolean startRiding(Entity vehicle, boolean force) { @@ -1078,7 +1170,7 @@ return false; } else { for (Entity entity = vehicle; entity.vehicle != null; entity = entity.vehicle) { -@@ -2110,6 +_,27 @@ +@@ -2278,6 +_,27 @@ } if (force || this.canRide(vehicle) && vehicle.canAddPassenger(this)) { @@ -1106,7 +1198,7 @@ if (this.isPassenger()) { this.stopRiding(); } -@@ -2138,15 +_,26 @@ +@@ -2306,15 +_,26 @@ } public void removeVehicle() { @@ -1135,7 +1227,7 @@ } protected void addPassenger(Entity passenger) { -@@ -2170,10 +_,43 @@ +@@ -2338,10 +_,43 @@ } } @@ -1180,7 +1272,7 @@ if (this.passengers.size() == 1 && this.passengers.get(0) == passenger) { this.passengers = ImmutableList.of(); } else { -@@ -2183,6 +_,7 @@ +@@ -2351,6 +_,7 @@ passenger.boardingCooldown = 60; this.gameEvent(GameEvent.ENTITY_DISMOUNT, passenger); } @@ -1188,7 +1280,7 @@ } protected boolean canAddPassenger(Entity passenger) { -@@ -2266,8 +_,8 @@ +@@ -2434,8 +_,8 @@ TeleportTransition portalDestination = this.portalProcess.getPortalDestination(serverLevel, this); if (portalDestination != null) { ServerLevel level = portalDestination.newLevel(); @@ -1199,7 +1291,7 @@ this.teleport(portalDestination); } } -@@ -2348,7 +_,7 @@ +@@ -2516,7 +_,7 @@ } public boolean isCrouching() { @@ -1208,7 +1300,7 @@ } public boolean isSprinting() { -@@ -2364,7 +_,7 @@ +@@ -2532,7 +_,7 @@ } public boolean isVisuallySwimming() { @@ -1217,7 +1309,7 @@ } public boolean isVisuallyCrawling() { -@@ -2372,6 +_,13 @@ +@@ -2540,6 +_,13 @@ } public void setSwimming(boolean swimming) { @@ -1231,7 +1323,7 @@ this.setSharedFlag(4, swimming); } -@@ -2410,6 +_,7 @@ +@@ -2578,6 +_,7 @@ @Nullable public PlayerTeam getTeam() { @@ -1239,7 +1331,7 @@ return this.level().getScoreboard().getPlayersTeam(this.getScoreboardName()); } -@@ -2426,7 +_,11 @@ +@@ -2594,7 +_,11 @@ } public void setInvisible(boolean invisible) { @@ -1252,7 +1344,7 @@ } public boolean getSharedFlag(int flag) { -@@ -2443,7 +_,7 @@ +@@ -2611,7 +_,7 @@ } public int getMaxAirSupply() { @@ -1261,7 +1353,7 @@ } public int getAirSupply() { -@@ -2451,10 +_,22 @@ +@@ -2619,10 +_,22 @@ } public void setAirSupply(int air) { @@ -1285,7 +1377,7 @@ this.setTicksFrozen(0); } -@@ -2481,11 +_,43 @@ +@@ -2649,11 +_,43 @@ public void thunderHit(ServerLevel level, LightningBolt lightning) { this.setRemainingFireTicks(this.remainingFireTicks + 1); @@ -1333,7 +1425,7 @@ } public void onAboveBubbleColumn(boolean downwards, BlockPos pos) { -@@ -2641,26 +_,30 @@ +@@ -2809,26 +_,30 @@ return this.removalReason != null ? String.format( Locale.ROOT, @@ -1367,7 +1459,7 @@ ); } -@@ -2684,6 +_,13 @@ +@@ -2852,6 +_,13 @@ } public void restoreFrom(Entity entity) { @@ -1378,10 +1470,10 @@ + this.bukkitEntity = bukkitEntity; + } + // Paper end - Forward CraftEntity in teleport command - CompoundTag compoundTag = entity.saveWithoutId(new CompoundTag()); - compoundTag.remove("Dimension"); - this.load(compoundTag); -@@ -2693,7 +_,56 @@ + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) { + TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector, entity.registryAccess()); + entity.saveWithoutId(tagValueOutput); +@@ -2864,7 +_,65 @@ @Nullable public Entity teleport(TeleportTransition teleportTransition) { @@ -1415,18 +1507,27 @@ + velocity = Vec3.ZERO; + } + if (this.portalProcess != null) { // if in a portal -+ org.bukkit.craftbukkit.entity.CraftEntity bukkitEntity = this.getBukkitEntity(); ++ org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); ++ org.bukkit.util.Vector before = bukkitEntity.getVelocity(); ++ org.bukkit.util.Vector after = org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity); + org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent( + bukkitEntity, + bukkitEntity.getLocation(), to.clone(), -+ bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(velocity) ++ before, after + ); + event.callEvent(); + + // Only change the target if actually needed, since we reset relative flags -+ if (!event.isCancelled() && event.getTo() != null && (!event.getTo().equals(event.getFrom()) || !event.getAfter().equals(event.getBefore()))) { // todo this looks broken -+ to = event.getTo().clone(); -+ velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getAfter()); ++ if (event.isCancelled() || !to.equals(event.getTo()) || !after.equals(event.getAfter())) { ++ if (event.isCancelled() || event.getTo() == null) { ++ org.bukkit.World toWorld = to.getWorld(); ++ to = event.getFrom().clone(); ++ to.setWorld(toWorld); // cancelling doesn't cancel the teleport just the position/velocity (old quirk) ++ velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getBefore()); ++ } else { ++ to = event.getTo().clone(); ++ velocity = org.bukkit.craftbukkit.util.CraftVector.toVec3(event.getAfter()); ++ } + teleportTransition = new TeleportTransition(((org.bukkit.craftbukkit.CraftWorld) to.getWorld()).getHandle(), org.bukkit.craftbukkit.util.CraftLocation.toVec3(to), velocity, to.getYaw(), to.getPitch(), teleportTransition.missingRespawnBlock(), teleportTransition.asPassenger(), Set.of(), teleportTransition.postTeleportTransition(), teleportTransition.cause()); + } + } @@ -1438,7 +1539,7 @@ ServerLevel level = teleportTransition.newLevel(); boolean flag = level.dimension() != serverLevel.dimension(); if (!teleportTransition.asPassenger()) { -@@ -2742,10 +_,15 @@ +@@ -2913,10 +_,15 @@ profilerFiller.pop(); return null; } else { @@ -1450,12 +1551,12 @@ entityx.restoreFrom(this); this.removeAfterChangingDimensions(); entityx.teleportSetPosition(PositionMoveRotation.of(teleportTransition), teleportTransition.relatives()); -- level.addDuringTeleport(entityx); -+ if (this.inWorld) level.addDuringTeleport(entityx); // CraftBukkit - Don't spawn the new entity if the current entity isn't spawned +- newLevel.addDuringTeleport(entityx); ++ if (this.inWorld) newLevel.addDuringTeleport(entityx); // CraftBukkit - Don't spawn the new entity if the current entity isn't spawned for (Entity entity2 : list) { entity2.startRiding(entityx, true); -@@ -2818,9 +_,17 @@ +@@ -2999,9 +_,17 @@ } protected void removeAfterChangingDimensions() { @@ -1474,9 +1575,9 @@ + } + // Paper end - Expand EntityUnleashEvent } - } -@@ -2828,11 +_,37 @@ + if (this instanceof WaypointTransmitter waypointTransmitter && this.level instanceof ServerLevel serverLevel) { +@@ -3013,11 +_,37 @@ return PortalShape.getRelativePosition(portal, axis, this.position(), this.getDimensions(this.getPose())); } @@ -1514,7 +1615,7 @@ if (fromLevel.dimension() == Level.END && toLevel.dimension() == Level.OVERWORLD) { for (Entity entity : this.getPassengers()) { if (entity instanceof ServerPlayer serverPlayer && !serverPlayer.seenCredits) { -@@ -2940,8 +_,14 @@ +@@ -3125,8 +_,14 @@ return this.entityData.get(DATA_CUSTOM_NAME_VISIBLE); } @@ -1531,7 +1632,7 @@ return entity != null; } -@@ -3055,7 +_,26 @@ +@@ -3240,7 +_,26 @@ } public final void setBoundingBox(AABB bb) { @@ -1559,7 +1660,7 @@ } public final float getEyeHeight(Pose pose) { -@@ -3099,6 +_,12 @@ +@@ -3272,6 +_,12 @@ } public void stopSeenByPlayer(ServerPlayer serverPlayer) { @@ -1572,7 +1673,7 @@ } public float rotate(Rotation transformRotation) { -@@ -3132,7 +_,7 @@ +@@ -3305,7 +_,7 @@ } @Nullable @@ -1581,7 +1682,7 @@ return null; } -@@ -3164,21 +_,32 @@ +@@ -3337,21 +_,32 @@ } private Stream getIndirectPassengersStream() { @@ -1615,7 +1716,7 @@ } public int countPlayerPassengers() { -@@ -3186,6 +_,7 @@ +@@ -3359,6 +_,7 @@ } public boolean hasExactlyOnePlayerPassenger() { @@ -1623,8 +1724,8 @@ return this.countPlayerPassengers() == 1; } -@@ -3268,9 +_,38 @@ - return 1; +@@ -3441,9 +_,38 @@ + return 0; } + // CraftBukkit start @@ -1663,7 +1764,7 @@ ); } -@@ -3328,6 +_,11 @@ +@@ -3501,6 +_,11 @@ vec3 = vec3.add(flow); i++; } @@ -1675,7 +1776,7 @@ } } } -@@ -3425,7 +_,9 @@ +@@ -3598,7 +_,9 @@ } public void setDeltaMovement(Vec3 deltaMovement) { @@ -1685,7 +1786,7 @@ } public void addDeltaMovement(Vec3 addend) { -@@ -3488,9 +_,45 @@ +@@ -3661,9 +_,45 @@ return this.getZ((2.0 * this.random.nextDouble() - 1.0) * scale); } @@ -1731,9 +1832,9 @@ int floor = Mth.floor(x); int floor1 = Mth.floor(y); int floor2 = Mth.floor(z); -@@ -3504,6 +_,12 @@ - - this.levelCallback.onMove(); +@@ -3686,6 +_,12 @@ + } + } } + // Paper start - Block invalid positions and bounding box; don't allow desync of pos and AABB + // hanging has its own special logic @@ -1744,7 +1845,7 @@ } public void checkDespawn() { -@@ -3543,6 +_,12 @@ +@@ -3739,6 +_,12 @@ return this.getTicksFrozen() > 0; } @@ -1757,7 +1858,7 @@ public float getYRot() { return this.yRot; } -@@ -3593,7 +_,9 @@ +@@ -3789,7 +_,9 @@ } @Override @@ -1768,7 +1869,7 @@ if (this.removalReason == null) { this.removalReason = removalReason; } -@@ -3605,12 +_,28 @@ +@@ -3801,12 +_,28 @@ this.getPassengers().forEach(Entity::stopRiding); this.levelCallback.onRemove(removalReason); this.onRemoval(removalReason); @@ -1797,7 +1898,7 @@ @Override public void setLevelCallback(EntityInLevelCallback levelCallback) { this.levelCallback = levelCallback; -@@ -3780,4 +_,14 @@ +@@ -3991,4 +_,14 @@ return this.save; } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/EntitySelector.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/EntitySelector.java.patch index 8f2df071ba..df8244216b 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/EntitySelector.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/EntitySelector.java.patch @@ -2,7 +2,7 @@ +++ b/net/minecraft/world/entity/EntitySelector.java @@ -17,6 +_,22 @@ public static final Predicate NO_SPECTATORS = entity -> !entity.isSpectator(); - public static final Predicate CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(Entity::canBeCollidedWith); + public static final Predicate CAN_BE_COLLIDED_WITH = NO_SPECTATORS.and(entity -> entity.canBeCollidedWith(null)); public static final Predicate CAN_BE_PICKED = NO_SPECTATORS.and(Entity::isPickable); + // Paper start - Ability to control player's insomnia and phantoms + public static Predicate IS_INSOMNIAC = (player) -> { @@ -38,12 +38,13 @@ return (Predicate)(collisionRule == Team.CollisionRule.NEVER ? Predicates.alwaysFalse() : NO_SPECTATORS.and( - pushedEntity -> { -- if (!pushedEntity.isPushable()) { +- entity1 -> { +- if (!entity1.isPushable()) { ++ entity1 -> { final Entity pushedEntity = entity1; // Paper - OBFHELPER + if (!pushedEntity.isCollidable(ignoreClimbing) || !pushedEntity.canCollideWithBukkit(entity) || !entity.canCollideWithBukkit(pushedEntity)) { // CraftBukkit - collidable API // Paper - Climbing should not bypass cramming gamerule return false; - } else if (!entity.level().isClientSide || pushedEntity instanceof Player player && player.isLocalPlayer()) { - Team team1 = pushedEntity.getTeam(); + } else if (!entity.level().isClientSide || entity1 instanceof Player player && player.isLocalPlayer()) { + Team team1 = entity1.getTeam(); Team.CollisionRule collisionRule1 = team1 == null ? Team.CollisionRule.ALWAYS : team1.getCollisionRule(); - if (collisionRule1 == Team.CollisionRule.NEVER) { + if (collisionRule1 == Team.CollisionRule.NEVER || (pushedEntity instanceof Player && !io.papermc.paper.configuration.GlobalConfiguration.get().collisions.enablePlayerCollisions)) { // Paper - Configurable player collision diff --git a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch index c07d1f48c9..7086a880cc 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/EntityType.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/EntityType.java +++ b/net/minecraft/world/entity/EntityType.java -@@ -216,7 +_,7 @@ +@@ -217,7 +_,7 @@ .fireImmune() .sized(6.0F, 0.5F) .clientTrackingRange(10) @@ -9,7 +9,7 @@ ); public static final EntityType ARMADILLO = register( "armadillo", EntityType.Builder.of(Armadillo::new, MobCategory.CREATURE).sized(0.7F, 0.65F).eyeHeight(0.26F).clientTrackingRange(10) -@@ -1145,6 +_,22 @@ +@@ -1155,6 +_,22 @@ boolean shouldOffsetY, boolean shouldOffsetYMore ) { @@ -32,7 +32,7 @@ Consumer consumer; if (spawnedFrom != null) { consumer = createDefaultStackConfig(level, spawnedFrom, owner); -@@ -1152,7 +_,7 @@ +@@ -1162,7 +_,7 @@ consumer = entity -> {}; } @@ -41,7 +41,7 @@ } public static Consumer createDefaultStackConfig(Level level, ItemStack stack, @Nullable LivingEntity owner) { -@@ -1169,19 +_,56 @@ +@@ -1179,19 +_,56 @@ public static Consumer appendCustomEntityStackConfig(Consumer consumer, Level level, ItemStack stack, @Nullable LivingEntity owner) { CustomData customData = stack.getOrDefault(DataComponents.ENTITY_DATA, CustomData.EMPTY); @@ -101,7 +101,7 @@ if (entity instanceof Mob mob) { mob.playAmbientSound(); } -@@ -1237,6 +_,15 @@ +@@ -1247,6 +_,15 @@ if (level.isClientSide || !entity.getType().onlyOpCanSetNbt() || owner instanceof Player player && server.getPlayerList().isOp(player.getGameProfile())) { @@ -117,25 +117,25 @@ customData.loadInto(entity); } } -@@ -1308,9 +_,20 @@ +@@ -1318,9 +_,20 @@ } - public static Optional create(CompoundTag tag, Level level, EntitySpawnReason spawnReason) { + public static Optional create(ValueInput input, Level level, EntitySpawnReason spawnReason) { + // Paper start - Don't fire sync event during generation -+ return create(tag, level, spawnReason, false); ++ return create(input, level, spawnReason, false); + } + -+ public static Optional create(CompoundTag tag, Level level, EntitySpawnReason spawnReason, boolean generation) { ++ public static Optional create(ValueInput input, Level level, EntitySpawnReason spawnReason, boolean generation) { + // Paper end - Don't fire sync event during generation return Util.ifElse( - by(tag).map(entityType -> entityType.create(level, spawnReason)), -- entity -> entity.load(tag), -+ // Paper start - Don't fire sync event during generation -+ entity -> { -+ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation -+ entity.load(tag); -+ }, -+ // Paper end - Don't fire sync event during generation - () -> LOGGER.warn("Skipping Entity with id {}", tag.getStringOr("id", "[invalid]")) + by(input).map(entityType -> entityType.create(level, spawnReason)), +- entity -> entity.load(input), ++ // Paper start - Don't fire sync event during generation ++ entity -> { ++ if (generation) entity.generation = true; // Paper - Don't fire sync event during generation ++ entity.load(input); ++ }, ++ // Paper end - Don't fire sync event during generation + () -> LOGGER.warn("Skipping Entity with id {}", input.getStringOr("id", "[invalid]")) ); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch index 295adfef55..3c45786a01 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ExperienceOrb.java.patch @@ -1,62 +1,67 @@ --- a/net/minecraft/world/entity/ExperienceOrb.java +++ b/net/minecraft/world/entity/ExperienceOrb.java -@@ -41,9 +_,54 @@ +@@ -44,13 +_,59 @@ @Nullable private Player followingPlayer; private final InterpolationHandler interpolation = new InterpolationHandler(this); -- + // Paper start + @Nullable + public java.util.UUID sourceEntityId; + @Nullable + public java.util.UUID triggerEntityId; + public org.bukkit.entity.ExperienceOrb.SpawnReason spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN; -+ -+ private void loadPaperNBT(CompoundTag tag) { -+ CompoundTag expData = tag.getCompoundOrEmpty("Paper.ExpData"); -+ if (expData.isEmpty()) { -+ return; -+ } -+ -+ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null); -+ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null); -+ expData.getString("reason").ifPresent(reason -> { -+ try { -+ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason); -+ } catch (Exception e) { -+ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason); -+ } + ++ private void loadPaperNBT(ValueInput input) { ++ input.read("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC).ifPresent(expData -> { ++ this.sourceEntityId = expData.read("source", net.minecraft.core.UUIDUtil.CODEC).orElse(null); ++ this.triggerEntityId = expData.read("trigger", net.minecraft.core.UUIDUtil.CODEC).orElse(null); ++ expData.getString("reason").ifPresent(reason -> { ++ try { ++ this.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.valueOf(reason); ++ } catch (Exception e) { ++ this.level().getCraftServer().getLogger().warning("Invalid spawnReason set for experience orb: " + e.getMessage() + " - " + reason); ++ } ++ }); + }); + } -+ private void savePaperNBT(CompoundTag tag) { -+ CompoundTag expData = new CompoundTag(); ++ private void savePaperNBT(ValueOutput output) { ++ net.minecraft.nbt.CompoundTag expData = new net.minecraft.nbt.CompoundTag(); + expData.storeNullable("source", net.minecraft.core.UUIDUtil.CODEC, this.sourceEntityId); + expData.storeNullable("trigger", net.minecraft.core.UUIDUtil.CODEC, this.triggerEntityId); + if (this.spawnReason != org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN) { + expData.putString("reason", this.spawnReason.name()); + } -+ tag.put("Paper.ExpData", expData); ++ output.store("Paper.ExpData", net.minecraft.nbt.CompoundTag.CODEC, expData); + } -+ -+ @Deprecated @io.papermc.paper.annotation.DoNotUse ++ // Paper end ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor public ExperienceOrb(Level level, double x, double y, double z, int value) { -+ this(level, x, y, z, value, null, null); +- this(level, new Vec3(x, y, z), Vec3.ZERO, value); ++ // Paper start - add reasons for orbs ++ this(level, x, y, z, value, null, null, null); + } -+ -+ public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) { -+ this(level, x, y, z, value, reason, triggerId, null); -+ } -+ + public ExperienceOrb(Level level, double x, double y, double z, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) { ++ this(level, new Vec3(x, y, z), Vec3.ZERO, value, reason, triggerId, sourceId); ++ // Paper end - add reasons for orbs + } + ++ @Deprecated @io.papermc.paper.annotation.DoNotUse // Paper - overload ctor + public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value) { ++ // Paper start - add reasons for orbs ++ this(level, pos, direction, value, null, null, null); ++ } ++ public ExperienceOrb(Level level, Vec3 pos, Vec3 direction, int value, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) { ++ // Paper end - add reasons for orbs this(EntityType.EXPERIENCE_ORB, level); ++ // Paper start - add reasons for orbs + this.sourceEntityId = sourceId != null ? sourceId.getUUID() : null; + this.triggerEntityId = triggerId != null ? triggerId.getUUID() : null; + this.spawnReason = reason != null ? reason : org.bukkit.entity.ExperienceOrb.SpawnReason.UNKNOWN; -+ // Paper end - this.setPos(x, y, z); - if (!this.level().isClientSide) { - this.setYRot((float)(this.random.nextDouble() * 360.0)); -@@ -119,12 +_,13 @@ ++ // Paper end - add reasons for orbs + this.setPos(pos); + if (!level.isClientSide) { + this.setYRot(this.random.nextFloat() * 360.0F); +@@ -147,12 +_,13 @@ this.age++; if (this.age >= 6000) { @@ -71,7 +76,7 @@ if (this.followingPlayer == null || this.followingPlayer.isSpectator() || this.followingPlayer.distanceToSqr(this) > 64.0) { Player nearestPlayer = this.level().getNearestPlayer(this, 8.0); if (nearestPlayer != null && !nearestPlayer.isSpectator() && !nearestPlayer.isDeadOrDying()) { -@@ -134,7 +_,24 @@ +@@ -162,7 +_,24 @@ } } @@ -97,26 +102,21 @@ Vec3 vec3 = new Vec3( this.followingPlayer.getX() - this.getX(), this.followingPlayer.getY() + this.followingPlayer.getEyeHeight() / 2.0 - this.getY(), -@@ -161,18 +_,29 @@ +@@ -193,18 +_,24 @@ } - public static void award(ServerLevel level, Vec3 pos, int amount) { -+ // Paper start - add reasons for orbs -+ award(level, pos, amount, null, null, null); + public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount) { ++ // Paper start - add reason to orbs ++ awardWithDirection(level, pos, direction, amount, null, null, null); + } -+ -+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId) { -+ award(level, pos, amount, reason, triggerId, null); -+ } -+ -+ public static void award(ServerLevel level, Vec3 pos, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) { -+ // Paper end - add reasons for orbs ++ public static void awardWithDirection(ServerLevel level, Vec3 pos, Vec3 direction, int amount, @Nullable org.bukkit.entity.ExperienceOrb.SpawnReason reason, @Nullable Entity triggerId, @Nullable Entity sourceId) { ++ // Paper end - add reason to orbs while (amount > 0) { int experienceValue = getExperienceValue(amount); amount -= experienceValue; if (!tryMergeToExisting(level, pos, experienceValue)) { -- level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue)); -+ level.addFreshEntity(new ExperienceOrb(level, pos.x(), pos.y(), pos.z(), experienceValue, reason, triggerId, sourceId)); // Paper - add reason +- level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue)); ++ level.addFreshEntity(new ExperienceOrb(level, pos, direction, experienceValue, reason, triggerId, sourceId)); // Paper - add reason to orbs } } } @@ -126,10 +126,10 @@ AABB aabb = AABB.ofSize(pos, 1.0, 1.0, 1.0); - int randomInt = level.getRandom().nextInt(40); + int randomInt = level.getRandom().nextInt(io.papermc.paper.configuration.GlobalConfiguration.get().misc.xpOrbGroupsPerArea.or(ORB_GROUPS_PER_AREA)); // Paper - Configure how many orb groups per area - List entities = level.getEntities(EntityTypeTest.forClass(ExperienceOrb.class), aabb, orb -> canMerge(orb, randomInt, amount)); - if (!entities.isEmpty()) { - ExperienceOrb experienceOrb = entities.get(0); -@@ -189,13 +_,18 @@ + List entities = level.getEntities( + EntityTypeTest.forClass(ExperienceOrb.class), aabb, experienceOrb1 -> canMerge(experienceOrb1, randomInt, amount) + ); +@@ -223,13 +_,18 @@ } private static boolean canMerge(ExperienceOrb orb, int amount, int other) { @@ -150,7 +150,7 @@ } private void setUnderwaterMovement() { -@@ -220,7 +_,7 @@ +@@ -254,7 +_,7 @@ this.markHurt(); this.health = (int)(this.health - amount); if (this.health <= 0) { @@ -159,24 +159,24 @@ } return true; -@@ -231,32 +_,34 @@ - public void addAdditionalSaveData(CompoundTag compound) { - compound.putShort("Health", (short)this.health); - compound.putShort("Age", (short)this.age); -- compound.putShort("Value", (short)this.getValue()); -+ compound.putInt("Value", this.getValue()); // Paper - save as Integer - compound.putInt("Count", this.count); -+ this.savePaperNBT(compound); // Paper +@@ -265,32 +_,34 @@ + protected void addAdditionalSaveData(ValueOutput output) { + output.putShort("Health", (short)this.health); + output.putShort("Age", (short)this.age); +- output.putShort("Value", (short)this.getValue()); ++ output.putInt("Value", this.getValue()); // Paper - save as Integer + output.putInt("Count", this.count); ++ this.savePaperNBT(output); // Paper } @Override - public void readAdditionalSaveData(CompoundTag compound) { - this.health = compound.getShortOr("Health", (short)5); - this.age = compound.getShortOr("Age", (short)0); -- this.setValue(compound.getShortOr("Value", (short)0)); -+ this.setValue(compound.getIntOr("Value", 0)); // Paper - load as Integer - this.count = compound.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1); -+ this.loadPaperNBT(compound); // Paper + protected void readAdditionalSaveData(ValueInput input) { + this.health = input.getShortOr("Health", (short)5); + this.age = input.getShortOr("Age", (short)0); +- this.setValue(input.getShortOr("Value", (short)0)); ++ this.setValue(input.getIntOr("Value", 0)); // Paper - load as Integer + this.count = input.read("Count", ExtraCodecs.POSITIVE_INT).orElse(1); ++ this.loadPaperNBT(input); // Paper } @Override @@ -200,9 +200,9 @@ } } } -@@ -270,9 +_,19 @@ +@@ -304,9 +_,19 @@ ItemStack itemStack = randomItemWith.get().itemStack(); - int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.serverLevel(), itemStack, value); + int i = EnchantmentHelper.modifyDurabilityToRepairFromXp(player.level(), itemStack, value); int min = Math.min(i, itemStack.getDamageValue()); + // CraftBukkit start + // Paper start - mending event @@ -221,7 +221,7 @@ if (i1 > 0) { return this.repairPlayerItems(player, i1); } -@@ -318,6 +_,24 @@ +@@ -352,6 +_,24 @@ } public static int getExperienceValue(int expValue) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch index 9da5f68808..a047e73e59 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Interaction.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/Interaction.java +++ b/net/minecraft/world/entity/Interaction.java -@@ -100,9 +_,16 @@ +@@ -101,9 +_,16 @@ @Override public boolean skipAttackInteraction(Entity entity) { if (entity instanceof Player player) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Leashable.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Leashable.java.patch index e4ab3df083..fa98a74a96 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Leashable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Leashable.java.patch @@ -1,18 +1,18 @@ --- a/net/minecraft/world/entity/Leashable.java +++ b/net/minecraft/world/entity/Leashable.java -@@ -56,6 +_,11 @@ +@@ -80,6 +_,11 @@ } - default void writeLeashData(CompoundTag tag, @Nullable Leashable.LeashData leashData) { + default void writeLeashData(ValueOutput output, @Nullable Leashable.LeashData leashData) { + // CraftBukkit start - SPIGOT-7487: Don't save (and possible drop) leash, when the holder was removed by a plugin + if (leashData != null && leashData.leashHolder != null && leashData.leashHolder.pluginRemoved) { + return; + } + // CraftBukkit end - tag.storeNullable("leash", Leashable.LeashData.CODEC, leashData); + output.storeNullable("leash", Leashable.LeashData.CODEC, leashData); } -@@ -75,7 +_,9 @@ +@@ -99,7 +_,9 @@ } if (entity.tickCount > 100) { @@ -22,7 +22,7 @@ entity.setLeashData(null); } } -@@ -99,7 +_,9 @@ +@@ -123,7 +_,9 @@ entity.onLeashRemoved(); if (entity.level() instanceof ServerLevel serverLevel) { if (dropItem) { @@ -32,7 +32,7 @@ } if (broadcastPacket) { -@@ -117,7 +_,15 @@ +@@ -143,7 +_,15 @@ if (leashData != null && leashData.leashHolder != null) { if (!entity.isAlive() || !leashData.leashHolder.isAlive()) { @@ -49,16 +49,29 @@ entity.dropLeash(); } else { entity.removeLeash(); -@@ -131,7 +_,7 @@ - return; - } - -- if (f > 10.0) { -+ if (f > entity.level().paperConfig().misc.maxLeashDistance.or(LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance +@@ -154,7 +_,7 @@ + if (leashHolder != null && leashHolder.level() == entity.level()) { + double d = entity.leashDistanceTo(leashHolder); + entity.whenLeashedTo(leashHolder); +- if (d > entity.leashSnapDistance()) { ++ if (d > entity.leashSnapDistanceOrConfig()) { // Paper - Configurable max leash distance + level.playSound(null, leashHolder.getX(), leashHolder.getY(), leashHolder.getZ(), SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F); entity.leashTooFarBehaviour(); - } else if (f > 6.0) { - entity.elasticRangeLeashBehaviour(leashHolder, f); -@@ -148,7 +_,21 @@ + } else if (d > entity.leashElasticDistance() - leashHolder.getBbWidth() - entity.getBbWidth() +@@ -175,6 +_,12 @@ + entity.checkFallDistanceAccumulation(); + } + ++ // Paper start - Configurable max leash distance ++ default double leashSnapDistanceOrConfig() { ++ if (!(this instanceof final Entity entity)) return leashSnapDistance(); ++ return entity.level().paperConfig().misc.maxLeashDistance.or(leashSnapDistance()); ++ } ++ // Paper end - Configurable max leash distance + default double leashSnapDistance() { + return 12.0; + } +@@ -196,7 +_,21 @@ } default void leashTooFarBehaviour() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LightningBolt.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LightningBolt.java.patch index ec4c7e1727..b3fba00ef7 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LightningBolt.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LightningBolt.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LightningBolt.java +++ b/net/minecraft/world/entity/LightningBolt.java -@@ -39,6 +_,7 @@ +@@ -40,6 +_,7 @@ private ServerPlayer cause; private final Set hitEntities = Sets.newHashSet(); private int blocksSetOnFire; @@ -8,7 +8,7 @@ public LightningBolt(EntityType entityType, Level level) { super(entityType, level); -@@ -76,7 +_,7 @@ +@@ -77,7 +_,7 @@ @Override public void tick() { super.tick(); @@ -17,7 +17,7 @@ if (this.level().isClientSide()) { this.level() .playLocalSound( -@@ -107,7 +_,7 @@ +@@ -108,7 +_,7 @@ } this.powerLightningRod(); @@ -26,7 +26,7 @@ this.gameEvent(GameEvent.LIGHTNING_STRIKE); } } -@@ -130,7 +_,7 @@ +@@ -131,7 +_,7 @@ } } @@ -35,7 +35,7 @@ } else if (this.life < -this.random.nextInt(10)) { this.flashes--; this.life = 1; -@@ -139,10 +_,10 @@ +@@ -140,10 +_,10 @@ } } @@ -48,7 +48,7 @@ List entities = this.level() .getEntities( this, -@@ -168,26 +_,34 @@ +@@ -169,26 +_,34 @@ } private void spawnFire(int extraIgnitions) { @@ -89,7 +89,7 @@ BlockState blockState = level.getBlockState(pos); BlockPos blockPos; BlockState blockState1; -@@ -200,22 +_,27 @@ +@@ -201,22 +_,27 @@ } if (blockState1.getBlock() instanceof WeatheringCopper) { @@ -121,7 +121,7 @@ if (optional.isEmpty()) { break; } -@@ -224,11 +_,17 @@ +@@ -225,11 +_,17 @@ } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch index 8778cc24ea..3553abdf60 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/LivingEntity.java +++ b/net/minecraft/world/entity/LivingEntity.java -@@ -135,6 +_,17 @@ +@@ -138,6 +_,17 @@ import org.jetbrains.annotations.Contract; import org.slf4j.Logger; @@ -15,13 +15,13 @@ +import org.bukkit.event.entity.EntityResurrectEvent; +// CraftBukkit end + - public abstract class LivingEntity extends Entity implements Attackable { + public abstract class LivingEntity extends Entity implements Attackable, WaypointTransmitter { private static final Logger LOGGER = LogUtils.getLogger(); private static final String TAG_ACTIVE_EFFECTS = "active_effects"; -@@ -251,11 +_,25 @@ - EquipmentSlot.class +@@ -264,11 +_,25 @@ ); protected final EntityEquipment equipment; + private Waypoint.Icon locatorBarIcon = new Waypoint.Icon(); + // CraftBukkit start + public int expToDrop; + public List drops = new java.util.ArrayList<>(); // Paper - Restore vanilla drops behavior @@ -45,7 +45,7 @@ this.equipment = this.createEquipment(); this.blocksBuilding = true; this.reapplyPosition(); -@@ -350,7 +_,13 @@ +@@ -364,7 +_,13 @@ double d1 = Math.min(0.2F + d / 15.0, 2.5); int i = (int)(150.0 * d1); @@ -60,7 +60,7 @@ } } -@@ -535,7 +_,7 @@ +@@ -549,7 +_,7 @@ this.deathTime++; if (this.deathTime >= 20 && !this.level().isClientSide() && !this.isRemoved()) { this.level().broadcastEntityEvent(this, (byte)60); @@ -69,7 +69,7 @@ } } -@@ -640,7 +_,7 @@ +@@ -654,7 +_,7 @@ } public boolean shouldDiscardFriction() { @@ -78,7 +78,7 @@ } public void setDiscardFriction(boolean discardFriction) { -@@ -652,10 +_,15 @@ +@@ -666,10 +_,15 @@ } public void onEquipItem(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem) { @@ -95,7 +95,7 @@ this.level() .playSeededSound( null, -@@ -682,12 +_,12 @@ +@@ -696,12 +_,12 @@ } @Override @@ -110,7 +110,7 @@ this.brain.clearMemories(); } -@@ -696,11 +_,17 @@ +@@ -718,11 +_,17 @@ mobEffectInstance.onMobRemoved(level, this, removalReason); } @@ -119,16 +119,16 @@ } @Override - public void addAdditionalSaveData(CompoundTag compound) { + protected void addAdditionalSaveData(ValueOutput output) { + // Paper start - Friction API + if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { -+ compound.putString("Paper.FrictionState", this.frictionState.toString()); ++ output.putString("Paper.FrictionState", this.frictionState.toString()); + } + // Paper end - Friction API - compound.putFloat("Health", this.getHealth()); - compound.putShort("HurtTime", (short)this.hurtTime); - compound.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp); -@@ -731,8 +_,15 @@ + output.putFloat("Health", this.getHealth()); + output.putShort("HurtTime", (short)this.hurtTime); + output.putInt("HurtByTimestamp", this.lastHurtByMobTimestamp); +@@ -756,8 +_,15 @@ } } @@ -146,7 +146,7 @@ if (stack.isEmpty()) { return null; } else if (this.level().isClientSide) { -@@ -741,6 +_,31 @@ +@@ -766,6 +_,31 @@ } else { ItemEntity itemEntity = this.createItemStackToDrop(stack, randomizeMotion, includeThrower); if (itemEntity != null) { @@ -178,20 +178,20 @@ this.level().addFreshEntity(itemEntity); } -@@ -750,7 +_,22 @@ +@@ -775,7 +_,22 @@ @Override - public void readAdditionalSaveData(CompoundTag compound) { -- this.internalSetAbsorptionAmount(compound.getFloatOr("AbsorptionAmount", 0.0F)); + protected void readAdditionalSaveData(ValueInput input) { +- this.internalSetAbsorptionAmount(input.getFloatOr("AbsorptionAmount", 0.0F)); + // Paper start - Check for NaN -+ float absorptionAmount = compound.getFloatOr("AbsorptionAmount", 0.0F); ++ float absorptionAmount = input.getFloatOr("AbsorptionAmount", 0.0F); + if (Float.isNaN(absorptionAmount)) { + absorptionAmount = 0; + } + this.internalSetAbsorptionAmount(absorptionAmount); + // Paper end - Check for NaN + // Paper start - Friction API -+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> { ++ input.getString("Paper.FrictionState").ifPresent(frictionState -> { + try { + this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState); + } catch (Exception ignored) { @@ -200,32 +200,32 @@ + }); + // Paper end - Friction API if (this.level() != null && !this.level().isClientSide) { - compound.getList("attributes").ifPresent(this.getAttributes()::load); + input.read("attributes", AttributeInstance.Packed.LIST_CODEC).ifPresent(this.getAttributes()::apply); } -@@ -763,6 +_,11 @@ +@@ -787,6 +_,11 @@ this.activeEffects.put(mobEffectInstance.getEffect(), mobEffectInstance); } + // CraftBukkit start -+ compound.getDouble("Bukkit.MaxHealth").ifPresent(maxHealth -> { ++ input.read("Bukkit.MaxHealth", com.mojang.serialization.Codec.DOUBLE).ifPresent(maxHealth -> { + this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(maxHealth); + }); + // CraftBukkit end - this.setHealth(compound.getFloatOr("Health", this.getMaxHealth())); - this.hurtTime = compound.getShortOr("HurtTime", (short)0); - this.deathTime = compound.getShortOr("DeathTime", (short)0); -@@ -770,6 +_,7 @@ - compound.getString("Team").ifPresent(string -> { + this.setHealth(input.getFloatOr("Health", this.getMaxHealth())); + this.hurtTime = input.getShortOr("HurtTime", (short)0); + this.deathTime = input.getShortOr("DeathTime", (short)0); +@@ -794,6 +_,7 @@ + input.getString("Team").ifPresent(string -> { Scoreboard scoreboard = this.level().getScoreboard(); PlayerTeam playerTeam = scoreboard.getPlayerTeam(string); + if (!this.level().paperConfig().scoreboards.allowNonPlayerEntitiesOnScoreboards && !(this instanceof net.minecraft.world.entity.player.Player)) { playerTeam = null; } // Paper - Perf: Disable Scoreboards for non players by default boolean flag = playerTeam != null && scoreboard.addPlayerToTeam(this.getStringUUID(), playerTeam); if (!flag) { LOGGER.warn("Unable to add mob to team \"{}\" (that team probably doesn't exist)", string); -@@ -777,11 +_,13 @@ +@@ -801,11 +_,13 @@ }); - this.setSharedFlag(7, compound.getBooleanOr("FallFlying", false)); - compound.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> { + this.setSharedFlag(7, input.getBooleanOr("FallFlying", false)); + input.read("sleeping_pos", BlockPos.CODEC).ifPresentOrElse(blockPos -> { + if (this.position().distanceToSqr(blockPos.getX(), blockPos.getY(), blockPos.getZ()) < Mth.square(16)) { // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong this.setSleepingPos(blockPos); this.entityData.set(DATA_POSE, Pose.SLEEPING); @@ -234,10 +234,10 @@ } + } // Paper - The sleeping pos will always also set the actual pos, so a desync suggests something is wrong }, this::clearSleepingPos); - compound.getCompound("Brain").ifPresent(compoundTag -> this.brain = this.makeBrain(new Dynamic<>(NbtOps.INSTANCE, compoundTag))); - this.lastHurtByPlayer = EntityReference.read(compound, "last_hurt_by_player"); -@@ -791,15 +_,44 @@ - this.equipment.setAll(compound.read("equipment", EntityEquipment.CODEC, registryOps).orElseGet(EntityEquipment::new)); + input.read("Brain", Codec.PASSTHROUGH).ifPresent(dynamic -> this.brain = this.makeBrain((Dynamic)dynamic)); + this.lastHurtByPlayer = EntityReference.read(input, "last_hurt_by_player"); +@@ -816,15 +_,44 @@ + this.locatorBarIcon = input.read("locator_bar_icon", Waypoint.Icon.CODEC).orElseGet(Waypoint.Icon::new); } + // CraftBukkit start @@ -281,7 +281,7 @@ iterator.remove(); this.onEffectsRemoved(List.of(mobEffectInstance)); } else if (mobEffectInstance.getDuration() % 600 == 0) { -@@ -809,6 +_,17 @@ +@@ -834,6 +_,17 @@ } catch (ConcurrentModificationException var6) { } @@ -299,7 +299,7 @@ if (this.effectsDirty) { this.updateInvisibilityStatus(); this.updateGlowingStatus(); -@@ -916,15 +_,33 @@ +@@ -941,15 +_,33 @@ } public boolean removeAllEffects() { @@ -337,7 +337,7 @@ } } -@@ -951,21 +_,57 @@ +@@ -976,21 +_,57 @@ } public final boolean addEffect(MobEffectInstance effectInstance) { @@ -397,7 +397,7 @@ this.onEffectUpdated(mobEffectInstance, true, entity); flag = true; } -@@ -1004,11 +_,37 @@ +@@ -1029,11 +_,37 @@ @Nullable public final MobEffectInstance removeEffectNoUpdate(Holder effect) { @@ -436,7 +436,7 @@ if (mobEffectInstance != null) { this.onEffectsRemoved(List.of(mobEffectInstance)); return true; -@@ -1092,17 +_,62 @@ +@@ -1124,17 +_,62 @@ } public void heal(float healAmount) { @@ -500,7 +500,7 @@ this.entityData.set(DATA_HEALTH_ID, Mth.clamp(health, 0.0F, this.getMaxHealth())); } -@@ -1114,7 +_,7 @@ +@@ -1146,7 +_,7 @@ public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { if (this.isInvulnerableTo(level, damageSource)) { return false; @@ -509,15 +509,14 @@ return false; } else if (damageSource.is(DamageTypeTags.IS_FIRE) && this.hasEffect(MobEffects.FIRE_RESISTANCE)) { return false; -@@ -1128,35 +_,59 @@ - amount = 0.0F; +@@ -1161,35 +_,58 @@ } + float originAmount = amount; - float f1 = this.applyItemBlocking(level, damageSource, amount); - amount -= f1; -+ final float originalAmount = amount; // Paper - revert to vanilla #hurt - OBFHELPER + float f1 = this.applyItemBlocking(level, damageSource, amount, true); // Paper -+ // Paper end ++ // amount -= f1; // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to allow modification boolean flag = f1 > 0.0F; - if (damageSource.is(DamageTypeTags.IS_FREEZING) && this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES)) { + // CraftBukkit - Moved into handleEntityDamage(DamageSource, float) to get amount @@ -554,7 +553,7 @@ + if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) { // Paper - fix invulnerability reduction in EntityDamageEvent - no longer subtract lastHurt, that is part of the damage event calc now + return false; + } -+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. ++ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. + // CraftBukkit end this.lastHurt = amount; flag1 = false; @@ -567,7 +566,7 @@ + if (!this.actuallyHurt(level, damageSource, (float) event.getFinalDamage(), event)) { + return false; + } -+ if (this instanceof ServerPlayer && event.getDamage() == 0 && originalAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. ++ if (this instanceof ServerPlayer && event.getDamage() == 0 && originAmount == 0) return false; // Paper - revert to vanilla damage - players are not affected by damage that is 0 - skip damage if the vanilla damage is 0 and was not modified by plugins in the event. this.lastHurt = amount; - this.invulnerableTime = 20; - this.actuallyHurt(level, damageSource, amount); @@ -577,7 +576,7 @@ this.hurtDuration = 10; this.hurtTime = this.hurtDuration; } -@@ -1171,7 +_,7 @@ +@@ -1204,7 +_,7 @@ level.broadcastDamageEvent(this, damageSource); } @@ -586,7 +585,7 @@ this.markHurt(); } -@@ -1186,8 +_,16 @@ +@@ -1219,8 +_,16 @@ d = damageSource.getSourcePosition().x() - this.getX(); d1 = damageSource.getSourcePosition().z() - this.getZ(); } @@ -604,7 +603,7 @@ if (!flag) { this.indicateDamage(d, d1); } -@@ -1196,19 +_,19 @@ +@@ -1229,19 +_,19 @@ if (this.isDeadOrDying()) { if (!this.checkTotemDeathProtection(damageSource)) { @@ -629,7 +628,7 @@ if (flag2) { this.lastDamageSource = damageSource; this.lastDamageStamp = this.level().getGameTime(); -@@ -1234,6 +_,12 @@ +@@ -1267,6 +_,12 @@ } public float applyItemBlocking(ServerLevel level, DamageSource damageSource, float damageAmount) { @@ -642,7 +641,7 @@ if (damageAmount <= 0.0F) { return 0.0F; } else { -@@ -1258,10 +_,12 @@ +@@ -1291,10 +_,12 @@ } float f = blocksAttacks.resolveBlockedDamage(damageSource, damageAmount, acos); @@ -656,7 +655,7 @@ return f; } -@@ -1272,6 +_,59 @@ +@@ -1305,6 +_,59 @@ } } @@ -716,7 +715,7 @@ public void playSecondaryHurtSound(DamageSource damageSource) { if (damageSource.is(DamageTypes.THORNS)) { SoundSource soundSource = this instanceof Player ? SoundSource.PLAYERS : SoundSource.HOSTILE; -@@ -1304,12 +_,24 @@ +@@ -1337,12 +_,24 @@ return EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class); } @@ -742,7 +741,7 @@ } private boolean checkTotemDeathProtection(DamageSource damageSource) { -@@ -1319,18 +_,39 @@ +@@ -1352,18 +_,39 @@ ItemStack itemStack = null; DeathProtection deathProtection = null; @@ -789,7 +788,7 @@ serverPlayer.awardStat(Stats.ITEM_USED.get(itemStack.getItem())); CriteriaTriggers.USED_TOTEM.trigger(serverPlayer, itemStack); this.gameEvent(GameEvent.ITEM_INTERACT_FINISH); -@@ -1389,6 +_,7 @@ +@@ -1422,6 +_,7 @@ if (!this.isRemoved() && !this.dead) { Entity entity = damageSource.getEntity(); LivingEntity killCredit = this.getKillCredit(); @@ -797,7 +796,7 @@ if (killCredit != null) { killCredit.awardKillScore(this, damageSource); } -@@ -1398,68 +_,141 @@ +@@ -1431,68 +_,141 @@ } if (!this.level().isClientSide && this.hasCustomName()) { @@ -945,14 +944,14 @@ + protected void dropExperience(ServerLevel level, @Nullable Entity entity) { + // CraftBukkit start - Update getExpReward() above if the removed if() changes! + if (!(this instanceof net.minecraft.world.entity.boss.enderdragon.EnderDragon)) { // CraftBukkit - SPIGOT-2420: Special case ender dragon will drop the xp over time -+ ExperienceOrb.award(level, this.position(), this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper ++ ExperienceOrb.awardWithDirection(level, this.position(), net.minecraft.world.phys.Vec3.ZERO, this.expToDrop, this instanceof ServerPlayer ? org.bukkit.entity.ExperienceOrb.SpawnReason.PLAYER_DEATH : org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, entity, this); // Paper + this.expToDrop = 0; + } + // CraftBukkit end } protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) { -@@ -1539,9 +_,14 @@ +@@ -1572,9 +_,14 @@ } public void knockback(double strength, double x, double z) { @@ -969,7 +968,7 @@ Vec3 deltaMovement = this.getDeltaMovement(); while (x * x + z * z < 1.0E-5F) { -@@ -1550,11 +_,22 @@ +@@ -1583,11 +_,22 @@ } Vec3 vec3 = new Vec3(x, 0.0, z).normalize().scale(strength); @@ -993,7 +992,7 @@ } } -@@ -1639,7 +_,7 @@ +@@ -1672,7 +_,7 @@ @Override public boolean isAlive() { @@ -1002,7 +1001,7 @@ } public boolean isLookingAtMe(LivingEntity entity, double tolerance, boolean scaleByDistance, boolean visual, double... yValues) { -@@ -1673,9 +_,14 @@ +@@ -1706,9 +_,14 @@ boolean flag = super.causeFallDamage(fallDistance, damageMultiplier, damageSource); int i = this.calculateFallDamage(fallDistance, damageMultiplier); if (i > 0) { @@ -1018,7 +1017,7 @@ return true; } else { return flag; -@@ -1740,7 +_,7 @@ +@@ -1773,7 +_,7 @@ protected float getDamageAfterArmorAbsorb(DamageSource damageSource, float damageAmount) { if (!damageSource.is(DamageTypeTags.BYPASSES_ARMOR)) { @@ -1027,7 +1026,7 @@ damageAmount = CombatRules.getDamageAfterAbsorb( this, damageAmount, damageSource, this.getArmorValue(), (float)this.getAttributeValue(Attributes.ARMOR_TOUGHNESS) ); -@@ -1753,7 +_,8 @@ +@@ -1786,7 +_,8 @@ if (damageSource.is(DamageTypeTags.BYPASSES_EFFECTS)) { return damageAmount; } else { @@ -1037,7 +1036,7 @@ int i = (this.getEffect(MobEffects.RESISTANCE).getAmplifier() + 1) * 5; int i1 = 25 - i; float f = damageAmount * i1; -@@ -1790,24 +_,201 @@ +@@ -1823,24 +_,201 @@ } } @@ -1249,7 +1248,7 @@ } public CombatTracker getCombatTracker() { -@@ -1836,7 +_,17 @@ +@@ -1869,7 +_,17 @@ } public final void setArrowCount(int count) { @@ -1268,7 +1267,7 @@ } public final int getStingerCount() { -@@ -1991,7 +_,7 @@ +@@ -2024,7 +_,7 @@ @Override protected void onBelowWorld() { @@ -1277,7 +1276,7 @@ } protected void updateSwingTime() { -@@ -2087,8 +_,15 @@ +@@ -2120,8 +_,15 @@ } public void setItemSlot(EquipmentSlot slot, ItemStack stack) { @@ -1295,7 +1294,7 @@ public float getArmorCoverPercentage() { int i = 0; -@@ -2180,14 +_,27 @@ +@@ -2213,14 +_,27 @@ return this.hasEffect(MobEffects.JUMP_BOOST) ? 0.1F * (this.getEffect(MobEffects.JUMP_BOOST).getAmplifier() + 1.0F) : 0.0F; } @@ -1323,7 +1322,7 @@ this.addDeltaMovement(new Vec3(-Mth.sin(f) * 0.2, 0.0, Mth.cos(f) * 0.2)); } -@@ -2327,8 +_,10 @@ +@@ -2380,8 +_,10 @@ } public void stopFallFlying() { @@ -1334,7 +1333,7 @@ } private Vec3 updateFallFlyingMovement(Vec3 deltaMovement) { -@@ -2454,7 +_,7 @@ +@@ -2507,7 +_,7 @@ } protected float getFlyingSpeed() { @@ -1343,7 +1342,7 @@ } public float getSpeed() { -@@ -2538,37 +_,15 @@ +@@ -2591,37 +_,15 @@ profilerFiller.pop(); profilerFiller.push("rangeChecks"); @@ -1390,7 +1389,7 @@ profilerFiller.pop(); if (this.isFallFlying()) { -@@ -2598,16 +_,39 @@ +@@ -2651,16 +_,39 @@ @Nullable private Map collectEquipmentChanges() { Map map = null; @@ -1430,7 +1429,7 @@ AttributeMap attributes = this.getAttributes(); if (!itemStack.isEmpty()) { this.stopLocationBasedEffects(itemStack, equipmentSlot, attributes); -@@ -2632,6 +_,8 @@ +@@ -2685,6 +_,8 @@ } } } @@ -1439,7 +1438,7 @@ } return map; -@@ -2663,7 +_,7 @@ +@@ -2716,7 +_,7 @@ list.add(Pair.of(equipmentSlot, itemStack1)); this.lastEquipmentItems.put(equipmentSlot, itemStack1); }); @@ -1448,7 +1447,7 @@ } protected void tickHeadTurn(float yBodyRot) { -@@ -2749,8 +_,10 @@ +@@ -2802,8 +_,10 @@ if (!flag || this.onGround() && !(fluidHeight > fluidJumpThreshold)) { if (!this.isInLava() || this.onGround() && !(fluidHeight > fluidJumpThreshold)) { if ((this.onGround() || flag && fluidHeight <= fluidJumpThreshold) && this.noJumpDelay == 0) { @@ -1459,7 +1458,7 @@ } } else { this.jumpInLiquid(FluidTags.LAVA); -@@ -2791,7 +_,7 @@ +@@ -2844,7 +_,7 @@ profilerFiller.pop(); if (this.level() instanceof ServerLevel serverLevel) { profilerFiller.push("freezing"); @@ -1468,7 +1467,7 @@ this.setTicksFrozen(Math.max(0, this.getTicksFrozen() - 2)); } -@@ -2812,6 +_,20 @@ +@@ -2865,6 +_,20 @@ this.pushEntities(); profilerFiller.pop(); @@ -1489,15 +1488,15 @@ if (this.level() instanceof ServerLevel serverLevel && this.isSensitiveToWater() && this.isInWaterOrRain()) { this.hurtServer(serverLevel, this.damageSources().drown(), 1.0F); } -@@ -2830,6 +_,7 @@ - this.checkSlowFallDistance(); +@@ -2887,6 +_,7 @@ + this.checkFallDistanceAccumulation(); if (!this.level().isClientSide) { if (!this.canGlide()) { + if (this.getSharedFlag(7) != false && !CraftEventFactory.callToggleGlideEvent(this, false).isCancelled()) // CraftBukkit this.setSharedFlag(7, false); return; } -@@ -2869,10 +_,25 @@ +@@ -2926,10 +_,25 @@ } protected void pushEntities() { @@ -1524,7 +1523,7 @@ if (_int > 0 && pushableEntities.size() > _int - 1 && this.random.nextInt(4) == 0) { int i = 0; -@@ -2888,7 +_,16 @@ +@@ -2945,7 +_,16 @@ } } @@ -1541,7 +1540,7 @@ this.doPush(entity1); } } -@@ -2930,9 +_,16 @@ +@@ -2987,9 +_,16 @@ @Override public void stopRiding() { @@ -1560,16 +1559,16 @@ this.dismountVehicle(vehicle); } } -@@ -2959,7 +_,7 @@ +@@ -3016,7 +_,7 @@ } public void onItemPickup(ItemEntity itemEntity) { - Entity owner = itemEntity.getOwner(); -+ Entity owner = itemEntity.thrower != null ? this.level().getGlobalPlayerByUUID(itemEntity.thrower) : null; // Paper - check global player list where appropriate ++ Entity owner = EntityReference.get(itemEntity.thrower, this.level()::getGlobalPlayerByUUID, Entity.class); // Paper - check global player list where appropriate if (owner instanceof ServerPlayer) { CriteriaTriggers.THROWN_ITEM_PICKED_UP_BY_ENTITY.trigger((ServerPlayer)owner, itemEntity.getItem(), this); } -@@ -2969,7 +_,7 @@ +@@ -3026,7 +_,7 @@ if (!entity.isRemoved() && !this.level().isClientSide && (entity instanceof ItemEntity || entity instanceof AbstractArrow || entity instanceof ExperienceOrb)) { @@ -1578,7 +1577,7 @@ } } -@@ -2983,7 +_,8 @@ +@@ -3040,7 +_,8 @@ } else { Vec3 vec3 = new Vec3(this.getX(), this.getEyeY(), this.getZ()); Vec3 vec31 = new Vec3(entity.getX(), y, entity.getZ()); @@ -1588,7 +1587,7 @@ } } -@@ -3003,13 +_,27 @@ +@@ -3060,13 +_,27 @@ @Override public boolean isPickable() { @@ -1619,7 +1618,7 @@ @Override public float getYHeadRot() { -@@ -3040,7 +_,7 @@ +@@ -3097,7 +_,7 @@ } public final void setAbsorptionAmount(float absorptionAmount) { @@ -1628,7 +1627,7 @@ } protected void internalSetAbsorptionAmount(float absorptionAmount) { -@@ -3067,6 +_,15 @@ +@@ -3124,6 +_,15 @@ return (this.entityData.get(DATA_LIVING_ENTITY_FLAGS) & 2) > 0 ? InteractionHand.OFF_HAND : InteractionHand.MAIN_HAND; } @@ -1644,7 +1643,7 @@ private void updatingUsingItem() { if (this.isUsingItem()) { if (ItemStack.isSameItem(this.getItemInHand(this.getUsedItemHand()), this.useItem)) { -@@ -3084,6 +_,11 @@ +@@ -3141,6 +_,11 @@ return null; } else { double d = this.getEyeY() - 0.3F; @@ -1656,7 +1655,7 @@ ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), d, this.getZ(), stack); itemEntity.setPickUpDelay(40); if (includeThrower) { -@@ -3115,7 +_,12 @@ +@@ -3172,7 +_,12 @@ protected void updateUsingItem(ItemStack usingItem) { usingItem.onUseTick(this.level(), this, this.getUseItemRemainingTicks()); @@ -1670,7 +1669,7 @@ this.completeUsingItem(); } } -@@ -3141,10 +_,19 @@ +@@ -3198,10 +_,19 @@ } public void startUsingItem(InteractionHand hand) { @@ -1692,7 +1691,7 @@ if (!this.level().isClientSide) { this.setLivingEntityFlag(1, true); this.setLivingEntityFlag(2, hand == InteractionHand.OFF_HAND); -@@ -3168,7 +_,10 @@ +@@ -3225,7 +_,10 @@ } } else if (!this.isUsingItem() && !this.useItem.isEmpty()) { this.useItem = ItemStack.EMPTY; @@ -1704,7 +1703,7 @@ } } } -@@ -3207,12 +_,49 @@ +@@ -3264,12 +_,49 @@ this.releaseUsingItem(); } else { if (!this.useItem.isEmpty() && this.isUsingItem()) { @@ -1755,7 +1754,7 @@ } } } -@@ -3237,6 +_,7 @@ +@@ -3294,6 +_,7 @@ ItemStack itemInHand = this.getItemInHand(this.getUsedItemHand()); if (!this.useItem.isEmpty() && ItemStack.isSameItem(itemInHand, this.useItem)) { this.useItem = itemInHand; @@ -1763,7 +1762,7 @@ this.useItem.releaseUsing(this.level(), this, this.getUseItemRemainingTicks()); if (this.useItem.useOnRelease()) { this.updatingUsingItem(); -@@ -3256,7 +_,10 @@ +@@ -3313,7 +_,10 @@ } this.useItem = ItemStack.EMPTY; @@ -1775,7 +1774,7 @@ } public boolean isBlocking() { -@@ -3280,6 +_,60 @@ +@@ -3337,6 +_,60 @@ } } @@ -1836,7 +1835,7 @@ public boolean isSuppressingSlidingDownLadder() { return this.isShiftKeyDown(); } -@@ -3298,6 +_,12 @@ +@@ -3355,6 +_,12 @@ } public boolean randomTeleport(double x, double y, double z, boolean broadcastTeleport) { @@ -1849,7 +1848,7 @@ double x1 = this.getX(); double y1 = this.getY(); double z1 = this.getZ(); -@@ -3320,16 +_,39 @@ +@@ -3377,16 +_,39 @@ } if (flag1) { @@ -1892,7 +1891,7 @@ } else { if (broadcastTeleport) { level.broadcastEntityEvent(this, (byte)46); -@@ -3339,7 +_,7 @@ +@@ -3396,7 +_,7 @@ pathfinderMob.getNavigation().stop(); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch index 2b7c135d39..74a0fcfb95 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/Mob.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/Mob.java +++ b/net/minecraft/world/entity/Mob.java -@@ -83,6 +_,14 @@ - import net.minecraft.world.phys.AABB; +@@ -82,6 +_,14 @@ + import net.minecraft.world.phys.Vec3; import net.minecraft.world.ticks.ContainerSingleItem; +// CraftBukkit start @@ -15,7 +15,7 @@ public abstract class Mob extends LivingEntity implements EquipmentUser, Leashable, Targeting { private static final EntityDataAccessor DATA_MOB_FLAGS_ID = SynchedEntityData.defineId(Mob.class, EntityDataSerializers.BYTE); private static final int MOB_FLAG_NO_AI = 1; -@@ -112,6 +_,7 @@ +@@ -115,6 +_,7 @@ private final BodyRotationControl bodyRotationControl; protected PathNavigation navigation; public GoalSelector goalSelector; @@ -23,15 +23,15 @@ public GoalSelector targetSelector; @Nullable private LivingEntity target; -@@ -126,6 +_,7 @@ +@@ -129,6 +_,7 @@ private Leashable.LeashData leashData; - private BlockPos restrictCenter = BlockPos.ZERO; - private float restrictRadius = -1.0F; + private BlockPos homePosition = BlockPos.ZERO; + private int homeRadius = -1; + public boolean aware = true; // CraftBukkit protected Mob(EntityType entityType, Level level) { super(entityType, level); -@@ -142,6 +_,12 @@ +@@ -145,6 +_,12 @@ } } @@ -44,7 +44,7 @@ protected void registerGoals() { } -@@ -222,7 +_,39 @@ +@@ -225,7 +_,39 @@ } public void setTarget(@Nullable LivingEntity target) { @@ -84,40 +84,40 @@ } @Override -@@ -358,13 +_,22 @@ +@@ -365,13 +_,22 @@ if (this.isNoAi()) { - compound.putBoolean("NoAI", this.isNoAi()); + output.putBoolean("NoAI", this.isNoAi()); } -+ compound.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit ++ output.putBoolean("Bukkit.Aware", this.aware); // CraftBukkit } @Override - public void readAdditionalSaveData(CompoundTag compound) { - super.readAdditionalSaveData(compound); -- this.setCanPickUpLoot(compound.getBooleanOr("CanPickUpLoot", false)); -- this.persistenceRequired = compound.getBooleanOr("PersistenceRequired", false); + protected void readAdditionalSaveData(ValueInput input) { + super.readAdditionalSaveData(input); +- this.setCanPickUpLoot(input.getBooleanOr("CanPickUpLoot", false)); +- this.persistenceRequired = input.getBooleanOr("PersistenceRequired", false); + // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it -+ boolean canPickUpLoot = compound.getBooleanOr("CanPickUpLoot", false); -+ if (isLevelAtLeast(compound, 1) || canPickUpLoot) { ++ boolean canPickUpLoot = input.getBooleanOr("CanPickUpLoot", false); ++ if (isLevelAtLeast(input, 1) || canPickUpLoot) { + this.setCanPickUpLoot(canPickUpLoot); + } -+ boolean persistenceRequired = compound.getBooleanOr("PersistenceRequired", false); -+ if (isLevelAtLeast(compound, 1) || persistenceRequired) { ++ boolean persistenceRequired = input.getBooleanOr("PersistenceRequired", false); ++ if (isLevelAtLeast(input, 1) || persistenceRequired) { + this.persistenceRequired = persistenceRequired; + } + // CraftBukkit end - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - this.dropChances = compound.read("drop_chances", DropChances.CODEC, registryOps).orElse(DropChances.DEFAULT); - this.readLeashData(compound); -@@ -372,6 +_,7 @@ - this.lootTable = compound.read("DeathLootTable", LootTable.KEY_CODEC); - this.lootTableSeed = compound.getLongOr("DeathLootTableSeed", 0L); - this.setNoAi(compound.getBooleanOr("NoAI", false)); -+ this.aware = compound.getBooleanOr("Bukkit.Aware", true); // CraftBukkit + this.dropChances = input.read("drop_chances", DropChances.CODEC).orElse(DropChances.DEFAULT); + this.readLeashData(input); + this.homeRadius = input.getIntOr("home_radius", -1); +@@ -383,6 +_,7 @@ + this.lootTable = input.read("DeathLootTable", LootTable.KEY_CODEC); + this.lootTableSeed = input.getLongOr("DeathLootTableSeed", 0L); + this.setNoAi(input.getBooleanOr("NoAI", false)); ++ this.aware = input.getBooleanOr("Bukkit.Aware", true); // CraftBukkit } @Override -@@ -433,6 +_,11 @@ +@@ -446,6 +_,11 @@ && !itemEntity.getItem().isEmpty() && !itemEntity.hasPickUpDelay() && this.wantsToPickUp(serverLevel, itemEntity.getItem())) { @@ -129,7 +129,7 @@ this.pickUpItem(serverLevel, itemEntity); } } -@@ -447,18 +_,24 @@ +@@ -460,18 +_,24 @@ protected void pickUpItem(ServerLevel level, ItemEntity entity) { ItemStack item = entity.getItem(); @@ -156,7 +156,7 @@ EquipmentSlot equipmentSlotForItem = this.getEquipmentSlotForItem(stack); if (!this.isEquippableInSlot(stack, equipmentSlotForItem)) { return ItemStack.EMPTY; -@@ -471,10 +_,18 @@ +@@ -484,10 +_,18 @@ canReplaceCurrentItem = itemBySlot.isEmpty(); } @@ -176,7 +176,7 @@ } ItemStack itemStack = equipmentSlotForItem.limit(stack); -@@ -591,22 +_,29 @@ +@@ -608,22 +_,29 @@ @Override public void checkDespawn() { if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.shouldDespawnInPeaceful()) { @@ -219,7 +219,7 @@ this.noActionTime = 0; } } -@@ -618,6 +_,15 @@ +@@ -635,6 +_,15 @@ @Override protected final void serverAiStep() { this.noActionTime++; @@ -235,7 +235,7 @@ ProfilerFiller profilerFiller = Profiler.get(); profilerFiller.push("sensing"); this.sensing.tick(); -@@ -793,14 +_,69 @@ +@@ -814,14 +_,69 @@ public boolean stillValid(Player player) { return player.getVehicle() == Mob.this || player.canInteractWithEntity(Mob.this, 4.0); } @@ -305,7 +305,7 @@ ItemStack itemBySlot = this.getItemBySlot(equipmentSlot); float f = this.dropChances.byEquipment(equipmentSlot); if (f != 0.0F) { -@@ -820,7 +_,13 @@ +@@ -841,7 +_,13 @@ } this.spawnAtLocation(level, itemBySlot); @@ -319,7 +319,7 @@ } } } -@@ -844,7 +_,9 @@ +@@ -865,7 +_,9 @@ set.add(equipmentSlot); } else if (this.dropChances.isPreserved(equipmentSlot)) { this.setItemSlot(equipmentSlot, ItemStack.EMPTY); @@ -329,7 +329,7 @@ } } } -@@ -1122,6 +_,21 @@ +@@ -1147,6 +_,21 @@ public T convertTo( EntityType entityType, ConversionParams conversionParams, EntitySpawnReason spawnReason, ConversionParams.AfterConversion afterConversion ) { @@ -351,7 +351,7 @@ if (this.isRemoved()) { return null; } else { -@@ -1130,13 +_,23 @@ +@@ -1155,13 +_,23 @@ return null; } else { conversionParams.type().convert(this, mob, conversionParams); @@ -378,7 +378,7 @@ } return mob; -@@ -1146,7 +_,18 @@ +@@ -1171,7 +_,18 @@ @Nullable public T convertTo(EntityType entityType, ConversionParams coversionParams, ConversionParams.AfterConversion afterConversion) { @@ -398,7 +398,7 @@ } @Nullable -@@ -1182,7 +_,17 @@ +@@ -1213,7 +_,17 @@ public boolean startRiding(Entity entity, boolean force) { boolean flag = super.startRiding(entity, force); if (flag && this.isLeashed()) { @@ -417,7 +417,7 @@ } return flag; -@@ -1270,7 +_,7 @@ +@@ -1296,7 +_,7 @@ float knockback = this.getKnockback(source, damageSource); if (knockback > 0.0F && source instanceof LivingEntity livingEntity) { livingEntity.knockback( diff --git a/paper-server/patches/sources/net/minecraft/world/entity/NeutralMob.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/NeutralMob.java.patch index ab85a3a712..7ad0e181f8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/NeutralMob.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/NeutralMob.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/NeutralMob.java +++ b/net/minecraft/world/entity/NeutralMob.java -@@ -35,9 +_,11 @@ +@@ -36,9 +_,11 @@ if (level instanceof ServerLevel serverLevel) { - UUID uuid = tag.read("AngryAt", UUIDUtil.CODEC).orElse(null); + UUID uuid = input.read("AngryAt", UUIDUtil.CODEC).orElse(null); this.setPersistentAngerTarget(uuid); - if ((uuid != null ? serverLevel.getEntity(uuid) : null) instanceof LivingEntity livingEntity) { - this.setTarget(livingEntity); @@ -15,7 +15,7 @@ } } -@@ -90,7 +_,7 @@ +@@ -91,7 +_,7 @@ default void stopBeingAngry() { this.setLastHurtByMob(null); this.setPersistentAngerTarget(null); @@ -24,7 +24,7 @@ this.setRemainingPersistentAngerTime(0); } -@@ -101,8 +_,24 @@ +@@ -102,8 +_,24 @@ void setTarget(@Nullable LivingEntity livingEntity); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch index 1911584dfd..636d2542f8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/OminousItemSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/OminousItemSpawner.java +++ b/net/minecraft/world/entity/OminousItemSpawner.java -@@ -79,7 +_,7 @@ +@@ -77,7 +_,7 @@ entity = this.spawnProjectile(serverLevel, projectileItem, item); } else { entity = new ItemEntity(serverLevel, this.getX(), this.getY(), this.getZ(), item); @@ -9,7 +9,7 @@ } serverLevel.levelEvent(3021, this.blockPosition(), 1); -@@ -93,7 +_,7 @@ +@@ -91,7 +_,7 @@ ProjectileItem.DispenseConfig dispenseConfig = projectileItem.createDispenseConfig(); dispenseConfig.overrideDispenseEvent().ifPresent(i -> level.levelEvent(i, this.blockPosition(), 0)); Direction direction = Direction.DOWN; @@ -18,7 +18,7 @@ projectileItem.asProjectile(level, this.position(), stack, direction), level, stack, -@@ -102,7 +_,7 @@ +@@ -100,7 +_,7 @@ direction.getStepZ(), dispenseConfig.power(), dispenseConfig.uncertainty() diff --git a/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch index 1c01a87d0e..f3c9030375 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch @@ -1,34 +1,15 @@ --- a/net/minecraft/world/entity/TamableAnimal.java +++ b/net/minecraft/world/entity/TamableAnimal.java -@@ -77,7 +_,7 @@ +@@ -75,7 +_,7 @@ } - this.orderedToSit = compound.getBooleanOr("Sitting", false); + this.orderedToSit = input.getBooleanOr("Sitting", false); - this.setInSittingPose(this.orderedToSit); + this.setInSittingPose(this.orderedToSit, false); // Paper - Add EntityToggleSitEvent } @Override -@@ -88,8 +_,16 @@ - @Override - public boolean handleLeashAtDistance(Entity leashHolder, float distance) { - if (this.isInSittingPose()) { -- if (distance > 10.0F) { -- this.dropLeash(); -+ if (distance > (float) this.level().paperConfig().misc.maxLeashDistance.or(Leashable.LEASH_TOO_FAR_DIST)) { // Paper - Configurable max leash distance -+ // Paper start - Expand EntityUnleashEvent -+ org.bukkit.event.entity.EntityUnleashEvent event = new org.bukkit.event.entity.EntityUnleashEvent(this.getBukkitEntity(), org.bukkit.event.entity.EntityUnleashEvent.UnleashReason.DISTANCE, true); -+ if (!event.callEvent()) return false; -+ if (event.isDropLeash()) { -+ this.dropLeash(); -+ } else { -+ this.removeLeash(); -+ } -+ // Paper end - Expand EntityUnleashEvent - } - - return false; -@@ -148,6 +_,13 @@ +@@ -133,6 +_,13 @@ } public void setInSittingPose(boolean sitting) { @@ -42,7 +23,7 @@ byte b = this.entityData.get(DATA_FLAGS_ID); if (sitting) { this.entityData.set(DATA_FLAGS_ID, (byte)(b | 1)); -@@ -230,7 +_,12 @@ +@@ -215,7 +_,12 @@ if (this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES) && this.getOwner() instanceof ServerPlayer serverPlayer) { @@ -56,7 +37,7 @@ } super.die(cause); -@@ -273,7 +_,14 @@ +@@ -258,7 +_,14 @@ if (!this.canTeleportTo(new BlockPos(x, y, z))) { return false; } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeInstance.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeInstance.java.patch index 6b9c2bc8e0..e0094dde9c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeInstance.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeInstance.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/attributes/AttributeInstance.java +++ b/net/minecraft/world/entity/ai/attributes/AttributeInstance.java -@@ -155,20 +_,20 @@ +@@ -151,20 +_,20 @@ double baseValue = this.getBaseValue(); for (AttributeModifier attributeModifier : this.getModifiersOrEmpty(AttributeModifier.Operation.ADD_VALUE)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeMap.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeMap.java.patch index 180c8aadff..0963597315 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeMap.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/AttributeMap.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/ai/attributes/AttributeMap.java +++ b/net/minecraft/world/entity/ai/attributes/AttributeMap.java @@ -148,4 +_,12 @@ - .ifPresent(attributeInstance -> attributeInstance.load(compoundOrEmpty)); + } } } + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/Attributes.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/Attributes.java.patch index 85d0966158..ae547448e8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/Attributes.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/attributes/Attributes.java.patch @@ -9,7 +9,7 @@ public static final Holder ATTACK_KNOCKBACK = register("attack_knockback", new RangedAttribute("attribute.name.attack_knockback", 0.0, 0.0, 5.0)); public static final Holder ATTACK_SPEED = register( "attack_speed", new RangedAttribute("attribute.name.attack_speed", 4.0, 0.0, 1024.0).setSyncable(true) -@@ -49,10 +_,10 @@ +@@ -52,10 +_,10 @@ ); public static final Holder LUCK = register("luck", new RangedAttribute("attribute.name.luck", 0.0, -1024.0, 1024.0).setSyncable(true)); public static final Holder MAX_ABSORPTION = register( @@ -22,7 +22,7 @@ ); public static final Holder MINING_EFFICIENCY = register( "mining_efficiency", new RangedAttribute("attribute.name.mining_efficiency", 0.0, 0.0, 1024.0).setSyncable(true) -@@ -61,7 +_,7 @@ +@@ -64,7 +_,7 @@ "movement_efficiency", new RangedAttribute("attribute.name.movement_efficiency", 0.0, 0.0, 1.0).setSyncable(true) ); public static final Holder MOVEMENT_SPEED = register( diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch index 0695aae31f..1ba0031bec 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java.patch @@ -1,23 +1,20 @@ --- a/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java +++ b/net/minecraft/world/entity/ai/behavior/BabyFollowAdult.java -@@ -24,8 +_,19 @@ - if (!mob.isBaby()) { - return false; - } else { -- AgeableMob ageableMob = instance.get(nearestVisibleAdult); -+ LivingEntity ageableMob = instance.get(nearestVisibleAdult); // CraftBukkit - type - if (mob.closerThan(ageableMob, followRange.getMaxValue() + 1) && !mob.closerThan(ageableMob, followRange.getMinValue())) { -+ // CraftBukkit start -+ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(mob, ageableMob, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER); -+ if (event.isCancelled()) { -+ return false; -+ } -+ if (event.getTarget() == null) { -+ nearestVisibleAdult.erase(); -+ return true; -+ } -+ ageableMob = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); -+ // CraftBukkit end - WalkTarget walkTarget1 = new WalkTarget( - new EntityTracker(ageableMob, false), speedModifier.apply(mob), followRange.getMinValue() - 1 - ); +@@ -30,6 +_,17 @@ + } else { + LivingEntity livingEntity = instance.get(memoryAccessor); + if (entity.closerThan(livingEntity, followRange.getMaxValue() + 1) && !entity.closerThan(livingEntity, followRange.getMinValue())) { ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(entity, livingEntity, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FOLLOW_LEADER); ++ if (event.isCancelled()) { ++ return false; ++ } ++ if (event.getTarget() == null) { ++ memoryAccessor.erase(); ++ return true; ++ } ++ livingEntity = ((org.bukkit.craftbukkit.entity.CraftLivingEntity) event.getTarget()).getHandle(); ++ // CraftBukkit end + WalkTarget walkTarget = new WalkTarget( + new EntityTracker(livingEntity, targetEyeHeight, targetEyeHeight), + speedModifier.apply(entity), diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/TemptGoal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/TemptGoal.java.patch index 96b15bc9f4..cd8fcb0799 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/TemptGoal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/goal/TemptGoal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ai/goal/TemptGoal.java +++ b/net/minecraft/world/entity/ai/goal/TemptGoal.java -@@ -21,7 +_,7 @@ +@@ -24,7 +_,7 @@ private double pRotX; private double pRotY; @Nullable @@ -9,7 +9,7 @@ private int calmDown; private boolean isRunning; private final Predicate items; -@@ -44,6 +_,15 @@ +@@ -57,6 +_,15 @@ } else { this.player = getServerLevel(this.mob) .getNearestPlayer(this.targetingConditions.range(this.mob.getAttributeValue(Attributes.TEMPT_RANGE)), this.mob); @@ -25,3 +25,21 @@ return this.player != null; } } +@@ -123,7 +_,7 @@ + this.mob.getNavigation().stop(); + } + +- protected void navigateTowards(Player player) { ++ protected void navigateTowards(LivingEntity player) { // Paper + this.mob.getNavigation().moveTo(player, this.speedModifier); + } + +@@ -142,7 +_,7 @@ + } + + @Override +- protected void navigateTowards(Player player) { ++ protected void navigateTowards(LivingEntity player) { // Paper + Vec3 vec3 = player.getEyePosition().subtract(this.mob.position()).scale(this.mob.getRandom().nextDouble()).add(this.mob.position()); + this.mob.getMoveControl().setWantedPosition(vec3.x, vec3.y, vec3.z, this.speedModifier); + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java.patch index 1880055015..512ed5d15d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ai/navigation/GroundPathNavigation.java.patch @@ -12,7 +12,7 @@ @@ -54,7 +_,7 @@ } - if (mutableBlockPos.getY() > this.level.getMinY()) { + if (mutableBlockPos.getY() >= this.level.getMinY()) { - return super.createPath(mutableBlockPos.above(), accuracy); + return super.createPath(mutableBlockPos.above(), entity, accuracy); // Paper - EntityPathfindEvent } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/ambient/Bat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/ambient/Bat.java.patch index 68b4b71bb3..878b146c0d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/ambient/Bat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/ambient/Bat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/ambient/Bat.java +++ b/net/minecraft/world/entity/ambient/Bat.java -@@ -86,7 +_,7 @@ +@@ -87,7 +_,7 @@ } @Override @@ -9,7 +9,7 @@ return false; } -@@ -140,13 +_,13 @@ +@@ -141,13 +_,13 @@ this.yHeadRot = this.random.nextInt(360); } @@ -25,7 +25,7 @@ this.setResting(false); if (!isSilent) { level.levelEvent(null, 1025, blockPos, 0); -@@ -179,7 +_,7 @@ +@@ -180,7 +_,7 @@ float f1 = Mth.wrapDegrees(f - this.getYRot()); this.zza = 0.5F; this.setYRot(this.getYRot() + f1); @@ -34,7 +34,7 @@ this.setResting(true); } } -@@ -204,7 +_,7 @@ +@@ -205,7 +_,7 @@ if (this.isInvulnerableTo(level, damageSource)) { return false; } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch index 7563c46eb1..91eccbe3ea 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Animal.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/entity/animal/Animal.java +++ b/net/minecraft/world/entity/animal/Animal.java -@@ -41,6 +_,7 @@ +@@ -42,6 +_,7 @@ public int inLove = 0; @Nullable - public UUID loveCause; + public EntityReference loveCause; + public @Nullable ItemStack breedItem; // CraftBukkit - Add breedItem variable protected Animal(EntityType entityType, Level level) { super(entityType, level); -@@ -80,9 +_,13 @@ +@@ -81,9 +_,13 @@ } @Override @@ -24,18 +24,18 @@ } @Override -@@ -138,8 +_,9 @@ +@@ -139,8 +_,9 @@ if (this.isFood(itemInHand)) { int age = this.getAge(); - if (!this.level().isClientSide && age == 0 && this.canFallInLove()) { + if (player instanceof ServerPlayer serverPlayer && age == 0 && this.canFallInLove()) { + final ItemStack breedCopy = itemInHand.copy(); // Paper - Fix EntityBreedEvent copying this.usePlayerItem(player, hand, itemInHand); -- this.setInLove(player); -+ this.setInLove(player, breedCopy); // Paper - Fix EntityBreedEvent copying +- this.setInLove(serverPlayer); ++ this.setInLove(serverPlayer, breedCopy); // Paper - Fix EntityBreedEvent copying this.playEatingSound(); return InteractionResult.SUCCESS_SERVER; } -@@ -176,8 +_,23 @@ +@@ -177,8 +_,23 @@ return this.inLove <= 0; } @@ -57,10 +57,10 @@ + } + this.inLove = entityEnterLoveModeEvent.getTicksInLove(); + // CraftBukkit end - if (player != null) { - this.loveCause = player.getUUID(); + if (player instanceof ServerPlayer serverPlayer) { + this.loveCause = new EntityReference<>(serverPlayer); } -@@ -220,23 +_,45 @@ +@@ -216,23 +_,45 @@ if (breedOffspring != null) { breedOffspring.setBaby(true); breedOffspring.snapTo(this.getX(), this.getY(), this.getZ(), 0.0F, 0.0F); @@ -108,7 +108,7 @@ - if (level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), this.getRandom().nextInt(7) + 1)); + if (experience > 0 && level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { // Paper - Call EntityBreedEvent -+ level.addFreshEntity(new ExperienceOrb(level, this.getX(), this.getY(), this.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper - Call EntityBreedEvent, add spawn context ++ level.addFreshEntity(new ExperienceOrb(level, this.position(), net.minecraft.world.phys.Vec3.ZERO, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, player, baby)); // Paper - Call EntityBreedEvent, add spawn context } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch index 95a5823013..6deb58704e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Bee.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Bee.java +++ b/net/minecraft/world/entity/animal/Bee.java -@@ -145,10 +_,26 @@ +@@ -146,10 +_,26 @@ Bee.BeeGoToHiveGoal goToHiveGoal; private Bee.BeeGoToKnownFlowerGoal goToKnownFlowerGoal; private int underWaterTicks; @@ -28,26 +28,26 @@ this.lookControl = new Bee.BeeLookControl(this); this.setPathfindingMalus(PathType.DANGER_FIRE, -1.0F); this.setPathfindingMalus(PathType.WATER, -1.0F); -@@ -195,9 +_,18 @@ +@@ -196,9 +_,18 @@ @Override - public void addAdditionalSaveData(CompoundTag compound) { + protected void addAdditionalSaveData(ValueOutput output) { + // CraftBukkit start - selectively save data -+ this.addAdditionalSaveData(compound, true); ++ this.addAdditionalSaveData(output, true); + } + + @Override -+ public void addAdditionalSaveData(CompoundTag compound, boolean saveAll) { ++ public void addAdditionalSaveData(ValueOutput output, boolean saveAll) { + // CraftBukkit end - super.addAdditionalSaveData(compound); + super.addAdditionalSaveData(output); + if (saveAll) { // Paper - compound.storeNullable("hive_pos", BlockPos.CODEC, this.hivePos); - compound.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos); + output.storeNullable("hive_pos", BlockPos.CODEC, this.hivePos); + output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos); + } // Paper - compound.putBoolean("HasNectar", this.hasNectar()); - compound.putBoolean("HasStung", this.hasStung()); - compound.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); -@@ -235,7 +_,7 @@ + output.putBoolean("HasNectar", this.hasNectar()); + output.putBoolean("HasStung", this.hasStung()); + output.putInt("TicksSincePollination", this.ticksWithoutNectarSinceExitingHive); +@@ -236,7 +_,7 @@ } if (i > 0) { @@ -56,7 +56,7 @@ } } -@@ -490,7 +_,11 @@ +@@ -491,7 +_,11 @@ if (this.hivePos == null) { return null; } else { @@ -69,7 +69,7 @@ } } -@@ -523,6 +_,7 @@ +@@ -524,6 +_,7 @@ } public void setRolling(boolean isRolling) { @@ -77,7 +77,7 @@ this.setFlag(2, isRolling); } -@@ -579,7 +_,7 @@ +@@ -580,7 +_,7 @@ if (beeInteractionEffect != null) { this.usePlayerItem(player, hand, itemInHand); if (!this.level().isClientSide) { @@ -86,7 +86,7 @@ } return InteractionResult.SUCCESS; -@@ -648,8 +_,9 @@ +@@ -649,8 +_,9 @@ if (this.isInvulnerableTo(level, damageSource)) { return false; } else { @@ -97,25 +97,7 @@ } } -@@ -770,7 +_,7 @@ - @VisibleForDebug - public class BeeGoToHiveGoal extends Bee.BaseBeeGoal { - public static final int MAX_TRAVELLING_TICKS = 2400; -- int travellingTicks = Bee.this.level().random.nextInt(10); -+ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues - private static final int MAX_BLACKLISTED_TARGETS = 3; - final List blacklistedTargets = Lists.newArrayList(); - @Nullable -@@ -886,7 +_,7 @@ - - public class BeeGoToKnownFlowerGoal extends Bee.BaseBeeGoal { - private static final int MAX_TRAVELLING_TICKS = 2400; -- int travellingTicks = Bee.this.level().random.nextInt(10); -+ int travellingTicks = Bee.this.random.nextInt(10); // CraftBukkit - SPIGOT-7495: Give Bees another chance and let them use their own random, avoid concurrency issues - - BeeGoToKnownFlowerGoal() { - this.setFlags(EnumSet.of(Goal.Flag.MOVE)); -@@ -983,7 +_,7 @@ +@@ -981,7 +_,7 @@ } } @@ -124,7 +106,7 @@ Bee.this.level().levelEvent(2011, blockPos, 15); Bee.this.level().setBlockAndUpdate(blockPos, blockState1); Bee.this.incrementNumCropsGrownSincePollination(); -@@ -1007,7 +_,7 @@ +@@ -1005,7 +_,7 @@ @Override protected void alertOther(Mob mob, LivingEntity target) { if (mob instanceof Bee && this.mob.hasLineOfSight(target)) { @@ -133,7 +115,7 @@ } } } -@@ -1165,7 +_,7 @@ +@@ -1163,7 +_,7 @@ Bee.this.dropFlower(); this.pollinating = false; Bee.this.remainingCooldownBeforeLocatingNewFlower = 200; diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch index a4c4e2b824..27a429e814 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Cat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Cat.java +++ b/net/minecraft/world/entity/animal/Cat.java -@@ -372,6 +_,11 @@ +@@ -373,6 +_,11 @@ if (item instanceof DyeItem dyeItem) { DyeColor dyeColor = dyeItem.getDyeColor(); if (dyeColor != this.getCollarColor()) { @@ -12,7 +12,7 @@ if (!this.level().isClientSide()) { this.setCollarColor(dyeColor); itemInHand.consume(1, player); -@@ -384,7 +_,7 @@ +@@ -385,7 +_,7 @@ if (!this.level().isClientSide()) { this.usePlayerItem(player, hand, itemInHand); FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD); @@ -21,7 +21,7 @@ this.playEatingSound(); } -@@ -446,7 +_,7 @@ +@@ -447,7 +_,7 @@ } private void tryToTame(Player player) { @@ -30,7 +30,7 @@ this.tame(player); this.setOrderedToSit(true); this.level().broadcastEntityEvent(this, (byte)7); -@@ -580,15 +_,20 @@ +@@ -581,15 +_,20 @@ .dropFromGiftLootTable( getServerLevel(this.cat), BuiltInLootTables.CAT_MORNING_GIFT, @@ -55,7 +55,7 @@ ); } -@@ -615,7 +_,7 @@ +@@ -616,7 +_,7 @@ static class CatTemptGoal extends TemptGoal { @Nullable diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch index 994a2e508d..7c745c39be 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Chicken.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Chicken.java +++ b/net/minecraft/world/entity/animal/Chicken.java -@@ -111,10 +_,12 @@ +@@ -112,10 +_,12 @@ this.flap = this.flap + this.flapping * 2.0F; if (this.level() instanceof ServerLevel serverLevel && this.isAlive() && !this.isBaby() && !this.isChickenJockey() && --this.eggTime <= 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch index f8650c2b36..d010ebedbd 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Dolphin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Dolphin.java +++ b/net/minecraft/world/entity/animal/Dolphin.java -@@ -98,6 +_,13 @@ +@@ -99,6 +_,13 @@ return EntityType.DOLPHIN.create(level, EntitySpawnReason.BREEDING); } @@ -14,7 +14,7 @@ @Override public float getAgeScale() { return this.isBaby() ? 0.65F : 1.0F; -@@ -182,7 +_,7 @@ +@@ -183,7 +_,7 @@ @Override public int getMaxAirSupply() { @@ -23,7 +23,7 @@ } @Override -@@ -215,11 +_,15 @@ +@@ -216,11 +_,15 @@ if (this.getItemBySlot(EquipmentSlot.MAINHAND).isEmpty()) { ItemStack item = entity.getItem(); if (this.canHoldItem(item)) { @@ -40,7 +40,7 @@ } } } -@@ -486,7 +_,7 @@ +@@ -487,7 +_,7 @@ @Override public void start() { @@ -49,7 +49,7 @@ } @Override -@@ -505,7 +_,7 @@ +@@ -506,7 +_,7 @@ } if (this.player.isSwimming() && this.player.level().random.nextInt(6) == 0) { @@ -58,7 +58,7 @@ } } } -@@ -575,7 +_,7 @@ +@@ -576,7 +_,7 @@ 0.3F * Mth.cos(Dolphin.this.getYRot() * (float) (Math.PI / 180.0)) * Mth.cos(Dolphin.this.getXRot() * (float) (Math.PI / 180.0)) + Mth.sin(f1) * f2 ); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch index ea7e36b5aa..9966eed6ef 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Fox.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/animal/Fox.java +++ b/net/minecraft/world/entity/animal/Fox.java -@@ -429,7 +_,7 @@ - compound.read("Trusted", TRUSTED_LIST_CODEC).orElse(List.of()).forEach(this::addTrustedEntity); - this.setSleeping(compound.getBooleanOr("Sleeping", false)); - this.setVariant(compound.read("Type", Fox.Variant.CODEC).orElse(Fox.Variant.DEFAULT)); -- this.setSitting(compound.getBooleanOr("Sitting", false)); -+ this.setSitting(compound.getBooleanOr("Sitting", false), false); // Paper - Add EntityToggleSitEvent - this.setIsCrouching(compound.getBooleanOr("Crouching", false)); +@@ -430,7 +_,7 @@ + input.read("Trusted", TRUSTED_LIST_CODEC).orElse(List.of()).forEach(this::addTrustedEntity); + this.setSleeping(input.getBooleanOr("Sleeping", false)); + this.setVariant(input.read("Type", Fox.Variant.CODEC).orElse(Fox.Variant.DEFAULT)); +- this.setSitting(input.getBooleanOr("Sitting", false)); ++ this.setSitting(input.getBooleanOr("Sitting", false), false); // Paper - Add EntityToggleSitEvent + this.setIsCrouching(input.getBooleanOr("Crouching", false)); if (this.level() instanceof ServerLevel) { this.setTargetGoals(); -@@ -446,6 +_,12 @@ +@@ -447,6 +_,12 @@ } public void setSitting(boolean sitting) { @@ -22,7 +22,7 @@ this.setFlag(1, sitting); } -@@ -505,19 +_,20 @@ +@@ -506,19 +_,20 @@ itemEntity.setPickUpDelay(40); itemEntity.setThrower(this); this.playSound(SoundEvents.FOX_SPIT, 1.0F, 1.0F); @@ -46,7 +46,7 @@ int count = item.getCount(); if (count > 1) { this.dropItemStack(item.split(count - 1)); -@@ -528,7 +_,7 @@ +@@ -529,7 +_,7 @@ this.setItemSlot(EquipmentSlot.MAINHAND, item.split(1)); this.setGuaranteedDrop(EquipmentSlot.MAINHAND); this.take(entity, item.getCount()); @@ -55,7 +55,7 @@ this.ticksSinceEaten = 0; } } -@@ -623,12 +_,12 @@ +@@ -620,12 +_,12 @@ } @Override @@ -70,7 +70,7 @@ } void wakeUp() { -@@ -692,15 +_,33 @@ +@@ -689,15 +_,33 @@ return this.getTrustedEntities().anyMatch(entityReference -> entityReference.matches(entity)); } @@ -108,7 +108,7 @@ } public static boolean isPathClear(Fox fox, LivingEntity livingEntity) { -@@ -876,6 +_,19 @@ +@@ -873,6 +_,19 @@ fox.addTrustedEntity(loveCause1); } @@ -128,7 +128,7 @@ if (serverPlayer != null) { serverPlayer.awardStat(Stats.ANIMALS_BRED); CriteriaTriggers.BRED_ANIMALS.trigger(serverPlayer, this.animal, this.partner, fox); -@@ -885,14 +_,12 @@ +@@ -882,14 +_,12 @@ this.partner.setAge(6000); this.animal.resetLove(); this.partner.resetLove(); @@ -142,11 +142,11 @@ this.level .addFreshEntity( - new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), this.animal.getRandom().nextInt(7) + 1) -+ new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper - call EntityBreedEvent, add spawn context ++ new ExperienceOrb(this.level, this.animal.position(), net.minecraft.world.phys.Vec3.ZERO, experience, org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, fox) // Paper - call EntityBreedEvent, add spawn context ); } } -@@ -956,6 +_,7 @@ +@@ -953,6 +_,7 @@ private void pickSweetBerries(BlockState state) { int ageValue = state.getValue(SweetBerryBushBlock.AGE); state.setValue(SweetBerryBushBlock.AGE, 1); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/HappyGhast.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/HappyGhast.java.patch new file mode 100644 index 0000000000..9c18ebef4f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/HappyGhast.java.patch @@ -0,0 +1,25 @@ +--- a/net/minecraft/world/entity/animal/HappyGhast.java ++++ b/net/minecraft/world/entity/animal/HappyGhast.java +@@ -296,8 +_,12 @@ + } + + @Override +- protected void removePassenger(Entity passenger) { +- super.removePassenger(passenger); ++ // Paper start - cancellable passengers ++ protected boolean removePassenger(Entity passenger, boolean suppressCancellation) { ++ if (!super.removePassenger(passenger, suppressCancellation)) { ++ return false; ++ } ++ // Paper end - cancellable passengers + if (!this.level().isClientSide) { + this.setServerStillTimeout(10); + } +@@ -306,6 +_,7 @@ + this.clearHome(); + this.level().playSound(null, this.getX(), this.getY(), this.getZ(), SoundEvents.HARNESS_GOGGLES_UP, this.getSoundSource(), 1.0F, 1.0F); + } ++ return true; // Paper - cancellable passengers + } + + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch index 99afa7baa3..4ba5d7aede 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/IronGolem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/IronGolem.java +++ b/net/minecraft/world/entity/animal/IronGolem.java -@@ -105,7 +_,7 @@ +@@ -106,7 +_,7 @@ @Override protected void doPush(Entity entity) { if (entity instanceof Enemy && !(entity instanceof Creeper) && this.getRandom().nextInt(20) == 0) { @@ -9,7 +9,7 @@ } super.doPush(entity); -@@ -304,7 +_,7 @@ +@@ -305,7 +_,7 @@ BlockPos blockPos = this.blockPosition(); BlockPos blockPos1 = blockPos.below(); BlockState blockState = level.getBlockState(blockPos1); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch index e86dfd8dd0..5c835faf11 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/MushroomCow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/MushroomCow.java +++ b/net/minecraft/world/entity/animal/MushroomCow.java -@@ -116,7 +_,17 @@ +@@ -117,7 +_,17 @@ return InteractionResult.SUCCESS; } else if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) { if (this.level() instanceof ServerLevel serverLevel) { @@ -19,7 +19,7 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); } -@@ -169,15 +_,31 @@ +@@ -170,15 +_,31 @@ @Override public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch index 78611a0894..f8eec553b4 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Ocelot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Ocelot.java +++ b/net/minecraft/world/entity/animal/Ocelot.java -@@ -126,7 +_,7 @@ +@@ -127,7 +_,7 @@ @Override public boolean removeWhenFarAway(double distanceToClosestPlayer) { @@ -9,7 +9,7 @@ } public static AttributeSupplier.Builder createAttributes() { -@@ -160,7 +_,7 @@ +@@ -161,7 +_,7 @@ if ((this.temptGoal == null || this.temptGoal.isRunning()) && !this.isTrusting() && this.isFood(itemInHand) && player.distanceToSqr(this) < 9.0) { this.usePlayerItem(player, hand, itemInHand); if (!this.level().isClientSide) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch index 1b200435d5..099ff8dd57 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Panda.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Panda.java +++ b/net/minecraft/world/entity/animal/Panda.java -@@ -128,6 +_,7 @@ +@@ -129,6 +_,7 @@ } public void sit(boolean sitting) { @@ -8,7 +8,7 @@ this.setFlag(8, sitting); } -@@ -517,24 +_,28 @@ +@@ -518,24 +_,28 @@ for (Panda panda : level.getEntitiesOfClass(Panda.class, this.getBoundingBox().inflate(10.0))) { if (!panda.isBaby() && panda.onGround() && !panda.isInWater() && panda.canPerformAction()) { @@ -39,7 +39,7 @@ } } -@@ -625,8 +_,9 @@ +@@ -626,8 +_,9 @@ this.usePlayerItem(player, hand, itemInHand); this.ageUp((int)(-this.getAge() / 20 * 0.1F), true); } else if (!this.level().isClientSide && this.getAge() == 0 && this.canFallInLove()) { @@ -50,7 +50,7 @@ } else { if (!(this.level() instanceof ServerLevel serverLevel) || this.isSitting() || this.isInWater()) { return InteractionResult.PASS; -@@ -636,7 +_,9 @@ +@@ -637,7 +_,9 @@ this.eat(true); ItemStack itemBySlot = this.getItemBySlot(EquipmentSlot.MAINHAND); if (!itemBySlot.isEmpty() && !player.hasInfiniteMaterials()) { @@ -60,7 +60,7 @@ } this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemInHand.getItem(), 1)); -@@ -858,7 +_,7 @@ +@@ -859,7 +_,7 @@ @Override protected void alertOther(Mob mob, LivingEntity target) { if (mob instanceof Panda && mob.isAggressive()) { @@ -69,7 +69,7 @@ } } } -@@ -1087,7 +_,9 @@ +@@ -1088,7 +_,9 @@ public void stop() { ItemStack itemBySlot = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND); if (!itemBySlot.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch index 055daec243..ff8593cfe2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Parrot.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Parrot.java +++ b/net/minecraft/world/entity/animal/Parrot.java -@@ -262,7 +_,7 @@ +@@ -264,7 +_,7 @@ } if (!this.level().isClientSide) { @@ -9,7 +9,7 @@ this.tame(player); this.level().broadcastEntityEvent(this, (byte)7); } else { -@@ -283,7 +_,7 @@ +@@ -285,7 +_,7 @@ } } else { this.usePlayerItem(player, hand, itemInHand); @@ -18,7 +18,7 @@ if (player.isCreative() || !this.isInvulnerable()) { this.hurt(this.damageSources().playerAttack(player), Float.MAX_VALUE); } -@@ -378,8 +_,8 @@ +@@ -380,8 +_,8 @@ } @Override @@ -29,7 +29,7 @@ } @Override -@@ -394,8 +_,13 @@ +@@ -396,8 +_,13 @@ if (this.isInvulnerableTo(level, damageSource)) { return false; } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch index 31833a8584..472c9720c0 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pig.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Pig.java +++ b/net/minecraft/world/entity/animal/Pig.java -@@ -214,7 +_,14 @@ +@@ -215,7 +_,14 @@ } mob.setPersistenceRequired(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch index 953de330eb..d6249c7280 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Pufferfish.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Pufferfish.java +++ b/net/minecraft/world/entity/animal/Pufferfish.java -@@ -96,24 +_,36 @@ +@@ -97,24 +_,36 @@ public void tick() { if (!this.level().isClientSide && this.isAlive() && this.isEffectiveAi()) { if (this.inflateCounter > 0) { @@ -37,7 +37,7 @@ this.deflateTimer++; } } -@@ -137,7 +_,7 @@ +@@ -138,7 +_,7 @@ private void touch(ServerLevel level, Mob mob) { int puffState = this.getPuffState(); if (mob.hurtServer(level, this.damageSources().mobAttack(this), 1 + puffState)) { @@ -46,7 +46,7 @@ this.playSound(SoundEvents.PUFFER_FISH_STING, 1.0F, 1.0F); } } -@@ -152,7 +_,7 @@ +@@ -153,7 +_,7 @@ serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.PUFFER_FISH_STING, 0.0F)); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch index 0c050dea51..9a80e4c1d1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Rabbit.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Rabbit.java +++ b/net/minecraft/world/entity/animal/Rabbit.java -@@ -95,7 +_,7 @@ +@@ -96,7 +_,7 @@ super(entityType, level); this.jumpControl = new Rabbit.RabbitJumpControl(this); this.moveControl = new Rabbit.RabbitMoveControl(this); @@ -9,7 +9,7 @@ } @Override -@@ -588,9 +_,11 @@ +@@ -589,9 +_,11 @@ if (this.canRaid && block instanceof CarrotBlock) { int ageValue = blockState.getValue(CarrotBlock.AGE); if (ageValue == 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch index 367ba239ff..1ad8681888 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/ShoulderRidingEntity.java.patch @@ -1,11 +1,11 @@ --- a/net/minecraft/world/entity/animal/ShoulderRidingEntity.java +++ b/net/minecraft/world/entity/animal/ShoulderRidingEntity.java -@@ -19,7 +_,7 @@ - compoundTag.putString("id", this.getEncodeId()); - this.saveWithoutId(compoundTag); - if (player.setEntityOnShoulder(compoundTag)) { -- this.discard(); -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause - return true; - } else { - return false; +@@ -24,7 +_,7 @@ + this.saveWithoutId(tagValueOutput); + tagValueOutput.putString("id", this.getEncodeId()); + if (player.setEntityOnShoulder(tagValueOutput.buildResult())) { +- this.discard(); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.PICKUP); // CraftBukkit - add Bukkit remove cause + return true; + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch index b839210207..4b9b81032d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/SnowGolem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/SnowGolem.java +++ b/net/minecraft/world/entity/animal/SnowGolem.java -@@ -91,7 +_,7 @@ +@@ -92,7 +_,7 @@ super.aiStep(); if (this.level() instanceof ServerLevel serverLevel) { if (this.level().getBiome(this.blockPosition()).is(BiomeTags.SNOW_GOLEM_MELTS)) { @@ -9,7 +9,7 @@ } if (!serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) { -@@ -106,7 +_,7 @@ +@@ -107,7 +_,7 @@ int floor2 = Mth.floor(this.getZ() + (i / 2 % 2 * 2 - 1) * 0.25F); BlockPos blockPos = new BlockPos(floor, floor1, floor2); if (this.level().getBlockState(blockPos).isAir() && blockState.canSurvive(this.level(), blockPos)) { @@ -18,7 +18,7 @@ this.level().gameEvent(GameEvent.BLOCK_PLACE, blockPos, GameEvent.Context.of(this, blockState)); } } -@@ -134,7 +_,19 @@ +@@ -135,7 +_,19 @@ ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) { if (this.level() instanceof ServerLevel serverLevel) { @@ -39,7 +39,7 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); } -@@ -147,11 +_,29 @@ +@@ -148,11 +_,29 @@ @Override public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch index 0f161b3e87..6f29caadf8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/Turtle.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/Turtle.java +++ b/net/minecraft/world/entity/animal/Turtle.java -@@ -259,7 +_,9 @@ +@@ -260,7 +_,9 @@ protected void ageBoundaryReached() { super.ageBoundaryReached(); if (!this.isBaby() && this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { @@ -10,7 +10,7 @@ } } -@@ -284,7 +_,7 @@ +@@ -285,7 +_,7 @@ @Override public void thunderHit(ServerLevel level, LightningBolt lightning) { @@ -19,7 +19,7 @@ } @Override -@@ -311,6 +_,10 @@ +@@ -312,6 +_,10 @@ if (loveCause == null && this.partner.getLoveCause() != null) { loveCause = this.partner.getLoveCause(); } @@ -30,16 +30,16 @@ if (loveCause != null) { loveCause.awardStat(Stats.ANIMALS_BRED); -@@ -324,7 +_,7 @@ +@@ -325,7 +_,7 @@ this.partner.resetLove(); RandomSource random = this.animal.getRandom(); if (getServerLevel(this.level).getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), random.nextInt(7) + 1)); -+ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.getX(), this.animal.getY(), this.animal.getZ(), event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause)); // Paper - Add EntityFertilizeEggEvent event ++ if (event.getExperience() > 0) this.level.addFreshEntity(new ExperienceOrb(this.level, this.animal.position(), Vec3.ZERO, event.getExperience(), org.bukkit.entity.ExperienceOrb.SpawnReason.BREED, loveCause, this.turtle)); // Paper - Add EntityFertilizeEggEvent event } } } -@@ -347,7 +_,7 @@ +@@ -348,7 +_,7 @@ && ( this.turtle.hasEgg() || this.turtle.getRandom().nextInt(reducedTickDelay(700)) == 0 && !this.turtle.homePos.closerToCenterThan(this.turtle.position(), 64.0) @@ -48,7 +48,7 @@ } @Override -@@ -455,14 +_,20 @@ +@@ -456,14 +_,20 @@ BlockPos blockPos = this.turtle.blockPosition(); if (!this.turtle.isInWater() && this.isReachedTarget()) { if (this.turtle.layEggCounter < 1) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/allay/Allay.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/allay/Allay.java.patch index 07430fe6ad..501fcea92a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/allay/Allay.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/allay/Allay.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/allay/Allay.java +++ b/net/minecraft/world/entity/animal/allay/Allay.java -@@ -116,6 +_,7 @@ +@@ -113,6 +_,7 @@ private float dancingAnimationTicks; private float spinningAnimationTicks; private float spinningAnimationTicks0; @@ -8,7 +8,7 @@ public Allay(EntityType entityType, Level level) { super(entityType, level); -@@ -129,6 +_,12 @@ +@@ -126,6 +_,12 @@ ); } @@ -21,7 +21,7 @@ @Override protected Brain.Provider brainProvider() { return Brain.provider(MEMORY_TYPES, SENSOR_TYPES); -@@ -248,7 +_,7 @@ +@@ -233,7 +_,7 @@ public void aiStep() { super.aiStep(); if (!this.level().isClientSide && this.isAlive() && this.tickCount % 10 == 0) { @@ -30,7 +30,7 @@ } if (this.isDancing() && this.shouldStopDancing() && this.tickCount % 20 == 0) { -@@ -316,7 +_,12 @@ +@@ -301,7 +_,12 @@ ItemStack itemInHand = player.getItemInHand(hand); ItemStack itemInHand1 = this.getItemInHand(InteractionHand.MAIN_HAND); if (this.isDancing() && itemInHand.is(ItemTags.DUPLICATES_ALLAYS) && this.canDuplicate()) { @@ -44,7 +44,7 @@ this.level().broadcastEntityEvent(this, (byte)18); this.level().playSound(player, this, SoundEvents.AMETHYST_BLOCK_CHIME, SoundSource.NEUTRAL, 2.0F, 1.0F); this.removeInteractionItem(player, itemInHand); -@@ -421,6 +_,7 @@ +@@ -406,6 +_,7 @@ } private boolean shouldStopDancing() { @@ -52,16 +52,16 @@ return this.jukeboxPos == null || !this.jukeboxPos.closerToCenterThan(this.position(), GameEvent.JUKEBOX_PLAY.value().notificationRadius()) || !this.level().getBlockState(this.jukeboxPos).is(Blocks.JUKEBOX); -@@ -475,7 +_,7 @@ - this.readInventoryFromTag(compound, this.registryAccess()); - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - this.vibrationData = compound.read("listener", VibrationSystem.Data.CODEC, registryOps).orElseGet(VibrationSystem.Data::new); -- this.setDuplicationCooldown(compound.getIntOr("DuplicationCooldown", 0)); -+ this.setDuplicationCooldown(compound.getLongOr("DuplicationCooldown", 0)); // Paper - Load as long +@@ -458,7 +_,7 @@ + super.readAdditionalSaveData(input); + this.readInventoryFromTag(input); + this.vibrationData = input.read("listener", VibrationSystem.Data.CODEC).orElseGet(VibrationSystem.Data::new); +- this.setDuplicationCooldown(input.getIntOr("DuplicationCooldown", 0)); ++ this.setDuplicationCooldown(input.getLongOr("DuplicationCooldown", 0)); // Paper - Load as long } @Override -@@ -494,15 +_,17 @@ +@@ -477,15 +_,17 @@ this.entityData.set(DATA_CAN_DUPLICATE, duplicationCooldown == 0L); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch index 39350fabe6..2db2588403 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/armadillo/Armadillo.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/armadillo/Armadillo.java +++ b/net/minecraft/world/entity/animal/armadillo/Armadillo.java -@@ -142,10 +_,12 @@ +@@ -143,10 +_,12 @@ ArmadilloAi.updateActivity(this); profilerFiller.pop(); if (this.isAlive() && !this.isBaby() && --this.scuteTime <= 0) { @@ -13,7 +13,7 @@ this.scuteTime = this.pickNextScuteDropTime(); } -@@ -282,8 +_,11 @@ +@@ -283,8 +_,11 @@ } @Override @@ -27,7 +27,7 @@ if (!this.isNoAi() && !this.isDeadOrDying()) { if (damageSource.getEntity() instanceof LivingEntity) { this.getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, 80L); -@@ -294,6 +_,7 @@ +@@ -295,6 +_,7 @@ this.rollOut(); } } @@ -35,7 +35,7 @@ } @Override -@@ -312,7 +_,9 @@ +@@ -313,7 +_,9 @@ return false; } else { if (this.level() instanceof ServerLevel serverLevel) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/axolotl/Axolotl.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/axolotl/Axolotl.java.patch index d3630a4f3f..3326460fed 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/axolotl/Axolotl.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/axolotl/Axolotl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/axolotl/Axolotl.java +++ b/net/minecraft/world/entity/animal/axolotl/Axolotl.java -@@ -231,7 +_,7 @@ +@@ -233,7 +_,7 @@ @Override public int getMaxAirSupply() { @@ -9,7 +9,7 @@ } public Axolotl.Variant getVariant() { -@@ -449,10 +_,10 @@ +@@ -451,10 +_,10 @@ if (effect == null || effect.endsWithin(2399)) { int i = effect != null ? effect.getDuration() : 0; int min = Math.min(2400, 100 + i); @@ -22,7 +22,7 @@ } @Override -@@ -544,6 +_,13 @@ +@@ -546,6 +_,13 @@ ) { return level.getBlockState(pos.below()).is(BlockTags.AXOLOTLS_SPAWNABLE_ON); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch index 5bf2254e9f..9198149c43 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/camel/Camel.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/camel/Camel.java +++ b/net/minecraft/world/entity/animal/camel/Camel.java -@@ -398,12 +_,12 @@ +@@ -404,12 +_,12 @@ } else { boolean flag = this.getHealth() < this.getMaxHealth(); if (flag) { @@ -15,7 +15,7 @@ } boolean isBaby = this.isBaby(); -@@ -463,9 +_,13 @@ +@@ -469,9 +_,13 @@ } @Override @@ -31,7 +31,7 @@ } @Override -@@ -566,7 +_,7 @@ +@@ -572,7 +_,7 @@ } public void sitDown() { @@ -40,7 +40,7 @@ this.makeSound(SoundEvents.CAMEL_SIT); this.setPose(Pose.SITTING); this.gameEvent(GameEvent.ENTITY_ACTION); -@@ -575,7 +_,7 @@ +@@ -581,7 +_,7 @@ } public void standUp() { @@ -49,7 +49,7 @@ this.makeSound(SoundEvents.CAMEL_STAND); this.setPose(Pose.STANDING); this.gameEvent(GameEvent.ENTITY_ACTION); -@@ -584,6 +_,7 @@ +@@ -590,6 +_,7 @@ } public void standUpInstantly() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch index a2d12511c5..c45c270306 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Frog.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/frog/Frog.java +++ b/net/minecraft/world/entity/animal/frog/Frog.java -@@ -287,7 +_,12 @@ +@@ -288,7 +_,12 @@ @Override public void spawnChildFromBreeding(ServerLevel level, Animal mate) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch index df2b8ef34c..c15bae4fc3 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/frog/Tadpole.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/frog/Tadpole.java +++ b/net/minecraft/world/entity/animal/frog/Tadpole.java -@@ -63,6 +_,7 @@ +@@ -65,6 +_,7 @@ MemoryModuleType.BREED_TARGET, MemoryModuleType.IS_PANICKING ); @@ -8,7 +8,7 @@ public Tadpole(EntityType entityType, Level level) { super(entityType, level); -@@ -114,7 +_,7 @@ +@@ -116,7 +_,7 @@ @Override public void aiStep() { super.aiStep(); @@ -17,22 +17,22 @@ this.setAge(this.age + 1); } } -@@ -123,12 +_,14 @@ - public void addAdditionalSaveData(CompoundTag compound) { - super.addAdditionalSaveData(compound); - compound.putInt("Age", this.age); -+ compound.putBoolean("AgeLocked", this.ageLocked); // Paper +@@ -125,12 +_,14 @@ + protected void addAdditionalSaveData(ValueOutput output) { + super.addAdditionalSaveData(output); + output.putInt("Age", this.age); ++ output.putBoolean("AgeLocked", this.ageLocked); // Paper } @Override - public void readAdditionalSaveData(CompoundTag compound) { - super.readAdditionalSaveData(compound); - this.setAge(compound.getIntOr("Age", 0)); -+ this.ageLocked = compound.getBooleanOr("AgeLocked", false); // Paper + protected void readAdditionalSaveData(ValueInput input) { + super.readAdditionalSaveData(input); + this.setAge(input.getIntOr("Age", 0)); ++ this.ageLocked = input.getBooleanOr("AgeLocked", false); // Paper } @Nullable -@@ -178,13 +_,19 @@ +@@ -180,13 +_,19 @@ @Override public void saveToBucketTag(ItemStack stack) { Bucketable.saveDefaultDataToBucketTag(this, stack); @@ -53,7 +53,7 @@ } @Override -@@ -216,6 +_,7 @@ +@@ -218,6 +_,7 @@ } private void ageUp(int offset) { @@ -61,7 +61,7 @@ this.setAge(this.age + offset * 20); } -@@ -228,12 +_,17 @@ +@@ -230,12 +_,17 @@ private void ageUp() { if (this.level() instanceof ServerLevel serverLevel) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch index 64ee2102f4..df84e7375c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/goat/Goat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/goat/Goat.java +++ b/net/minecraft/world/entity/animal/goat/Goat.java -@@ -234,13 +_,22 @@ +@@ -235,13 +_,22 @@ public InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.BUCKET) && !this.isBaby()) { @@ -25,7 +25,7 @@ this.playEatingSound(); } -@@ -352,8 +_,7 @@ +@@ -353,8 +_,7 @@ double d1 = Mth.randomBetween(this.random, 0.3F, 0.7F); double d2 = Mth.randomBetween(this.random, -0.2F, 0.2F); ItemEntity itemEntity = new ItemEntity(this.level(), vec3.x(), vec3.y(), vec3.z(), itemStack, d, d1, d2); @@ -35,7 +35,7 @@ } } -@@ -384,4 +_,15 @@ +@@ -385,4 +_,15 @@ ) { return level.getBlockState(pos.below()).is(BlockTags.GOATS_SPAWNABLE_ON) && isBrightEnoughToSpawn(level, pos); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java.patch index 968d8c59dc..afe3272470 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java +++ b/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java -@@ -70,6 +_,12 @@ +@@ -73,6 +_,12 @@ super.dropEquipment(level); if (this.hasChest()) { this.spawnAtLocation(level, Blocks.CHEST); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch index b30638aa7a..816a48094a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/AbstractHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/AbstractHorse.java +++ b/net/minecraft/world/entity/animal/horse/AbstractHorse.java -@@ -122,6 +_,7 @@ +@@ -123,6 +_,7 @@ protected int gallopSoundCounter; @Nullable public EntityReference owner; @@ -8,7 +8,7 @@ protected AbstractHorse(EntityType entityType, Level level) { super(entityType, level); -@@ -250,7 +_,7 @@ +@@ -252,7 +_,7 @@ } @Override @@ -17,7 +17,7 @@ return !this.isVehicle(); } -@@ -301,7 +_,7 @@ +@@ -303,7 +_,7 @@ public void createInventory() { SimpleContainer simpleContainer = this.inventory; @@ -26,7 +26,7 @@ if (simpleContainer != null) { int min = Math.min(simpleContainer.getContainerSize(), this.inventory.getContainerSize()); -@@ -395,7 +_,7 @@ +@@ -397,7 +_,7 @@ } public int getMaxTemper() { @@ -35,7 +35,7 @@ } @Override -@@ -450,7 +_,7 @@ +@@ -456,7 +_,7 @@ i1 = 5; if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { flag = true; @@ -44,7 +44,7 @@ } } else if (stack.is(Items.GOLDEN_APPLE) || stack.is(Items.ENCHANTED_GOLDEN_APPLE)) { f = 10.0F; -@@ -458,12 +_,12 @@ +@@ -464,12 +_,12 @@ i1 = 10; if (!this.level().isClientSide && this.isTamed() && this.getAge() == 0 && !this.isInLove()) { flag = true; @@ -59,7 +59,7 @@ flag = true; } -@@ -534,7 +_,7 @@ +@@ -540,7 +_,7 @@ super.aiStep(); if (this.level() instanceof ServerLevel serverLevel && this.isAlive()) { if (this.random.nextInt(900) == 0 && this.deathTime == 0) { @@ -68,7 +68,7 @@ } if (this.canEatGrass()) { -@@ -637,6 +_,16 @@ +@@ -642,6 +_,16 @@ } } @@ -85,36 +85,23 @@ @Override public InteractionResult mobInteract(Player player, InteractionHand hand) { if (this.isVehicle() || this.isBaby()) { -@@ -674,6 +_,12 @@ - this.setFlag(16, eating); - } - -+ // Paper start - Horse API -+ public void setForceStanding(boolean standing) { -+ this.setFlag(FLAG_STANDING, standing); -+ } -+ // Paper end - Horse API -+ - public void setStanding(boolean standing) { - if (standing) { - this.setEating(false); -@@ -785,6 +_,7 @@ - if (this.owner != null) { - this.owner.store(compound, "Owner"); - } -+ compound.putInt("Bukkit.MaxDomestication", this.maxDomestication); // Paper - max domestication +@@ -788,6 +_,7 @@ + output.putInt("Temper", this.getTemper()); + output.putBoolean("Tame", this.isTamed()); + EntityReference.store(this.owner, output, "Owner"); ++ output.putInt("Bukkit.MaxDomestication", this.maxDomestication); // Paper - max domestication } @Override -@@ -795,6 +_,7 @@ - this.setTemper(compound.getIntOr("Temper", 0)); - this.setTamed(compound.getBooleanOr("Tame", false)); - this.owner = EntityReference.readWithOldOwnerConversion(compound, "Owner", this.level()); -+ this.maxDomestication = compound.getIntOr("Bukkit.MaxDomestication", this instanceof Llama ? 30 : 100); // Paper - max domestication +@@ -798,6 +_,7 @@ + this.setTemper(input.getIntOr("Temper", 0)); + this.setTamed(input.getBooleanOr("Tame", false)); + this.owner = EntityReference.readWithOldOwnerConversion(input, "Owner", this.level()); ++ this.maxDomestication = input.getIntOr("Bukkit.MaxDomestication", this instanceof Llama ? 30 : 100); // Paper - max domestication } @Override -@@ -883,6 +_,17 @@ +@@ -886,6 +_,17 @@ @Override public void handleStartJump(int jumpPower) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/Llama.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/Llama.java.patch index 25ab74cc3c..314091374a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/Llama.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/Llama.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/Llama.java +++ b/net/minecraft/world/entity/animal/horse/Llama.java -@@ -76,17 +_,23 @@ +@@ -77,17 +_,23 @@ @Nullable private Llama caravanHead; @Nullable @@ -25,7 +25,7 @@ private void setStrength(int strength) { this.entityData.set(DATA_STRENGTH_ID, Math.max(1, Math.min(5, strength))); } -@@ -193,12 +_,12 @@ +@@ -194,12 +_,12 @@ f = 10.0F; if (this.isTamed() && this.getAge() == 0 && this.canFallInLove()) { flag = true; @@ -40,7 +40,7 @@ flag = true; } -@@ -312,7 +_,7 @@ +@@ -313,7 +_,7 @@ @Override public int getMaxTemper() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/SkeletonHorse.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/SkeletonHorse.java.patch index 06a4c28691..cb9143e8fc 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/SkeletonHorse.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/SkeletonHorse.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/SkeletonHorse.java +++ b/net/minecraft/world/entity/animal/horse/SkeletonHorse.java -@@ -124,7 +_,7 @@ +@@ -125,7 +_,7 @@ public void aiStep() { super.aiStep(); if (this.isTrap() && this.trapTime++ >= 18000) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/TraderLlama.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/TraderLlama.java.patch index d499f9f39f..a446a4d6fe 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/TraderLlama.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/horse/TraderLlama.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/horse/TraderLlama.java +++ b/net/minecraft/world/entity/animal/horse/TraderLlama.java -@@ -88,7 +_,7 @@ +@@ -89,7 +_,7 @@ this.despawnDelay = this.isLeashedToWanderingTrader() ? ((WanderingTrader)this.getLeashHolder()).getDespawnDelay() - 1 : this.despawnDelay - 1; if (this.despawnDelay <= 0) { this.removeLeash(); @@ -9,7 +9,7 @@ } } } -@@ -147,7 +_,7 @@ +@@ -148,7 +_,7 @@ @Override public void start() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/sheep/Sheep.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/sheep/Sheep.java.patch index 4fe05450ca..b5bfe7ba4c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/sheep/Sheep.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/sheep/Sheep.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/sheep/Sheep.java +++ b/net/minecraft/world/entity/animal/sheep/Sheep.java -@@ -161,7 +_,19 @@ +@@ -139,7 +_,19 @@ ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.SHEARS)) { if (this.level() instanceof ServerLevel serverLevel && this.readyForShearing()) { @@ -21,7 +21,7 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); return InteractionResult.SUCCESS_SERVER; -@@ -175,14 +_,28 @@ +@@ -153,14 +_,28 @@ @Override public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { @@ -57,7 +57,7 @@ if (itemEntity != null) { itemEntity.setDeltaMovement( itemEntity.getDeltaMovement() -@@ -302,6 +_,7 @@ +@@ -280,6 +_,7 @@ @Override public void ate() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch index 14f23439db..aaf3e6e08c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/sniffer/Sniffer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/sniffer/Sniffer.java +++ b/net/minecraft/world/entity/animal/sniffer/Sniffer.java -@@ -267,6 +_,13 @@ +@@ -278,6 +_,13 @@ this.dropFromGiftLootTable(serverLevel, BuiltInLootTables.SNIFFER_DIGGING, (serverLevel1, itemStack) -> { ItemEntity itemEntity = new ItemEntity(this.level(), headBlock.getX(), headBlock.getY(), headBlock.getZ(), itemStack); itemEntity.setDefaultPickUpDelay(); @@ -14,7 +14,7 @@ serverLevel1.addFreshEntity(itemEntity); }); this.playSound(SoundEvents.SNIFFER_DROP_SEED, 1.0F, 1.0F); -@@ -325,12 +_,17 @@ +@@ -336,12 +_,17 @@ @Override public void spawnChildFromBreeding(ServerLevel level, Animal mate) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch index 795babca88..9077f78bd5 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/animal/wolf/Wolf.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/animal/wolf/Wolf.java +++ b/net/minecraft/world/entity/animal/wolf/Wolf.java -@@ -400,16 +_,18 @@ +@@ -399,16 +_,18 @@ if (this.isInvulnerableTo(level, damageSource)) { return false; } else { @@ -22,7 +22,7 @@ ItemStack bodyArmorItem = this.getBodyArmorItem(); int damageValue = bodyArmorItem.getDamageValue(); int maxDamage = bodyArmorItem.getMaxDamage(); -@@ -429,6 +_,7 @@ +@@ -428,6 +_,7 @@ ); } } @@ -30,7 +30,7 @@ } private boolean canArmorAbsorb(DamageSource damageSource) { -@@ -439,7 +_,7 @@ +@@ -438,7 +_,7 @@ protected void applyTamingSideEffects() { if (this.isTame()) { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(40.0); @@ -39,7 +39,7 @@ } else { this.getAttribute(Attributes.MAX_HEALTH).setBaseValue(8.0); } -@@ -459,7 +_,7 @@ +@@ -463,7 +_,7 @@ this.usePlayerItem(player, hand, itemInHand); FoodProperties foodProperties = itemInHand.get(DataComponents.FOOD); float f = foodProperties != null ? foodProperties.nutrition() : 1.0F; @@ -49,25 +49,15 @@ } @@ -492,7 +_,7 @@ - this.setOrderedToSit(!this.isOrderedToSit()); - this.jumping = false; - this.navigation.stop(); -- this.setTarget(null); -+ this.setTarget(null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET); // CraftBukkit - reason - return InteractionResult.SUCCESS.withoutItem(); - } - -@@ -504,7 +_,9 @@ - ItemStack bodyArmorItem = this.getBodyArmorItem(); - this.setBodyArmorItem(ItemStack.EMPTY); - if (this.level() instanceof ServerLevel serverLevel) { -+ this.forceDrops = true; // CraftBukkit - this.spawnAtLocation(serverLevel, bodyArmorItem); -+ this.forceDrops = false; // CraftBukkit + this.setOrderedToSit(!this.isOrderedToSit()); + this.jumping = false; + this.navigation.stop(); +- this.setTarget(null); ++ this.setTarget(null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.FORGOT_TARGET); // CraftBukkit - reason + return InteractionResult.SUCCESS.withoutItem(); } - return InteractionResult.SUCCESS; -@@ -512,6 +_,13 @@ +@@ -501,6 +_,13 @@ DyeColor dyeColor = dyeItem.getDyeColor(); if (dyeColor != this.getCollarColor()) { @@ -81,7 +71,7 @@ this.setCollarColor(dyeColor); itemInHand.consume(1, player); return InteractionResult.SUCCESS; -@@ -526,7 +_,7 @@ +@@ -515,7 +_,7 @@ } private void tryToTame(Player player) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch index a7a9b5e999..d0100a414a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java +++ b/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java -@@ -25,6 +_,7 @@ +@@ -26,6 +_,7 @@ private static final EntityDataAccessor DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN); private static final boolean DEFAULT_SHOW_BOTTOM = true; public int time; @@ -8,7 +8,7 @@ public EndCrystal(EntityType entityType, Level level) { super(entityType, level); -@@ -56,21 +_,37 @@ +@@ -57,21 +_,37 @@ if (this.level() instanceof ServerLevel) { BlockPos blockPos = this.blockPosition(); if (((ServerLevel)this.level()).getDragonFight() != null && this.level().getBlockState(blockPos).isAir()) { @@ -34,21 +34,21 @@ } @Override - protected void addAdditionalSaveData(CompoundTag compound) { - compound.storeNullable("beam_target", BlockPos.CODEC, this.getBeamTarget()); - compound.putBoolean("ShowBottom", this.showsBottom()); -+ compound.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals + protected void addAdditionalSaveData(ValueOutput output) { + output.storeNullable("beam_target", BlockPos.CODEC, this.getBeamTarget()); + output.putBoolean("ShowBottom", this.showsBottom()); ++ output.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals } @Override - protected void readAdditionalSaveData(CompoundTag compound) { - this.setBeamTarget(compound.read("beam_target", BlockPos.CODEC).orElse(null)); - this.setShowBottom(compound.getBooleanOr("ShowBottom", true)); -+ this.generatedByDragonFight = compound.getBooleanOr("Paper.GeneratedByDragonFight", false); // Paper - Fix invulnerable end crystals + protected void readAdditionalSaveData(ValueInput input) { + this.setBeamTarget(input.read("beam_target", BlockPos.CODEC).orElse(null)); + this.setShowBottom(input.getBooleanOr("ShowBottom", true)); ++ this.generatedByDragonFight = input.getBooleanOr("Paper.GeneratedByDragonFight", false); // Paper - Fix invulnerable end crystals } @Override -@@ -91,10 +_,24 @@ +@@ -92,10 +_,24 @@ return false; } else { if (!this.isRemoved()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch index 1fd4c7ef0e..a6ccd9f317 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java +++ b/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java -@@ -87,6 +_,10 @@ +@@ -88,6 +_,10 @@ private final Node[] nodes = new Node[24]; private final int[] nodeAdjacency = new int[24]; private final BinaryHeap openSet = new BinaryHeap(); @@ -11,7 +11,7 @@ public EnderDragon(EntityType entityType, Level level) { super(EntityType.ENDER_DRAGON, level); -@@ -102,6 +_,7 @@ +@@ -103,6 +_,7 @@ this.setHealth(this.getMaxHealth()); this.noPhysics = true; this.phaseManager = new EnderDragonPhaseManager(this); @@ -19,8 +19,8 @@ } public void setDragonFight(EndDragonFight dragonFight) { -@@ -120,6 +_,19 @@ - return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0); +@@ -121,6 +_,19 @@ + return Mob.createMobAttributes().add(Attributes.MAX_HEALTH, 200.0).add(Attributes.CAMERA_DISTANCE, 16.0); } + // Paper start - Allow changing the EnderDragon podium @@ -39,7 +39,7 @@ @Override public boolean isFlapping() { float cos = Mth.cos(this.flapTime * (float) (Math.PI * 2)); -@@ -211,7 +_,7 @@ +@@ -212,7 +_,7 @@ } Vec3 flyTargetLocation = currentPhase.getFlyTargetLocation(); @@ -48,7 +48,7 @@ double d = flyTargetLocation.x - this.getX(); double d1 = flyTargetLocation.y - this.getY(); double d2 = flyTargetLocation.z - this.getZ(); -@@ -366,7 +_,12 @@ +@@ -367,7 +_,12 @@ if (this.nearestCrystal.isRemoved()) { this.nearestCrystal = null; } else if (this.tickCount % 10 == 0 && this.getHealth() < this.getMaxHealth()) { @@ -62,7 +62,7 @@ } } -@@ -396,7 +_,7 @@ +@@ -397,7 +_,7 @@ double d2 = entity.getX() - d; double d3 = entity.getZ() - d1; double max = Math.max(d2 * d2 + d3 * d3, 0.1); @@ -71,7 +71,7 @@ if (!this.phaseManager.getCurrentPhase().isSitting() && livingEntity.getLastHurtByMobTimestamp() < entity.tickCount - 2) { DamageSource damageSource = this.damageSources().mobAttack(this); entity.hurtServer(level, damageSource, 5.0F); -@@ -429,6 +_,7 @@ +@@ -430,6 +_,7 @@ int floor5 = Mth.floor(box.maxZ); boolean flag = false; boolean flag1 = false; @@ -79,7 +79,7 @@ for (int i = floor; i <= floor3; i++) { for (int i1 = floor1; i1 <= floor4; i1++) { -@@ -437,7 +_,11 @@ +@@ -438,7 +_,11 @@ BlockState blockState = level.getBlockState(blockPos); if (!blockState.isAir() && !blockState.is(BlockTags.DRAGON_TRANSPARENT)) { if (level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && !blockState.is(BlockTags.DRAGON_IMMUNE)) { @@ -92,7 +92,7 @@ } else { flag = true; } -@@ -446,6 +_,58 @@ +@@ -447,6 +_,58 @@ } } @@ -151,7 +151,7 @@ if (flag1) { BlockPos blockPos1 = new BlockPos( floor + this.random.nextInt(floor3 - floor + 1), -@@ -503,7 +_,15 @@ +@@ -504,7 +_,15 @@ @Override public void kill(ServerLevel level) { @@ -168,7 +168,7 @@ this.gameEvent(GameEvent.ENTITY_DIE); if (this.dragonFight != null) { this.dragonFight.updateDragon(this); -@@ -525,18 +_,41 @@ +@@ -526,18 +_,41 @@ this.level().addParticle(ParticleTypes.EXPLOSION_EMITTER, this.getX() + f, this.getY() + 2.0 + f1, this.getZ() + f2, 0.0, 0.0, 0.0); } @@ -186,7 +186,7 @@ - if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0 && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - ExperienceOrb.award(serverLevel, this.position(), Mth.floor(i * 0.08F)); + if (this.dragonDeathTime > 150 && this.dragonDeathTime % 5 == 0) { // CraftBukkit - SPIGOT-2420: Already checked for the game rule when calculating the xp -+ ExperienceOrb.award(serverLevel, this.position(), Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper ++ ExperienceOrb.awardWithDirection(serverLevel, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.08F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper } if (this.dragonDeathTime == 1 && !this.isSilent()) { @@ -213,14 +213,14 @@ } } -@@ -549,15 +_,15 @@ +@@ -550,15 +_,15 @@ } if (this.dragonDeathTime == 200 && this.level() instanceof ServerLevel serverLevel1) { - if (serverLevel1.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) { - ExperienceOrb.award(serverLevel1, this.position(), Mth.floor(i * 0.2F)); + if (true) { // Paper - SPIGOT-2420: Already checked for the game rule when calculating the xp -+ ExperienceOrb.award(serverLevel1, this.position(), Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.Optionull.map(this.lastHurtByPlayer, lastHurtByPlayer -> lastHurtByPlayer.getEntity(this.level(), Player.class)), this); // Paper ++ ExperienceOrb.awardWithDirection(serverLevel1, this.position(), net.minecraft.world.phys.Vec3.ZERO, Mth.floor(i * 0.2F), org.bukkit.entity.ExperienceOrb.SpawnReason.ENTITY_DEATH, net.minecraft.world.entity.EntityReference.get(this.lastHurtByPlayer, this.level(), Player.class), this); // Paper } if (this.dragonFight != null) { @@ -232,23 +232,23 @@ this.gameEvent(GameEvent.ENTITY_DIE); } } -@@ -739,6 +_,7 @@ - super.addAdditionalSaveData(compound); - compound.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId()); - compound.putInt("DragonDeathTime", this.dragonDeathTime); -+ compound.putInt("Bukkit.expToDrop", this.expToDrop); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts +@@ -740,6 +_,7 @@ + super.addAdditionalSaveData(output); + output.putInt("DragonPhase", this.phaseManager.getCurrentPhase().getPhase().getId()); + output.putInt("DragonDeathTime", this.dragonDeathTime); ++ output.putInt("Bukkit.expToDrop", this.expToDrop); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts } @Override -@@ -746,6 +_,7 @@ - super.readAdditionalSaveData(compound); - compound.getInt("DragonPhase").ifPresent(integer -> this.phaseManager.setPhase(EnderDragonPhase.getById(integer))); - this.dragonDeathTime = compound.getIntOr("DragonDeathTime", 0); -+ this.expToDrop = compound.getIntOr("Bukkit.expToDrop", 0); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts +@@ -747,6 +_,7 @@ + super.readAdditionalSaveData(input); + input.getInt("DragonPhase").ifPresent(integer -> this.phaseManager.setPhase(EnderDragonPhase.getById(integer))); + this.dragonDeathTime = input.getIntOr("DragonDeathTime", 0); ++ this.expToDrop = input.getIntOr("Bukkit.expToDrop", 0); // CraftBukkit - SPIGOT-2420: The ender dragon drops xp over time which can also happen between server starts } @Override -@@ -786,7 +_,7 @@ +@@ -787,7 +_,7 @@ EnderDragonPhase phase = currentPhase.getPhase(); Vec3 viewVector; if (phase == EnderDragonPhase.LANDING || phase == EnderDragonPhase.TAKEOFF) { @@ -257,7 +257,7 @@ float max = Math.max((float)Math.sqrt(heightmapPos.distToCenterSqr(this.position())) / 4.0F, 1.0F); float f = 6.0F / max; float xRot = this.getXRot(); -@@ -874,4 +_,19 @@ +@@ -875,4 +_,19 @@ protected float sanitizeScale(float scale) { return 1.0F; } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java.patch index 918ba8a951..2a0cf8dd98 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java +++ b/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java @@ -83,7 +_,13 @@ - this.flame.setParticle(ParticleTypes.DRAGON_BREATH); + this.flame.setCustomParticle(ParticleTypes.DRAGON_BREATH); this.flame.setPotionDurationScale(0.25F); this.flame.addEffect(new MobEffectInstance(MobEffects.INSTANT_DAMAGE)); + if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper - EnderDragon Events diff --git a/paper-server/patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch index ca0712d6a4..1a07996263 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/boss/wither/WitherBoss.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/boss/wither/WitherBoss.java +++ b/net/minecraft/world/entity/boss/wither/WitherBoss.java -@@ -70,6 +_,7 @@ +@@ -71,6 +_,7 @@ private final int[] nextHeadUpdate = new int[2]; private final int[] idleHeadUpdates = new int[2]; private int destroyBlocksTick; @@ -8,7 +8,7 @@ public final ServerBossEvent bossEvent = (ServerBossEvent)new ServerBossEvent( this.getDisplayName(), BossEvent.BossBarColor.PURPLE, BossEvent.BossBarOverlay.PROGRESS ) -@@ -261,15 +_,40 @@ +@@ -262,15 +_,40 @@ int i = this.getInvulnerableTicks() - 1; this.bossEvent.setProgress(1.0F - i / 220.0F); if (i <= 0) { @@ -52,7 +52,7 @@ } } else { super.customServerAiStep(level); -@@ -306,6 +_,7 @@ +@@ -307,6 +_,7 @@ ); if (!nearbyEntities.isEmpty()) { LivingEntity livingEntity1 = nearbyEntities.get(this.random.nextInt(nearbyEntities.size())); @@ -60,7 +60,7 @@ this.setAlternativeTarget(ix, livingEntity1.getId()); } } -@@ -335,6 +_,11 @@ +@@ -336,6 +_,11 @@ )) { BlockState blockState = level.getBlockState(blockPos); if (canDestroy(blockState)) { @@ -72,7 +72,7 @@ flag = level.destroyBlock(blockPos, true, this) || flag; } } -@@ -346,7 +_,7 @@ +@@ -347,7 +_,7 @@ } if (this.tickCount % 20 == 0) { @@ -81,12 +81,12 @@ } this.bossEvent.setProgress(this.getHealth() / this.getMaxHealth()); -@@ -484,16 +_,16 @@ +@@ -485,16 +_,16 @@ @Override protected void dropCustomDeathLoot(ServerLevel level, DamageSource damageSource, boolean recentlyHit) { super.dropCustomDeathLoot(level, damageSource, recentlyHit); - ItemEntity itemEntity = this.spawnAtLocation(level, Items.NETHER_STAR); -+ ItemEntity itemEntity = this.spawnAtLocation(level, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), 0, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer ++ ItemEntity itemEntity = this.spawnAtLocation(level, new net.minecraft.world.item.ItemStack(Items.NETHER_STAR), net.minecraft.world.phys.Vec3.ZERO, ItemEntity::setExtendedLifetime); // Paper - Restore vanilla drops behavior; spawnAtLocation returns null so modify the item entity with a consumer if (itemEntity != null) { - itemEntity.setExtendedLifetime(); + itemEntity.setExtendedLifetime(); // Paper - diff on change @@ -101,7 +101,7 @@ } else { this.noActionTime = 0; } -@@ -548,12 +_,18 @@ +@@ -549,12 +_,18 @@ @Override public boolean canUsePortal(boolean allowPassengers) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch index 02c0dba9e6..72b14ed5b9 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ArmorStand.java.patch @@ -1,14 +1,13 @@ --- a/net/minecraft/world/entity/decoration/ArmorStand.java +++ b/net/minecraft/world/entity/decoration/ArmorStand.java -@@ -88,9 +_,17 @@ - public Rotations rightArmPose = DEFAULT_RIGHT_ARM_POSE; - public Rotations leftLegPose = DEFAULT_LEFT_LEG_POSE; - public Rotations rightLegPose = DEFAULT_RIGHT_LEG_POSE; +@@ -85,9 +_,16 @@ + private boolean invisible = false; + public long lastHit; + public int disabledSlots = 0; + public boolean canMove = true; // Paper + // Paper start - Allow ArmorStands not to tick + public boolean canTick = true; + public boolean canTickSetByAPI = false; -+ private boolean noTickPoseDirty = false; + private boolean noTickEquipmentDirty = false; + // Paper end - Allow ArmorStands not to tick @@ -18,7 +17,7 @@ } public ArmorStand(Level level, double x, double y, double z) { -@@ -102,6 +_,13 @@ +@@ -99,6 +_,13 @@ return createLivingAttributes().add(Attributes.STEP_HEIGHT, 0.0); } @@ -32,7 +31,7 @@ @Override public void refreshDimensions() { double x = this.getX(); -@@ -137,6 +_,14 @@ +@@ -134,6 +_,14 @@ return slot != EquipmentSlot.BODY && slot != EquipmentSlot.SADDLE && !this.isDisabled(slot); } @@ -45,39 +44,35 @@ + // Paper - Allow ArmorStands not to tick; Still update equipment + @Override - public void addAdditionalSaveData(CompoundTag compound) { - super.addAdditionalSaveData(compound); -@@ -150,6 +_,7 @@ + protected void addAdditionalSaveData(ValueOutput output) { + super.addAdditionalSaveData(output); +@@ -147,6 +_,7 @@ } - compound.put("Pose", this.writePose()); -+ if (this.canTickSetByAPI) compound.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick + output.store("Pose", ArmorStand.ArmorStandPose.CODEC, this.getArmorStandPose()); ++ if (this.canTickSetByAPI) output.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - Allow ArmorStands not to tick } @Override -@@ -163,6 +_,12 @@ - this.setMarker(compound.getBooleanOr("Marker", false)); +@@ -160,10 +_,16 @@ + this.setMarker(input.getBooleanOr("Marker", false)); this.noPhysics = !this.hasPhysics(); - this.readPose(compound.getCompoundOrEmpty("Pose")); + input.read("Pose", ArmorStand.ArmorStandPose.CODEC).ifPresent(this::setArmorStandPose); + // Paper start - Allow ArmorStands not to tick -+ compound.getBoolean("Paper.CanTickOverride").ifPresent(canTick -> { -+ this.canTick = canTick; ++ if (input.getInt("Paper.CanTickOverride").isPresent()) { // Check if is set ++ this.canTick = input.getBooleanOr("Paper.CanTickOverride", true); + this.canTickSetByAPI = true; -+ }); ++ } + // Paper end - Allow ArmorStands not to tick } - private void readPose(CompoundTag compound) { -@@ -204,7 +_,7 @@ - } - @Override - public boolean isPushable() { + public boolean isCollidable(boolean ignoreClimbing) { // Paper - Climbing should not bypass cramming gamerule return false; } -@@ -214,6 +_,7 @@ +@@ -173,6 +_,7 @@ @Override protected void pushEntities() { @@ -85,7 +80,7 @@ for (Entity entity : this.level().getEntities(this, this.getBoundingBox(), RIDABLE_MINECARTS)) { if (this.distanceToSqr(entity) <= 0.2) { entity.push(this); -@@ -286,7 +_,25 @@ +@@ -245,7 +_,25 @@ return false; } else if (itemBySlot.isEmpty() && (this.disabledSlots & 1 << slot.getFilterBit(16)) != 0) { return false; @@ -112,7 +107,7 @@ this.setItemSlot(slot, stack.copyWithCount(1)); return true; } else if (stack.isEmpty() || stack.getCount() <= 1) { -@@ -299,6 +_,7 @@ +@@ -258,6 +_,7 @@ this.setItemSlot(slot, stack.split(1)); return true; } @@ -120,7 +115,7 @@ } @Override -@@ -308,15 +_,32 @@ +@@ -267,15 +_,32 @@ } else if (!level.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING) && damageSource.getEntity() instanceof Mob) { return false; } else if (damageSource.is(DamageTypeTags.BYPASSES_INVULNERABILITY)) { @@ -157,7 +152,7 @@ if (this.isOnFire()) { this.causeDamage(level, damageSource, 0.15F); } else { -@@ -325,9 +_,19 @@ +@@ -284,9 +_,19 @@ return false; } else if (damageSource.is(DamageTypeTags.BURNS_ARMOR_STANDS) && this.getHealth() > 0.5F) { @@ -177,7 +172,7 @@ boolean isCanBreakArmorStand = damageSource.is(DamageTypeTags.CAN_BREAK_ARMOR_STAND); boolean isAlwaysKillsArmorStands = damageSource.is(DamageTypeTags.ALWAYS_KILLS_ARMOR_STANDS); if (!isCanBreakArmorStand && !isAlwaysKillsArmorStands) { -@@ -337,7 +_,7 @@ +@@ -296,7 +_,7 @@ } else if (damageSource.isCreativePlayer()) { this.playBrokenSound(); this.showBreakingParticles(); @@ -186,7 +181,7 @@ return true; } else { long gameTime = level.getGameTime(); -@@ -346,9 +_,9 @@ +@@ -305,9 +_,9 @@ this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity()); this.lastHit = gameTime; } else { @@ -198,7 +193,7 @@ } return true; -@@ -400,31 +_,42 @@ +@@ -359,31 +_,42 @@ float health = this.getHealth(); health -= damageAmount; if (health <= 0.5F) { @@ -252,17 +247,14 @@ } private void playBrokenSound() { -@@ -458,7 +_,28 @@ +@@ -431,9 +_,40 @@ + return this.isSmall(); + } - @Override - public void tick() { -+ // Paper start - Allow ArmorStands not to tick ++ // Paper start - Allow ArmorStands not to tick ++ @Override ++ public void tick() { + if (!this.canTick) { -+ if (this.noTickPoseDirty) { -+ this.noTickPoseDirty = false; -+ this.updatePose(); -+ } -+ + if (this.noTickEquipmentDirty) { + this.noTickEquipmentDirty = false; + this.detectEquipmentUpdates(); @@ -270,27 +262,9 @@ + + return; + } -+ // Paper end - Allow ArmorStands not to tick - super.tick(); -+ // Paper start - Allow ArmorStands not to tick -+ this.updatePose(); ++ super.tick(); + } -+ -+ public void updatePose() { -+ // Paper end - Allow ArmorStands not to tick - Rotations rotations = this.entityData.get(DATA_HEAD_POSE); - if (!this.headPose.equals(rotations)) { - this.setHeadPose(rotations); -@@ -506,9 +_,32 @@ - return this.isSmall(); - } - -+ // CraftBukkit start -+ @Override -+ public boolean shouldDropExperience() { -+ return true; // MC-157395, SPIGOT-5193 even small armor stands should drop -+ } -+ // CraftBukkit end ++ // Paper end - Allow ArmorStands not to tick + @Override public void kill(ServerLevel level) { @@ -315,47 +289,9 @@ this.gameEvent(GameEvent.ENTITY_DIE); } -@@ -572,31 +_,37 @@ - public void setHeadPose(Rotations headPose) { - this.headPose = headPose; - this.entityData.set(DATA_HEAD_POSE, headPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setBodyPose(Rotations bodyPose) { - this.bodyPose = bodyPose; - this.entityData.set(DATA_BODY_POSE, bodyPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setLeftArmPose(Rotations leftArmPose) { - this.leftArmPose = leftArmPose; - this.entityData.set(DATA_LEFT_ARM_POSE, leftArmPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setRightArmPose(Rotations rightArmPose) { - this.rightArmPose = rightArmPose; - this.entityData.set(DATA_RIGHT_ARM_POSE, rightArmPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setLeftLegPose(Rotations leftLegPose) { - this.leftLegPose = leftLegPose; - this.entityData.set(DATA_LEFT_LEG_POSE, leftLegPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public void setRightLegPose(Rotations rightLegPose) { - this.rightLegPose = rightLegPose; - this.entityData.set(DATA_RIGHT_LEG_POSE, rightLegPose); -+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking - } - - public Rotations getHeadPose() { -@@ -728,4 +_,13 @@ - public boolean canBeSeenByAnyone() { - return !this.isInvisible() && !this.isMarker(); +@@ -684,4 +_,13 @@ + .apply(instance, ArmorStand.ArmorStandPose::new) + ); } + + // Paper start diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch index 55a016fcd9..1e7680143c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/BlockAttachedEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/decoration/BlockAttachedEntity.java +++ b/net/minecraft/world/entity/decoration/BlockAttachedEntity.java -@@ -20,7 +_,7 @@ +@@ -21,7 +_,7 @@ public abstract class BlockAttachedEntity extends Entity { private static final Logger LOGGER = LogUtils.getLogger(); @@ -9,7 +9,7 @@ protected BlockPos pos; protected BlockAttachedEntity(EntityType entityType, Level level) { -@@ -38,10 +_,26 @@ +@@ -39,10 +_,26 @@ public void tick() { if (this.level() instanceof ServerLevel serverLevel) { this.checkBelowWorld(); @@ -38,7 +38,7 @@ this.dropItem(serverLevel, null); } } -@@ -74,6 +_,21 @@ +@@ -75,6 +_,21 @@ return false; } else { if (!this.isRemoved()) { @@ -60,7 +60,7 @@ this.kill(level); this.markHurt(); this.dropItem(level, damageSource.getEntity()); -@@ -91,18 +_,36 @@ +@@ -93,18 +_,36 @@ @Override public void move(MoverType type, Vec3 movement) { if (this.level() instanceof ServerLevel serverLevel && !this.isRemoved() && movement.lengthSqr() > 0.0) { @@ -100,12 +100,12 @@ + + // CraftBukkit start - selectively save tile position + @Override -+ public void addAdditionalSaveData(CompoundTag nbt, boolean includeAll) { ++ protected void addAdditionalSaveData(final net.minecraft.world.level.storage.ValueOutput output, final boolean includeAll) { + if (includeAll) { -+ this.addAdditionalSaveData(nbt); ++ this.addAdditionalSaveData(output); + } + } + // CraftBukkit end @Override - public void addAdditionalSaveData(CompoundTag tag) { + protected void addAdditionalSaveData(ValueOutput output) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch index ae6ec12ccd..4a425af40c 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/ItemFrame.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/decoration/ItemFrame.java +++ b/net/minecraft/world/entity/decoration/ItemFrame.java -@@ -56,6 +_,7 @@ +@@ -54,6 +_,7 @@ private static final boolean DEFAULT_FIXED = false; public float dropChance = 1.0F; public boolean fixed = false; @@ -8,7 +8,7 @@ public ItemFrame(EntityType entityType, Level level) { super(entityType, level); -@@ -97,6 +_,12 @@ +@@ -102,6 +_,12 @@ @Override protected AABB calculateBoundingBox(BlockPos pos, Direction direction) { @@ -21,7 +21,7 @@ float f = 0.46875F; Vec3 vec3 = Vec3.atCenterOf(pos).relative(direction, -0.46875); Direction.Axis axis = direction.getAxis(); -@@ -127,9 +_,9 @@ +@@ -132,9 +_,9 @@ } @Override @@ -33,7 +33,7 @@ } } -@@ -158,6 +_,18 @@ +@@ -163,6 +_,18 @@ if (this.isInvulnerableToBase(damageSource)) { return false; } else if (this.shouldDamageDropItem(damageSource)) { @@ -52,7 +52,7 @@ this.dropItem(level, damageSource.getEntity(), false); this.gameEvent(GameEvent.BLOCK_CHANGE, damageSource.getEntity()); this.playSound(this.getRemoveItemSound(), 1.0F, 1.0F); -@@ -243,6 +_,14 @@ +@@ -248,6 +_,14 @@ return this.getEntityData().get(DATA_ITEM); } @@ -67,7 +67,7 @@ @Nullable public MapId getFramedMapId(ItemStack stack) { return stack.get(DataComponents.MAP_ID); -@@ -257,13 +_,19 @@ +@@ -262,13 +_,19 @@ } public void setItem(ItemStack stack, boolean updateNeighbours) { @@ -88,7 +88,7 @@ this.playSound(this.getAddItemSound(), 1.0F, 1.0F); } -@@ -289,6 +_,7 @@ +@@ -295,6 +_,7 @@ } private void onItemChanged(ItemStack item) { @@ -96,7 +96,7 @@ if (!item.isEmpty() && item.getFrame() != this) { item.setEntityRepresentation(this); } -@@ -359,7 +_,13 @@ +@@ -363,7 +_,13 @@ if (savedData != null && savedData.isTrackedCountOverLimit(256)) { return InteractionResult.FAIL; } else { @@ -111,7 +111,7 @@ this.gameEvent(GameEvent.BLOCK_CHANGE, player); itemInHand.consume(1, player); return InteractionResult.SUCCESS; -@@ -368,6 +_,13 @@ +@@ -372,6 +_,13 @@ return InteractionResult.PASS; } } else { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch index 56d3dea16c..51f18a9293 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java.patch @@ -1,61 +1,29 @@ --- a/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java +++ b/net/minecraft/world/entity/decoration/LeashFenceKnotEntity.java -@@ -81,6 +_,15 @@ +@@ -82,7 +_,7 @@ + boolean flag = false; - for (Leashable leashable : list) { - if (leashable.getLeashHolder() == player) { -+ // CraftBukkit start -+ if (leashable instanceof Entity leashed) { -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, this, player, hand).isCancelled()) { -+ ((net.minecraft.server.level.ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(leashed, leashable.getLeashHolder())); -+ flag = true; // Also set true when the event is cancelled otherwise it tries to unleash the entities -+ continue; -+ } -+ } -+ // CraftBukkit end + for (Leashable leashable : Leashable.leashableLeashedTo(player)) { +- if (leashable.canHaveALeashAttachedTo(this)) { ++ if (leashable.canHaveALeashAttachedTo(this) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable, this, player, hand)) { // Paper - leash event leashable.setLeashedTo(this, true); flag = true; } -@@ -88,14 +_,39 @@ - +@@ -91,7 +_,7 @@ boolean flag1 = false; - if (!flag) { -- this.discard(); -- if (player.getAbilities().instabuild) { -+ // CraftBukkit start - Move below -+ // this.discard(); -+ boolean die = true; -+ // CraftBukkit end -+ if (true || player.getAbilities().instabuild) { // CraftBukkit - Process for non-creative as well - for (Leashable leashable1 : list) { - if (leashable1.isLeashed() && leashable1.getLeashHolder() == this) { -- leashable1.removeLeash(); -+ // CraftBukkit start -+ boolean dropLeash = !player.hasInfiniteMaterials(); -+ if (leashable1 instanceof Entity leashed) { -+ // Paper start - Expand EntityUnleashEvent -+ org.bukkit.event.player.PlayerUnleashEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerUnleashEntityEvent(leashed, player, hand, dropLeash); -+ dropLeash = event.isDropLeash(); -+ if (event.isCancelled()) { -+ // Paper end - Expand EntityUnleashEvent -+ die = false; -+ continue; -+ } -+ } -+ if (!dropLeash) { // Paper - Expand EntityUnleashEvent -+ leashable1.removeLeash(); -+ } else { -+ leashable1.dropLeash(); -+ } -+ // CraftBukkit end - flag1 = true; - } + if (!flag && !player.isSecondaryUseActive()) { + for (Leashable leashable1 : Leashable.leashableLeashedTo(this)) { +- if (leashable1.canHaveALeashAttachedTo(player)) { ++ if (leashable1.canHaveALeashAttachedTo(player) && org.bukkit.craftbukkit.event.CraftEventFactory.handlePlayerLeashEntityEvent(leashable1, player, player, hand)) { // Paper - leash event + leashable1.setLeashedTo(player, true); + flag1 = true; } -+ // CraftBukkit start -+ if (die) { -+ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause -+ } -+ // CraftBukkit end - } - } +@@ -111,7 +_,7 @@ + @Override + public void notifyLeasheeRemoved(Leashable leashHolder) { + if (Leashable.leashableLeashedTo(this).isEmpty()) { +- this.discard(); ++ this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DROP); // CraftBukkit - add Bukkit remove cause + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/decoration/Painting.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/decoration/Painting.java.patch index 5c59868f08..e448f719b0 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/decoration/Painting.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/decoration/Painting.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/decoration/Painting.java +++ b/net/minecraft/world/entity/decoration/Painting.java -@@ -146,21 +_,31 @@ +@@ -149,21 +_,31 @@ @Override protected AABB calculateBoundingBox(BlockPos pos, Direction direction) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch index 408a05cd3e..4b5a933737 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/FallingBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/FallingBlockEntity.java +++ b/net/minecraft/world/entity/item/FallingBlockEntity.java -@@ -69,6 +_,7 @@ +@@ -72,6 +_,7 @@ public CompoundTag blockData; public boolean forceTickAfterTeleportToDuplicate; protected static final EntityDataAccessor DATA_START_POS = SynchedEntityData.defineId(FallingBlockEntity.class, EntityDataSerializers.BLOCK_POS); @@ -8,7 +8,7 @@ public FallingBlockEntity(EntityType entityType, Level level) { super(entityType, level); -@@ -94,6 +_,7 @@ +@@ -97,6 +_,7 @@ pos.getZ() + 0.5, blockState.hasProperty(BlockStateProperties.WATERLOGGED) ? blockState.setValue(BlockStateProperties.WATERLOGGED, false) : blockState ); @@ -16,7 +16,7 @@ level.setBlock(pos, blockState.getFluidState().createLegacyBlock(), 3); level.addFreshEntity(fallingBlockEntity); return fallingBlockEntity; -@@ -144,13 +_,22 @@ +@@ -147,13 +_,22 @@ @Override public void tick() { if (this.blockState.isAir()) { @@ -40,7 +40,7 @@ this.handlePortal(); if (this.level() instanceof ServerLevel serverLevel && (this.isAlive() || this.forceTickAfterTeleportToDuplicate)) { BlockPos blockPos = this.blockPosition(); -@@ -171,12 +_,12 @@ +@@ -174,12 +_,12 @@ } if (!this.onGround() && !flag1) { @@ -55,7 +55,7 @@ } } else { BlockState blockState = this.level().getBlockState(blockPos); -@@ -194,12 +_,18 @@ +@@ -197,12 +_,18 @@ this.blockState = this.blockState.setValue(BlockStateProperties.WATERLOGGED, true); } @@ -75,7 +75,7 @@ if (block instanceof Fallable) { ((Fallable)block).onLand(this.level(), blockPos, this.blockState, blockState, this); } -@@ -220,19 +_,19 @@ +@@ -227,19 +_,19 @@ } } } else if (this.dropItem && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOENTITYDROPS)) { @@ -98,26 +98,26 @@ this.callOnBrokenAfterFall(block, blockPos); } } -@@ -293,6 +_,7 @@ +@@ -299,6 +_,7 @@ } - compound.putBoolean("CancelDrop", this.cancelDrop); -+ if (!this.autoExpire) compound.putBoolean("Paper.AutoExpire", false); // Paper - Expand FallingBlock API + output.putBoolean("CancelDrop", this.cancelDrop); ++ if (!this.autoExpire) output.putBoolean("Paper.AutoExpire", false); // Paper - Expand FallingBlock API } @Override -@@ -305,8 +_,9 @@ - this.fallDamagePerDistance = compound.getFloatOr("FallHurtAmount", 0.0F); - this.fallDamageMax = compound.getIntOr("FallHurtMax", 40); - this.dropItem = compound.getBooleanOr("DropItem", true); -- this.blockData = compound.getCompound("TileEntityData").map(CompoundTag::copy).orElse(null); -+ this.blockData = compound.getCompound("TileEntityData").map(blockData -> this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock ? null : blockData).map(CompoundTag::copy).orElse(null); // Paper - Filter bad block entity nbt data from falling blocks - this.cancelDrop = compound.getBooleanOr("CancelDrop", false); -+ this.autoExpire = compound.getBooleanOr("Paper.AutoExpire", true); // Paper - Expand FallingBlock API +@@ -310,8 +_,9 @@ + this.fallDamagePerDistance = input.getFloatOr("FallHurtAmount", 0.0F); + this.fallDamageMax = input.getIntOr("FallHurtMax", 40); + this.dropItem = input.getBooleanOr("DropItem", true); +- this.blockData = input.read("TileEntityData", CompoundTag.CODEC).orElse(null); ++ this.blockData = input.read("TileEntityData", CompoundTag.CODEC).map(blockData -> this.level().paperConfig().entities.spawning.filterBadTileEntityNbtFromFallingBlocks && this.blockState.getBlock() instanceof net.minecraft.world.level.block.GameMasterBlock ? null : blockData).map(CompoundTag::copy).orElse(null); // Paper - Filter bad block entity nbt data from falling blocks + this.cancelDrop = input.getBooleanOr("CancelDrop", false); ++ this.autoExpire = input.getBooleanOr("Paper.AutoExpire", true); // Paper - Expand FallingBlock API } public void setHurtsEntities(float fallDamagePerDistance, int fallDamageMax) { -@@ -363,7 +_,7 @@ +@@ -368,7 +_,7 @@ ResourceKey resourceKey1 = this.level().dimension(); boolean flag = (resourceKey1 == Level.END || resourceKey == Level.END) && resourceKey1 != resourceKey; Entity entity = super.teleport(teleportTransition); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch index 6f1d0c32b9..f3eb513394 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/ItemEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/item/ItemEntity.java +++ b/net/minecraft/world/entity/item/ItemEntity.java -@@ -56,6 +_,9 @@ +@@ -53,6 +_,9 @@ @Nullable public UUID target; public final float bobOffs; @@ -10,7 +10,7 @@ public ItemEntity(EntityType entityType, Level level) { super(entityType, level); -@@ -64,7 +_,12 @@ +@@ -61,7 +_,12 @@ } public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack) { @@ -24,7 +24,7 @@ } public ItemEntity(Level level, double posX, double posY, double posZ, ItemStack itemStack, double deltaX, double deltaY, double deltaZ) { -@@ -126,7 +_,7 @@ +@@ -116,7 +_,7 @@ @Override public void tick() { if (this.getItem().isEmpty()) { @@ -33,7 +33,7 @@ } else { super.tick(); if (this.pickupDelay > 0 && this.pickupDelay != 32767) { -@@ -154,11 +_,15 @@ +@@ -144,11 +_,15 @@ } } @@ -51,7 +51,7 @@ f = this.level().getBlockState(this.getBlockPosBelowThatAffectsMyMovement()).getBlock().getFriction() * 0.98F; } -@@ -191,8 +_,14 @@ +@@ -181,8 +_,14 @@ } } @@ -68,7 +68,7 @@ } } } -@@ -217,9 +_,18 @@ +@@ -207,9 +_,18 @@ private void mergeWithNeighbours() { if (this.isMergable()) { @@ -88,7 +88,7 @@ this.tryToMerge(itemEntity); if (this.isRemoved()) { break; -@@ -231,7 +_,7 @@ +@@ -221,7 +_,7 @@ private boolean isMergable() { ItemStack item = this.getItem(); @@ -97,7 +97,7 @@ } private void tryToMerge(ItemEntity itemEntity) { -@@ -264,11 +_,16 @@ +@@ -254,11 +_,16 @@ } private static void merge(ItemEntity destinationEntity, ItemStack destinationStack, ItemEntity originEntity, ItemStack originStack) { @@ -115,7 +115,7 @@ } } -@@ -296,12 +_,17 @@ +@@ -286,12 +_,17 @@ } else if (!this.getItem().canBeHurtBy(damageSource)) { return false; } else { @@ -134,25 +134,24 @@ } return true; -@@ -324,6 +_,11 @@ - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - compound.store("Item", ItemStack.CODEC, registryOps, this.getItem()); +@@ -313,6 +_,11 @@ + if (!this.getItem().isEmpty()) { + output.store("Item", ItemStack.CODEC, this.getItem()); } + // Paper start - Friction API + if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { -+ compound.putString("Paper.FrictionState", this.frictionState.toString()); ++ output.putString("Paper.FrictionState", this.frictionState.toString()); + } + // Paper end - Friction API } @Override -@@ -336,8 +_,19 @@ - this.cachedThrower = null; - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - this.setItem(compound.read("Item", ItemStack.CODEC, registryOps).orElse(ItemStack.EMPTY)); -+ +@@ -323,8 +_,17 @@ + this.target = input.read("Owner", UUIDUtil.CODEC).orElse(null); + this.thrower = EntityReference.read(input, "Thrower"); + this.setItem(input.read("Item", ItemStack.CODEC).orElse(ItemStack.EMPTY)); + // Paper start - Friction API -+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> { ++ input.getString("Paper.FrictionState").ifPresent(frictionState -> { + try { + this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState); + } catch (Exception ignored) { @@ -160,14 +159,13 @@ + } + }); + // Paper end - Friction API -+ if (this.getItem().isEmpty()) { - this.discard(); + this.discard(null); // CraftBukkit - add Bukkit remove cause } } -@@ -347,10 +_,73 @@ +@@ -334,10 +_,73 @@ ItemStack item = this.getItem(); Item item1 = item.getItem(); int count = item.getCount(); @@ -242,7 +240,7 @@ item.setCount(count); } -@@ -388,6 +_,7 @@ +@@ -375,6 +_,7 @@ public void setItem(ItemStack stack) { this.getEntityData().set(DATA_ITEM, stack); @@ -250,7 +248,7 @@ } @Override -@@ -441,7 +_,7 @@ +@@ -427,7 +_,7 @@ public void makeFakeItem() { this.setNeverPickUp(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch index 2908b32d6a..20915bf21e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/item/PrimedTnt.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/item/PrimedTnt.java +++ b/net/minecraft/world/entity/item/PrimedTnt.java -@@ -29,6 +_,12 @@ - import net.minecraft.world.level.material.FluidState; - import net.minecraft.world.level.portal.TeleportTransition; +@@ -28,6 +_,12 @@ + import net.minecraft.world.level.storage.ValueInput; + import net.minecraft.world.level.storage.ValueOutput; +// CraftBukkit start +import org.bukkit.craftbukkit.event.CraftEventFactory; @@ -13,15 +13,15 @@ public class PrimedTnt extends Entity implements TraceableEntity { private static final EntityDataAccessor DATA_FUSE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.INT); private static final EntityDataAccessor DATA_BLOCK_STATE_ID = SynchedEntityData.defineId(PrimedTnt.class, EntityDataSerializers.BLOCK_STATE); -@@ -53,6 +_,7 @@ - public LivingEntity owner; +@@ -52,6 +_,7 @@ + public EntityReference owner; private boolean usedPortal; public float explosionPower = 4.0F; + public boolean isIncendiary = false; // CraftBukkit public PrimedTnt(EntityType entityType, Level level) { super(entityType, level); -@@ -62,7 +_,7 @@ +@@ -61,7 +_,7 @@ public PrimedTnt(Level level, double x, double y, double z, @Nullable LivingEntity owner) { this(EntityType.TNT, level); this.setPos(x, y, z); @@ -30,7 +30,7 @@ this.setDeltaMovement(-Math.sin(d) * 0.02, 0.2F, -Math.cos(d) * 0.02); this.setFuse(80); this.xo = x; -@@ -94,10 +_,17 @@ +@@ -93,10 +_,17 @@ @Override public void tick() { @@ -48,7 +48,7 @@ this.setDeltaMovement(this.getDeltaMovement().scale(0.98)); if (this.onGround()) { this.setDeltaMovement(this.getDeltaMovement().multiply(0.7, -0.5, 0.7)); -@@ -106,20 +_,50 @@ +@@ -105,20 +_,50 @@ int i = this.getFuse() - 1; this.setFuse(i); if (i <= 0) { @@ -100,7 +100,7 @@ this.level() .explode( this, -@@ -128,8 +_,8 @@ +@@ -127,8 +_,8 @@ this.getX(), this.getY(0.0625), this.getZ(), diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch index f90f7c5153..4b66486e6a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/AbstractSkeleton.java.patch @@ -64,22 +64,22 @@ this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F)); @@ -222,11 +_,22 @@ - public void readAdditionalSaveData(CompoundTag compound) { - super.readAdditionalSaveData(compound); + protected void readAdditionalSaveData(ValueInput input) { + super.readAdditionalSaveData(input); this.reassessWeaponGoal(); - } - - @Override - public void onEquipItem(EquipmentSlot slot, ItemStack oldItem, ItemStack newItem) { - super.onEquipItem(slot, oldItem, newItem); -+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API ++ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - shouldBurnInDay API + } + + // Paper start - shouldBurnInDay API + @Override -+ public void addAdditionalSaveData(final net.minecraft.nbt.CompoundTag nbt) { -+ super.addAdditionalSaveData(nbt); -+ nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); ++ protected void addAdditionalSaveData(final net.minecraft.world.level.storage.ValueOutput output) { ++ super.addAdditionalSaveData(output); ++ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); + } + // Paper end - shouldBurnInDay API + diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch index 860b3734ce..b672095d97 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Bogged.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Bogged.java +++ b/net/minecraft/world/entity/monster/Bogged.java -@@ -73,7 +_,19 @@ +@@ -74,7 +_,19 @@ ItemStack itemInHand = player.getItemInHand(hand); if (itemInHand.is(Items.SHEARS) && this.readyForShearing()) { if (this.level() instanceof ServerLevel serverLevel) { @@ -21,7 +21,7 @@ this.gameEvent(GameEvent.SHEAR, player); itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); } -@@ -126,15 +_,33 @@ +@@ -127,15 +_,33 @@ @Override public void shear(ServerLevel level, SoundSource soundSource, ItemStack shears) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch index 752d2aaf67..a0754ed3e1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Creeper.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Creeper.java +++ b/net/minecraft/world/entity/monster/Creeper.java -@@ -53,6 +_,7 @@ +@@ -54,6 +_,7 @@ public int maxSwell = 30; public int explosionRadius = 3; private int droppedSkulls; @@ -8,16 +8,16 @@ public Creeper(EntityType entityType, Level level) { super(entityType, level); -@@ -116,7 +_,7 @@ - this.maxSwell = compound.getShortOr("Fuse", (short)30); - this.explosionRadius = compound.getByteOr("ExplosionRadius", (byte)3); - if (compound.getBooleanOr("ignited", false)) { +@@ -117,7 +_,7 @@ + this.maxSwell = input.getShortOr("Fuse", (short)30); + this.explosionRadius = input.getByteOr("ExplosionRadius", (byte)3); + if (input.getBooleanOr("ignited", false)) { - this.ignite(); + this.entityData.set(DATA_IS_IGNITED, true); // Paper - set directly to avoid firing event } } -@@ -149,10 +_,11 @@ +@@ -150,10 +_,11 @@ } @Override @@ -31,7 +31,7 @@ } @Override -@@ -199,9 +_,20 @@ +@@ -200,9 +_,20 @@ @Override public void thunderHit(ServerLevel level, LightningBolt lightning) { super.thunderHit(level, lightning); @@ -52,7 +52,7 @@ @Override protected InteractionResult mobInteract(Player player, InteractionHand hand) { ItemStack itemInHand = player.getItemInHand(hand); -@@ -210,8 +_,9 @@ +@@ -211,8 +_,9 @@ this.level() .playSound(player, this.getX(), this.getY(), this.getZ(), soundEvent, this.getSoundSource(), 1.0F, this.random.nextFloat() * 0.4F + 0.8F); if (!this.level().isClientSide) { @@ -63,7 +63,7 @@ itemInHand.shrink(1); } else { itemInHand.hurtAndBreak(1, player, getSlotForHand(hand)); -@@ -227,18 +_,29 @@ +@@ -228,18 +_,29 @@ public void explodeCreeper() { if (this.level() instanceof ServerLevel serverLevel) { float f = this.isPowered() ? 2.0F : 1.0F; @@ -96,7 +96,7 @@ areaEffectCloud.setRadius(2.5F); areaEffectCloud.setRadiusOnUse(-0.5F); areaEffectCloud.setWaitTime(10); -@@ -250,16 +_,27 @@ +@@ -251,16 +_,27 @@ areaEffectCloud.addEffect(new MobEffectInstance(mobEffectInstance)); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Drowned.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Drowned.java.patch index f28da7213d..766d4594da 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Drowned.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Drowned.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Drowned.java +++ b/net/minecraft/world/entity/monster/Drowned.java -@@ -85,7 +_,7 @@ +@@ -86,7 +_,7 @@ this.goalSelector.addGoal(7, new RandomStrollGoal(this, 1.0)); this.targetSelector.addGoal(1, new HurtByTargetGoal(this, Drowned.class).setAlertOthers(ZombifiedPiglin.class)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, (entity, level) -> this.okTarget(entity))); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch index 363c0d10d2..d8bae77513 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/EnderMan.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/EnderMan.java +++ b/net/minecraft/world/entity/monster/EnderMan.java -@@ -116,9 +_,20 @@ +@@ -114,9 +_,20 @@ .add(Attributes.STEP_HEIGHT, 1.0); } @@ -23,7 +23,7 @@ AttributeInstance attribute = this.getAttribute(Attributes.MOVEMENT_SPEED); if (livingEntity == null) { this.targetChangeTime = 0; -@@ -132,6 +_,7 @@ +@@ -130,6 +_,7 @@ attribute.addTransientModifier(SPEED_MODIFIER_ATTACKING); } } @@ -31,7 +31,7 @@ } @Override -@@ -207,6 +_,15 @@ +@@ -203,6 +_,15 @@ } boolean isBeingStaredBy(Player player) { @@ -47,7 +47,7 @@ return LivingEntity.PLAYER_NOT_WEARING_DISGUISE_ITEM.test(player) && this.isLookingAtMe(player, 0.025, true, false, new double[]{this.getEyeY()}); } -@@ -246,7 +_,7 @@ +@@ -242,7 +_,7 @@ float lightLevelDependentMagicValue = this.getLightLevelDependentMagicValue(); if (lightLevelDependentMagicValue > 0.5F && level.canSeeSky(this.blockPosition()) @@ -56,7 +56,7 @@ this.setTarget(null); this.teleport(); } -@@ -359,21 +_,25 @@ +@@ -355,21 +_,25 @@ AbstractThrownPotion abstractThrownPotion1 = damageSource.getDirectEntity() instanceof AbstractThrownPotion abstractThrownPotion ? abstractThrownPotion : null; @@ -83,7 +83,7 @@ return flag; } -@@ -398,6 +_,16 @@ +@@ -394,6 +_,16 @@ this.entityData.set(DATA_STARED_AT, true); } @@ -100,7 +100,7 @@ @Override public boolean requiresCustomPersistence() { return super.requiresCustomPersistence() || this.getCarriedBlock() != null; -@@ -457,16 +_,19 @@ +@@ -453,16 +_,19 @@ int floor1 = Mth.floor(this.enderman.getY() + random.nextDouble() * 2.0); int floor2 = Mth.floor(this.enderman.getZ() - 1.0 + random.nextDouble() * 2.0); BlockPos blockPos = new BlockPos(floor, floor1, floor2); @@ -121,7 +121,7 @@ } } } -@@ -564,7 +_,7 @@ +@@ -560,7 +_,7 @@ } else { if (this.target != null && !this.enderman.isPassenger()) { if (this.enderman.isBeingStaredBy((Player)this.target)) { @@ -130,7 +130,7 @@ this.enderman.teleport(); } -@@ -603,15 +_,18 @@ +@@ -599,15 +_,18 @@ int floor1 = Mth.floor(this.enderman.getY() + random.nextDouble() * 3.0); int floor2 = Mth.floor(this.enderman.getZ() - 2.0 + random.nextDouble() * 4.0); BlockPos blockPos = new BlockPos(floor, floor1, floor2); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Endermite.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Endermite.java.patch index c7ee828a8b..1ad07be537 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Endermite.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Endermite.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Endermite.java +++ b/net/minecraft/world/entity/monster/Endermite.java -@@ -122,7 +_,7 @@ +@@ -123,7 +_,7 @@ } if (this.life >= 2400) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Evoker.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Evoker.java.patch index 5329db11c5..ebbd045b20 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Evoker.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Evoker.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Evoker.java +++ b/net/minecraft/world/entity/monster/Evoker.java -@@ -264,7 +_,7 @@ +@@ -247,7 +_,7 @@ serverLevel.getScoreboard().addPlayerToTeam(vex.getScoreboardName(), team); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch index b6a2416463..5428be8f21 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ghast.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Ghast.java +++ b/net/minecraft/world/entity/monster/Ghast.java -@@ -64,6 +_,12 @@ +@@ -73,6 +_,12 @@ return this.explosionPower; } @@ -13,7 +13,7 @@ @Override protected boolean shouldDespawnInPeaceful() { return true; -@@ -276,6 +_,7 @@ +@@ -372,6 +_,7 @@ } LargeFireball largeFireball = new LargeFireball(level, this.ghast, vec3.normalize(), this.ghast.getExplosionPower()); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch index 8f0a286259..bb7b266104 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Phantom.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Phantom.java +++ b/net/minecraft/world/entity/monster/Phantom.java -@@ -48,6 +_,11 @@ +@@ -49,6 +_,11 @@ @Nullable public BlockPos anchorPoint; Phantom.AttackPhase attackPhase = Phantom.AttackPhase.CIRCLE; @@ -12,7 +12,7 @@ public Phantom(EntityType entityType, Level level) { super(entityType, level); -@@ -142,7 +_,7 @@ +@@ -143,7 +_,7 @@ @Override public void aiStep() { @@ -21,29 +21,29 @@ this.igniteForSeconds(8.0F); } -@@ -163,6 +_,10 @@ - super.readAdditionalSaveData(compound); - this.anchorPoint = compound.read("anchor_pos", BlockPos.CODEC).orElse(null); - this.setPhantomSize(compound.getIntOr("size", 0)); +@@ -178,6 +_,10 @@ + super.readAdditionalSaveData(input); + this.anchorPoint = input.read("anchor_pos", BlockPos.CODEC).orElse(null); + this.setPhantomSize(input.getIntOr("size", 0)); + // Paper start -+ this.spawningEntity = compound.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); -+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); ++ this.spawningEntity = input.read("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); ++ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); + // Paper end } @Override -@@ -170,6 +_,10 @@ - super.addAdditionalSaveData(compound); - compound.storeNullable("anchor_pos", BlockPos.CODEC, this.anchorPoint); - compound.putInt("size", this.getPhantomSize()); +@@ -185,6 +_,10 @@ + super.addAdditionalSaveData(output); + output.storeNullable("anchor_pos", BlockPos.CODEC, this.anchorPoint); + output.putInt("size", this.getPhantomSize()); + // Paper start -+ compound.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); -+ compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); ++ output.storeNullable("Paper.SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); ++ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); + // Paper end } @Override -@@ -243,7 +_,8 @@ +@@ -258,7 +_,8 @@ for (Player player : nearbyPlayers) { if (Phantom.this.canAttack(serverLevel, player, TargetingConditions.DEFAULT)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Pillager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Pillager.java.patch index baac9f090b..1df33fe9b1 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Pillager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Pillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Pillager.java +++ b/net/minecraft/world/entity/monster/Pillager.java -@@ -214,7 +_,7 @@ +@@ -215,7 +_,7 @@ this.onItemPickup(entity); ItemStack itemStack = this.inventory.addItem(item); if (itemStack.isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch index 08ac93679e..2e53eba6ad 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Ravager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Ravager.java +++ b/net/minecraft/world/entity/monster/Ravager.java -@@ -154,12 +_,19 @@ +@@ -155,12 +_,19 @@ BlockState blockState = serverLevel.getBlockState(blockPos); Block block = blockState.getBlock(); if (block instanceof LeavesBlock) { @@ -20,7 +20,7 @@ } } -@@ -260,7 +_,7 @@ +@@ -252,7 +_,7 @@ double d = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); double max = Math.max(d * d + d1 * d1, 0.001); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch index ce2d73c67c..dc34e2bb75 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Shulker.java +++ b/net/minecraft/world/entity/monster/Shulker.java -@@ -277,7 +_,13 @@ +@@ -278,7 +_,13 @@ @Override public void stopRiding() { @@ -15,7 +15,7 @@ if (this.level().isClientSide) { this.clientOldAttachPosition = this.blockPosition(); } -@@ -390,6 +_,14 @@ +@@ -391,6 +_,14 @@ && this.level().getWorldBorder().isWithinBounds(blockPos1) && this.level().noCollision(this, new AABB(blockPos1).deflate(1.0E-6))) { Direction direction = this.findAttachableSurface(blockPos1); @@ -30,7 +30,7 @@ if (direction != null) { this.unRide(); this.setAttachFace(direction); -@@ -454,7 +_,12 @@ +@@ -455,7 +_,12 @@ if (shulker != null) { shulker.setVariant(this.getVariant()); shulker.snapTo(vec3); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Skeleton.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Skeleton.java.patch index 15552624ca..9ca4e99b2a 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Skeleton.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Skeleton.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Skeleton.java +++ b/net/minecraft/world/entity/monster/Skeleton.java -@@ -93,11 +_,17 @@ +@@ -94,11 +_,17 @@ } protected void doFreezeConversion() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch index 92cbd9db79..1aa9141d46 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Slime.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Slime.java +++ b/net/minecraft/world/entity/monster/Slime.java -@@ -57,6 +_,7 @@ +@@ -58,6 +_,7 @@ public float squish; public float oSquish; private boolean wasOnGround = false; @@ -8,23 +8,23 @@ public Slime(EntityType entityType, Level level) { super(entityType, level); -@@ -111,6 +_,7 @@ - super.addAdditionalSaveData(compound); - compound.putInt("Size", this.getSize() - 1); - compound.putBoolean("wasOnGround", this.wasOnGround); -+ compound.putBoolean("Paper.canWander", this.canWander); // Paper +@@ -112,6 +_,7 @@ + super.addAdditionalSaveData(output); + output.putInt("Size", this.getSize() - 1); + output.putBoolean("wasOnGround", this.wasOnGround); ++ output.putBoolean("Paper.canWander", this.canWander); // Paper } @Override -@@ -118,6 +_,7 @@ - this.setSize(compound.getIntOr("Size", 0) + 1, false); - super.readAdditionalSaveData(compound); - this.wasOnGround = compound.getBooleanOr("wasOnGround", false); -+ this.canWander = compound.getBooleanOr("Paper.canWander", true); // Paper +@@ -119,6 +_,7 @@ + this.setSize(input.getIntOr("Size", 0) + 1, false); + super.readAdditionalSaveData(input); + this.wasOnGround = input.getBooleanOr("wasOnGround", false); ++ this.canWander = input.getBooleanOr("Paper.canWander", true); // Paper } public boolean isTiny() { -@@ -197,7 +_,7 @@ +@@ -198,7 +_,7 @@ } @Override @@ -33,7 +33,7 @@ int size = this.getSize(); if (!this.level().isClientSide && size > 1 && this.isDeadOrDying()) { float width = this.getDimensions(this.getPose()).width(); -@@ -205,18 +_,43 @@ +@@ -206,18 +_,43 @@ int i = size / 2; int i1 = 2 + this.random.nextInt(3); PlayerTeam team = this.getTeam(); @@ -81,7 +81,7 @@ } @Override -@@ -282,9 +_,13 @@ +@@ -283,9 +_,13 @@ return checkMobSpawnRules(entityType, level, spawnReason, pos, random); } @@ -97,7 +97,7 @@ && random.nextFloat() < 0.5F && random.nextFloat() < level.getMoonBrightness() && level.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) { -@@ -296,8 +_,11 @@ +@@ -297,8 +_,11 @@ } ChunkPos chunkPos = new ChunkPos(pos); @@ -111,7 +111,7 @@ return checkMobSpawnRules(entityType, level, spawnReason, pos, random); } } -@@ -356,6 +_,16 @@ +@@ -357,6 +_,16 @@ return super.getDefaultDimensions(pose).scale(this.getSize()); } @@ -128,7 +128,7 @@ static class SlimeAttackGoal extends Goal { private final Slime slime; private int growTiredTimer; -@@ -368,7 +_,16 @@ +@@ -369,7 +_,16 @@ @Override public boolean canUse() { LivingEntity target = this.slime.getTarget(); @@ -146,7 +146,7 @@ } @Override -@@ -380,7 +_,16 @@ +@@ -381,7 +_,16 @@ @Override public boolean canContinueToUse() { LivingEntity target = this.slime.getTarget(); @@ -164,7 +164,7 @@ } @Override -@@ -399,6 +_,13 @@ +@@ -400,6 +_,13 @@ slimeMoveControl.setDirection(this.slime.getYRot(), this.slime.isDealsDamage()); } } @@ -178,7 +178,7 @@ } static class SlimeFloatGoal extends Goal { -@@ -412,7 +_,7 @@ +@@ -413,7 +_,7 @@ @Override public boolean canUse() { @@ -187,7 +187,7 @@ } @Override -@@ -442,7 +_,7 @@ +@@ -443,7 +_,7 @@ @Override public boolean canUse() { @@ -196,7 +196,7 @@ } @Override -@@ -520,7 +_,7 @@ +@@ -521,7 +_,7 @@ @Override public boolean canUse() { @@ -205,7 +205,7 @@ && (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl; } -@@ -530,6 +_,11 @@ +@@ -531,6 +_,11 @@ if (--this.nextRandomizeTime <= 0) { this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60)); this.chosenDegrees = this.slime.getRandom().nextInt(360); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/SpellcasterIllager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/SpellcasterIllager.java.patch index 37a4f010c1..b959b59a0e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/SpellcasterIllager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/SpellcasterIllager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/SpellcasterIllager.java +++ b/net/minecraft/world/entity/monster/SpellcasterIllager.java -@@ -209,6 +_,11 @@ +@@ -210,6 +_,11 @@ public void tick() { this.attackWarmupDelay--; if (this.attackWarmupDelay == 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Vex.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Vex.java.patch index fe70c2af71..0b1c9a9bdd 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Vex.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Vex.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/monster/Vex.java +++ b/net/minecraft/world/entity/monster/Vex.java -@@ -286,7 +_,7 @@ - +@@ -293,7 +_,7 @@ @Override public void start() { -- Vex.this.setTarget(Vex.this.owner.getTarget()); -+ Vex.this.setTarget(Vex.this.owner.getTarget(), org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET); // CraftBukkit + Mob owner = Vex.this.getOwner(); +- Vex.this.setTarget(owner != null ? owner.getTarget() : null); ++ Vex.this.setTarget(owner != null ? owner.getTarget() : null, org.bukkit.event.entity.EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET); // CraftBukkit super.start(); } } -@@ -345,7 +_,10 @@ +@@ -352,7 +_,10 @@ for (int i = 0; i < 3; i++) { BlockPos blockPos = boundOrigin.offset(Vex.this.random.nextInt(15) - 7, Vex.this.random.nextInt(11) - 5, Vex.this.random.nextInt(15) - 7); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch index 3d00b8fa85..70543fd76e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Vindicator.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Vindicator.java +++ b/net/minecraft/world/entity/monster/Vindicator.java -@@ -183,7 +_,7 @@ +@@ -184,7 +_,7 @@ static class VindicatorBreakDoorGoal extends BreakDoorGoal { public VindicatorBreakDoorGoal(Mob mob) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch index 2d2f46e638..b5c0e44801 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Zombie.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/Zombie.java +++ b/net/minecraft/world/entity/monster/Zombie.java -@@ -68,9 +_,7 @@ +@@ -67,9 +_,7 @@ public class Zombie extends Monster { private static final ResourceLocation SPEED_MODIFIER_BABY_ID = ResourceLocation.withDefaultNamespace("baby"); @@ -11,7 +11,7 @@ private static final ResourceLocation REINFORCEMENT_CALLER_CHARGE_ID = ResourceLocation.withDefaultNamespace("reinforcement_caller_charge"); private static final AttributeModifier ZOMBIE_REINFORCEMENT_CALLEE_CHARGE = new AttributeModifier( ResourceLocation.withDefaultNamespace("reinforcement_callee_charge"), -0.05F, AttributeModifier.Operation.ADD_VALUE -@@ -91,13 +_,15 @@ +@@ -90,13 +_,15 @@ private static final boolean DEFAULT_BABY = false; private static final boolean DEFAULT_CAN_BREAK_DOORS = false; private static final int DEFAULT_IN_WATER_TIME = 0; @@ -28,7 +28,7 @@ } public Zombie(Level level) { -@@ -106,7 +_,7 @@ +@@ -105,7 +_,7 @@ @Override protected void registerGoals() { @@ -37,7 +37,7 @@ this.goalSelector.addGoal(8, new LookAtPlayerGoal(this, Player.class, 8.0F)); this.goalSelector.addGoal(8, new RandomLookAroundGoal(this)); this.addBehaviourGoals(); -@@ -118,7 +_,7 @@ +@@ -117,7 +_,7 @@ this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0)); this.targetSelector.addGoal(1, new HurtByTargetGoal(this).setAlertOthers(ZombifiedPiglin.class)); this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, true)); @@ -46,7 +46,7 @@ this.targetSelector.addGoal(3, new NearestAttackableTargetGoal<>(this, IronGolem.class, true)); this.targetSelector.addGoal(5, new NearestAttackableTargetGoal<>(this, Turtle.class, 10, true, false, Turtle.BABY_ON_LAND_SELECTOR)); } -@@ -172,11 +_,16 @@ +@@ -171,11 +_,16 @@ @Override protected int getBaseExperienceReward(ServerLevel level) { @@ -64,7 +64,7 @@ } @Override -@@ -184,9 +_,9 @@ +@@ -183,9 +_,9 @@ this.getEntityData().set(DATA_BABY_ID, childZombie); if (this.level() != null && !this.level().isClientSide) { AttributeInstance attribute = this.getAttribute(Attributes.MOVEMENT_SPEED); @@ -76,7 +76,7 @@ } } } -@@ -255,6 +_,13 @@ +@@ -254,6 +_,13 @@ super.aiStep(); } @@ -90,7 +90,7 @@ public void startUnderWaterConversion(int conversionTime) { this.conversionTime = conversionTime; this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, true); -@@ -268,31 +_,50 @@ +@@ -267,31 +_,50 @@ } protected void convertToZombieType(EntityType entityType) { @@ -150,7 +150,7 @@ @Override public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { -@@ -325,13 +_,13 @@ +@@ -324,13 +_,13 @@ if (SpawnPlacements.isSpawnPositionOk(type, level, blockPos) && SpawnPlacements.checkSpawnRules(type, level, EntitySpawnReason.REINFORCEMENT, blockPos, level.random)) { zombie.setPos(i1, i2, i3); @@ -167,7 +167,7 @@ AttributeInstance attribute = this.getAttribute(Attributes.SPAWN_REINFORCEMENTS_CHANCE); AttributeModifier modifier = attribute.getModifier(REINFORCEMENT_CALLER_CHARGE_ID); double d = modifier != null ? modifier.amount() : 0.0; -@@ -356,7 +_,12 @@ +@@ -355,7 +_,12 @@ if (flag) { float effectiveDifficulty = this.level().getCurrentDifficultyAt(this.blockPosition()).getEffectiveDifficulty(); if (this.getMainHandItem().isEmpty() && this.isOnFire() && this.random.nextFloat() < effectiveDifficulty * 0.3F) { @@ -181,19 +181,19 @@ } } -@@ -416,6 +_,7 @@ - compound.putBoolean("CanBreakDoors", this.canBreakDoors()); - compound.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); - compound.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); -+ compound.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API +@@ -415,6 +_,7 @@ + output.putBoolean("CanBreakDoors", this.canBreakDoors()); + output.putInt("InWaterTime", this.isInWater() ? this.inWaterTime : -1); + output.putInt("DrownedConversionTime", this.isUnderWaterConverting() ? this.conversionTime : -1); ++ output.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay); // Paper - Add more Zombie API } @Override -@@ -430,13 +_,15 @@ +@@ -429,13 +_,15 @@ } else { this.getEntityData().set(DATA_DROWNED_CONVERSION_ID, false); } -+ this.shouldBurnInDay = compound.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API ++ this.shouldBurnInDay = input.getBooleanOr("Paper.ShouldBurnInDay", true); // Paper - Add more Zombie API } @Override @@ -207,7 +207,7 @@ return flag; } -@@ -472,7 +_,7 @@ +@@ -471,7 +_,7 @@ spawnGroupData = super.finalizeSpawn(level, difficulty, spawnReason, spawnGroupData); float specialMultiplier = difficulty.getSpecialMultiplier(); if (spawnReason != EntitySpawnReason.CONVERSION) { @@ -216,7 +216,7 @@ } if (spawnGroupData == null) { -@@ -499,7 +_,7 @@ +@@ -498,7 +_,7 @@ chicken1.finalizeSpawn(level, difficulty, EntitySpawnReason.JOCKEY, null); chicken1.setChickenJockey(true); this.startRiding(chicken1); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch index abef56c219..cb8a3b8de2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombieVillager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/ZombieVillager.java +++ b/net/minecraft/world/entity/monster/ZombieVillager.java -@@ -160,12 +_,20 @@ +@@ -159,12 +_,20 @@ } public void startConverting(@Nullable UUID conversionStarter, int villagerConversionTime) { @@ -24,7 +24,7 @@ } @Override -@@ -190,7 +_,7 @@ +@@ -189,7 +_,7 @@ } private void finishConversion(ServerLevel level) { @@ -32,21 +32,21 @@ + Villager converted = this.convertTo( // CraftBukkit EntityType.VILLAGER, ConversionParams.single(this, false, false), - villager -> { -@@ -214,19 +_,24 @@ - villager.finalizeSpawn(level, level.getCurrentDifficultyAt(villager.blockPosition()), EntitySpawnReason.CONVERSION, null); - villager.refreshBrain(level); + mob -> { +@@ -213,19 +_,24 @@ + mob.finalizeSpawn(level, level.getCurrentDifficultyAt(mob.blockPosition()), EntitySpawnReason.CONVERSION, null); + mob.refreshBrain(level); if (this.conversionStarter != null) { - Player playerByUuid = level.getPlayerByUUID(this.conversionStarter); + Player playerByUuid = level.getGlobalPlayerByUUID(this.conversionStarter); // Paper - check global player list where appropriate if (playerByUuid instanceof ServerPlayer) { - CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, villager); - level.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, villager); + CriteriaTriggers.CURED_ZOMBIE_VILLAGER.trigger((ServerPlayer)playerByUuid, this, mob); + level.onReputationEvent(ReputationEventType.ZOMBIE_VILLAGER_CURED, playerByUuid, mob); } } -- villager.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0)); -+ villager.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit +- mob.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0)); ++ mob.addEffect(new MobEffectInstance(MobEffects.NAUSEA, 200, 0), org.bukkit.event.entity.EntityPotionEffectEvent.Cause.CONVERSION); // CraftBukkit if (!this.isSilent()) { level.levelEvent(null, 1027, this.blockPosition(), 0); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombifiedPiglin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombifiedPiglin.java.patch index d01e312425..f937a033e8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombifiedPiglin.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/ZombifiedPiglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/ZombifiedPiglin.java +++ b/net/minecraft/world/entity/monster/ZombifiedPiglin.java -@@ -56,6 +_,7 @@ +@@ -57,6 +_,7 @@ private static final int ALERT_RANGE_Y = 10; private static final UniformInt ALERT_INTERVAL = TimeUtil.rangeOfSeconds(4, 6); private int ticksUntilNextAlert; @@ -8,7 +8,7 @@ public ZombifiedPiglin(EntityType entityType, Level level) { super(entityType, level); -@@ -71,7 +_,7 @@ +@@ -72,7 +_,7 @@ protected void addBehaviourGoals() { this.goalSelector.addGoal(2, new ZombieAttackGoal(this, 1.0, false)); this.goalSelector.addGoal(7, new WaterAvoidingRandomStrollGoal(this, 1.0)); @@ -17,7 +17,7 @@ this.targetSelector.addGoal(2, new NearestAttackableTargetGoal<>(this, Player.class, 10, true, false, this::isAngryAt)); this.targetSelector.addGoal(3, new ResetUniversalAngerTargetGoal<>(this, true)); } -@@ -144,7 +_,7 @@ +@@ -145,7 +_,7 @@ .filter(zombifiedPiglin -> zombifiedPiglin != this) .filter(zombifiedPiglin -> zombifiedPiglin.getTarget() == null) .filter(zombifiedPiglin -> !zombifiedPiglin.isAlliedTo(this.getTarget())) @@ -26,7 +26,7 @@ } private void playAngerSound() { -@@ -152,18 +_,27 @@ +@@ -153,18 +_,27 @@ } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch index 6637f43a8f..9c22b2427b 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/creaking/Creaking.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/creaking/Creaking.java +++ b/net/minecraft/world/entity/monster/creaking/Creaking.java -@@ -191,9 +_,9 @@ +@@ -192,9 +_,9 @@ } @Override @@ -12,7 +12,7 @@ } } -@@ -318,7 +_,7 @@ +@@ -319,7 +_,7 @@ } this.makeSound(this.getDeathSound()); @@ -21,7 +21,7 @@ } public void creakingDeathEffects(DamageSource damageSource) { -@@ -471,9 +_,9 @@ +@@ -472,9 +_,9 @@ } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch index 1f80452973..3d2981564d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/hoglin/Hoglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/hoglin/Hoglin.java +++ b/net/minecraft/world/entity/monster/hoglin/Hoglin.java -@@ -265,7 +_,12 @@ +@@ -266,7 +_,12 @@ } private void finishConversion() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch index e9702e1120..b9b4c33f01 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java +++ b/net/minecraft/world/entity/monster/piglin/AbstractPiglin.java -@@ -102,9 +_,14 @@ +@@ -101,9 +_,14 @@ } protected void finishConversion(ServerLevel serverLevel) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/Piglin.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/Piglin.java.patch index 30f18c374f..d0b839ed55 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/Piglin.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/piglin/Piglin.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/piglin/Piglin.java +++ b/net/minecraft/world/entity/monster/piglin/Piglin.java -@@ -124,6 +_,12 @@ +@@ -125,6 +_,12 @@ MemoryModuleType.ATE_RECENTLY, MemoryModuleType.NEAREST_REPELLENT ); @@ -13,29 +13,29 @@ public Piglin(EntityType entityType, Level level) { super(entityType, level); -@@ -136,6 +_,10 @@ - compound.putBoolean("IsBaby", this.isBaby()); - compound.putBoolean("CannotHunt", this.cannotHunt); - this.writeInventoryToTag(compound, this.registryAccess()); +@@ -137,6 +_,10 @@ + output.putBoolean("IsBaby", this.isBaby()); + output.putBoolean("CannotHunt", this.cannotHunt); + this.writeInventoryToTag(output); + // CraftBukkit start -+ compound.store("Bukkit.BarterList", ITEM_SET_CODEC, this.allowedBarterItems); -+ compound.store("Bukkit.InterestList", ITEM_SET_CODEC, this.interestItems); ++ output.store("Bukkit.BarterList", ITEM_SET_CODEC, this.allowedBarterItems); ++ output.store("Bukkit.InterestList", ITEM_SET_CODEC, this.interestItems); + // CraftBukkit end } @Override -@@ -144,6 +_,10 @@ - this.setBaby(compound.getBooleanOr("IsBaby", false)); - this.setCannotHunt(compound.getBooleanOr("CannotHunt", false)); - this.readInventoryFromTag(compound, this.registryAccess()); +@@ -145,6 +_,10 @@ + this.setBaby(input.getBooleanOr("IsBaby", false)); + this.setCannotHunt(input.getBooleanOr("CannotHunt", false)); + this.readInventoryFromTag(input); + // CraftBukkit start -+ this.allowedBarterItems = compound.read("Bukkit.BarterList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new); -+ this.interestItems = compound.read("Bukkit.InterestList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new); ++ this.allowedBarterItems = input.read("Bukkit.BarterList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new); ++ this.interestItems = input.read("Bukkit.InterestList", ITEM_SET_CODEC).orElseGet(java.util.HashSet::new); + // CraftBukkit end } @VisibleForDebug -@@ -321,7 +_,9 @@ +@@ -322,7 +_,9 @@ @Override protected void finishConversion(ServerLevel serverLevel) { PiglinAi.cancelAdmiring(serverLevel, this); @@ -45,7 +45,7 @@ super.finishConversion(serverLevel); } -@@ -397,7 +_,7 @@ +@@ -398,7 +_,7 @@ } protected void holdInOffHand(ItemStack stack) { @@ -54,7 +54,7 @@ this.setItemSlot(EquipmentSlot.OFFHAND, stack); this.setGuaranteedDrop(EquipmentSlot.OFFHAND); } else { -@@ -422,15 +_,15 @@ +@@ -423,15 +_,15 @@ return false; } else { TagKey preferredWeaponType = this.getPreferredWeaponType(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/warden/Warden.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/warden/Warden.java.patch index 6818c28f8a..3511c384fc 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/monster/warden/Warden.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/warden/Warden.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/monster/warden/Warden.java +++ b/net/minecraft/world/entity/monster/warden/Warden.java -@@ -404,7 +_,7 @@ +@@ -402,7 +_,7 @@ public static void applyDarknessAround(ServerLevel level, Vec3 pos, @Nullable Entity source, int radius) { MobEffectInstance mobEffectInstance = new MobEffectInstance(MobEffects.DARKNESS, 260, 0, false, false); @@ -9,7 +9,7 @@ } @Override -@@ -450,6 +_,15 @@ +@@ -446,6 +_,15 @@ @VisibleForTesting public void increaseAngerAt(@Nullable Entity entity, int offset, boolean playListeningSound) { if (!this.isNoAi() && this.canTargetEntity(entity)) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch index cfe727be29..99d6601db2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/Villager.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/Villager.java +++ b/net/minecraft/world/entity/npc/Villager.java -@@ -286,7 +_,7 @@ +@@ -287,7 +_,7 @@ this.increaseProfessionLevelOnUpdate = false; } @@ -9,7 +9,7 @@ } } -@@ -395,7 +_,12 @@ +@@ -396,7 +_,12 @@ this.updateDemand(); for (MerchantOffer merchantOffer : this.getOffers()) { @@ -23,7 +23,7 @@ } this.resendOffersToTradingPlayer(); -@@ -456,7 +_,12 @@ +@@ -457,7 +_,12 @@ int i = 2 - this.numberOfRestocksToday; if (i > 0) { for (MerchantOffer merchantOffer : this.getOffers()) { @@ -37,7 +37,7 @@ } } -@@ -477,6 +_,7 @@ +@@ -478,6 +_,7 @@ int playerReputation = this.getPlayerReputation(player); if (playerReputation != 0) { for (MerchantOffer merchantOffer : this.getOffers()) { @@ -45,7 +45,7 @@ merchantOffer.addToSpecialPriceDiff(-Mth.floor(playerReputation * merchantOffer.getPriceMultiplier())); } } -@@ -486,6 +_,7 @@ +@@ -487,6 +_,7 @@ int amplifier = effect.getAmplifier(); for (MerchantOffer merchantOffer1 : this.getOffers()) { @@ -53,7 +53,7 @@ double d = 0.3 + 0.0625 * amplifier; int i = (int)Math.floor(d * merchantOffer1.getBaseCostA().getCount()); merchantOffer1.addToSpecialPriceDiff(-Math.max(i, 1)); -@@ -594,7 +_,7 @@ +@@ -595,7 +_,7 @@ } if (offer.shouldRewardExp()) { @@ -62,7 +62,7 @@ } } -@@ -612,7 +_,7 @@ +@@ -613,7 +_,7 @@ @Override public void die(DamageSource cause) { @@ -71,7 +71,7 @@ Entity entity = cause.getEntity(); if (entity != null) { this.tellWitnessesThatIWasMurdered(entity); -@@ -780,12 +_,19 @@ +@@ -781,12 +_,19 @@ @Override public void thunderHit(ServerLevel level, LightningBolt lightning) { if (level.getDifficulty() != Difficulty.PEACEFUL) { @@ -93,7 +93,7 @@ if (witch == null) { super.thunderHit(level, lightning); } -@@ -825,6 +_,12 @@ +@@ -826,6 +_,12 @@ @Override protected void updateTrades() { @@ -106,7 +106,7 @@ VillagerData villagerData = this.getVillagerData(); ResourceKey resourceKey = villagerData.profession().unwrapKey().orElse(null); if (resourceKey != null) { -@@ -840,10 +_,12 @@ +@@ -841,10 +_,12 @@ VillagerTrades.ItemListing[] itemListings = map1.get(villagerData.level()); if (itemListings != null) { MerchantOffers offers = this.getOffers(); @@ -120,7 +120,7 @@ } public void gossip(ServerLevel serverLevel, Villager target, long gameTime) { -@@ -872,7 +_,7 @@ +@@ -873,7 +_,7 @@ List entitiesOfClass = serverLevel.getEntitiesOfClass(Villager.class, aabb); List list = entitiesOfClass.stream().filter(villager -> villager.wantsToSpawnGolem(gameTime)).limit(5L).toList(); if (list.size() >= minVillagerAmount) { @@ -129,7 +129,7 @@ EntityType.IRON_GOLEM, EntitySpawnReason.MOB_SUMMONED, serverLevel, -@@ -881,9 +_,11 @@ +@@ -882,9 +_,11 @@ 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch index bc4d784f7a..6a9b5fa730 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTrader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/npc/WanderingTrader.java +++ b/net/minecraft/world/entity/npc/WanderingTrader.java -@@ -45,11 +_,15 @@ +@@ -46,11 +_,15 @@ import net.minecraft.world.phys.Vec3; import org.apache.commons.lang3.tuple.Pair; @@ -17,7 +17,7 @@ public WanderingTrader(EntityType entityType, Level level) { super(entityType, level); -@@ -65,7 +_,7 @@ +@@ -66,7 +_,7 @@ this, PotionContents.createItemStack(Items.POTION, Potions.INVISIBILITY), SoundEvents.WANDERING_TRADER_DISAPPEARED, @@ -26,7 +26,7 @@ ) ); this.goalSelector -@@ -75,7 +_,7 @@ +@@ -76,7 +_,7 @@ this, new ItemStack(Items.MILK_BUCKET), SoundEvents.WANDERING_TRADER_REAPPEARED, @@ -35,7 +35,7 @@ ) ); this.goalSelector.addGoal(1, new TradeWithPlayerGoal(this)); -@@ -163,7 +_,7 @@ +@@ -164,7 +_,7 @@ protected void rewardTradeXp(MerchantOffer offer) { if (offer.shouldRewardExp()) { int i = 3 + this.random.nextInt(4); @@ -44,7 +44,7 @@ } } -@@ -215,7 +_,7 @@ +@@ -216,7 +_,7 @@ private void maybeDespawn() { if (this.despawnDelay > 0 && !this.isTrading() && --this.despawnDelay == 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTraderSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTraderSpawner.java.patch index 2b63aabd02..3b665f42b9 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTraderSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/npc/WanderingTraderSpawner.java.patch @@ -81,7 +81,7 @@ - wanderingTrader.setDespawnDelay(48000); + // wanderingTrader.setDespawnDelay(48000); // Paper - moved above, modifiable by plugins on CreatureSpawnEvent wanderingTrader.setWanderTarget(blockPos1); - wanderingTrader.restrictTo(blockPos1, 16); + wanderingTrader.setHomeTo(blockPos1, 16); return true; @@ -112,7 +_,7 @@ private void tryToSpawnLlamaFor(ServerLevel serverLevel, WanderingTrader trader, int maxDistance) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch index 7cc58e6e47..c8c7861a75 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Inventory.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Inventory.java +++ b/net/minecraft/world/entity/player/Inventory.java -@@ -49,6 +_,70 @@ +@@ -56,6 +_,80 @@ public final Player player; public final EntityEquipment equipment; private int timesChanged; @@ -24,9 +24,19 @@ + } + + public java.util.List getArmorContents() { ++ java.util.List items = new java.util.ArrayList<>(4); ++ for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) { ++ if (equipmentSlot.getType() == EquipmentSlot.Type.HUMANOID_ARMOR) { ++ items.add(this.equipment.get(equipmentSlot)); ++ } ++ } ++ return items; ++ } ++ ++ public java.util.List getExtraContent() { + java.util.List items = new java.util.ArrayList<>(); + for (EquipmentSlot equipmentSlot : EQUIPMENT_SLOTS_SORTED_BY_INDEX) { -+ if (equipmentSlot.isArmor()) { ++ if (equipmentSlot.getType() != EquipmentSlot.Type.HUMANOID_ARMOR) { // Non humanoid armor is considered extra + items.add(this.equipment.get(equipmentSlot)); + } + } @@ -71,7 +81,7 @@ public Inventory(Player player, EntityEquipment equipment) { this.player = player; -@@ -85,10 +_,39 @@ +@@ -92,10 +_,39 @@ private boolean hasRemainingSpaceForItem(ItemStack destination, ItemStack origin) { return !destination.isEmpty() @@ -114,7 +124,7 @@ public int getFreeSlot() { for (int i = 0; i < this.items.size(); i++) { -@@ -100,8 +_,10 @@ +@@ -107,8 +_,10 @@ return -1; } @@ -127,7 +137,7 @@ if (!this.items.get(this.selected).isEmpty()) { int freeSlot = this.getFreeSlot(); if (freeSlot != -1) { -@@ -112,8 +_,10 @@ +@@ -119,8 +_,10 @@ this.items.set(this.selected, stack); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch index fec8afea55..e79835e6ac 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/player/Player.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/player/Player.java +++ b/net/minecraft/world/entity/player/Player.java -@@ -169,7 +_,7 @@ +@@ -178,7 +_,7 @@ private static final int DEFAULT_CURRENT_IMPULSE_CONTEXT_RESET_GRACE_TIME = 0; private long timeEntitySatOnShoulder; final Inventory inventory; @@ -9,7 +9,7 @@ public final InventoryMenu inventoryMenu; public AbstractContainerMenu containerMenu; protected FoodData foodData = new FoodData(); -@@ -208,6 +_,18 @@ +@@ -217,6 +_,18 @@ public Entity currentExplosionCause; private boolean ignoreFallDamageFromCurrentImpulse = false; private int currentImpulseContextResetGraceTime = 0; @@ -26,9 +26,9 @@ + } + // CraftBukkit end - public Player(Level level, BlockPos pos, float yRot, GameProfile gameProfile) { + public Player(Level level, GameProfile gameProfile) { super(EntityType.PLAYER, level); -@@ -276,6 +_,13 @@ +@@ -286,6 +_,13 @@ if (this.isSleeping()) { this.sleepCounter++; @@ -42,7 +42,7 @@ if (this.sleepCounter > 100) { this.sleepCounter = 100; } -@@ -293,7 +_,7 @@ +@@ -303,7 +_,7 @@ this.updateIsUnderwater(); super.tick(); if (!this.level().isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) { @@ -51,7 +51,7 @@ this.containerMenu = this.inventoryMenu; } -@@ -380,7 +_,7 @@ +@@ -390,7 +_,7 @@ } private void turtleHelmetTick() { @@ -60,7 +60,7 @@ } private boolean isEquipped(Item item) { -@@ -527,6 +_,18 @@ +@@ -537,6 +_,18 @@ } } @@ -79,7 +79,7 @@ public void closeContainer() { this.containerMenu = this.inventoryMenu; } -@@ -538,8 +_,14 @@ +@@ -548,8 +_,14 @@ public void rideTick() { if (!this.level().isClientSide && this.wantsToStopRiding() && this.isPassenger()) { this.stopRiding(); @@ -96,7 +96,7 @@ super.rideTick(); this.oBob = this.bob; this.bob = 0.0F; -@@ -598,6 +_,7 @@ +@@ -608,6 +_,7 @@ this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft()); this.playShoulderEntityAmbientSound(this.getShoulderEntityRight()); if (!this.level().isClientSide && (this.fallDistance > 0.5 || this.isInWater()) || this.abilities.flying || this.isSleeping() || this.isInPowderSnow) { @@ -104,7 +104,7 @@ this.removeEntitiesOnShoulder(); } } -@@ -841,10 +_,10 @@ +@@ -850,10 +_,10 @@ if (this.isDeadOrDying()) { return false; } else { @@ -117,7 +117,7 @@ } if (level.getDifficulty() == Difficulty.EASY) { -@@ -856,7 +_,14 @@ +@@ -865,7 +_,14 @@ } } @@ -133,7 +133,7 @@ } } } -@@ -868,7 +_,7 @@ +@@ -877,7 +_,7 @@ BlocksAttacks blocksAttacks = itemBlockingWith != null ? itemBlockingWith.get(DataComponents.BLOCKS_ATTACKS) : null; float secondsToDisableBlocking = entity.getSecondsToDisableBlocking(); if (secondsToDisableBlocking > 0.0F && blocksAttacks != null) { @@ -142,7 +142,7 @@ } } -@@ -878,9 +_,29 @@ +@@ -887,9 +_,29 @@ } public boolean canHarmPlayer(Player other) { @@ -175,7 +175,7 @@ } @Override -@@ -894,7 +_,12 @@ +@@ -903,7 +_,12 @@ } @Override @@ -189,7 +189,7 @@ if (!this.isInvulnerableTo(level, damageSource)) { amount = this.getDamageAfterArmorAbsorb(damageSource, amount); amount = this.getDamageAfterMagicAbsorb(damageSource, amount); -@@ -906,7 +_,7 @@ +@@ -915,7 +_,7 @@ } if (var8 != 0.0F) { @@ -198,7 +198,7 @@ this.getCombatTracker().recordDamage(damageSource, var8); this.setHealth(this.getHealth() - var8); if (var8 < 3.4028235E37F) { -@@ -916,6 +_,7 @@ +@@ -925,6 +_,7 @@ this.gameEvent(GameEvent.ENTITY_DAMAGE); } } @@ -206,7 +206,7 @@ } public boolean isTextFilteringEnabled() { -@@ -997,13 +_,19 @@ +@@ -1009,13 +_,19 @@ @Override public void removeVehicle() { @@ -228,7 +228,7 @@ } @Override -@@ -1082,8 +_,17 @@ +@@ -1094,8 +_,17 @@ } public void attack(Entity target) { @@ -248,7 +248,7 @@ float f = this.isAutoSpinAttack() ? this.autoSpinAttackDmg : (float)this.getAttributeValue(Attributes.ATTACK_DAMAGE); ItemStack weaponItem = this.getWeaponItem(); DamageSource damageSource = Optional.ofNullable(weaponItem.getItem().getDamageSource(this)).orElse(this.damageSources().playerAttack(this)); -@@ -1091,18 +_,25 @@ +@@ -1103,18 +_,25 @@ float attackStrengthScale = this.getAttackStrengthScale(0.5F); f *= 0.2F + attackStrengthScale * attackStrengthScale * 0.8F; f1 *= attackStrengthScale; @@ -281,7 +281,7 @@ flag1 = true; } else { flag1 = false; -@@ -1118,7 +_,9 @@ +@@ -1130,7 +_,9 @@ && !this.isPassenger() && target instanceof LivingEntity && !this.isSprinting(); @@ -291,7 +291,7 @@ f *= 1.5F; } -@@ -1145,17 +_,23 @@ +@@ -1157,17 +_,23 @@ if (target instanceof LivingEntity livingEntity1) { livingEntity1.knockback( f4 * 0.5F, Mth.sin(this.getYRot() * (float) (Math.PI / 180.0)), -Mth.cos(this.getYRot() * (float) (Math.PI / 180.0)) @@ -315,7 +315,7 @@ } if (flag3) { -@@ -1169,42 +_,59 @@ +@@ -1181,42 +_,59 @@ && !(livingEntity2 instanceof ArmorStand armorStand && armorStand.isMarker()) && this.distanceToSqr(livingEntity2) < 9.0) { float f6 = this.getEnchantedDamage(livingEntity2, f5, damageSource) * attackStrengthScale; @@ -386,7 +386,7 @@ ); } } -@@ -1252,10 +_,11 @@ +@@ -1264,10 +_,11 @@ } } @@ -401,7 +401,7 @@ } } } -@@ -1290,8 +_,8 @@ +@@ -1302,8 +_,8 @@ } @Override @@ -412,7 +412,7 @@ this.inventoryMenu.removed(this); if (this.containerMenu != null && this.hasContainerOpen()) { this.doCloseContainer(); -@@ -1355,6 +_,12 @@ +@@ -1367,6 +_,12 @@ } public Either startSleepInBed(BlockPos bedPos) { @@ -425,7 +425,7 @@ this.startSleeping(bedPos); this.sleepCounter = 0; return Either.right(Unit.INSTANCE); -@@ -1466,7 +_,7 @@ +@@ -1478,7 +_,7 @@ @Override public boolean causeFallDamage(double fallDistance, float damageMultiplier, DamageSource damageSource) { @@ -434,7 +434,7 @@ return false; } else { if (fallDistance >= 2.0) { -@@ -1507,7 +_,15 @@ +@@ -1519,7 +_,15 @@ } public void startFallFlying() { @@ -451,7 +451,7 @@ } @Override -@@ -1613,15 +_,35 @@ +@@ -1625,15 +_,35 @@ public int getXpNeededForNextLevel() { if (this.experienceLevel >= 30) { return 112 + (this.experienceLevel - 30) * 9; @@ -489,7 +489,7 @@ } } } -@@ -1715,24 +_,53 @@ +@@ -1727,31 +_,60 @@ public void removeEntitiesOnShoulder() { if (this.timeEntitySatOnShoulder + 20L < this.level().getGameTime()) { @@ -532,24 +532,32 @@ + @Nullable + private Entity respawnEntityOnShoulder0(CompoundTag entityCompound) { // CraftBukkit void->boolean + // Paper end - release entity api - return entity - overload - if (!this.level().isClientSide && !entityCompound.isEmpty()) { -- EntityType.create(entityCompound, this.level(), EntitySpawnReason.LOAD).ifPresent(entity -> { -+ return EntityType.create(entityCompound, this.level(), EntitySpawnReason.LOAD).map((entity) -> { // CraftBukkit - if (entity instanceof TamableAnimal tamableAnimal) { - tamableAnimal.setOwner(this); - } + if (this.level() instanceof ServerLevel serverLevel && !entityCompound.isEmpty()) { + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.problemPath(), LOGGER)) { +- EntityType.create( ++ return EntityType.create( // Paper - release entity api + TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), serverLevel.registryAccess(), entityCompound), + serverLevel, + EntitySpawnReason.LOAD + ) +- .ifPresent(entity -> { ++ .map(entity -> { // Paper - release entity api + if (entity instanceof TamableAnimal tamableAnimal) { + tamableAnimal.setOwner(this); + } - entity.setPos(this.getX(), this.getY() + 0.7F, this.getZ()); -- ((ServerLevel)this.level()).addWithUUID(entity); -- }); -+ return ((ServerLevel)this.level()).addWithUUID(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY) ? entity : null; // CraftBukkit // Paper start - release entity api - return entity -+ }).orElse(null); // CraftBukkit // Paper end - release entity api - return entity + entity.setPos(this.getX(), this.getY() + 0.7F, this.getZ()); +- serverLevel.addWithUUID(entity); +- }); ++ return serverLevel.addWithUUID(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SHOULDER_ENTITY) ? entity : null; // Paper - spawn reason ++ }).orElse(null); // Paper - release entity api - return entity + } } + return null; // Paper - return null } @Nullable -@@ -1926,17 +_,32 @@ +@@ -1945,17 +_,32 @@ return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING); } @@ -584,7 +592,7 @@ for (int i = 0; i < this.inventory.getContainerSize(); i++) { ItemStack item = this.inventory.getItem(i); -@@ -1945,6 +_,7 @@ +@@ -1964,6 +_,7 @@ } } @@ -592,7 +600,7 @@ return this.hasInfiniteMaterials() ? new ItemStack(Items.ARROW) : ItemStack.EMPTY; } } -@@ -2027,12 +_,20 @@ +@@ -2046,12 +_,20 @@ } public boolean hasClientLoaded() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch index f677c94f3e..276c538e6e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractArrow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractArrow.java +++ b/net/minecraft/world/entity/projectile/AbstractArrow.java -@@ -93,7 +_,14 @@ +@@ -90,7 +_,14 @@ ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon ) { @@ -15,7 +15,7 @@ this.pickupItemStack = pickupItemStack.copy(); this.applyComponentsFromItemStack(pickupItemStack); Unit unit = pickupItemStack.remove(DataComponents.INTANGIBLE_PROJECTILE); -@@ -118,8 +_,8 @@ +@@ -115,8 +_,8 @@ protected AbstractArrow( EntityType entityType, LivingEntity owner, Level level, ItemStack pickupItemStack, @Nullable ItemStack firedFromWeapon ) { @@ -26,7 +26,7 @@ } public void setSoundEvent(SoundEvent soundEvent) { -@@ -214,6 +_,7 @@ +@@ -211,6 +_,7 @@ this.setSharedFlagOnFire(this.getRemainingFireTicks() > 0); } } else { @@ -34,7 +34,7 @@ this.inGroundTime = 0; Vec3 vec31 = this.position(); if (this.isInWater()) { -@@ -280,12 +_,12 @@ +@@ -277,12 +_,12 @@ if (entityHitResult == null) { if (this.isAlive() && hitResult.getType() != HitResult.Type.MISS) { @@ -49,7 +49,7 @@ this.hasImpulse = true; if (this.getPierceLevel() > 0 && projectileDeflection == ProjectileDeflection.NONE) { continue; -@@ -318,13 +_,26 @@ +@@ -315,13 +_,26 @@ } } @@ -77,7 +77,7 @@ } private void startFalling() { -@@ -357,8 +_,8 @@ +@@ -354,8 +_,8 @@ protected void tickDespawn() { this.life++; @@ -88,7 +88,7 @@ } } -@@ -392,9 +_,9 @@ +@@ -389,9 +_,9 @@ } @Override @@ -100,7 +100,7 @@ } } -@@ -421,7 +_,7 @@ +@@ -418,7 +_,7 @@ } if (this.piercingIgnoreEntityIds.size() >= this.getPierceLevel() + 1) { @@ -109,7 +109,7 @@ return; } -@@ -437,10 +_,16 @@ +@@ -434,10 +_,16 @@ livingEntity.setLastHurtMob(entity); } @@ -127,7 +127,7 @@ } if (entity.hurtOrSimulate(damageSource, ceil)) { -@@ -478,7 +_,7 @@ +@@ -475,7 +_,7 @@ this.playSound(this.soundEvent, 1.0F, 1.2F / (this.random.nextFloat() * 0.2F + 0.9F)); if (this.getPierceLevel() <= 0) { @@ -136,7 +136,7 @@ } } else { entity.setRemainingFireTicks(remainingFireTicks); -@@ -489,7 +_,7 @@ +@@ -486,7 +_,7 @@ this.spawnAtLocation(serverLevel2, this.getPickupItem(), 0.1F); } @@ -145,7 +145,7 @@ } } } -@@ -502,7 +_,7 @@ +@@ -499,7 +_,7 @@ double max = Math.max(0.0, 1.0 - entity.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE)); Vec3 vec3 = this.getDeltaMovement().multiply(1.0, 0.0, 1.0).normalize().scale(d * 0.6 * max); if (vec3.lengthSqr() > 0.0) { @@ -154,7 +154,7 @@ } } } -@@ -610,7 +_,14 @@ +@@ -605,7 +_,14 @@ @Override public void setOwner(@Nullable Entity entity) { @@ -169,7 +169,7 @@ this.pickup = switch (entity) { case Player player when this.pickup == AbstractArrow.Pickup.DISALLOWED -> AbstractArrow.Pickup.ALLOWED; -@@ -622,9 +_,22 @@ +@@ -617,9 +_,22 @@ @Override public void playerTouch(Player entity) { if (!this.level().isClientSide && (this.isInGround() || this.isNoPhysics()) && this.shakeTime <= 0) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch index 0f392f4b0a..c29625926e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java +++ b/net/minecraft/world/entity/projectile/AbstractHurtingProjectile.java -@@ -19,6 +_,8 @@ +@@ -20,6 +_,8 @@ public static final double INITAL_ACCELERATION_POWER = 0.1; public static final double DEFLECTION_SCALE = 0.5; public double accelerationPower = 0.1; @@ -9,7 +9,7 @@ protected AbstractHurtingProjectile(EntityType entityType, Level level) { super(entityType, level); -@@ -83,12 +_,12 @@ +@@ -84,12 +_,12 @@ } if (hitResultOnMoveVector.getType() != HitResult.Type.MISS && this.isAlive()) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractThrownPotion.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractThrownPotion.java.patch index 3423029d7c..c060924241 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractThrownPotion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/AbstractThrownPotion.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/AbstractThrownPotion.java +++ b/net/minecraft/world/entity/projectile/AbstractThrownPotion.java -@@ -70,54 +_,95 @@ +@@ -67,54 +_,95 @@ @Override protected void onHit(HitResult result) { super.onHit(result); @@ -8,7 +8,7 @@ + this.splash(result); + } + -+ public void splash(@Nullable HitResult result) { ++ public void splash(HitResult result) { + // Paper end - More projectile API if (this.level() instanceof ServerLevel serverLevel) { ItemStack item = this.getItem(); @@ -17,10 +17,10 @@ if (potionContents.is(Potions.WATER)) { - this.onHitAsWater(serverLevel); - } else if (potionContents.hasEffects()) { -- this.onHitAsPotion(serverLevel, item, result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null); +- this.onHitAsPotion(serverLevel, item, result); + showParticles = this.onHitAsWater(serverLevel, result); // Paper - Fix potions splash events + } else if (true || potionContents.hasEffects()) { // CraftBukkit - Call event even if no effects to apply -+ showParticles = this.onHitAsPotion(serverLevel, item, result != null && result.getType() == HitResult.Type.ENTITY ? ((EntityHitResult)result).getEntity() : null, result); // Paper - pass HitResult ++ showParticles = this.onHitAsPotion(serverLevel, item, result); // Paper - pass HitResult } + if (showParticles) { // Paper - Fix potions splash events @@ -35,7 +35,7 @@ - private void onHitAsWater(ServerLevel level) { + private static final Predicate APPLY_WATER_GET_ENTITIES_PREDICATE = AbstractThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper - Fix potions splash events + -+ private boolean onHitAsWater(ServerLevel level, @Nullable HitResult result) { // Paper - Fix potions splash events ++ private boolean onHitAsWater(ServerLevel level, HitResult result) { // Paper - Fix potions splash events AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0); - for (LivingEntity livingEntity : this.level().getEntitiesOfClass(LivingEntity.class, aabb, WATER_SENSITIVE_OR_ON_FIRE)) { @@ -85,8 +85,8 @@ + return !event.isCancelled(); // Paper - Fix potions splash events } -- protected abstract void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity); -+ protected abstract boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable HitResult hitResult); // Paper - Pass HitResult // Paper - Fix potions splash events & More Projectile API +- protected abstract void onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult); ++ protected abstract boolean onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult); // Paper - Fix potions splash events & More Projectile API private void dowseFire(BlockPos pos) { BlockState blockState = this.level().getBlockState(pos); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch index 61eaaa3aab..e606fa6862 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EvokerFangs.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/EvokerFangs.java +++ b/net/minecraft/world/entity/projectile/EvokerFangs.java -@@ -107,7 +_,7 @@ +@@ -97,7 +_,7 @@ } if (--this.lifeTicks < 0) { @@ -9,7 +9,7 @@ } } } -@@ -116,7 +_,7 @@ +@@ -106,7 +_,7 @@ LivingEntity owner = this.getOwner(); if (target.isAlive() && !target.isInvulnerable() && target != owner) { if (owner == null) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EyeOfEnder.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EyeOfEnder.java.patch index 573bb6f991..3659c39076 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/EyeOfEnder.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/EyeOfEnder.java.patch @@ -1,20 +1,20 @@ --- a/net/minecraft/world/entity/projectile/EyeOfEnder.java +++ b/net/minecraft/world/entity/projectile/EyeOfEnder.java -@@ -73,6 +_,12 @@ +@@ -72,6 +_,12 @@ } - public void signalTo(BlockPos pos) { + public void signalTo(Vec3 pos) { + // Paper start - Change EnderEye target without changing other things + this.signalTo(pos, true); + } + -+ public void signalTo(BlockPos pos, boolean update) { ++ public void signalTo(Vec3 pos, boolean update) { + // Paper end - Change EnderEye target without changing other things - double d = pos.getX(); - int y = pos.getY(); - double d1 = pos.getZ(); -@@ -89,8 +_,10 @@ - this.tz = d1; + Vec3 vec3 = pos.subtract(this.position()); + double d = vec3.horizontalDistance(); + if (d > 12.0) { +@@ -80,8 +_,10 @@ + this.target = pos; } + if (update) { // Paper - Change EnderEye target without changing other things @@ -24,7 +24,7 @@ } @Override -@@ -164,7 +_,7 @@ +@@ -102,7 +_,7 @@ this.life++; if (this.life > 80 && !this.level().isClientSide) { this.playSound(SoundEvents.ENDER_EYE_DEATH, 1.0F, 1.0F); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch index 12bdfc47b5..73824263a6 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FireworkRocketEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/FireworkRocketEntity.java +++ b/net/minecraft/world/entity/projectile/FireworkRocketEntity.java -@@ -50,6 +_,7 @@ +@@ -48,6 +_,7 @@ public int lifetime = 0; @Nullable public LivingEntity attachedToEntity; @@ -8,7 +8,7 @@ public FireworkRocketEntity(EntityType entityType, Level level) { super(entityType, level); -@@ -165,7 +_,7 @@ +@@ -163,7 +_,7 @@ } if (!this.noPhysics && this.isAlive() && hitResultOnMoveVector.getType() != HitResult.Type.MISS) { @@ -17,7 +17,7 @@ this.hasImpulse = true; } -@@ -189,7 +_,11 @@ +@@ -187,7 +_,11 @@ } if (this.life > this.lifetime && this.level() instanceof ServerLevel serverLevel) { @@ -30,7 +30,7 @@ } } -@@ -197,14 +_,18 @@ +@@ -195,14 +_,18 @@ level.broadcastEntityEvent(this, (byte)17); this.gameEvent(GameEvent.EXPLODE, this.getOwner()); this.dealExplosionDamage(level); @@ -51,7 +51,7 @@ } } -@@ -213,7 +_,11 @@ +@@ -211,7 +_,11 @@ BlockPos blockPos = new BlockPos(result.getBlockPos()); this.level().getBlockState(blockPos).entityInside(this.level(), blockPos, this, InsideBlockEffectApplier.NOOP); if (this.level() instanceof ServerLevel serverLevel && this.hasExplosion()) { @@ -64,19 +64,19 @@ } super.onHitBlock(result); -@@ -286,6 +_,7 @@ - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - compound.store("FireworksItem", ItemStack.CODEC, registryOps, this.getItem()); - compound.putBoolean("ShotAtAngle", this.entityData.get(DATA_SHOT_AT_ANGLE)); -+ compound.storeNullable("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); // Paper +@@ -283,6 +_,7 @@ + output.putInt("LifeTime", this.lifetime); + output.store("FireworksItem", ItemStack.CODEC, this.getItem()); + output.putBoolean("ShotAtAngle", this.entityData.get(DATA_SHOT_AT_ANGLE)); ++ output.storeNullable("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC, this.spawningEntity); // Paper } @Override -@@ -296,6 +_,7 @@ - RegistryOps registryOps = this.registryAccess().createSerializationContext(NbtOps.INSTANCE); - this.entityData.set(DATA_ID_FIREWORKS_ITEM, compound.read("FireworksItem", ItemStack.CODEC, registryOps).orElse(getDefaultItem())); - this.entityData.set(DATA_SHOT_AT_ANGLE, compound.getBooleanOr("ShotAtAngle", false)); -+ this.spawningEntity = compound.read("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); // Paper +@@ -292,6 +_,7 @@ + this.lifetime = input.getIntOr("LifeTime", 0); + this.entityData.set(DATA_ID_FIREWORKS_ITEM, input.read("FireworksItem", ItemStack.CODEC).orElse(getDefaultItem())); + this.entityData.set(DATA_SHOT_AT_ANGLE, input.getBooleanOr("ShotAtAngle", false)); ++ this.spawningEntity = input.read("SpawningEntity", net.minecraft.core.UUIDUtil.CODEC).orElse(null); // Paper } private List getExplosions() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch index bcd4ec06fe..81cd2f4684 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/FishingHook.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/entity/projectile/FishingHook.java +++ b/net/minecraft/world/entity/projectile/FishingHook.java -@@ -66,10 +_,26 @@ - private final int luck; +@@ -70,10 +_,26 @@ private final int lureSpeed; + private final InterpolationHandler interpolationHandler = new InterpolationHandler(this); + // CraftBukkit start - Extra variables to enable modification of fishing wait time, values are minecraft defaults + public int minWaitTime = 100; @@ -27,7 +27,7 @@ } public FishingHook(EntityType entityType, Level level) { -@@ -143,12 +_,12 @@ +@@ -154,12 +_,12 @@ super.tick(); Player playerOwner = this.getPlayerOwner(); if (playerOwner == null) { @@ -42,7 +42,7 @@ return; } } else { -@@ -166,12 +_,14 @@ +@@ -177,12 +_,14 @@ if (this.currentState == FishingHook.FishHookState.FLYING) { if (this.hookedIn != null) { this.setDeltaMovement(Vec3.ZERO); @@ -57,7 +57,7 @@ this.currentState = FishingHook.FishHookState.BOBBING; return; } -@@ -184,6 +_,7 @@ +@@ -195,6 +_,7 @@ this.setPos(this.hookedIn.getX(), this.hookedIn.getY(0.8), this.hookedIn.getZ()); } else { this.setHookedEntity(null); @@ -65,7 +65,7 @@ this.currentState = FishingHook.FishHookState.FLYING; } } -@@ -247,14 +_,14 @@ +@@ -258,14 +_,14 @@ if (!player.isRemoved() && player.isAlive() && (isFishingRod || isFishingRod1) && !(this.distanceToSqr(player) > 1024.0)) { return false; } else { @@ -82,7 +82,7 @@ } @Override -@@ -285,11 +_,11 @@ +@@ -296,11 +_,11 @@ ServerLevel serverLevel = (ServerLevel)this.level(); int i = 1; BlockPos blockPos = pos.above(); @@ -96,7 +96,7 @@ i--; } -@@ -299,6 +_,10 @@ +@@ -310,6 +_,10 @@ this.timeUntilLured = 0; this.timeUntilHooked = 0; this.getEntityData().set(DATA_BITING, false); @@ -107,7 +107,7 @@ } } else if (this.timeUntilHooked > 0) { this.timeUntilHooked -= i; -@@ -322,6 +_,12 @@ +@@ -333,6 +_,12 @@ serverLevel.sendParticles(ParticleTypes.FISHING, d, d1, d2, 0, -f2, 0.01, f1, 1.0); } } else { @@ -120,7 +120,7 @@ this.playSound(SoundEvents.FISHING_BOBBER_SPLASH, 0.25F, 1.0F + (this.random.nextFloat() - this.random.nextFloat()) * 0.4F); double d3 = this.getY() + 0.5; serverLevel.sendParticles( -@@ -373,14 +_,31 @@ +@@ -384,14 +_,31 @@ } if (this.timeUntilLured <= 0) { @@ -156,8 +156,8 @@ public boolean calculateOpenWater(BlockPos pos) { FishingHook.OpenWaterType openWaterType = FishingHook.OpenWaterType.INVALID; -@@ -439,15 +_,31 @@ - public void readAdditionalSaveData(CompoundTag compound) { +@@ -450,15 +_,31 @@ + protected void readAdditionalSaveData(ValueInput input) { } + @@ -188,7 +188,7 @@ } else if (this.nibble > 0) { LootParams lootParams = new LootParams.Builder((ServerLevel)this.level()) .withParameter(LootContextParams.ORIGIN, this.position()) -@@ -461,18 +_,27 @@ +@@ -472,18 +_,27 @@ for (ItemStack itemStack : randomItems) { ItemEntity itemEntity = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), itemStack); @@ -215,14 +215,14 @@ + playerOwner.level() + .addFreshEntity( + new ExperienceOrb( -+ playerOwner.level(), playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this // Paper ++ playerOwner.level(), new net.minecraft.world.phys.Vec3(playerOwner.getX(), playerOwner.getY() + 0.5, playerOwner.getZ() + 0.5), net.minecraft.world.phys.Vec3.ZERO, playerFishEvent.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.FISHING, this.getPlayerOwner(), this // Paper + ) + ); + } if (itemStack.is(ItemTags.FISHES)) { playerOwner.awardStat(Stats.FISH_CAUGHT, 1); } -@@ -482,10 +_,24 @@ +@@ -493,10 +_,24 @@ } if (this.onGround()) { @@ -248,7 +248,7 @@ return i; } else { return 0; -@@ -515,9 +_,9 @@ +@@ -526,9 +_,9 @@ } @Override @@ -260,7 +260,7 @@ } @Override -@@ -565,7 +_,7 @@ +@@ -576,7 +_,7 @@ if (this.getPlayerOwner() == null) { int data = packet.getData(); LOGGER.error("Failed to recreate fishing hook on client. {} (id: {}) is not a valid owner.", this.level().getEntity(data), data); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/LargeFireball.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/LargeFireball.java.patch index d38248aedc..c59d7a4f15 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/LargeFireball.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/LargeFireball.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/LargeFireball.java +++ b/net/minecraft/world/entity/projectile/LargeFireball.java -@@ -19,11 +_,13 @@ +@@ -20,11 +_,13 @@ public LargeFireball(EntityType entityType, Level level) { super(entityType, level); @@ -14,7 +14,7 @@ } @Override -@@ -31,8 +_,13 @@ +@@ -32,8 +_,13 @@ super.onHit(result); if (this.level() instanceof ServerLevel serverLevel) { boolean _boolean = serverLevel.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING); @@ -30,11 +30,11 @@ } } -@@ -57,6 +_,6 @@ +@@ -58,6 +_,6 @@ @Override - public void readAdditionalSaveData(CompoundTag compound) { - super.readAdditionalSaveData(compound); -- this.explosionPower = compound.getByteOr("ExplosionPower", (byte)1); -+ this.bukkitYield = this.explosionPower = compound.getByteOr("ExplosionPower", (byte)1); // CraftBukkit - set bukkitYield when setting explosionPower + protected void readAdditionalSaveData(ValueInput input) { + super.readAdditionalSaveData(input); +- this.explosionPower = input.getByteOr("ExplosionPower", (byte)1); ++ this.bukkitYield = this.explosionPower = input.getByteOr("ExplosionPower", (byte)1); // CraftBukkit - set bukkitYield when setting explosionPower } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch index bb7fe41e49..b16a8c78af 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/Projectile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/Projectile.java +++ b/net/minecraft/world/entity/projectile/Projectile.java -@@ -47,6 +_,7 @@ +@@ -44,6 +_,7 @@ public boolean hasBeenShot = false; @Nullable private Entity lastDeflectedBy; @@ -8,18 +8,11 @@ Projectile(EntityType entityType, Level level) { super(entityType, level); -@@ -57,15 +_,36 @@ - this.ownerUUID = owner.getUUID(); - this.cachedOwner = owner; - } +@@ -55,7 +_,20 @@ + + public void setOwner(@Nullable Entity owner) { + this.setOwner(owner != null ? new EntityReference<>(owner) : null); - } -+ // Paper start - Refresh ProjectileSource for projectiles -+ else { -+ this.ownerUUID = null; -+ this.cachedOwner = null; -+ this.projectileSource = null; -+ } -+ // Paper end - Refresh ProjectileSource for projectiles + this.refreshProjectileSource(false); // Paper + } + @@ -28,7 +21,8 @@ + if (fillCache) { + this.getOwner(); + } -+ if (this.cachedOwner != null && !this.cachedOwner.isRemoved() && this.projectileSource == null && this.cachedOwner.getBukkitEntity() instanceof org.bukkit.projectiles.ProjectileSource projSource) { ++ Entity owner = this.getOwner(); ++ if (owner != null && this.projectileSource == null && owner.getBukkitEntity() instanceof org.bukkit.projectiles.ProjectileSource projSource) { + this.projectileSource = projSource; + } + } @@ -36,25 +30,15 @@ @Nullable @Override - public Entity getOwner() { - if (this.cachedOwner != null && !this.cachedOwner.isRemoved()) { -+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles - return this.cachedOwner; - } else if (this.ownerUUID != null) { - this.cachedOwner = this.findOwner(this.ownerUUID); -+ this.refreshProjectileSource(false); // Paper - Refresh ProjectileSource for projectiles - return this.cachedOwner; - } else { - return null; -@@ -98,6 +_,7 @@ +@@ -84,6 +_,7 @@ @Override - protected void readAdditionalSaveData(CompoundTag compound) { - this.setOwnerThroughUUID(compound.read("Owner", UUIDUtil.CODEC).orElse(null)); -+ if (this instanceof ThrownEnderpearl && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.ownerUUID = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit - this.leftOwner = compound.getBooleanOr("LeftOwner", false); - this.hasBeenShot = compound.getBooleanOr("HasBeenShot", false); + protected void readAdditionalSaveData(ValueInput input) { + this.setOwner(EntityReference.read(input, "Owner")); ++ if (this instanceof ThrownEnderpearl && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && this.level().paperConfig().misc.legacyEnderPearlBehavior) { this.owner = null; } // Paper - Reset pearls when they stop being ticked; Don't store shooter name for pearls to block enderpearl travel exploit + this.leftOwner = input.getBooleanOr("LeftOwner", false); + this.hasBeenShot = input.getBooleanOr("HasBeenShot", false); } -@@ -173,7 +_,14 @@ +@@ -151,7 +_,14 @@ float f2 = Mth.cos(y * (float) (Math.PI / 180.0)) * Mth.cos(x * (float) (Math.PI / 180.0)); this.shoot(f, f1, f2, velocity, inaccuracy); Vec3 knownMovement = shooter.getKnownMovement(); @@ -69,7 +53,7 @@ } @Override -@@ -193,7 +_,12 @@ +@@ -171,7 +_,12 @@ public static T spawnProjectileFromRotation( Projectile.ProjectileFactory factory, ServerLevel level, ItemStack spawnedFrom, LivingEntity owner, float z, float velocity, float innaccuracy ) { @@ -83,7 +67,7 @@ factory.create(level, owner, spawnedFrom), level, spawnedFrom, -@@ -218,7 +_,13 @@ +@@ -196,7 +_,13 @@ public static T spawnProjectileUsingShoot( T projectile, ServerLevel level, ItemStack spawnedFrom, double x, double y, double z, float velocity, float inaccuracy ) { @@ -98,7 +82,7 @@ } public static T spawnProjectile(T projectile, ServerLevel level, ItemStack spawnedFrom) { -@@ -226,11 +_,46 @@ +@@ -204,11 +_,46 @@ } public static T spawnProjectile(T projectile, ServerLevel level, ItemStack stack, Consumer adapter) { @@ -149,7 +133,7 @@ public void applyOnProjectileSpawned(ServerLevel level, ItemStack spawnedFrom) { EnchantmentHelper.onProjectileSpawned(level, spawnedFrom, this, item -> {}); -@@ -242,6 +_,17 @@ +@@ -220,6 +_,17 @@ } } @@ -167,7 +151,7 @@ protected ProjectileDeflection hitTargetOrDeflectSelf(HitResult hitResult) { if (hitResult.getType() == HitResult.Type.ENTITY) { EntityHitResult entityHitResult = (EntityHitResult)hitResult; -@@ -273,7 +_,13 @@ +@@ -251,7 +_,13 @@ public boolean deflect(ProjectileDeflection deflection, @Nullable Entity entity, @Nullable Entity owner, boolean deflectedByPlayer) { deflection.deflect(this, entity, this.random); if (!this.level().isClientSide) { @@ -182,7 +166,7 @@ this.onDeflection(entity, deflectedByPlayer); } -@@ -309,15 +_,35 @@ +@@ -287,15 +_,35 @@ } protected void onHitBlock(BlockHitResult result) { @@ -218,7 +202,7 @@ return owner == null || this.leftOwner || !owner.isPassengerOfSameVehicle(target); } } -@@ -330,13 +_,7 @@ +@@ -308,13 +_,7 @@ } protected static float lerpRotation(float currentRotation, float targetRotation) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch index 82901360fe..1cad2ef152 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ShulkerBullet.java.patch @@ -1,9 +1,9 @@ --- a/net/minecraft/world/entity/projectile/ShulkerBullet.java +++ b/net/minecraft/world/entity/projectile/ShulkerBullet.java -@@ -58,7 +_,21 @@ - this.finalTarget = finalTarget; +@@ -57,7 +_,21 @@ + this.finalTarget = new EntityReference<>(finalTarget); this.currentMoveDirection = Direction.UP; - this.selectNextMoveDirection(axis); + this.selectNextMoveDirection(axis, finalTarget); - } + this.projectileSource = shooter.getBukkitLivingEntity(); // CraftBukkit + } @@ -11,19 +11,19 @@ + // CraftBukkit start + @Nullable + public Entity getTarget() { -+ return this.finalTarget; ++ return EntityReference.get(this.finalTarget, this.level(), Entity.class); + } + + public void setTarget(@Nullable Entity finalTarget) { -+ this.finalTarget = finalTarget; ++ this.finalTarget = finalTarget == null ? null : new net.minecraft.world.entity.EntityReference<>(finalTarget); + this.currentMoveDirection = Direction.UP; -+ this.selectNextMoveDirection(Direction.Axis.X); ++ this.selectNextMoveDirection(Direction.Axis.X, finalTarget); + } + // CraftBukkit end @Override public SoundSource getSoundSource() { -@@ -180,7 +_,7 @@ +@@ -179,7 +_,7 @@ @Override public void checkDespawn() { if (this.level().getDifficulty() == Difficulty.PEACEFUL) { @@ -32,7 +32,7 @@ } } -@@ -226,7 +_,7 @@ +@@ -223,7 +_,7 @@ } if (hitResult != null && this.isAlive() && hitResult.getType() != HitResult.Type.MISS) { @@ -41,7 +41,7 @@ } ProjectileUtil.rotateTowardsMovement(this, 0.5F); -@@ -299,7 +_,7 @@ +@@ -296,7 +_,7 @@ } if (entity instanceof LivingEntity livingEntity1) { @@ -50,7 +50,7 @@ } } } -@@ -312,14 +_,20 @@ +@@ -309,14 +_,20 @@ } private void destroy() { @@ -73,7 +73,7 @@ } @Override -@@ -334,9 +_,14 @@ +@@ -331,9 +_,14 @@ @Override public boolean hurtServer(ServerLevel level, DamageSource damageSource, float amount) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/SpectralArrow.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/SpectralArrow.java.patch index 9aefb48e44..4e62d6c472 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/SpectralArrow.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/SpectralArrow.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/SpectralArrow.java +++ b/net/minecraft/world/entity/projectile/SpectralArrow.java -@@ -39,7 +_,7 @@ +@@ -40,7 +_,7 @@ protected void doPostHurtEffects(LivingEntity living) { super.doPostHurtEffects(living); MobEffectInstance mobEffectInstance = new MobEffectInstance(MobEffects.GLOWING, this.duration, 0); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch index 93f24a1db5..c12af27e86 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownEnderpearl.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/ThrownEnderpearl.java +++ b/net/minecraft/world/entity/projectile/ThrownEnderpearl.java -@@ -122,11 +_,18 @@ +@@ -119,11 +_,18 @@ Vec3 vec3 = this.oldPosition(); if (owner instanceof ServerPlayer serverPlayer) { if (serverPlayer.connection.isAcceptingMessages()) { @@ -20,7 +20,7 @@ } } -@@ -134,15 +_,17 @@ +@@ -131,15 +_,17 @@ owner.setPortalCooldown(); } @@ -39,12 +39,12 @@ if (serverPlayer1 != null) { serverPlayer1.resetFallDistance(); serverPlayer1.resetCurrentImpulseContext(); -- serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl(), 5.0F); -+ serverPlayer1.hurtServer(serverPlayer.serverLevel(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API +- serverPlayer1.hurtServer(serverPlayer.level(), this.damageSources().enderPearl(), 5.0F); ++ serverPlayer1.hurtServer(serverPlayer.level(), this.damageSources().enderPearl().eventEntityDamager(this), 5.0F); // CraftBukkit // Paper - fix DamageSource API } this.playSound(serverLevel, vec3); -@@ -158,9 +_,9 @@ +@@ -155,9 +_,9 @@ this.playSound(serverLevel, vec3); } @@ -56,16 +56,16 @@ } } } -@@ -181,7 +_,7 @@ +@@ -178,7 +_,7 @@ if (owner instanceof ServerPlayer serverPlayer && !owner.isAlive() - && serverPlayer.serverLevel().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) { + && serverPlayer.level().getGameRules().getBoolean(GameRules.RULE_ENDER_PEARLS_VANISH_ON_DEATH)) { - this.discard(); + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - add Bukkit remove cause } else { super.tick(); } -@@ -208,7 +_,7 @@ +@@ -205,7 +_,7 @@ public Entity teleport(TeleportTransition teleportTransition) { Entity entity = super.teleport(teleportTransition); if (entity != null) { @@ -74,7 +74,7 @@ } return entity; -@@ -216,7 +_,7 @@ +@@ -213,7 +_,7 @@ @Override public boolean canTeleport(Level fromLevel, Level toLevel) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java.patch index 81432d05ea..5c4dabc734 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java.patch @@ -1,22 +1,32 @@ --- a/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java +++ b/net/minecraft/world/entity/projectile/ThrownExperienceBottle.java -@@ -37,10 +_,17 @@ +@@ -39,16 +_,25 @@ protected void onHit(HitResult result) { super.onHit(result); - if (this.level() instanceof ServerLevel) { -- this.level().levelEvent(2002, this.blockPosition(), -13083194); + if (this.level() instanceof ServerLevel serverLevel) { +- serverLevel.levelEvent(2002, this.blockPosition(), -13083194); + // CraftBukkit - moved to after event - int i = 3 + this.level().random.nextInt(5) + this.level().random.nextInt(5); -- ExperienceOrb.award((ServerLevel)this.level(), result.getLocation(), i); -- this.discard(); -+ // CraftBukkit start + int i = 3 + serverLevel.random.nextInt(5) + serverLevel.random.nextInt(5); ++ // Paper start - exp bottle event + org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, result, i); + i = event.getExperience(); ++ // Paper end - exp bottle event + if (result instanceof BlockHitResult blockHitResult) { + Vec3 unitVec3 = blockHitResult.getDirection().getUnitVec3(); +- ExperienceOrb.awardWithDirection(serverLevel, result.getLocation(), unitVec3, i); ++ ExperienceOrb.awardWithDirection(serverLevel, result.getLocation(), unitVec3, i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper + } else { +- ExperienceOrb.awardWithDirection(serverLevel, result.getLocation(), this.getDeltaMovement().scale(-1.0), i); +- } ++ ExperienceOrb.awardWithDirection(serverLevel, result.getLocation(), this.getDeltaMovement().scale(-1.0), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper ++ } ++ // Paper start - exp bottle event + if (event.getShowEffect()) { + this.level().levelEvent(net.minecraft.world.level.block.LevelEvent.PARTICLES_SPELL_POTION_SPLASH, this.blockPosition(), net.minecraft.world.item.alchemy.PotionContents.BASE_POTION_COLOR); + } -+ // CraftBukkit end -+ ExperienceOrb.award((ServerLevel)this.level(), result.getLocation(), i, org.bukkit.entity.ExperienceOrb.SpawnReason.EXP_BOTTLE, this.getOwner(), this); // Paper ++ // Paper end - exp bottle event + +- this.discard(); + this.discard(org.bukkit.event.entity.EntityRemoveEvent.Cause.HIT); // CraftBukkit - add Bukkit remove cause } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java.patch index f945feb017..8fc9c61e7f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java +++ b/net/minecraft/world/entity/projectile/ThrownLingeringPotion.java -@@ -30,7 +_,7 @@ +@@ -29,7 +_,7 @@ } @Override -- public void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity) { -+ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable net.minecraft.world.phys.HitResult hitResult) { // Paper - Pass HitResult // Paper - More projectile API +- public void onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult) { ++ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult) { // Paper - More projectile API AreaEffectCloud areaEffectCloud = new AreaEffectCloud(this.level(), this.getX(), this.getY(), this.getZ()); if (this.getOwner() instanceof LivingEntity livingEntity) { areaEffectCloud.setOwner(livingEntity); -@@ -42,6 +_,15 @@ +@@ -41,6 +_,15 @@ areaEffectCloud.setWaitTime(10); areaEffectCloud.setRadiusPerTick(-areaEffectCloud.getRadius() / areaEffectCloud.getDuration()); areaEffectCloud.applyComponentsFromItemStack(stack); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownSplashPotion.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownSplashPotion.java.patch index a5890d24b2..64d6f78a89 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownSplashPotion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownSplashPotion.java.patch @@ -1,31 +1,28 @@ --- a/net/minecraft/world/entity/projectile/ThrownSplashPotion.java +++ b/net/minecraft/world/entity/projectile/ThrownSplashPotion.java -@@ -36,12 +_,13 @@ +@@ -36,13 +_,14 @@ } @Override -- public void onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity) { -+ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, @Nullable Entity entity, @Nullable net.minecraft.world.phys.HitResult hitResult) { // Paper - Add HitResult parameter // Paper - More projectile API +- public void onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult) { ++ public boolean onHitAsPotion(ServerLevel level, ItemStack stack, HitResult hitResult) { // Paper - More projectile API PotionContents potionContents = stack.getOrDefault(DataComponents.POTION_CONTENTS, PotionContents.EMPTY); float orDefault = stack.getOrDefault(DataComponents.POTION_DURATION_SCALE, 1.0F); Iterable allEffects = potionContents.getAllEffects(); - AABB aabb = this.getBoundingBox().inflate(4.0, 2.0, 4.0); - List entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, aabb); + AABB aabb = this.getBoundingBox().move(hitResult.getLocation().subtract(this.position())); + AABB aabb1 = aabb.inflate(4.0, 2.0, 4.0); + List entitiesOfClass = this.level().getEntitiesOfClass(LivingEntity.class, aabb1); + java.util.Map affected = new java.util.HashMap<>(); // CraftBukkit + float f = ProjectileUtil.computeMargin(this); if (!entitiesOfClass.isEmpty()) { Entity effectSource = this.getEffectSource(); - -@@ -50,12 +_,31 @@ - double d = this.distanceToSqr(livingEntity); +@@ -51,8 +_,25 @@ + if (livingEntity.isAffectedByPotions()) { + double d = aabb.distanceToSqr(livingEntity.getBoundingBox().inflate(f)); if (d < 16.0) { - double d1; -+ // Paper - diff on change, used when calling the splash event for water splash potions - if (livingEntity == entity) { - d1 = 1.0; - } else { - d1 = 1.0 - Math.sqrt(d) / 4.0; - } - +- double d1 = 1.0 - Math.sqrt(d) / 4.0; +- ++ double d1 = 1.0 - Math.sqrt(d) / 4.0; // Paper - diff on change, used when calling the splash event for water splash potions + // CraftBukkit start + affected.put(livingEntity.getBukkitLivingEntity(), d1); + } @@ -47,7 +44,7 @@ for (MobEffectInstance mobEffectInstance : allEffects) { Holder effect = mobEffectInstance.getEffect(); if (effect.value().isInstantenous()) { -@@ -66,7 +_,7 @@ +@@ -63,7 +_,7 @@ effect, i, mobEffectInstance.getAmplifier(), mobEffectInstance.isAmbient(), mobEffectInstance.isVisible() ); if (!mobEffectInstance1.endsWithin(20)) { @@ -56,7 +53,7 @@ } } } -@@ -74,5 +_,6 @@ +@@ -71,5 +_,6 @@ } } } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownTrident.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownTrident.java.patch index 6b8b6812e8..0b5d3d6fcf 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownTrident.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/ThrownTrident.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/ThrownTrident.java +++ b/net/minecraft/world/entity/projectile/ThrownTrident.java -@@ -33,16 +_,19 @@ +@@ -34,16 +_,19 @@ public ThrownTrident(EntityType entityType, Level level) { super(entityType, level); @@ -20,7 +20,7 @@ this.entityData.set(ID_LOYALTY, this.getLoyaltyFromItem(pickupItemStack)); this.entityData.set(ID_FOIL, pickupItemStack.hasFoil()); } -@@ -68,10 +_,10 @@ +@@ -69,10 +_,10 @@ this.spawnAtLocation(serverLevel, this.getPickupItem(), 0.1F); } @@ -33,7 +33,7 @@ return; } -@@ -100,6 +_,20 @@ +@@ -101,6 +_,20 @@ return this.entityData.get(ID_FOIL); } @@ -54,7 +54,7 @@ @Nullable @Override protected EntityHitResult findHitEntity(Vec3 startVec, Vec3 endVec) { -@@ -109,7 +_,7 @@ +@@ -110,7 +_,7 @@ @Override protected void onHitEntity(EntityHitResult result) { Entity entity = result.getEntity(); diff --git a/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch index 71e3572b0c..c7a62ddc69 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/projectile/WitherSkull.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/projectile/WitherSkull.java +++ b/net/minecraft/world/entity/projectile/WitherSkull.java -@@ -66,11 +_,11 @@ +@@ -67,11 +_,11 @@ if (var8.isAlive()) { EnchantmentHelper.doPostAttackEffects(serverLevel, var8, damageSource); } else { @@ -14,7 +14,7 @@ } if (flag && var8 instanceof LivingEntity livingEntityx) { -@@ -82,7 +_,7 @@ +@@ -83,7 +_,7 @@ } if (i > 0) { @@ -23,7 +23,7 @@ } } } -@@ -92,8 +_,13 @@ +@@ -93,8 +_,13 @@ protected void onHit(HitResult result) { super.onHit(result); if (!this.level().isClientSide) { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/raid/Raider.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/raid/Raider.java.patch index dac5a3ee4d..aad332a382 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/raid/Raider.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/raid/Raider.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/raid/Raider.java +++ b/net/minecraft/world/entity/raid/Raider.java -@@ -213,17 +_,24 @@ +@@ -214,17 +_,24 @@ if (this.hasActiveRaid() && !flag && ItemStack.matches(item, Raid.getOminousBannerInstance(this.registryAccess().lookupOrThrow(Registries.BANNER_PATTERN)))) { @@ -26,7 +26,7 @@ this.getCurrentRaid().setLeader(this.getWave(), this); this.setPatrolLeader(true); } else { -@@ -297,7 +_,7 @@ +@@ -298,7 +_,7 @@ for (Raider raider : getServerLevel(this.mob) .getNearbyEntities(Raider.class, this.shoutTargeting, this.mob, this.mob.getBoundingBox().inflate(8.0, 8.0, 8.0))) { @@ -35,7 +35,7 @@ } } -@@ -308,7 +_,7 @@ +@@ -309,7 +_,7 @@ if (target != null) { for (Raider raider : getServerLevel(this.mob) .getNearbyEntities(Raider.class, this.shoutTargeting, this.mob, this.mob.getBoundingBox().inflate(8.0, 8.0, 8.0))) { @@ -44,7 +44,7 @@ raider.setAggressive(true); } -@@ -393,6 +_,7 @@ +@@ -394,6 +_,7 @@ } private boolean cannotPickUpBanner() { diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch index 8d37dc1177..7ca3c64fb2 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractBoat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractBoat.java +++ b/net/minecraft/world/entity/vehicle/AbstractBoat.java -@@ -79,6 +_,15 @@ +@@ -80,6 +_,15 @@ private Leashable.LeashData leashData; private final Supplier dropItem; @@ -16,7 +16,7 @@ public AbstractBoat(EntityType entityType, Level level, Supplier dropItem) { super(entityType, level); this.dropItem = dropItem; -@@ -120,7 +_,7 @@ +@@ -121,7 +_,7 @@ } @Override @@ -25,7 +25,7 @@ return true; } -@@ -175,11 +_,30 @@ +@@ -176,11 +_,30 @@ @Override public void push(Entity entity) { @@ -56,7 +56,7 @@ super.push(entity); } } -@@ -246,6 +_,18 @@ +@@ -247,6 +_,18 @@ this.setDeltaMovement(Vec3.ZERO); } @@ -75,7 +75,7 @@ this.applyEffectsFromBlocks(); this.applyEffectsFromBlocks(); this.tickBubbleColumn(); -@@ -548,7 +_,7 @@ +@@ -551,7 +_,7 @@ this.waterLevel = this.getY(1.0); double d2 = this.getWaterLevelAbove() - this.getBbHeight() + 0.101; if (this.level().noCollision(this, this.getBoundingBox().move(0.0, d2 - this.getY(), 0.0))) { @@ -84,7 +84,7 @@ this.setDeltaMovement(this.getDeltaMovement().multiply(1.0, 0.0, 1.0)); this.lastYd = 0.0; } -@@ -711,12 +_,12 @@ +@@ -714,12 +_,12 @@ } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch index 80087e5352..8fe709355f 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractChestBoat.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractChestBoat.java +++ b/net/minecraft/world/entity/vehicle/AbstractChestBoat.java -@@ -65,12 +_,12 @@ +@@ -66,12 +_,12 @@ } @Override @@ -15,7 +15,7 @@ } @Override -@@ -97,8 +_,8 @@ +@@ -94,8 +_,8 @@ @Override public void openCustomInventoryScreen(Player player) { @@ -26,7 +26,7 @@ this.gameEvent(GameEvent.CONTAINER_OPEN, player); PiglinAi.angerNearbyPiglins(serverLevel, player, true); } -@@ -151,7 +_,7 @@ +@@ -148,7 +_,7 @@ @Nullable @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { @@ -35,7 +35,7 @@ return null; } else { this.unpackLootTable(playerInventory.player); -@@ -198,4 +_,58 @@ +@@ -195,4 +_,58 @@ public void stopOpen(Player player) { this.level().gameEvent(GameEvent.CONTAINER_CLOSE, this.position(), GameEvent.Context.of(player)); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch index 64ad7c0437..a607de2d8d 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecart.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractMinecart.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecart.java -@@ -94,6 +_,17 @@ +@@ -93,6 +_,17 @@ } ) ); @@ -18,7 +18,7 @@ protected AbstractMinecart(EntityType entityType, Level level) { super(entityType, level); -@@ -153,11 +_,19 @@ +@@ -152,11 +_,19 @@ @Override public boolean canCollideWith(Entity entity) { @@ -40,7 +40,7 @@ return true; } -@@ -258,6 +_,14 @@ +@@ -257,6 +_,14 @@ @Override public void tick() { @@ -55,7 +55,7 @@ if (this.getHurtTime() > 0) { this.setHurtTime(this.getHurtTime() - 1); } -@@ -267,8 +_,20 @@ +@@ -266,8 +_,20 @@ } this.checkBelowWorld(); @@ -77,7 +77,7 @@ this.updateInWaterStateAndDoFluidPushing(); if (this.isInLava()) { this.lavaIgnite(); -@@ -350,12 +_,16 @@ +@@ -356,12 +_,16 @@ Vec3 deltaMovement = this.getDeltaMovement(); this.setDeltaMovement(Mth.clamp(deltaMovement.x, -maxSpeed, maxSpeed), deltaMovement.y, Mth.clamp(deltaMovement.z, -maxSpeed, maxSpeed)); if (this.onGround()) { @@ -96,20 +96,12 @@ } } -@@ -386,6 +_,7 @@ - public void applyEffectsFromBlocks() { - if (!useExperimentalMovement(this.level())) { - this.applyEffectsFromBlocks(this.position(), this.position()); -+ this.clearMovementsThisTick(); // Paper - MC-296337 - } else { - super.applyEffectsFromBlocks(); - } -@@ -457,6 +_,15 @@ - this.setDisplayOffset(compound.getIntOr("DisplayOffset", this.getDefaultDisplayOffset())); - this.flipped = compound.getBooleanOr("FlippedRotation", false); - this.firstTick = compound.getBooleanOr("HasTicked", false); +@@ -463,6 +_,15 @@ + this.setDisplayOffset(input.getIntOr("DisplayOffset", this.getDefaultDisplayOffset())); + this.flipped = input.getBooleanOr("FlippedRotation", false); + this.firstTick = input.getBooleanOr("HasTicked", false); + // Paper start - Friction API -+ compound.getString("Paper.FrictionState").ifPresent(frictionState -> { ++ input.getString("Paper.FrictionState").ifPresent(frictionState -> { + try { + this.frictionState = net.kyori.adventure.util.TriState.valueOf(frictionState); + } catch (Exception ignored) { @@ -120,14 +112,13 @@ } @Override -@@ -472,13 +_,27 @@ +@@ -475,13 +_,26 @@ - compound.putBoolean("FlippedRotation", this.flipped); - compound.putBoolean("HasTicked", this.firstTick); -+ + output.putBoolean("FlippedRotation", this.flipped); + output.putBoolean("HasTicked", this.firstTick); + // Paper start - Friction API + if (this.frictionState != net.kyori.adventure.util.TriState.NOT_SET) { -+ compound.putString("Paper.FrictionState", this.frictionState.toString()); ++ output.putString("Paper.FrictionState", this.frictionState.toString()); + } + // Paper end - Friction API } @@ -148,7 +139,7 @@ double d = entity.getX() - this.getX(); double d1 = entity.getZ() - this.getZ(); double d2 = d * d + d1 * d1; -@@ -587,4 +_,26 @@ +@@ -590,4 +_,26 @@ public boolean isFurnace() { return false; } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch index 9b1cbd4231..c9eb634483 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java +++ b/net/minecraft/world/entity/vehicle/AbstractMinecartContainer.java -@@ -21,10 +_,11 @@ +@@ -22,10 +_,11 @@ import net.minecraft.world.phys.Vec3; public abstract class AbstractMinecartContainer extends AbstractMinecart implements ContainerEntity { @@ -13,7 +13,7 @@ protected AbstractMinecartContainer(EntityType entityType, Level level) { super(entityType, level); -@@ -71,12 +_,12 @@ +@@ -72,12 +_,12 @@ } @Override @@ -28,7 +28,7 @@ } @Override -@@ -164,4 +_,56 @@ +@@ -165,4 +_,56 @@ public void clearItemStacks() { this.itemStacks = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch index 72cec8ed42..1c88402773 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/ContainerEntity.java.patch @@ -1,32 +1,32 @@ --- a/net/minecraft/world/entity/vehicle/ContainerEntity.java +++ b/net/minecraft/world/entity/vehicle/ContainerEntity.java @@ -60,12 +_,12 @@ - default void addChestVehicleSaveData(CompoundTag tag, HolderLookup.Provider levelRegistry) { + default void addChestVehicleSaveData(ValueOutput output) { if (this.getContainerLootTable() != null) { - tag.putString("LootTable", this.getContainerLootTable().location().toString()); -+ this.lootableData().saveNbt(tag); // Paper + output.putString("LootTable", this.getContainerLootTable().location().toString()); ++ this.lootableData().saveNbt(output); // Paper if (this.getContainerLootTableSeed() != 0L) { - tag.putLong("LootTableSeed", this.getContainerLootTableSeed()); + output.putLong("LootTableSeed", this.getContainerLootTableSeed()); } - } else { -- ContainerHelper.saveAllItems(tag, this.getItemStacks(), levelRegistry); +- ContainerHelper.saveAllItems(output, this.getItemStacks()); } -+ ContainerHelper.saveAllItems(tag, this.getItemStacks(), levelRegistry); // Paper - always save the items, table may still remain ++ ContainerHelper.saveAllItems(output, this.getItemStacks()); // Paper - always save the items, table may still remain } - default void readChestVehicleSaveData(CompoundTag tag, HolderLookup.Provider levelRegistry) { + default void readChestVehicleSaveData(ValueInput input) { @@ -73,7 +_,12 @@ - ResourceKey resourceKey = tag.read("LootTable", LootTable.KEY_CODEC).orElse(null); + ResourceKey resourceKey = input.read("LootTable", LootTable.KEY_CODEC).orElse(null); this.setContainerLootTable(resourceKey); - this.setContainerLootTableSeed(tag.getLongOr("LootTableSeed", 0L)); + this.setContainerLootTableSeed(input.getLongOr("LootTableSeed", 0L)); - if (resourceKey == null) { + // Paper start - LootTable API + if (this.getContainerLootTable() != null) { -+ this.lootableData().loadNbt(tag); ++ this.lootableData().loadNbt(input); + } + // Paper end - LootTable API + if (true || resourceKey == null) { // Paper - always read the items, table may still remain - ContainerHelper.loadAllItems(tag, this.getItemStacks(), levelRegistry); + ContainerHelper.loadAllItems(input, this.getItemStacks()); } } @@ -89,19 +_,27 @@ diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch index 7a3a6b08c0..9726ec2fa8 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java +++ b/net/minecraft/world/entity/vehicle/MinecartCommandBlock.java -@@ -126,7 +_,7 @@ +@@ -127,7 +_,7 @@ MinecartCommandBlock.this.position(), MinecartCommandBlock.this.getRotationVector(), this.getLevel(), @@ -9,7 +9,7 @@ this.getName().getString(), MinecartCommandBlock.this.getDisplayName(), this.getLevel().getServer(), -@@ -138,5 +_,12 @@ +@@ -139,5 +_,12 @@ public boolean isValid() { return !MinecartCommandBlock.this.isRemoved(); } diff --git a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch index 19c33d666a..1abaf4596e 100644 --- a/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/entity/vehicle/MinecartTNT.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/entity/vehicle/MinecartTNT.java +++ b/net/minecraft/world/entity/vehicle/MinecartTNT.java -@@ -38,6 +_,7 @@ +@@ -39,6 +_,7 @@ public int fuse = -1; public float explosionPowerBase = 4.0F; public float explosionSpeedFactor = 1.0F; @@ -8,7 +8,7 @@ public MinecartTNT(EntityType entityType, Level level) { super(entityType, level); -@@ -52,6 +_,12 @@ +@@ -53,6 +_,12 @@ public void tick() { super.tick(); if (this.fuse > 0) { @@ -21,7 +21,7 @@ this.fuse--; this.level().addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5, this.getZ(), 0.0, 0.0, 0.0); } else if (this.fuse == 0) { -@@ -107,6 +_,17 @@ +@@ -108,6 +_,17 @@ if (this.level() instanceof ServerLevel serverLevel) { if (serverLevel.getGameRules().getBoolean(GameRules.RULE_TNT_EXPLODES)) { double min = Math.min(Math.sqrt(radiusModifier), 5.0); @@ -39,7 +39,7 @@ serverLevel.explode( this, damageSource, -@@ -114,13 +_,13 @@ +@@ -115,13 +_,13 @@ this.getX(), this.getY(), this.getZ(), diff --git a/paper-server/patches/sources/net/minecraft/world/food/FoodData.java.patch b/paper-server/patches/sources/net/minecraft/world/food/FoodData.java.patch index a13b83e496..3440f33d83 100644 --- a/paper-server/patches/sources/net/minecraft/world/food/FoodData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/food/FoodData.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/food/FoodData.java +++ b/net/minecraft/world/food/FoodData.java -@@ -14,6 +_,11 @@ +@@ -15,6 +_,11 @@ public float saturationLevel = 5.0F; public float exhaustionLevel; private int tickTimer; @@ -12,7 +12,7 @@ private void add(int foodLevel, float saturationLevel) { this.foodLevel = Mth.clamp(foodLevel + this.foodLevel, 0, 20); -@@ -28,6 +_,17 @@ +@@ -29,6 +_,17 @@ this.add(foodProperties.nutrition(), foodProperties.saturation()); } @@ -28,9 +28,9 @@ + // CraftBukkit end + public void tick(ServerPlayer player) { - ServerLevel serverLevel = player.serverLevel(); + ServerLevel serverLevel = player.level(); Difficulty difficulty = serverLevel.getDifficulty(); -@@ -36,29 +_,39 @@ +@@ -37,29 +_,39 @@ if (this.saturationLevel > 0.0F) { this.saturationLevel = Math.max(this.saturationLevel - 1.0F, 0.0F); } else if (difficulty != Difficulty.PEACEFUL) { diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch index 30f6703759..3bfe900bd4 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/AnvilMenu.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/inventory/AnvilMenu.java +++ b/net/minecraft/world/inventory/AnvilMenu.java -@@ -43,6 +_,12 @@ +@@ -44,6 +_,12 @@ private static final int ADDITIONAL_SLOT_X_PLACEMENT = 76; private static final int RESULT_SLOT_X_PLACEMENT = 134; private static final int SLOT_Y_PLACEMENT = 47; @@ -13,7 +13,7 @@ public AnvilMenu(int containerId, Inventory playerInventory) { this(containerId, playerInventory, ContainerLevelAccess.NULL); -@@ -68,7 +_,7 @@ +@@ -69,7 +_,7 @@ @Override protected boolean mayPickup(Player player, boolean hasStack) { @@ -22,14 +22,16 @@ } @Override -@@ -89,12 +_,22 @@ +@@ -90,7 +_,7 @@ this.inputSlots.setItem(1, ItemStack.EMPTY); } - this.cost.set(0); + this.cost.set(AnvilMenu.DEFAULT_DENIED_COST); // CraftBukkit - use a variable for set a cost for denied item - this.inputSlots.setItem(0, ItemStack.EMPTY); - this.access.execute((level, blockPos) -> { + if (player instanceof ServerPlayer serverPlayer + && !StringUtil.isBlank(this.itemName) + && !this.inputSlots.getItem(0).getHoverName().getString().equals(this.itemName)) { +@@ -102,6 +_,16 @@ BlockState blockState = level.getBlockState(blockPos); if (!player.hasInfiniteMaterials() && blockState.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) { BlockState blockState1 = AnvilBlock.damage(blockState); @@ -46,7 +48,7 @@ if (blockState1 == null) { level.removeBlock(blockPos, false); level.levelEvent(1029, blockPos, 0); -@@ -127,8 +_,8 @@ +@@ -134,8 +_,8 @@ if (itemStack.isDamageableItem() && item.isValidRepairItem(item1)) { int min = Math.min(itemStack.getDamageValue(), itemStack.getMaxDamage() / 4); if (min <= 0) { @@ -57,7 +59,7 @@ return; } -@@ -143,8 +_,8 @@ +@@ -150,8 +_,8 @@ this.repairItemCountCost = i2; } else { if (!hasStoredEnchantments && (!itemStack.is(item1.getItem()) || !itemStack.isDamageableItem())) { @@ -68,7 +70,7 @@ return; } -@@ -190,7 +_,7 @@ +@@ -197,7 +_,7 @@ flag1 = true; } else { flag = true; @@ -77,7 +79,7 @@ intValue = enchantment.getMaxLevel(); } -@@ -208,8 +_,8 @@ +@@ -215,8 +_,8 @@ } if (flag1 && !flag) { @@ -88,7 +90,7 @@ return; } } -@@ -234,14 +_,16 @@ +@@ -241,14 +_,16 @@ } if (i1 == i && i1 > 0) { @@ -108,7 +110,7 @@ itemStack = ItemStack.EMPTY; } -@@ -259,12 +_,13 @@ +@@ -266,12 +_,13 @@ EnchantmentHelper.setEnchantments(itemStack, mutable.toImmutable()); } @@ -125,7 +127,7 @@ } public static int calculateIncreasedRepairCost(int oldRepairCost) { -@@ -285,6 +_,7 @@ +@@ -292,6 +_,7 @@ } this.createResult(); @@ -133,7 +135,7 @@ return true; } else { return false; -@@ -300,4 +_,19 @@ +@@ -307,4 +_,19 @@ public int getCost() { return this.cost.get(); } diff --git a/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch b/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch index ec3ca35574..39b09b925f 100644 --- a/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/inventory/GrindstoneMenu.java.patch @@ -70,7 +70,7 @@ + // Paper start - Fire BlockExpEvent on grindstone use + org.bukkit.event.block.BlockExpEvent event = new org.bukkit.event.block.BlockExpEvent(org.bukkit.craftbukkit.block.CraftBlock.at(level, blockPos), this.getExperienceAmount(level)); + event.callEvent(); -+ ExperienceOrb.award((ServerLevel) level, Vec3.atCenterOf(blockPos), event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player); ++ ExperienceOrb.awardWithDirection((ServerLevel) level, Vec3.atCenterOf(blockPos), Vec3.ZERO, event.getExpToDrop(), org.bukkit.entity.ExperienceOrb.SpawnReason.GRINDSTONE, player, null); + // Paper end - Fire BlockExpEvent on grindstone use } diff --git a/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch index 522f735710..c699e34a36 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/EnderEyeItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/EnderEyeItem.java +++ b/net/minecraft/world/item/EnderEyeItem.java -@@ -42,6 +_,11 @@ +@@ -43,6 +_,11 @@ return InteractionResult.SUCCESS; } else { BlockState blockState1 = blockState.setValue(EndPortalFrameBlock.HAS_EYE, true); @@ -12,7 +12,7 @@ Block.pushEntitiesUp(blockState, blockState1, level, clickedPos); level.setBlock(clickedPos, blockState1, 2); level.updateNeighbourForOutputSignal(clickedPos, Blocks.END_PORTAL_FRAME); -@@ -59,7 +_,27 @@ +@@ -60,7 +_,27 @@ } } @@ -41,9 +41,9 @@ } return InteractionResult.SUCCESS; -@@ -89,7 +_,11 @@ +@@ -90,7 +_,11 @@ eyeOfEnder.setItem(itemInHand); - eyeOfEnder.signalTo(blockPos); + eyeOfEnder.signalTo(Vec3.atLowerCornerOf(blockPos)); level.gameEvent(GameEvent.PROJECTILE_SHOOT, eyeOfEnder.position(), GameEvent.Context.of(player)); - level.addFreshEntity(eyeOfEnder); + // CraftBukkit start diff --git a/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch index 82cda7233f..39ba53dc6f 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/FireworkRocketItem.java.patch @@ -1,43 +1,45 @@ --- a/net/minecraft/world/item/FireworkRocketItem.java +++ b/net/minecraft/world/item/FireworkRocketItem.java -@@ -29,7 +_,7 @@ - ItemStack itemInHand = context.getItemInHand(); - Vec3 clickLocation = context.getClickLocation(); - Direction clickedFace = context.getClickedFace(); -- Projectile.spawnProjectile( -+ final Projectile.Delayed fireworkRocketEntity = Projectile.spawnProjectileDelayed( // Paper - PlayerLaunchProjectileEvent - new FireworkRocketEntity( - level, - context.getPlayer(), -@@ -39,9 +_,14 @@ - itemInHand - ), - serverLevel, -- itemInHand -+ itemInHand, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid - ); -- itemInHand.shrink(1); -+ // Paper start - PlayerLaunchProjectileEvent -+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity()); -+ if (!event.callEvent() || !fireworkRocketEntity.attemptSpawn()) return InteractionResult.PASS; -+ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemInHand.shrink(1); -+ else context.getPlayer().containerMenu.sendAllDataToRemote(); -+ // Paper end - PlayerLaunchProjectileEvent - } +@@ -35,7 +_,7 @@ + ItemStack itemInHand = context.getItemInHand(); + Vec3 clickLocation = context.getClickLocation(); + Direction clickedFace = context.getClickedFace(); +- Projectile.spawnProjectile( ++ final Projectile.Delayed fireworkRocketEntity = Projectile.spawnProjectileDelayed( // Paper - PlayerLaunchProjectileEvent + new FireworkRocketEntity( + level, + context.getPlayer(), +@@ -45,9 +_,14 @@ + itemInHand + ), + serverLevel, +- itemInHand ++ itemInHand, f -> f.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID() // Paper - firework api - assign spawning entity uuid + ); +- itemInHand.shrink(1); ++ // Paper start - PlayerLaunchProjectileEvent ++ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) fireworkRocketEntity.projectile().getBukkitEntity()); ++ if (!event.callEvent() || !fireworkRocketEntity.attemptSpawn()) return InteractionResult.PASS; ++ if (event.shouldConsume() && !context.getPlayer().hasInfiniteMaterials()) itemInHand.shrink(1); ++ else context.getPlayer().containerMenu.sendAllDataToRemote(); ++ // Paper end - PlayerLaunchProjectileEvent + } - return InteractionResult.SUCCESS; -@@ -52,9 +_,21 @@ + return InteractionResult.SUCCESS; +@@ -59,13 +_,24 @@ if (player.isFallFlying()) { ItemStack itemInHand = player.getItemInHand(hand); if (level instanceof ServerLevel serverLevel) { -- Projectile.spawnProjectile(new FireworkRocketEntity(level, itemInHand, player), serverLevel, itemInHand); -- itemInHand.consume(1, player); -- player.awardStat(Stats.ITEM_USED.get(this)); +- if (player.dropAllLeashConnections(null)) { +- level.playSound(null, player, SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F); + // Paper start - PlayerElytraBoostEvent + final Projectile.Delayed delayed = Projectile.spawnProjectileDelayed(new FireworkRocketEntity(level, itemInHand, player), serverLevel, itemInHand, f -> f.spawningEntity = player.getUUID()); // Paper - firework api - assign spawning entity uuid + com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) player.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemInHand), (org.bukkit.entity.Firework) delayed.projectile().getBukkitEntity(), org.bukkit.craftbukkit.CraftEquipmentSlot.getHand(hand)); + if (event.callEvent() && delayed.attemptSpawn()) { + player.awardStat(Stats.ITEM_USED.get(this)); // Moved up from below ++ if (player.dropAllLeashConnections(null)) { ++ level.playSound(null, player, SoundEvents.LEAD_BREAK, SoundSource.NEUTRAL, 1.0F, 1.0F); ++ } + if (event.shouldConsume() && !player.hasInfiniteMaterials()) { + itemInHand.shrink(1); // Moved up from below + } else { @@ -45,7 +47,11 @@ + } + } else { + player.containerMenu.sendAllDataToRemote(); -+ } + } +- +- Projectile.spawnProjectile(new FireworkRocketEntity(level, itemInHand, player), serverLevel, itemInHand); +- itemInHand.consume(1, player); +- player.awardStat(Stats.ITEM_USED.get(this)); + // Moved up consume and changed consume to shrink + // Paper end - PlayerElytraBoostEvent } diff --git a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch index 443385a232..37f7b9819f 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/ItemStack.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/ItemStack.java +++ b/net/minecraft/world/item/ItemStack.java -@@ -198,12 +_,20 @@ +@@ -195,12 +_,20 @@ @Override public void encode(RegistryFriendlyByteBuf buffer, ItemStack value) { @@ -23,7 +23,7 @@ } } }; -@@ -373,10 +_,166 @@ +@@ -365,10 +_,166 @@ return InteractionResult.PASS; } else { Item item = this.getItem(); @@ -192,7 +192,7 @@ return interactionResult; } -@@ -473,31 +_,71 @@ +@@ -449,31 +_,71 @@ return this.isDamageableItem() && this.getDamageValue() >= this.getMaxDamage() - 1; } @@ -272,7 +272,7 @@ this.shrink(1); onBreak.accept(item); } -@@ -510,15 +_,39 @@ +@@ -486,7 +_,26 @@ return; } @@ -300,6 +300,8 @@ this.applyDamage(min, serverPlayer, item -> {}); } } +@@ -496,9 +_,14 @@ + } public void hurtAndBreak(int amount, LivingEntity entity, EquipmentSlot slot) { + // Paper start - add param to skip infinite mats check @@ -314,7 +316,7 @@ ); } } -@@ -732,6 +_,12 @@ +@@ -712,6 +_,12 @@ return this.getItem().useOnRelease(this); } @@ -327,7 +329,7 @@ @Nullable public T set(DataComponentType component, @Nullable T value) { return this.components.set(component, value); -@@ -779,6 +_,28 @@ +@@ -759,6 +_,28 @@ this.getItem().verifyComponentsAfterLoad(this); } @@ -356,7 +358,7 @@ public Component getHoverName() { Component customName = this.getCustomName(); return customName != null ? customName : this.getItemName(); -@@ -1054,6 +_,19 @@ +@@ -986,6 +_,19 @@ EnchantmentHelper.forEachModifier(this, equipmentSLot, action); } @@ -376,7 +378,7 @@ public Component getDisplayName() { MutableComponent mutableComponent = Component.empty().append(this.getHoverName()); if (this.has(DataComponents.CUSTOM_NAME)) { -@@ -1109,7 +_,7 @@ +@@ -1041,7 +_,7 @@ } public void consume(int amount, @Nullable LivingEntity entity) { diff --git a/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch b/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch index 284a57db81..c9fcda66a5 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/LeadItem.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/LeadItem.java +++ b/net/minecraft/world/item/LeadItem.java -@@ -28,23 +_,43 @@ +@@ -26,24 +_,43 @@ if (blockState.is(BlockTags.FENCES)) { Player player = context.getPlayer(); if (!level.isClientSide && player != null) { @@ -15,7 +15,8 @@ - public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos) { + public static InteractionResult bindPlayerMobs(Player player, Level level, BlockPos pos, net.minecraft.world.InteractionHand interactionHand) { // CraftBukkit - Add InteractionHand LeashFenceKnotEntity leashFenceKnotEntity = null; - List list = leashableInArea(level, pos, leashable1 -> leashable1.getLeashHolder() == player); + List list = Leashable.leashableInArea(level, Vec3.atCenterOf(pos), leashable1 -> leashable1.getLeashHolder() == player); + boolean flag = false; - for (Leashable leashable : list) { + for (java.util.Iterator iterator = list.iterator(); iterator.hasNext();) { // Paper - use iterator to remove @@ -36,18 +37,17 @@ } + // CraftBukkit start -+ if (leashable instanceof Entity leashed) { ++ if (leashable instanceof net.minecraft.world.entity.Entity leashed) { + if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(leashed, leashFenceKnotEntity, player, interactionHand).isCancelled()) { + iterator.remove(); + continue; + } + } + // CraftBukkit end -+ - leashable.setLeashedTo(leashFenceKnotEntity, true); - } - -@@ -52,9 +_,20 @@ + if (leashable.canHaveALeashAttachedTo(leashFenceKnotEntity)) { + leashable.setLeashedTo(leashFenceKnotEntity, true); + flag = true; +@@ -54,7 +_,18 @@ level.gameEvent(GameEvent.BLOCK_ATTACH, pos, GameEvent.Context.of(player)); return InteractionResult.SUCCESS_SERVER; } else { @@ -65,6 +65,4 @@ + return LeadItem.bindPlayerMobs(player, world, pos, net.minecraft.world.InteractionHand.MAIN_HAND); + } + // CraftBukkit end - - public static List leashableInArea(Level level, BlockPos pos, Predicate predicate) { - double d = 7.0; + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/Consumable.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/Consumable.java.patch index d39f21455d..fff05a6ec0 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/component/Consumable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/component/Consumable.java.patch @@ -30,7 +30,7 @@ + stack.getAllOfType(ConsumableListener.class).forEach(listener -> { + listener.cancelUsingItem(player, stack, packets); // Paper - properly resend entities - collect packets for bundle + }); -+ player.server.getPlayerList().sendActiveEffects(player, packets::add); // Paper - properly resend entities - collect packets for bundle ++ player.getServer().getPlayerList().sendActiveEffects(player, packets::add); // Paper - properly resend entities - collect packets for bundle + player.connection.send(new net.minecraft.network.protocol.game.ClientboundBundlePacket(packets)); + } + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/CustomData.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/CustomData.java.patch index 825f0b35ca..41dff9eebf 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/component/CustomData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/component/CustomData.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/component/CustomData.java +++ b/net/minecraft/world/item/component/CustomData.java -@@ -33,7 +_,17 @@ +@@ -36,7 +_,17 @@ private static final Logger LOGGER = LogUtils.getLogger(); public static final CustomData EMPTY = new CustomData(new CompoundTag()); private static final String TYPE_TAG = "id"; diff --git a/paper-server/patches/sources/net/minecraft/world/item/component/ResolvableProfile.java.patch b/paper-server/patches/sources/net/minecraft/world/item/component/ResolvableProfile.java.patch index e12079be3f..7d874011f1 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/component/ResolvableProfile.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/component/ResolvableProfile.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/item/component/ResolvableProfile.java +++ b/net/minecraft/world/item/component/ResolvableProfile.java -@@ -20,9 +_,10 @@ +@@ -21,9 +_,10 @@ instance -> instance.group( ExtraCodecs.PLAYER_NAME.optionalFieldOf("name").forGetter(ResolvableProfile::name), UUIDUtil.CODEC.optionalFieldOf("id").forGetter(ResolvableProfile::id), @@ -12,12 +12,21 @@ ); public static final Codec CODEC = Codec.withAlternative( FULL_CODEC, ExtraCodecs.PLAYER_NAME, name -> new ResolvableProfile(Optional.of(name), Optional.empty(), new PropertyMap()) -@@ -49,7 +_,7 @@ - if (this.isResolved()) { +@@ -53,7 +_,7 @@ + } else { + Optional optional; + if (this.id.isPresent()) { +- optional = SkullBlockEntity.fetchGameProfile(this.id.get()).getNow(null); ++ optional = SkullBlockEntity.fetchGameProfile(this.id.get(), this.name.orElse(null)).getNow(null); // Paper - player profile events - pass name + } else { + optional = SkullBlockEntity.fetchGameProfile(this.name.orElseThrow()).getNow(null); + } +@@ -67,7 +_,7 @@ return CompletableFuture.completedFuture(this); } else { -- return this.id.isPresent() ? SkullBlockEntity.fetchGameProfile(this.id.get()).thenApply(optional -> { -+ return this.id.isPresent() ? SkullBlockEntity.fetchGameProfile(this.id.get(), this.name.orElse(null)).thenApply(optional -> { // Paper - player profile events - GameProfile gameProfile = optional.orElseGet(() -> new GameProfile(this.id.get(), this.name.orElse(""))); - return new ResolvableProfile(gameProfile); - }) : SkullBlockEntity.fetchGameProfile(this.name.orElseThrow()).thenApply(optional -> { + return this.id.isPresent() +- ? SkullBlockEntity.fetchGameProfile(this.id.get()).thenApply(this::createProfile) ++ ? SkullBlockEntity.fetchGameProfile(this.id.get(), this.name.orElse(null)).thenApply(this::createProfile) // Paper - player profile events - pass name + : SkullBlockEntity.fetchGameProfile(this.name.orElseThrow()).thenApply(this::createProfile); + } + } diff --git a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch index 1e5f3e0f5d..723d1f665f 100644 --- a/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/item/crafting/RecipeManager.java.patch @@ -17,7 +17,7 @@ + if (this.featureflagset != null) { + this.finalizeRecipeLoading(this.featureflagset); + -+ net.minecraft.server.MinecraftServer.getServer().getPlayerList().reloadRecipes(); ++ net.minecraft.server.MinecraftServer.getServer().getPlayerList().reloadResources(); + } + } + @@ -39,15 +39,7 @@ } public Optional> byKey(ResourceKey> key) { -@@ -184,6 +_,7 @@ - - @Nullable - public RecipeManager.ServerDisplayInfo getRecipeFromDisplay(RecipeDisplayId display) { -+ if (display.index() < 0 || display.index() >= this.allDisplays.size()) return null; // Paper - return this.allDisplays.get(display.index()); - } - -@@ -199,6 +_,22 @@ +@@ -200,6 +_,22 @@ Recipe recipe1 = Recipe.CODEC.parse(registries.createSerializationContext(JsonOps.INSTANCE), json).getOrThrow(JsonParseException::new); return new RecipeHolder<>(recipe, recipe1); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch index 0c982e858c..4d22b3d012 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BaseCommandBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/BaseCommandBlock.java +++ b/net/minecraft/world/level/BaseCommandBlock.java -@@ -37,6 +_,11 @@ +@@ -34,6 +_,11 @@ private String command = ""; @Nullable private Component customName; @@ -12,7 +12,7 @@ public int getSuccessCount() { return this.successCount; -@@ -114,7 +_,7 @@ +@@ -108,7 +_,7 @@ this.successCount++; } }); @@ -21,7 +21,7 @@ } catch (Throwable var6) { CrashReport crashReport = CrashReport.forThrowable(var6, "Executing command block"); CrashReportCategory crashReportCategory = crashReport.addCategory("Command to be executed"); -@@ -150,6 +_,7 @@ +@@ -144,6 +_,7 @@ @Override public void sendSystemMessage(Component component) { if (this.trackOutput) { @@ -29,7 +29,7 @@ this.lastOutput = Component.literal("[" + TIME_FORMAT.format(new Date()) + "] ").append(component); this.onUpdated(); } -@@ -172,7 +_,7 @@ +@@ -166,7 +_,7 @@ } public InteractionResult usedBy(Player player) { @@ -37,4 +37,4 @@ + if (!player.canUseGameMasterBlocks() && (!player.isCreative() || !player.getBukkitEntity().hasPermission("minecraft.commandblock"))) { // Paper - command block permission return InteractionResult.PASS; } else { - if (player.getCommandSenderWorld().isClientSide) { + if (player.level().isClientSide) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch index 3d0ff5e496..22448caa9f 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/BaseSpawner.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/BaseSpawner.java +++ b/net/minecraft/world/level/BaseSpawner.java -@@ -46,13 +_,15 @@ +@@ -53,13 +_,15 @@ public int maxNearbyEntities = 6; public int requiredPlayerRange = 16; public int spawnRange = 4; @@ -17,7 +17,7 @@ } public void clientTick(Level level, BlockPos pos) { -@@ -75,13 +_,19 @@ +@@ -82,13 +_,19 @@ } public void serverTick(ServerLevel serverLevel, BlockPos pos) { @@ -39,108 +39,107 @@ } else { boolean flag = false; RandomSource random = serverLevel.getRandom(); -@@ -118,6 +_,21 @@ - continue; - } - -+ // Paper start - PreCreatureSpawnEvent -+ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent( -+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(vec3, serverLevel.getWorld()), -+ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()), -+ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, serverLevel) -+ ); -+ if (!event.callEvent()) { -+ flag = true; -+ if (event.shouldAbortSpawn()) { -+ break; -+ } -+ continue; -+ } -+ // Paper end - PreCreatureSpawnEvent -+ - Entity entity = EntityType.loadEntityRecursive(entityToSpawn, serverLevel, EntitySpawnReason.SPAWNER, entity1 -> { - entity1.snapTo(vec3.x, vec3.y, vec3.z, entity1.getYRot(), entity1.getXRot()); - return entity1; -@@ -138,6 +_,7 @@ - return; - } - -+ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag - entity.snapTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F); - if (entity instanceof Mob mob) { - if (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER) -@@ -152,9 +_,22 @@ +@@ -128,6 +_,21 @@ + continue; } - nextSpawnData.getEquipment().ifPresent(mob::equip); -+ // Spigot start -+ if (mob.level().spigotConfig.nerfSpawnerMobs) { -+ mob.aware = false; ++ // Paper start - PreCreatureSpawnEvent ++ com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent event = new com.destroystokyo.paper.event.entity.PreSpawnerSpawnEvent( ++ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(vec3, serverLevel.getWorld()), ++ org.bukkit.craftbukkit.entity.CraftEntityType.minecraftToBukkit(optional.get()), ++ org.bukkit.craftbukkit.util.CraftLocation.toBukkit(pos, serverLevel) ++ ); ++ if (!event.callEvent()) { ++ flag = true; ++ if (event.shouldAbortSpawn()) { ++ break; ++ } ++ continue; + } -+ // Spigot end - } ++ // Paper end - PreCreatureSpawnEvent ++ + Entity entity = EntityType.loadEntityRecursive(valueInput, serverLevel, EntitySpawnReason.SPAWNER, entity1 -> { + entity1.snapTo(vec3.x, vec3.y, vec3.z, entity1.getYRot(), entity1.getXRot()); + return entity1; +@@ -148,6 +_,7 @@ + return; + } -- if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) { -+ entity.spawnedViaMobSpawner = true; // Paper -+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; // Paper - Entity#getEntitySpawnReason -+ flag = true; // Paper -+ // CraftBukkit start -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { -+ continue; -+ } -+ if (!serverLevel.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) { -+ // CraftBukkit end - this.delay(serverLevel, pos); - return; - } -@@ -165,7 +_,7 @@ - ((Mob)entity).spawnAnim(); - } ++ entity.preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; preserve entity motion from tag + entity.snapTo(entity.getX(), entity.getY(), entity.getZ(), random.nextFloat() * 360.0F, 0.0F); + if (entity instanceof Mob mob) { + if (nextSpawnData.getCustomSpawnRules().isEmpty() && !mob.checkSpawnRules(serverLevel, EntitySpawnReason.SPAWNER) +@@ -162,9 +_,22 @@ + } -- flag = true; -+ //flag = true; // Paper - moved up above cancellable event + nextSpawnData.getEquipment().ifPresent(mob::equip); ++ // Spigot start ++ if (mob.level().spigotConfig.nerfSpawnerMobs) { ++ mob.aware = false; ++ } ++ // Spigot end + } + +- if (!serverLevel.tryAddFreshEntityWithPassengers(entity)) { ++ // Paper start ++ entity.spawnedViaMobSpawner = true; ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER; ++ flag = true; ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) { ++ continue; ++ } ++ if (!serverLevel.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER)) { ++ // Paper end + this.delay(serverLevel, pos); + return; + } +@@ -175,7 +_,7 @@ + ((Mob)entity).spawnAnim(); + } + +- flag = true; ++ //flag = true; // Paper - moved up above cancellable event + } } } - -@@ -189,12 +_,14 @@ +@@ -202,12 +_,14 @@ } - public void load(@Nullable Level level, BlockPos pos, CompoundTag tag) { -- this.spawnDelay = tag.getShortOr("Delay", (short)20); -+ this.spawnDelay = tag.getIntOr("Paper.Delay", tag.getShortOr("Delay", (short) 20)); // Paper - use int if set - tag.read("SpawnData", SpawnData.CODEC).ifPresent(spawnData -> this.setNextSpawnData(level, pos, spawnData)); - this.spawnPotentials = tag.read("SpawnPotentials", SpawnData.LIST_CODEC) -- .orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData())); -- this.minSpawnDelay = tag.getIntOr("MinSpawnDelay", 200); -- this.maxSpawnDelay = tag.getIntOr("MaxSpawnDelay", 800); -+ .orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData())); + public void load(@Nullable Level level, BlockPos pos, ValueInput input) { +- this.spawnDelay = input.getShortOr("Delay", (short)20); ++ this.spawnDelay = input.getIntOr("Paper.Delay", input.getShortOr("Delay", (short) 20)); // Paper - use int if set + input.read("SpawnData", SpawnData.CODEC).ifPresent(spawnData -> this.setNextSpawnData(level, pos, spawnData)); + this.spawnPotentials = input.read("SpawnPotentials", SpawnData.LIST_CODEC) + .orElseGet(() -> WeightedList.of(this.nextSpawnData != null ? this.nextSpawnData : new SpawnData())); +- this.minSpawnDelay = input.getIntOr("MinSpawnDelay", 200); +- this.maxSpawnDelay = input.getIntOr("MaxSpawnDelay", 800); + // Paper start - use int if set -+ this.minSpawnDelay = tag.getIntOr("Paper.MinSpawnDelay", tag.getIntOr("MinSpawnDelay", 200)); -+ this.maxSpawnDelay = tag.getIntOr("Paper.MaxSpawnDelay", tag.getIntOr("MaxSpawnDelay", 800)); ++ this.minSpawnDelay = input.getIntOr("Paper.MinSpawnDelay", input.getIntOr("MinSpawnDelay", 200)); ++ this.maxSpawnDelay = input.getIntOr("Paper.MaxSpawnDelay", input.getIntOr("MaxSpawnDelay", 800)); + // Paper end - use int if set - this.spawnCount = tag.getIntOr("SpawnCount", 4); - this.maxNearbyEntities = tag.getIntOr("MaxNearbyEntities", 6); - this.requiredPlayerRange = tag.getIntOr("RequiredPlayerRange", 16); -@@ -203,9 +_,19 @@ + this.spawnCount = input.getIntOr("SpawnCount", 4); + this.maxNearbyEntities = input.getIntOr("MaxNearbyEntities", 6); + this.requiredPlayerRange = input.getIntOr("RequiredPlayerRange", 16); +@@ -216,9 +_,19 @@ } - public CompoundTag save(CompoundTag tag) { -- tag.putShort("Delay", (short)this.spawnDelay); -- tag.putShort("MinSpawnDelay", (short)this.minSpawnDelay); -- tag.putShort("MaxSpawnDelay", (short)this.maxSpawnDelay); + public void save(ValueOutput output) { +- output.putShort("Delay", (short)this.spawnDelay); +- output.putShort("MinSpawnDelay", (short)this.minSpawnDelay); +- output.putShort("MaxSpawnDelay", (short)this.maxSpawnDelay); + // Paper start + if (this.spawnDelay > Short.MAX_VALUE) { -+ tag.putInt("Paper.Delay", this.spawnDelay); ++ output.putInt("Paper.Delay", this.spawnDelay); + } -+ tag.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay)); ++ output.putShort("Delay", (short) Math.min(Short.MAX_VALUE, this.spawnDelay)); + + if (this.minSpawnDelay > Short.MAX_VALUE || this.maxSpawnDelay > Short.MAX_VALUE) { -+ tag.putInt("Paper.MinSpawnDelay", this.minSpawnDelay); -+ tag.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay); ++ output.putInt("Paper.MinSpawnDelay", this.minSpawnDelay); ++ output.putInt("Paper.MaxSpawnDelay", this.maxSpawnDelay); + } -+ tag.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay)); -+ tag.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay)); ++ output.putShort("MinSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.minSpawnDelay)); ++ output.putShort("MaxSpawnDelay", (short) Math.min(Short.MAX_VALUE, this.maxSpawnDelay)); + // Paper end - tag.putShort("SpawnCount", (short)this.spawnCount); - tag.putShort("MaxNearbyEntities", (short)this.maxNearbyEntities); - tag.putShort("RequiredPlayerRange", (short)this.requiredPlayerRange); + output.putShort("SpawnCount", (short)this.spawnCount); + output.putShort("MaxNearbyEntities", (short)this.maxNearbyEntities); + output.putShort("RequiredPlayerRange", (short)this.requiredPlayerRange); diff --git a/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch b/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch index 12d60c59e2..49bef8c203 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/GameRules.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/GameRules.java +++ b/net/minecraft/world/level/GameRules.java -@@ -34,6 +_,14 @@ +@@ -35,6 +_,14 @@ import org.slf4j.Logger; public class GameRules { @@ -15,7 +15,7 @@ public static final int DEFAULT_RANDOM_TICK_SPEED = 3; static final Logger LOGGER = LogUtils.getLogger(); public static final Map, GameRules.Type> GAME_RULE_TYPES = Maps.newTreeMap(Comparator.comparing(entry -> entry.id)); -@@ -86,10 +_,10 @@ +@@ -87,10 +_,10 @@ "sendCommandFeedback", GameRules.Category.CHAT, GameRules.BooleanValue.create(true) ); public static final GameRules.Key RULE_REDUCEDDEBUGINFO = register( @@ -28,7 +28,7 @@ serverPlayer.connection.send(new ClientboundEntityEventPacket(serverPlayer, b)); } }) -@@ -113,8 +_,8 @@ +@@ -114,8 +_,8 @@ "doWeatherCycle", GameRules.Category.UPDATES, GameRules.BooleanValue.create(true) ); public static final GameRules.Key RULE_LIMITED_CRAFTING = register( @@ -39,7 +39,7 @@ serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LIMITED_CRAFTING, value.get() ? 1.0F : 0.0F)); } }) -@@ -138,8 +_,8 @@ +@@ -139,8 +_,8 @@ "doInsomnia", GameRules.Category.SPAWNING, GameRules.BooleanValue.create(true) ); public static final GameRules.Key RULE_DO_IMMEDIATE_RESPAWN = register( @@ -50,7 +50,7 @@ serverPlayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, value.get() ? 1.0F : 0.0F)); } }) -@@ -210,11 +_,11 @@ +@@ -211,11 +_,11 @@ public static final GameRules.Key RULE_MINECART_MAX_SPEED = register( "minecartMaxSpeed", GameRules.Category.MISC, @@ -65,7 +65,16 @@ serverLevel.setDefaultSpawnPos(serverLevel.getSharedSpawnPos(), serverLevel.getSharedSpawnAngle()); }) ); -@@ -223,6 +_,7 @@ +@@ -223,7 +_,7 @@ + "tntExplodes", GameRules.Category.MISC, GameRules.BooleanValue.create(true) + ); + public static final GameRules.Key RULE_LOCATOR_BAR = register( +- "locatorBar", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true, (server, value) -> server.getAllLevels().forEach(level -> { ++ "locatorBar", GameRules.Category.PLAYER, GameRules.BooleanValue.create(true, (server, value) -> java.util.Optional.of(server).ifPresent(level -> { // Paper - per world game rules + ServerWaypointManager waypointManager = level.getWaypointManager(); + if (value.get()) { + level.players().forEach(waypointManager::updatePlayer); +@@ -234,6 +_,7 @@ ); private final Map, GameRules.Value> rules; private final FeatureFlagSet enabledFeatures; @@ -73,7 +82,7 @@ public static > GameRules.Type getType(GameRules.Key key) { return (GameRules.Type)GAME_RULE_TYPES.get(key); -@@ -270,10 +_,21 @@ +@@ -281,10 +_,21 @@ private GameRules(Map, GameRules.Value> rules, FeatureFlagSet enabledFeatures) { this.rules = rules; this.enabledFeatures = enabledFeatures; @@ -96,7 +105,7 @@ if (value == null) { throw new IllegalArgumentException("Tried to access invalid game rule"); } else { -@@ -314,13 +_,13 @@ +@@ -325,13 +_,13 @@ } } @@ -114,16 +123,25 @@ } public boolean getBoolean(GameRules.Key key) { -@@ -334,7 +_,7 @@ - public static class BooleanValue extends GameRules.Value { +@@ -346,7 +_,7 @@ private boolean value; + private static GameRules.Type create( +- boolean defaultValue, BiConsumer changeListener, FeatureFlagSet requiredFeatures ++ boolean defaultValue, BiConsumer changeListener, FeatureFlagSet requiredFeatures // Paper - per world gamerules + ) { + return new GameRules.Type<>( + BoolArgumentType::bool, +@@ -358,7 +_,7 @@ + ); + } + - static GameRules.Type create(boolean defaultValue, BiConsumer changeListener) { -+ static GameRules.Type create(boolean defaultValue, BiConsumer changeListener) { // CraftBukkit - per-world ++ static GameRules.Type create(boolean defaultValue, BiConsumer changeListener) { // Paper - per world gamerules return new GameRules.Type<>( BoolArgumentType::bool, type -> new GameRules.BooleanValue(type, defaultValue), -@@ -355,17 +_,21 @@ +@@ -379,17 +_,21 @@ } @Override @@ -149,7 +167,7 @@ } @Override -@@ -394,9 +_,9 @@ +@@ -418,9 +_,9 @@ } @Override @@ -161,7 +179,7 @@ } } -@@ -434,7 +_,7 @@ +@@ -458,7 +_,7 @@ public static class IntegerValue extends GameRules.Value { private int value; @@ -170,7 +188,7 @@ return new GameRules.Type<>( IntegerArgumentType::integer, type -> new GameRules.IntegerValue(type, defaultValue), -@@ -446,7 +_,7 @@ +@@ -470,7 +_,7 @@ } static GameRules.Type create( @@ -179,7 +197,7 @@ ) { return new GameRules.Type<>( () -> IntegerArgumentType.integer(min, max), -@@ -468,17 +_,21 @@ +@@ -492,17 +_,21 @@ } @Override @@ -205,7 +223,7 @@ } @Override -@@ -529,13 +_,17 @@ +@@ -553,13 +_,17 @@ } @Override @@ -225,7 +243,7 @@ final String id; private final GameRules.Category category; -@@ -575,7 +_,7 @@ +@@ -599,7 +_,7 @@ public static class Type> { final Supplier> argument; private final Function, T> constructor; @@ -234,7 +252,7 @@ private final GameRules.VisitorCaller visitorCaller; final Class valueClass; final FeatureFlagSet requiredFeatures; -@@ -583,7 +_,7 @@ +@@ -607,7 +_,7 @@ Type( Supplier> argument, Function, T> constructor, @@ -243,7 +261,7 @@ GameRules.VisitorCaller visitorCaller, Class valueClass, FeatureFlagSet requiredFeatures -@@ -611,6 +_,12 @@ +@@ -635,6 +_,12 @@ public FeatureFlagSet requiredFeatures() { return this.requiredFeatures; } @@ -256,7 +274,7 @@ } public abstract static class Value> { -@@ -620,16 +_,16 @@ +@@ -644,16 +_,16 @@ this.type = type; } @@ -280,7 +298,7 @@ } } -@@ -648,7 +_,7 @@ +@@ -672,7 +_,7 @@ protected abstract T copy(); diff --git a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch index c8c164d1a7..348a42a9a9 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/Level.java.patch @@ -547,23 +547,16 @@ public boolean shouldTickDeath(Entity entity) { return true; -@@ -608,6 +_,19 @@ +@@ -608,6 +_,12 @@ @Nullable @Override public BlockEntity getBlockEntity(BlockPos pos) { -+ // CraftBukkit start -+ return this.getBlockEntity(pos, true); -+ } -+ -+ @Nullable -+ public BlockEntity getBlockEntity(BlockPos pos, boolean validate) { + // Paper start - Perf: Optimize capturedTileEntities lookup + net.minecraft.world.level.block.entity.BlockEntity blockEntity; + if (!this.capturedTileEntities.isEmpty() && (blockEntity = this.capturedTileEntities.get(pos)) != null) { + return blockEntity; + } + // Paper end - Perf: Optimize capturedTileEntities lookup -+ // CraftBukkit end if (this.isOutsideBuildHeight(pos)) { return null; } else { @@ -580,7 +573,7 @@ this.getChunkAt(blockPos).addAndRegisterBlockEntity(blockEntity); } } -@@ -1009,7 +_,8 @@ +@@ -1013,7 +_,8 @@ BLOCK("block"), MOB("mob"), TNT("tnt"), diff --git a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch index 5d4fa1818a..215dbdad70 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/ServerExplosion.java.patch @@ -224,7 +224,7 @@ this.level.gameEvent(this.source, GameEvent.EXPLODE, this.center); List list = this.calculateExplodedPositions(); this.hurtEntities(); -@@ -339,4 +_,86 @@ +@@ -338,4 +_,86 @@ } } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/TicketStorage.java.patch b/paper-server/patches/sources/net/minecraft/world/level/TicketStorage.java.patch index ff5aabed75..0085bb153a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/TicketStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/TicketStorage.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/TicketStorage.java +++ b/net/minecraft/world/level/TicketStorage.java -@@ -161,7 +_,7 @@ +@@ -163,7 +_,7 @@ } private static boolean isTicketSameTypeAndLevel(Ticket first, Ticket second) { @@ -9,16 +9,16 @@ } public int getTicketLevelAt(long chunkPos, boolean requireSimulation) { -@@ -264,7 +_,7 @@ +@@ -272,7 +_,7 @@ } public void deactivateTicketsOnClosing() { -- this.removeTicketIf(ticket -> ticket.getType() != TicketType.UNKNOWN, this.deactivatedTickets); -+ this.removeTicketIf(ticket -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets); +- this.removeTicketIf((_long, ticket) -> ticket.getType() != TicketType.UNKNOWN, this.deactivatedTickets); ++ this.removeTicketIf((_long, ticket) -> ticket.getType() != TicketType.UNKNOWN && ticket.getType() != TicketType.CHUNK_LOAD && ticket.getType() != TicketType.FUTURE_AWAIT, this.deactivatedTickets); } - public void removeTicketIf(Predicate predicate, @Nullable Long2ObjectOpenHashMap> tickets) { -@@ -369,4 +_,19 @@ + public void removeTicketIf(BiPredicate biPredicate, @Nullable Long2ObjectOpenHashMap> map) { +@@ -378,4 +_,19 @@ public interface ChunkUpdated { void update(long chunkPos, int i, boolean ticketLevel); } @@ -34,7 +34,7 @@ + } + + public void removeAllPluginRegionTickets(TicketType ticketType, int ticketLevel, org.bukkit.plugin.Plugin ticketIdentifier) { -+ removeTicketIf(ticket -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null); ++ removeTicketIf((chunkKey, ticket) -> ticket.getType() == ticketType && ticket.getTicketLevel() == ticketLevel && ticket.getIdentifier() == ticketIdentifier, null); + } + // Paper end } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch index a63dec69ec..84b3f16b69 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/AbstractCauldronBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/AbstractCauldronBlock.java +++ b/net/minecraft/world/level/block/AbstractCauldronBlock.java -@@ -62,7 +_,7 @@ +@@ -57,7 +_,7 @@ ItemStack stack, BlockState state, Level level, BlockPos pos, Player player, InteractionHand hand, BlockHitResult hitResult ) { CauldronInteraction cauldronInteraction = this.interactions.map().get(stack.getItem()); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch index 557a1c5cf8..cfcc81eb86 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/Block.java.patch @@ -90,7 +90,7 @@ + // Paper end - add entity parameter if (level.getGameRules().getBoolean(GameRules.RULE_DOBLOCKDROPS)) { - ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount); -+ ExperienceOrb.award(level, Vec3.atCenterOf(pos), amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity); // Paper ++ ExperienceOrb.awardWithDirection(level, Vec3.atCenterOf(pos), net.minecraft.world.phys.Vec3.ZERO, amount, org.bukkit.entity.ExperienceOrb.SpawnReason.BLOCK_BREAK, entity, null); // Paper } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch index 4ea4f1ba5b..e5eea68e2e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/CactusBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/CactusBlock.java +++ b/net/minecraft/world/level/block/CactusBlock.java -@@ -58,25 +_,29 @@ +@@ -58,18 +_,22 @@ int ageValue = state.getValue(AGE); while (level.getBlockState(pos.below(i)).is(this)) { @@ -29,14 +29,6 @@ BlockState blockState = state.setValue(AGE, 0); level.setBlock(pos, blockState, 260); level.neighborChanged(blockState, blockPos, this, null, false); - } - - if (ageValue < 15) { -- level.setBlock(pos, state.setValue(AGE, ageValue + 1), 260); -+ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(level, pos, state.setValue(AGE, ageValue + 1), 260); // Paper - } - } - } @@ -124,7 +_,8 @@ @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch index bb6b957fbc..014b2ac935 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/EndPortalBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/EndPortalBlock.java +++ b/net/minecraft/world/level/block/EndPortalBlock.java -@@ -57,8 +_,15 @@ +@@ -58,8 +_,15 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { @@ -16,8 +16,8 @@ serverPlayer.showEndCredits(); } else { entity.setAsInsidePortal(this, pos); -@@ -68,7 +_,7 @@ - +@@ -70,7 +_,7 @@ + @Nullable @Override public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) { - ResourceKey resourceKey = level.dimension() == Level.END ? Level.OVERWORLD : Level.END; @@ -25,7 +25,7 @@ ServerLevel level1 = level.getServer().getLevel(resourceKey); if (level1 == null) { return null; -@@ -79,7 +_,7 @@ +@@ -81,7 +_,7 @@ float f; Set set; if (flag) { @@ -34,8 +34,8 @@ f = Direction.WEST.toYRot(); set = Relative.union(Relative.DELTA, Set.of(Relative.X_ROT)); if (entity instanceof ServerPlayer) { -@@ -89,15 +_,23 @@ - f = 0.0F; +@@ -91,15 +_,23 @@ + f = level1.getSharedSpawnAngle(); set = Relative.union(Relative.DELTA, Relative.ROTATION); if (entity instanceof ServerPlayer serverPlayer) { - return serverPlayer.findRespawnPositionAndUseSpawnBlock(false, TeleportTransition.DO_NOTHING); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch index 4b532f0d3a..dff7b42d9d 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LavaCauldronBlock.java.patch @@ -1,15 +1,14 @@ --- a/net/minecraft/world/level/block/LavaCauldronBlock.java +++ b/net/minecraft/world/level/block/LavaCauldronBlock.java -@@ -33,9 +_,10 @@ +@@ -44,8 +_,10 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (this.isEntityInsideContent(state, pos, entity)) { -- entity.lavaIgnite(); -- entity.lavaHurt(); -+ entity.lavaIgnite(pos); // Paper - track lava contact -+ entity.lavaHurt(pos); // Paper - track lava contact - } ++ BlockPos savedPos = pos.immutable(); // Paper - track lava contact + effectApplier.apply(InsideBlockEffectType.LAVA_IGNITE); +- effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, Entity::lavaHurt); ++ effectApplier.runAfter(InsideBlockEffectType.LAVA_IGNITE, ignitedEntity -> ignitedEntity.lavaHurt(savedPos)); // Paper - track lava contact } + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch index c0a3c2eb17..54f850ca56 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/LayeredCauldronBlock.java.patch @@ -1,23 +1,27 @@ --- a/net/minecraft/world/level/block/LayeredCauldronBlock.java +++ b/net/minecraft/world/level/block/LayeredCauldronBlock.java -@@ -62,35 +_,67 @@ +@@ -79,39 +_,71 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { + if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(level, pos)).callEvent()) { return; } // Paper - Add EntityInsideBlockEvent - if (level instanceof ServerLevel serverLevel && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) { -- entity.clearFire(); -- if (entity.mayInteract(serverLevel, pos)) { -- this.handleEntityOnFireInside(state, level, pos); -+ // CraftBukkit start - moved down -+ // entity.clearFire(); -+ if ((entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity.mayInteract(serverLevel, pos)) { // Paper - Fixes MC-248588 -+ if (this.handleEntityOnFireInside(state, level, pos, entity)) { // Paper - fix powdered snow cauldron extinguishing entities -+ entity.clearFire(); -+ } -+ // CraftBukkit end - } + if (level instanceof ServerLevel serverLevel) { + BlockPos blockPos = pos.immutable(); + effectApplier.runBefore(InsideBlockEffectType.EXTINGUISH, entity1 -> { +- if (entity1.isOnFire() && entity1.mayInteract(serverLevel, blockPos)) { +- this.handleEntityOnFireInside(state, level, blockPos); ++ if (entity1.isOnFire() && (entity instanceof net.minecraft.world.entity.player.Player || serverLevel.getGameRules().getBoolean(net.minecraft.world.level.GameRules.RULE_MOBGRIEFING)) && entity1.mayInteract(serverLevel, blockPos)) { // Paper - Fixes MC-248588 ++ // Paper start - cauldron level change event ++ if (this.handleEntityOnFireInside(state, level, blockPos, entity1)) { // Paper - track entity ++ InsideBlockEffectType.EXTINGUISH.effect().affect(entity1, blockPos); // apply extinguishing if event was not cancelled. ++ } ++ // Paper end - cauldron level change event + } + }); } + +- effectApplier.apply(InsideBlockEffectType.EXTINGUISH); ++ // effectApplier.apply(InsideBlockEffectType.EXTINGUISH); // Paper - manually applied above - cauldron level change event - delay to not extinguish when event is cancelled } - private void handleEntityOnFireInside(BlockState state, Level level, BlockPos pos) { @@ -79,7 +83,7 @@ } } -@@ -108,8 +_,11 @@ +@@ -129,8 +_,11 @@ protected void receiveStalactiteDrip(BlockState state, Level level, BlockPos pos, Fluid fluid) { if (!this.isFull(state)) { BlockState blockState = state.setValue(LEVEL, state.getValue(LEVEL) + 1); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch index 34ec03d1fa..b9a4770e7e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/NetherPortalBlock.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/NetherPortalBlock.java +++ b/net/minecraft/world/level/block/NetherPortalBlock.java -@@ -70,7 +_,7 @@ +@@ -65,7 +_,7 @@ @Override protected void randomTick(BlockState state, ServerLevel level, BlockPos pos, RandomSource random) { @@ -9,7 +9,7 @@ && level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && random.nextInt(2000) < level.getDifficulty().getId() && level.anyPlayerCloseEnoughForSpawning(pos)) { -@@ -79,9 +_,13 @@ +@@ -74,9 +_,13 @@ } if (level.getBlockState(pos).isValidSpawn(level, pos, EntityType.ZOMBIFIED_PIGLIN)) { @@ -24,7 +24,7 @@ Entity vehicle = entity.getVehicle(); if (vehicle != null) { vehicle.setPortalCooldown(); -@@ -112,7 +_,13 @@ +@@ -107,7 +_,13 @@ @Override protected void entityInside(BlockState state, Level level, BlockPos pos, Entity entity, InsideBlockEffectApplier effectApplier) { @@ -38,7 +38,7 @@ entity.setAsInsidePortal(this, pos); } } -@@ -135,22 +_,46 @@ +@@ -130,22 +_,46 @@ @Nullable @Override public TeleportTransition getPortalDestination(ServerLevel level, Entity entity, BlockPos pos) { @@ -90,7 +90,7 @@ BlockUtil.FoundRectangle largestRectangleAround; TeleportTransition.PostTeleportTransition postTeleportTransition; if (optional.isPresent()) { -@@ -165,17 +_,22 @@ +@@ -160,17 +_,22 @@ blockPos1 -> level.getBlockState(blockPos1) == blockState ); postTeleportTransition = TeleportTransition.PLAY_PORTAL_SOUND.then(entity1 -> entity1.placePortalTicket(blockPos)); @@ -116,7 +116,7 @@ return getDimensionTransitionFromExit(entity, pos, largestRectangleAround, level, postTeleportTransition); } -@@ -221,7 +_,7 @@ +@@ -216,7 +_,7 @@ boolean flag = axis1 == Direction.Axis.X; Vec3 vec3 = new Vec3(blockPos.getX() + (flag ? d2 : d4), blockPos.getY() + d3, blockPos.getZ() + (flag ? d4 : d2)); Vec3 vec31 = PortalShape.findCollisionFreePosition(vec3, level, entity, dimensions); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch index 06a57c6717..07036182c0 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SculkSpreader.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/SculkSpreader.java +++ b/net/minecraft/world/level/block/SculkSpreader.java -@@ -45,6 +_,7 @@ +@@ -46,6 +_,7 @@ private final int chargeDecayRate; private final int additionalDecayRate; private List cursors = new ArrayList<>(); @@ -8,16 +8,16 @@ public SculkSpreader( boolean isWorldGeneration, TagKey replaceableBlocks, int growthSpawnCoat, int noGrowthRadius, int chargeDecayRate, int additionalDecayRate -@@ -100,7 +_,7 @@ +@@ -101,7 +_,7 @@ - public void load(CompoundTag tag) { + public void load(ValueInput input) { this.cursors.clear(); -- tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor); -+ tag.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading +- input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach(this::addCursor); ++ input.read("cursors", SculkSpreader.ChargeCursor.CODEC.sizeLimitedListOf(32)).orElse(List.of()).forEach((cursor) -> this.addCursor(cursor, false)); // Paper - don't fire event for block entity loading } - public void save(CompoundTag tag) { -@@ -110,13 +_,24 @@ + public void save(ValueOutput output) { +@@ -111,13 +_,24 @@ public void addCursors(BlockPos pos, int charge) { while (charge > 0) { int min = Math.min(charge, 1000); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch index 0e34b8cc08..eb1e38d31a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SignBlock.java.patch @@ -1,15 +1,15 @@ --- a/net/minecraft/world/level/block/SignBlock.java +++ b/net/minecraft/world/level/block/SignBlock.java @@ -133,7 +_,7 @@ - } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) - && player.mayBuild() - && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) { -- this.openTextEdit(player, signBlockEntity, isFacingFrontText); -+ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent - return InteractionResult.SUCCESS_SERVER; - } else { - return InteractionResult.PASS; -@@ -175,7 +_,34 @@ + } else if (!this.otherPlayerIsEditingSign(player, signBlockEntity) + && player.mayBuild() + && this.hasEditableText(player, signBlockEntity, isFacingFrontText)) { +- this.openTextEdit(player, signBlockEntity, isFacingFrontText); ++ this.openTextEdit(player, signBlockEntity, isFacingFrontText, io.papermc.paper.event.player.PlayerOpenSignEvent.Cause.INTERACT); // Paper - Add PlayerOpenSignEvent + return InteractionResult.SUCCESS_SERVER; + } else { + return InteractionResult.PASS; +@@ -179,7 +_,34 @@ return woodType; } @@ -44,7 +44,7 @@ signEntity.setAllowedPlayerEditor(player.getUUID()); player.openTextEdit(signEntity, isFrontText); } -@@ -188,6 +_,6 @@ +@@ -192,6 +_,6 @@ @Nullable @Override public BlockEntityTicker getTicker(Level level, BlockState state, BlockEntityType blockEntityType) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch index 4012238116..650392ae7d 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/SpongeBlock.java.patch @@ -10,7 +10,7 @@ pos, 6, 65, -@@ -63,8 +_,10 @@ +@@ -63,16 +_,18 @@ if (blockPos.equals(pos)) { return BlockPos.TraversalNodeStatus.ACCEPT; } else { @@ -23,7 +23,8 @@ if (!fluidState.is(FluidTags.WATER)) { return BlockPos.TraversalNodeStatus.SKIP; } else if (blockState.getBlock() instanceof BucketPickup bucketPickup -@@ -72,7 +_,7 @@ +- && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) { ++ && !bucketPickup.pickupBlock(null, blockList, blockPos, blockState).isEmpty()) { // CraftBukkit return BlockPos.TraversalNodeStatus.ACCEPT; } else { if (blockState.getBlock() instanceof LiquidBlock) { @@ -32,7 +33,7 @@ } else { if (!blockState.is(Blocks.KELP) && !blockState.is(Blocks.KELP_PLANT) -@@ -81,16 +_,55 @@ +@@ -81,16 +_,49 @@ return BlockPos.TraversalNodeStatus.SKIP; } @@ -42,7 +43,6 @@ + // CraftBukkit start + // BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null; + // dropResources(blockState, level, blockPos, blockEntity); -+ // level.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); + blockList.setBlock(blockPos, Blocks.AIR.defaultBlockState(), 3); + // CraftBukkit end } @@ -66,22 +66,17 @@ + + for (org.bukkit.craftbukkit.block.CraftBlockState snapshot : snapshots) { + BlockPos blockPos = snapshot.getPosition(); -+ BlockState state = level.getBlockState(blockPos); -+ FluidState fluid = level.getFluidState(blockPos); ++ BlockState blockState = level.getBlockState(blockPos); ++ FluidState fluidState = level.getFluidState(blockPos); + -+ if (fluid.is(FluidTags.WATER)) { -+ if (state.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, blockList, blockPos, state).isEmpty()) { -+ // NOP -+ } else if (state.getBlock() instanceof LiquidBlock) { -+ // NOP -+ } else if (state.is(Blocks.KELP) || state.is(Blocks.KELP_PLANT) || state.is(Blocks.SEAGRASS) || state.is(Blocks.TALL_SEAGRASS)) { -+ BlockEntity blockEntity = state.hasBlockEntity() ? level.getBlockEntity(blockPos) : null; ++ if (!fluidState.is(FluidTags.WATER)) { ++ } else if (blockState.getBlock() instanceof BucketPickup bucketPickup && !bucketPickup.pickupBlock(null, level, blockPos, blockState).isEmpty()) { ++ } else if (blockState.getBlock() instanceof LiquidBlock) { ++ } else if (blockState.is(Blocks.KELP) || blockState.is(Blocks.KELP_PLANT) || blockState.is(Blocks.SEAGRASS) || blockState.is(Blocks.TALL_SEAGRASS)) { ++ BlockEntity blockEntity = blockState.hasBlockEntity() ? level.getBlockEntity(blockPos) : null; + -+ // Paper start - Fix SpongeAbsortEvent handling -+ if (snapshot.getHandle().isAir()) { -+ dropResources(state, level, blockPos, blockEntity); -+ } -+ // Paper end - Fix SpongeAbsortEvent handling ++ if (snapshot.getHandle().isAir()) { ++ dropResources(blockState, level, blockPos, blockEntity); + } + } + snapshot.place(snapshot.getFlags()); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch index 2cef802e67..6145f471fc 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/AbstractFurnaceBlockEntity.java.patch @@ -52,20 +52,20 @@ private boolean isLit() { return this.litTimeRemaining > 0; @@ -125,6 +_,7 @@ - this.litTotalTime = tag.getShortOr("lit_total_time", (short)0); + this.litTotalTime = input.getShortOr("lit_total_time", (short)0); this.recipesUsed.clear(); - this.recipesUsed.putAll(tag.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of())); -+ this.cookSpeedMultiplier = tag.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API + this.recipesUsed.putAll(input.read("RecipesUsed", RECIPES_USED_CODEC).orElse(Map.of())); ++ this.cookSpeedMultiplier = input.getDoubleOr("Paper.CookSpeedMultiplier", 1); // Paper - cook speed multiplier API } @Override @@ -134,6 +_,7 @@ - tag.putShort("cooking_total_time", (short)this.cookingTotalTime); - tag.putShort("lit_time_remaining", (short)this.litTimeRemaining); - tag.putShort("lit_total_time", (short)this.litTotalTime); -+ tag.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API - ContainerHelper.saveAllItems(tag, this.items, registries); - tag.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed); + output.putShort("cooking_total_time", (short)this.cookingTotalTime); + output.putShort("lit_time_remaining", (short)this.litTimeRemaining); + output.putShort("lit_total_time", (short)this.litTotalTime); ++ output.putDouble("Paper.CookSpeedMultiplier", this.cookSpeedMultiplier); // Paper - cook speed multiplier API + ContainerHelper.saveAllItems(output, this.items); + output.store("RecipesUsed", RECIPES_USED_CODEC, this.recipesUsed); } @@ -160,11 +_,22 @@ @@ -210,9 +210,9 @@ } - public void awardUsedRecipesAndPopExperience(ServerPlayer player) { -- List> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position()); +- List> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position()); + public void awardUsedRecipesAndPopExperience(ServerPlayer player, ItemStack itemstack, int amount) { // CraftBukkit -+ List> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.serverLevel(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events ++ List> recipesToAwardAndPopExperience = this.getRecipesToAwardAndPopExperience(player.level(), player.position(), this.worldPosition, player, itemstack, amount); // CraftBukkit - overload for exp spawn events player.awardRecipes(recipesToAwardAndPopExperience); for (RecipeHolder recipeHolder : recipesToAwardAndPopExperience) { @@ -268,7 +268,7 @@ + floor = event.getExpToDrop(); + // CraftBukkit end + -+ ExperienceOrb.award(level, popVec, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer); // Paper ++ ExperienceOrb.awardWithDirection(level, popVec, net.minecraft.world.phys.Vec3.ZERO, floor, org.bukkit.entity.ExperienceOrb.SpawnReason.FURNACE, serverPlayer, null); // Paper } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BannerBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BannerBlockEntity.java.patch index a3aef845c4..8ead2cd710 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BannerBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BannerBlockEntity.java.patch @@ -1,24 +1,24 @@ --- a/net/minecraft/world/level/block/entity/BannerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BannerBlockEntity.java -@@ -52,7 +_,7 @@ - protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - RegistryOps registryOps = registries.createSerializationContext(NbtOps.INSTANCE); +@@ -50,7 +_,7 @@ + @Override + protected void saveAdditional(ValueOutput output) { + super.saveAdditional(output); - if (!this.patterns.equals(BannerPatternLayers.EMPTY)) { + if (!this.patterns.equals(BannerPatternLayers.EMPTY) || serialisingForNetwork.get()) { // Paper - always send patterns to client - tag.store("patterns", BannerPatternLayers.CODEC, registryOps, this.patterns); + output.store("patterns", BannerPatternLayers.CODEC, this.patterns); } -@@ -64,7 +_,7 @@ - super.loadAdditional(tag, registries); - this.name = parseCustomNameSafe(tag.get("CustomName"), registries); - RegistryOps registryOps = registries.createSerializationContext(NbtOps.INSTANCE); -- this.patterns = tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY); -+ this.setPatterns(tag.read("patterns", BannerPatternLayers.CODEC, registryOps).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits +@@ -61,7 +_,7 @@ + protected void loadAdditional(ValueInput input) { + super.loadAdditional(input); + this.name = parseCustomNameSafe(input, "CustomName"); +- this.patterns = input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY); ++ this.setPatterns(input.read("patterns", BannerPatternLayers.CODEC).orElse(BannerPatternLayers.EMPTY)); // CraftBukkit - apply limits } @Override -@@ -72,9 +_,18 @@ +@@ -69,9 +_,18 @@ return ClientboundBlockEntityDataPacket.create(this); } @@ -37,7 +37,7 @@ } public BannerPatternLayers getPatterns() { -@@ -94,7 +_,7 @@ +@@ -91,7 +_,7 @@ @Override protected void applyImplicitComponents(DataComponentGetter componentGetter) { super.applyImplicitComponents(componentGetter); @@ -46,9 +46,9 @@ this.name = componentGetter.get(DataComponents.CUSTOM_NAME); } -@@ -110,4 +_,13 @@ - tag.remove("patterns"); - tag.remove("CustomName"); +@@ -107,4 +_,13 @@ + output.discard("patterns"); + output.discard("CustomName"); } + + // CraftBukkit start diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch index eaf144169d..7b56f0f082 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BarrelBlockEntity.java.patch @@ -1,7 +1,7 @@ --- a/net/minecraft/world/level/block/entity/BarrelBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BarrelBlockEntity.java @@ -21,6 +_,41 @@ - import net.minecraft.world.level.block.state.BlockState; + import net.minecraft.world.level.storage.ValueOutput; public class BarrelBlockEntity extends RandomizableContainerBlockEntity { + // CraftBukkit start - add fields and methods diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch index fe19601364..d705523e0a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BaseContainerBlockEntity.java -@@ -69,17 +_,45 @@ +@@ -66,17 +_,45 @@ protected abstract Component getDefaultName(); public boolean canOpen(Player player) { @@ -48,9 +48,9 @@ } protected abstract NonNullList getItems(); -@@ -167,4 +_,12 @@ - tag.remove("lock"); - tag.remove("Items"); +@@ -164,4 +_,12 @@ + output.discard("lock"); + output.discard("Items"); } + + // CraftBukkit start diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch index b55f64efaf..98ccaff1f7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeaconBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BeaconBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeaconBlockEntity.java -@@ -109,6 +_,53 @@ +@@ -110,6 +_,53 @@ return 3; } }; @@ -54,7 +54,7 @@ @Nullable static Holder filterEffect(@Nullable Holder effect) { -@@ -166,17 +_,26 @@ +@@ -167,17 +_,26 @@ blockEntity.lastCheckY++; } @@ -83,7 +83,7 @@ if (blockEntity.lastCheckY >= height) { blockEntity.lastCheckY = level.getMinY() - 1; -@@ -227,35 +_,100 @@ +@@ -228,35 +_,100 @@ @Override public void setRemoved() { @@ -202,35 +202,35 @@ public static void playSound(Level level, BlockPos pos, SoundEvent sound) { level.playSound(null, pos, sound, SoundSource.BLOCKS, 1.0F, 1.0F); -@@ -284,7 +_,7 @@ +@@ -285,7 +_,7 @@ @Nullable - private static Holder loadEffect(CompoundTag tag, String key) { -- return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null); -+ return tag.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598) + private static Holder loadEffect(ValueInput input, String key) { +- return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).filter(VALID_EFFECTS::contains).orElse(null); ++ return input.read(key, BuiltInRegistries.MOB_EFFECT.holderByNameCodec()).orElse(null); // CraftBukkit - persist manually set non-default beacon effects (SPIGOT-3598) } @Override -@@ -292,8 +_,10 @@ - super.loadAdditional(tag, registries); - this.primaryPower = loadEffect(tag, "primary_effect"); - this.secondaryPower = loadEffect(tag, "secondary_effect"); -+ this.levels = tag.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available - this.name = parseCustomNameSafe(tag.get("CustomName"), registries); - this.lockKey = LockCode.fromTag(tag, registries); -+ this.effectRange = tag.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges +@@ -293,8 +_,10 @@ + super.loadAdditional(input); + this.primaryPower = loadEffect(input, "primary_effect"); + this.secondaryPower = loadEffect(input, "secondary_effect"); ++ this.levels = input.getIntOr("Levels", 0); // CraftBukkit - SPIGOT-5053, use where available + this.name = parseCustomNameSafe(input, "CustomName"); + this.lockKey = LockCode.fromTag(input); ++ this.effectRange = input.getDoubleOr(PAPER_RANGE_TAG, -1); // Paper - Custom beacon ranges } @Override -@@ -304,6 +_,7 @@ - tag.putInt("Levels", this.levels); - tag.storeNullable("CustomName", ComponentSerialization.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.name); - this.lockKey.addToTag(tag, registries); -+ tag.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges +@@ -305,6 +_,7 @@ + output.putInt("Levels", this.levels); + output.storeNullable("CustomName", ComponentSerialization.CODEC, this.name); + this.lockKey.addToTag(output); ++ output.putDouble(PAPER_RANGE_TAG, this.effectRange); // Paper - Custom beacon ranges } public void setCustomName(@Nullable Component name) { -@@ -319,7 +_,7 @@ +@@ -320,7 +_,7 @@ @Nullable @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch index a05c77e85b..8a3722fdd6 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java -@@ -79,6 +_,7 @@ +@@ -82,6 +_,7 @@ private List stored = Lists.newArrayList(); @Nullable public BlockPos savedFlowerPos; @@ -8,7 +8,7 @@ public BeehiveBlockEntity(BlockPos pos, BlockState blockState) { super(BlockEntityType.BEEHIVE, pos, blockState); -@@ -112,7 +_,7 @@ +@@ -115,7 +_,7 @@ } public boolean isFull() { @@ -17,7 +17,7 @@ } public void emptyAllLivingFromHive(@Nullable Player player, BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) { -@@ -121,7 +_,7 @@ +@@ -124,7 +_,7 @@ for (Entity entity : list) { if (entity instanceof Bee bee && player.position().distanceToSqr(entity.position()) <= 16.0) { if (!this.isSedated()) { @@ -26,7 +26,7 @@ } else { bee.setStayOutOfHiveCountdown(400); } -@@ -131,8 +_,14 @@ +@@ -134,8 +_,14 @@ } private List releaseAllOccupants(BlockState state, BeehiveBlockEntity.BeeReleaseStatus releaseStatus) { @@ -42,7 +42,7 @@ if (!list.isEmpty()) { super.setChanged(); } -@@ -145,6 +_,11 @@ +@@ -148,6 +_,11 @@ return this.stored.size(); } @@ -54,7 +54,7 @@ public static int getHoneyLevel(BlockState state) { return state.getValue(BeehiveBlock.HONEY_LEVEL); } -@@ -155,7 +_,16 @@ +@@ -158,7 +_,16 @@ } public void addOccupant(Bee bee) { @@ -72,7 +72,7 @@ bee.stopRiding(); bee.ejectPassengers(); bee.dropLeash(); -@@ -180,7 +_,7 @@ +@@ -183,7 +_,7 @@ this.level.gameEvent(GameEvent.BLOCK_CHANGE, blockPos, GameEvent.Context.of(bee, this.getBlockState())); } @@ -81,7 +81,7 @@ super.setChanged(); } } -@@ -198,7 +_,21 @@ +@@ -201,7 +_,21 @@ BeehiveBlockEntity.BeeReleaseStatus releaseStatus, @Nullable BlockPos storedFlowerPos ) { @@ -104,7 +104,7 @@ return false; } else { Direction direction = state.getValue(BeehiveBlock.FACING); -@@ -209,6 +_,17 @@ +@@ -212,6 +_,17 @@ } else { Entity entity = occupant.createEntity(level, pos); if (entity != null) { @@ -122,7 +122,7 @@ if (entity instanceof Bee bee) { if (storedFlowerPos != null && !bee.hasSavedFlowerPos() && level.random.nextFloat() < 0.9F) { bee.setSavedFlowerPos(storedFlowerPos); -@@ -224,7 +_,13 @@ +@@ -227,7 +_,13 @@ i--; } @@ -137,7 +137,7 @@ } } } -@@ -233,17 +_,19 @@ +@@ -236,17 +_,19 @@ storedInHives.add(bee); } @@ -158,7 +158,7 @@ } else { return false; } -@@ -269,6 +_,11 @@ +@@ -272,6 +_,11 @@ flag = true; iterator.remove(); } @@ -170,23 +170,23 @@ } } -@@ -292,9 +_,10 @@ +@@ -295,9 +_,10 @@ @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.loadAdditional(tag, registries); + protected void loadAdditional(ValueInput input) { + super.loadAdditional(input); - this.stored.clear(); + this.stored = Lists.newArrayList(); // CraftBukkit - SPIGOT-7790: create new copy (may be modified in physics event triggered by honey change) - tag.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee); - this.savedFlowerPos = tag.read("flower_pos", BlockPos.CODEC).orElse(null); -+ this.maxBees = tag.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants + input.read("bees", BeehiveBlockEntity.Occupant.LIST_CODEC).orElse(List.of()).forEach(this::storeBee); + this.savedFlowerPos = input.read("flower_pos", BlockPos.CODEC).orElse(null); ++ this.maxBees = input.getIntOr("Bukkit.MaxEntities", MAX_OCCUPANTS); // Paper - persist max bukkit occupants } @Override -@@ -302,12 +_,13 @@ - super.saveAdditional(tag, registries); - tag.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees()); - tag.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos); -+ tag.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants +@@ -305,12 +_,13 @@ + super.saveAdditional(output); + output.store("bees", BeehiveBlockEntity.Occupant.LIST_CODEC, this.getBees()); + output.storeNullable("flower_pos", BlockPos.CODEC, this.savedFlowerPos); ++ output.putInt("Bukkit.MaxEntities", this.maxBees); // Paper - persist max bukkit occupants } @Override @@ -197,7 +197,7 @@ List list = componentGetter.getOrDefault(DataComponents.BEES, Bees.EMPTY).bees(); list.forEach(this::storeBee); } -@@ -330,15 +_,18 @@ +@@ -333,15 +_,18 @@ static class BeeData { private final BeehiveBlockEntity.Occupant occupant; @@ -217,7 +217,7 @@ } public BeehiveBlockEntity.Occupant toOccupant() { -@@ -409,6 +_,7 @@ +@@ -418,6 +_,7 @@ } private static void setBeeReleaseData(int ticksInHive, Bee bee) { @@ -225,7 +225,7 @@ int age = bee.getAge(); if (age < 0) { bee.setAge(Math.min(0, age + ticksInHive)); -@@ -417,6 +_,7 @@ +@@ -426,6 +_,7 @@ } bee.setInLoveTime(Math.max(0, bee.getInLoveTime() - ticksInHive)); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch index b72693d017..462a2e2c90 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BlockEntity.java +++ b/net/minecraft/world/level/block/entity/BlockEntity.java -@@ -33,6 +_,10 @@ +@@ -35,6 +_,10 @@ import org.slf4j.Logger; public abstract class BlockEntity { @@ -11,7 +11,7 @@ private static final Codec> TYPE_CODEC = BuiltInRegistries.BLOCK_ENTITY_TYPE.byNameCodec(); private static final Logger LOGGER = LogUtils.getLogger(); private final BlockEntityType type; -@@ -48,6 +_,7 @@ +@@ -50,6 +_,7 @@ this.worldPosition = pos.immutable(); this.validateBlockState(blockState); this.blockState = blockState; @@ -19,7 +19,7 @@ } private void validateBlockState(BlockState state) { -@@ -64,6 +_,7 @@ +@@ -66,6 +_,7 @@ int intOr = tag.getIntOr("x", 0); int intOr1 = tag.getIntOr("y", 0); int intOr2 = tag.getIntOr("z", 0); @@ -27,7 +27,7 @@ int sectionPosCoord = SectionPos.blockToSectionCoord(intOr); int sectionPosCoord1 = SectionPos.blockToSectionCoord(intOr2); if (sectionPosCoord != chunkPos.x || sectionPosCoord1 != chunkPos.z) { -@@ -71,6 +_,7 @@ +@@ -73,6 +_,7 @@ intOr = chunkPos.getBlockX(SectionPos.sectionRelative(intOr)); intOr2 = chunkPos.getBlockZ(SectionPos.sectionRelative(intOr2)); } @@ -35,45 +35,44 @@ return new BlockPos(intOr, intOr1, intOr2); } -@@ -89,6 +_,14 @@ +@@ -91,6 +_,12 @@ } - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { + protected void loadAdditional(ValueInput input) { + // Paper start - read persistent data container + this.persistentDataContainer.clear(); // Paper - clear instead of init + -+ net.minecraft.nbt.Tag persistentDataTag = tag.get("PublicBukkitValues"); -+ if (persistentDataTag instanceof CompoundTag) { -+ this.persistentDataContainer.putAll((CompoundTag) persistentDataTag); -+ } ++ input.read("PublicBukkitValues", CompoundTag.CODEC) ++ .ifPresent(this.persistentDataContainer::putAll); + // Paper end - read persistent data container } - public final void loadWithComponents(CompoundTag tag, HolderLookup.Provider registries) { -@@ -120,12 +_,22 @@ - CompoundTag compoundTag = new CompoundTag(); - this.saveAdditional(compoundTag, registries); - compoundTag.store(BlockEntity.ComponentHelper.COMPONENTS_CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.components); + public final void loadWithComponents(ValueInput input) { +@@ -140,6 +_,11 @@ + public void saveWithoutMetadata(ValueOutput output) { + this.saveAdditional(output); + output.store("components", DataComponentMap.CODEC, this.components); + // CraftBukkit start - store container + if (!this.persistentDataContainer.isEmpty()) { -+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound()); ++ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound()); + } + // CraftBukkit end - return compoundTag; } public final CompoundTag saveCustomOnly(HolderLookup.Provider registries) { - CompoundTag compoundTag = new CompoundTag(); - this.saveAdditional(compoundTag, registries); +@@ -155,6 +_,11 @@ + + public void saveCustomOnly(ValueOutput output) { + this.saveAdditional(output); + // Paper start - store PDC here as well + if (!this.persistentDataContainer.isEmpty()) { -+ compoundTag.put("PublicBukkitValues", this.persistentDataContainer.toTagCompound()); ++ output.store("PublicBukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound()); + } + // Paper end - return compoundTag; } -@@ -260,6 +_,12 @@ + public void saveId(ValueOutput output) { +@@ -287,6 +_,12 @@ } public final void applyComponents(DataComponentMap components, DataComponentPatch patch) { @@ -86,7 +85,7 @@ final Set> set = new HashSet<>(); set.add(DataComponents.BLOCK_ENTITY_DATA); set.add(DataComponents.BLOCK_STATE); -@@ -280,6 +_,10 @@ +@@ -307,6 +_,10 @@ }); DataComponentPatch dataComponentPatch = patch.forget(set::contains); this.components = dataComponentPatch.split().added(); @@ -97,9 +96,9 @@ } protected void collectImplicitComponents(DataComponentMap.Builder components) { -@@ -313,6 +_,28 @@ - .resultOrPartial(string -> LOGGER.warn("Failed to parse custom name, discarding: {}", string)) - .orElse(null); +@@ -339,6 +_,27 @@ + public ProblemReporter.PathElement problemPath() { + return new BlockEntity.BlockEntityPathElement(this); } + + // CraftBukkit start - add method @@ -122,7 +121,6 @@ + return tag; + } + // Paper end - Sanitize sent data -+ - static class ComponentHelper { - public static final MapCodec COMPONENTS_CODEC = DataComponentMap.CODEC.optionalFieldOf("components", DataComponentMap.EMPTY); + record BlockEntityPathElement(BlockEntity blockEntity) implements ProblemReporter.PathElement { + @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch index a71b4f55ae..5d7c86f4f3 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/BrushableBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/BrushableBlockEntity.java +++ b/net/minecraft/world/level/block/entity/BrushableBlockEntity.java -@@ -65,9 +_,26 @@ +@@ -67,9 +_,26 @@ return false; } else { this.coolDownEndsAtTick = startTick + 10L; @@ -29,7 +29,7 @@ this.brushingCompleted(level, brusher, stack); return true; } else { -@@ -75,7 +_,7 @@ +@@ -77,7 +_,7 @@ int completionState1 = this.getCompletionState(); if (completionState != completionState1) { BlockState blockState = this.getBlockState(); @@ -38,7 +38,7 @@ level.setBlock(this.getBlockPos(), blockState1, 3); } -@@ -116,6 +_,11 @@ +@@ -118,6 +_,11 @@ this.dropContent(level, brusher, stack); BlockState blockState = this.getBlockState(); level.levelEvent(3008, this.getBlockPos(), Block.getId(blockState)); @@ -50,7 +50,7 @@ Block turnsInto; if (this.getBlockState().getBlock() instanceof BrushableBlock brushableBlock) { turnsInto = brushableBlock.getTurnsInto(); -@@ -123,6 +_,11 @@ +@@ -125,6 +_,11 @@ turnsInto = Blocks.AIR; } @@ -62,7 +62,7 @@ level.setBlock(this.worldPosition, turnsInto.defaultBlockState(), 3); } -@@ -139,7 +_,12 @@ +@@ -141,7 +_,12 @@ double d5 = blockPos.getZ() + 0.5 * d1 + d2; ItemEntity itemEntity = new ItemEntity(level, d3, d4, d5, this.item.split(level.random.nextInt(21) + 10)); itemEntity.setDeltaMovement(Vec3.ZERO); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java.patch index 196b1b49d7..2c30547282 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/CalibratedSculkSensorBlockEntity.java.patch @@ -6,8 +6,8 @@ } + // Paper start - Configurable sculk sensor listener range + @Override -+ protected void saveRangeOverride(final net.minecraft.nbt.CompoundTag nbt) { -+ if (this.rangeOverride != null && this.rangeOverride != 16) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default ++ protected void saveRangeOverride(final net.minecraft.world.level.storage.ValueOutput output) { ++ if (this.rangeOverride != null && this.rangeOverride != 16) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default + } + // Paper end - Configurable sculk sensor listener range diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/CampfireBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/CampfireBlockEntity.java.patch index bf5891b2d9..6bcd4fbe91 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/CampfireBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/CampfireBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/CampfireBlockEntity.java +++ b/net/minecraft/world/level/block/entity/CampfireBlockEntity.java -@@ -38,6 +_,7 @@ +@@ -45,6 +_,7 @@ private final NonNullList items = NonNullList.withSize(4, ItemStack.EMPTY); public final int[] cookingProgress = new int[4]; public final int[] cookingTime = new int[4]; @@ -8,7 +8,7 @@ public CampfireBlockEntity(BlockPos pos, BlockState blockState) { super(BlockEntityType.CAMPFIRE, pos, blockState); -@@ -56,14 +_,44 @@ +@@ -63,14 +_,44 @@ ItemStack itemStack = campfire.items.get(i); if (!itemStack.isEmpty()) { flag = true; @@ -55,38 +55,38 @@ campfire.items.set(i, ItemStack.EMPTY); level.sendBlockUpdated(pos, state, state, 3); level.gameEvent(GameEvent.BLOCK_CHANGE, pos, GameEvent.Context.of(state)); -@@ -135,6 +_,16 @@ +@@ -142,6 +_,16 @@ .ifPresentOrElse( ints -> System.arraycopy(ints, 0, this.cookingTime, 0, Math.min(this.cookingTime.length, ints.length)), () -> Arrays.fill(this.cookingTime, 0) ); + + // Paper start - Add more Campfire API -+ tag.getByteArray("Paper.StopCooking").ifPresent(bytes -> { ++ input.read("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER).ifPresent(bytes -> { + final boolean[] cookingState = new boolean[4]; -+ for (int index = 0; index < bytes.length; index++) { -+ cookingState[index] = bytes[index] == 1; ++ for (int index = 0; bytes.hasRemaining() && index < cookingState.length; index++) { ++ cookingState[index] = bytes.get() == 1; + } -+ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.length)); ++ System.arraycopy(cookingState, 0, this.stopCooking, 0, Math.min(this.stopCooking.length, bytes.capacity())); + }); + // Paper end - Add more Campfire API } @Override -@@ -143,6 +_,13 @@ - ContainerHelper.saveAllItems(tag, this.items, true, registries); - tag.putIntArray("CookingTimes", this.cookingProgress); - tag.putIntArray("CookingTotalTimes", this.cookingTime); +@@ -150,6 +_,13 @@ + ContainerHelper.saveAllItems(output, this.items, true); + output.putIntArray("CookingTimes", this.cookingProgress); + output.putIntArray("CookingTotalTimes", this.cookingTime); + // Paper start - Add more Campfire API + byte[] cookingState = new byte[4]; + for (int index = 0; index < cookingState.length; index++) { + cookingState[index] = (byte) (this.stopCooking[index] ? 1 : 0); + } -+ tag.putByteArray("Paper.StopCooking", cookingState); ++ output.store("Paper.StopCooking", com.mojang.serialization.Codec.BYTE_BUFFER, java.nio.ByteBuffer.wrap(cookingState)); + // Paper end - Add more Campfire API } @Override -@@ -167,7 +_,15 @@ +@@ -179,7 +_,15 @@ return false; } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch index 9dec426184..a609ca82f7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/ConduitBlockEntity.java.patch @@ -21,7 +21,7 @@ int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); -@@ -175,13 +_,19 @@ +@@ -175,20 +_,25 @@ if (!entitiesOfClass.isEmpty()) { for (Player player : entitiesOfClass) { if (pos.closerThan(player.blockPosition(), i) && player.isInWaterOrRain()) { @@ -32,31 +32,21 @@ } } - private static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List positions, ConduitBlockEntity blockEntity) { -+ // CraftBukkit start - add "damageTarget" boolean -+ ConduitBlockEntity.updateDestroyTarget(level, pos, state, positions, blockEntity, true); + private static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy) { ++ // CraftBukkit start - add "damageTarget" boolean ++ updateAndAttackTarget(level, pos, state, blockEntity, canDestroy, true); + } -+ -+ public static void updateDestroyTarget(Level level, BlockPos pos, BlockState state, List positions, ConduitBlockEntity blockEntity, boolean damageTarget) { -+ // CraftBukkit end - LivingEntity livingEntity = blockEntity.destroyTarget; - int size = positions.size(); - if (size < 42) { -@@ -200,7 +_,8 @@ - blockEntity.destroyTarget = null; - } - -- if (blockEntity.destroyTarget != null) { -+ if (damageTarget && blockEntity.destroyTarget != null) { // CraftBukkit -+ if (blockEntity.destroyTarget.hurtServer((net.minecraft.server.level.ServerLevel) level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit ++ public static void updateAndAttackTarget(ServerLevel level, BlockPos pos, BlockState state, ConduitBlockEntity blockEntity, boolean canDestroy, boolean damageTarget) { ++ // CraftBukkit end - add "damageTarget" boolean + EntityReference entityReference = updateDestroyTarget(blockEntity.destroyTarget, level, pos, canDestroy); + LivingEntity livingEntity = EntityReference.get(entityReference, level, LivingEntity.class); +- if (livingEntity != null) { ++ if (damageTarget && livingEntity != null) { // CraftBukkit ++ if (livingEntity.hurtServer(level, level.damageSources().magic().eventBlockDamager(level, pos), 4.0F)) // CraftBukkit - move up level.playSound( - null, - blockEntity.destroyTarget.getX(), -@@ -211,7 +_,6 @@ - 1.0F, - 1.0F + null, livingEntity.getX(), livingEntity.getY(), livingEntity.getZ(), SoundEvents.CONDUIT_ATTACK_TARGET, SoundSource.BLOCKS, 1.0F, 1.0F ); -- blockEntity.destroyTarget.hurt(level.damageSources().magic(), 4.0F); +- livingEntity.hurtServer(level, level.damageSources().magic(), 4.0F); } - if (livingEntity != blockEntity.destroyTarget) { + if (!Objects.equals(entityReference, blockEntity.destroyTarget)) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch index 5d078a0854..0540b499b8 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java +++ b/net/minecraft/world/level/block/entity/DecoratedPotBlockEntity.java -@@ -24,6 +_,48 @@ +@@ -23,6 +_,48 @@ import net.minecraft.world.ticks.ContainerSingleItem; public class DecoratedPotBlockEntity extends BlockEntity implements RandomizableContainer, ContainerSingleItem.BlockContainerSingleItem { @@ -49,18 +49,18 @@ public static final String TAG_SHERDS = "sherds"; public static final String TAG_ITEM = "item"; public static final int EVENT_POT_WOBBLES = 1; -@@ -48,8 +_,8 @@ - tag.store("sherds", PotDecorations.CODEC, this.decorations); +@@ -47,8 +_,8 @@ + output.store("sherds", PotDecorations.CODEC, this.decorations); } -- if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { -- tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item); -+ if (!this.trySaveLootTable(tag) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data -+ tag.store("item", ItemStack.CODEC, registries.createSerializationContext(NbtOps.INSTANCE), this.item); // Paper - diff on change - hide unnecessary update data +- if (!this.trySaveLootTable(output) && !this.item.isEmpty()) { +- output.store("item", ItemStack.CODEC, this.item); ++ if (!this.trySaveLootTable(output) && !this.item.isEmpty()) { // Paper - diff on change - hide unnecessary update data ++ output.store("item", ItemStack.CODEC, this.item); // Paper - diff on change - hide unnecessary update data } } -@@ -72,7 +_,14 @@ +@@ -70,7 +_,14 @@ @Override public CompoundTag getUpdateTag(HolderLookup.Provider registries) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JigsawBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JigsawBlockEntity.java.patch index b594c6775e..489b7dec14 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JigsawBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JigsawBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/JigsawBlockEntity.java +++ b/net/minecraft/world/level/block/entity/JigsawBlockEntity.java -@@ -138,7 +_,12 @@ +@@ -140,7 +_,12 @@ public void generate(ServerLevel level, int maxDepth, boolean keepJigsaws) { BlockPos blockPos = this.getBlockPos().relative(this.getBlockState().getValue(JigsawBlock.ORIENTATION).front()); Registry registry = level.registryAccess().lookupOrThrow(Registries.TEMPLATE_POOL); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch index 4c24cff260..8a3e9a2f02 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java +++ b/net/minecraft/world/level/block/entity/JukeboxBlockEntity.java -@@ -23,6 +_,44 @@ +@@ -20,6 +_,44 @@ import net.minecraft.world.ticks.ContainerSingleItem; public class JukeboxBlockEntity extends BlockEntity implements ContainerSingleItem.BlockContainerSingleItem { @@ -45,7 +45,7 @@ public static final String SONG_ITEM_TAG_ID = "RecordItem"; public static final String TICKS_SINCE_SONG_STARTED_TAG_ID = "ticks_since_song_started"; private ItemStack item = ItemStack.EMPTY; -@@ -128,7 +_,7 @@ +@@ -123,7 +_,7 @@ @Override public int getMaxStackSize() { @@ -54,7 +54,7 @@ } @Override -@@ -152,11 +_,16 @@ +@@ -147,11 +_,16 @@ } @VisibleForTesting diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/LecternBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/LecternBlockEntity.java.patch index a630a1986d..aaa6977fcd 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/LecternBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/LecternBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/LecternBlockEntity.java +++ b/net/minecraft/world/level/block/entity/LecternBlockEntity.java -@@ -36,7 +_,53 @@ +@@ -33,7 +_,53 @@ public static final int NUM_DATA = 1; public static final int SLOT_BOOK = 0; public static final int NUM_SLOTS = 1; @@ -55,7 +55,7 @@ @Override public int getContainerSize() { return 1; -@@ -80,11 +_,19 @@ +@@ -77,11 +_,19 @@ @Override public void setItem(int slot, ItemStack stack) { @@ -76,7 +76,7 @@ } @Override -@@ -162,7 +_,7 @@ +@@ -159,7 +_,7 @@ if (i != this.page) { this.page = i; this.setChanged(); @@ -85,7 +85,7 @@ } } -@@ -183,6 +_,36 @@ +@@ -180,6 +_,36 @@ return stack; } @@ -122,7 +122,7 @@ private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level) { String string; Component component; -@@ -195,7 +_,7 @@ +@@ -192,7 +_,7 @@ } Vec3 vec3 = Vec3.atCenterOf(this.worldPosition); @@ -131,7 +131,7 @@ } @Override -@@ -237,7 +_,7 @@ +@@ -232,7 +_,7 @@ @Override public AbstractContainerMenu createMenu(int containerId, Inventory playerInventory, Player player) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java.patch index e5ce59bb81..83a42ad68e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java.patch @@ -1,8 +1,8 @@ --- a/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/RandomizableContainerBlockEntity.java @@ -116,4 +_,13 @@ - tag.remove("LootTable"); - tag.remove("LootTableSeed"); + output.discard("LootTable"); + output.discard("LootTableSeed"); } + + // Paper start - LootTable API diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java.patch index f6e656549b..aa3908f8b0 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java -@@ -24,6 +_,7 @@ +@@ -21,6 +_,7 @@ private final VibrationSystem.Listener vibrationListener; private final VibrationSystem.User vibrationUser; public int lastVibrationFrequency = 0; @@ -8,32 +8,31 @@ protected SculkSensorBlockEntity(BlockEntityType type, BlockPos pos, BlockState blockState) { super(type, pos, blockState); -@@ -46,15 +_,23 @@ - this.lastVibrationFrequency = tag.getIntOr("last_vibration_frequency", 0); - RegistryOps registryOps = registries.createSerializationContext(NbtOps.INSTANCE); - this.vibrationData = tag.read("listener", VibrationSystem.Data.CODEC, registryOps).orElseGet(VibrationSystem.Data::new); -+ this.rangeOverride = tag.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range +@@ -42,14 +_,22 @@ + super.loadAdditional(input); + this.lastVibrationFrequency = input.getIntOr("last_vibration_frequency", 0); + this.vibrationData = input.read("listener", VibrationSystem.Data.CODEC).orElseGet(VibrationSystem.Data::new); ++ this.rangeOverride = input.getInt(PAPER_LISTENER_RANGE_NBT_KEY).orElse(null); // Paper start - Configurable sculk sensor listener range } + protected static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper - Configurable sculk sensor listener range @Override - protected void saveAdditional(CompoundTag tag, HolderLookup.Provider registries) { - super.saveAdditional(tag, registries); - tag.putInt("last_vibration_frequency", this.lastVibrationFrequency); - RegistryOps registryOps = registries.createSerializationContext(NbtOps.INSTANCE); - tag.store("listener", VibrationSystem.Data.CODEC, registryOps, this.vibrationData); + protected void saveAdditional(ValueOutput output) { + super.saveAdditional(output); + output.putInt("last_vibration_frequency", this.lastVibrationFrequency); + output.store("listener", VibrationSystem.Data.CODEC, this.vibrationData); - } -+ this.saveRangeOverride(tag); // Paper - Configurable sculk sensor listener range ++ this.saveRangeOverride(output); // Paper - Configurable sculk sensor listener range + } + // Paper start - Configurable sculk sensor listener range -+ protected void saveRangeOverride(CompoundTag tag) { -+ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) tag.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default ++ protected void saveRangeOverride(ValueOutput output) { ++ if (this.rangeOverride != null && this.rangeOverride != VibrationUser.LISTENER_RANGE) output.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.rangeOverride); // only save if it's different from the default + } + // Paper end - Configurable sculk sensor listener range @Override public VibrationSystem.Data getVibrationData() { -@@ -91,6 +_,7 @@ +@@ -86,6 +_,7 @@ @Override public int getListenerRadius() { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch index ad2ef7f8dc..c7d6e63f73 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SculkShriekerBlockEntity.java -@@ -91,6 +_,13 @@ +@@ -86,6 +_,13 @@ @Nullable public static ServerPlayer tryGetPlayer(@Nullable Entity entity) { @@ -14,7 +14,7 @@ if (entity instanceof ServerPlayer serverPlayer) { return serverPlayer; } else if (entity != null && entity.getControllingPassenger() instanceof ServerPlayer serverPlayer) { -@@ -166,7 +_,7 @@ +@@ -161,7 +_,7 @@ private boolean trySummonWarden(ServerLevel level) { return this.warningLevel >= 4 && SpawnUtil.trySpawnMob( diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch index b03a8a8c64..cba6af85d7 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SignBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SignBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SignBlockEntity.java -@@ -58,10 +_,15 @@ +@@ -57,10 +_,15 @@ } public boolean isFacingFrontText(Player player) { @@ -18,7 +18,7 @@ float yRotationDegrees = signBlock.getYRotationDegrees(this.getBlockState()); float f = (float)(Mth.atan2(d1, d) * 180.0F / (float)Math.PI) - 90.0F; return Mth.degreesDifferenceAbs(yRotationDegrees, f) <= 90.0F; -@@ -131,11 +_,13 @@ +@@ -128,11 +_,13 @@ public void updateSignText(Player player, boolean isFrontText, List filteredText) { if (!this.isWaxed() && player.getUUID().equals(this.getPlayerWhoMayEdit()) && this.level != null) { @@ -33,7 +33,7 @@ } } -@@ -144,18 +_,40 @@ +@@ -141,19 +_,41 @@ return this.setText(updater.apply(text), isFrontText); } @@ -53,7 +53,7 @@ ); } } -+ + + // CraftBukkit start + org.bukkit.entity.Player apiPlayer = ((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(); + List lines = new java.util.ArrayList<>(); // Paper - adventure @@ -74,41 +74,40 @@ + } + } + // CraftBukkit end - ++ return text; } -@@ -193,8 +_,24 @@ - for (Component component : this.getText(frontText).getMessages(player.isTextFilteringEnabled())) { +@@ -192,7 +_,23 @@ Style style = component.getStyle(); -- if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) { -- player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), var14); -+ if (style.getClickEvent() instanceof ClickEvent.RunCommand(String var14)) { final String runCommand = var14; // Paper - OBFHELPER -+ // Paper start - Fix commands from signs not firing command events -+ String command = runCommand.startsWith("/") ? runCommand : "/" + runCommand; -+ if (org.spigotmc.SpigotConfig.logCommands) { -+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command); -+ } -+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent( -+ (org.bukkit.entity.Player) player.getBukkitEntity(), -+ command, -+ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), -+ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(), -+ frontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK -+ ); -+ if (!event.callEvent()) { -+ return false; -+ } -+ player.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage()); -+ // Paper end - Fix commands from signs not firing command events - flag = true; - } - } -@@ -202,10 +_,55 @@ + switch (style.getClickEvent()) { + case ClickEvent.RunCommand runCommand: +- level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(player, level, pos), runCommand.command()); ++ // Paper start - Fix commands from signs not firing command events ++ String command = runCommand.command().startsWith("/") ? runCommand.command() : "/" + runCommand.command(); ++ if (org.spigotmc.SpigotConfig.logCommands) { ++ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command); ++ } ++ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent( ++ (org.bukkit.entity.Player) player.getBukkitEntity(), ++ command, ++ new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), ++ (org.bukkit.block.Sign) org.bukkit.craftbukkit.block.CraftBlock.at(this.level, this.worldPosition).getState(), ++ isFrontText ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK ++ ); ++ if (!event.callEvent()) { ++ return false; ++ } ++ level.getServer().getCommands().performPrefixedCommand(createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle(), level, pos), event.getMessage()); ++ // Paper end - Fix commands from signs not firing command events + flag = true; + break; + case ClickEvent.ShowDialog showDialog: +@@ -211,10 +_,55 @@ return flag; } -- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) { +- private static CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) { + // CraftBukkit start + private final CommandSource commandSource = new CommandSource() { + @@ -136,11 +135,11 @@ + } + }; + -+ private CommandSourceStack createCommandSourceStack(@Nullable Player player, Level level, BlockPos pos) { ++ private CommandSourceStack createCommandSourceStack(@Nullable Player player, ServerLevel level, BlockPos pos) { + // CraftBukkit end String string = player == null ? "Sign" : player.getName().getString(); Component component = (Component)(player == null ? Component.literal("Sign") : player.getDisplayName()); -- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); +- return new CommandSourceStack(CommandSource.NULL, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player); + + // Paper start - Fix commands from signs not firing command events + CommandSource commandSource = level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this.commandSource) { @@ -158,11 +157,11 @@ + } : this.commandSource; + // Paper end - Fix commands from signs not firing command events + // CraftBukkit - this -+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, (ServerLevel)level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events ++ return new CommandSourceStack(commandSource, Vec3.atCenterOf(pos), Vec2.ZERO, level, 2, string, component, level.getServer(), player); // Paper - Fix commands from signs not firing command events } @Override -@@ -224,12 +_,17 @@ +@@ -233,12 +_,17 @@ @Nullable public UUID getPlayerWhoMayEdit() { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch index 9e047d5b50..fd75d22b16 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/SkullBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/SkullBlockEntity.java +++ b/net/minecraft/world/level/block/entity/SkullBlockEntity.java -@@ -40,7 +_,7 @@ +@@ -41,7 +_,7 @@ @Nullable private static LoadingCache>> profileCacheByName; @Nullable @@ -9,7 +9,7 @@ public static final Executor CHECKED_MAIN_THREAD_EXECUTOR = runnable -> { Executor executor = mainThreadExecutor; if (executor != null) { -@@ -75,9 +_,9 @@ +@@ -76,9 +_,9 @@ profileCacheById = CacheBuilder.newBuilder() .expireAfterAccess(Duration.ofMinutes(10L)) .maximumSize(256L) @@ -21,7 +21,7 @@ return SkullBlockEntity.fetchProfileById(id, services, booleanSupplier); } }); -@@ -88,23 +_,29 @@ +@@ -89,23 +_,29 @@ .getAsync(name) .thenCompose( optional -> { @@ -56,7 +56,7 @@ } public static void clear() { -@@ -188,9 +_,11 @@ +@@ -189,9 +_,11 @@ : CompletableFuture.completedFuture(Optional.empty()); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestBlockEntity.java.patch index 82324d9d12..b515c4ea49 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestBlockEntity.java.patch @@ -1,10 +1,10 @@ --- a/net/minecraft/world/level/block/entity/TestBlockEntity.java +++ b/net/minecraft/world/level/block/entity/TestBlockEntity.java -@@ -36,6 +_,7 @@ +@@ -38,6 +_,7 @@ @Override - public void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { -+ super.loadAdditional(tag, registries); // Paper - load the PDC - this.mode = tag.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL); - this.message = tag.getStringOr("message", ""); - this.powered = tag.getBooleanOr("powered", false); + protected void loadAdditional(ValueInput input) { ++ super.loadAdditional(input); // Paper - load the PDC + this.mode = input.read("mode", TestBlockMode.CODEC).orElse(TestBlockMode.FAIL); + this.message = input.getStringOr("message", ""); + this.powered = input.getBooleanOr("powered", false); diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java.patch index ee7a1ecc79..258e1a8af2 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java.patch @@ -1,14 +1,14 @@ --- a/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java +++ b/net/minecraft/world/level/block/entity/TestInstanceBlockEntity.java -@@ -157,6 +_,7 @@ +@@ -154,6 +_,7 @@ @Override - protected void loadAdditional(CompoundTag tag, HolderLookup.Provider registries) { -+ super.loadAdditional(tag, registries); // Paper - load the PDC - Tag tag1 = tag.get("data"); - if (tag1 != null) { - TestInstanceBlockEntity.Data.CODEC.parse(NbtOps.INSTANCE, tag1).ifSuccess(this::set); -@@ -320,7 +_,7 @@ + protected void loadAdditional(ValueInput input) { ++ super.loadAdditional(input); // Paper - load the PDC + input.read("data", TestInstanceBlockEntity.Data.CODEC).ifPresent(this::set); + } + +@@ -317,7 +_,7 @@ } private void removeEntities() { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch index 7c9a9bdfb5..09f5bd3726 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java +++ b/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java -@@ -129,7 +_,7 @@ +@@ -131,7 +_,7 @@ @Nullable public Vec3 getPortalPosition(ServerLevel level, BlockPos pos) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch index 1a32ca9000..ea3f2309d0 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java.patch @@ -1,22 +1,22 @@ --- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java +++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawner.java -@@ -238,7 +_,14 @@ - nextSpawnData.getEquipment().ifPresent(mob::equip); - } +@@ -214,7 +_,14 @@ + nextSpawnData.getEquipment().ifPresent(mob::equip); + } -- if (!level.tryAddFreshEntityWithPassengers(entity)) { -+ // Paper start - TrialSpawnerSpawnEvent + SpawnReason -+ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner -+ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason -+ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) { -+ return Optional.empty(); -+ } -+ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) { -+ // Paper end - TrialSpawnerSpawnEvent + SpawnReason - return Optional.empty(); - } else { - TrialSpawner.FlameParticle flameParticle = this.isOminous ? TrialSpawner.FlameParticle.OMINOUS : TrialSpawner.FlameParticle.NORMAL; -@@ -258,6 +_,19 @@ +- if (!level.tryAddFreshEntityWithPassengers(entity)) { ++ // Paper start - TrialSpawnerSpawnEvent + SpawnReason ++ entity.spawnedViaMobSpawner = true; // Mark entity as spawned via spawner ++ entity.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER; // Paper - Entity#getEntitySpawnReason ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callTrialSpawnerSpawnEvent(entity, pos).isCancelled()) { ++ return Optional.empty(); ++ } ++ if (!level.tryAddFreshEntityWithPassengers(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.TRIAL_SPAWNER)) { ++ // Paper end - TrialSpawnerSpawnEvent + SpawnReason + return Optional.empty(); + } + +@@ -233,6 +_,19 @@ LootParams lootParams = new LootParams.Builder(level).create(LootContextParamSets.EMPTY); ObjectArrayList randomItems = lootTable1.getRandomItems(lootParams); if (!randomItems.isEmpty()) { @@ -36,3 +36,39 @@ for (ItemStack itemStack : randomItems) { DefaultDispenseItemBehavior.spawnItem(level, itemStack, 2, Direction.UP, Vec3.atBottomCenterOf(pos).relative(Direction.UP, 1.2)); } +@@ -402,6 +_,35 @@ + this.requiredPlayerRange + ); + } ++ ++ // Paper start - trial spawner API - withers ++ public TrialSpawner.FullConfig overrideTargetCooldownLength(final int targetCooldownLength) { ++ return new TrialSpawner.FullConfig( ++ this.normal, ++ this.ominous, ++ targetCooldownLength, ++ this.requiredPlayerRange ++ ); ++ } ++ ++ public TrialSpawner.FullConfig overrideRequiredPlayerRange(final int requiredPlayerRange) { ++ return new TrialSpawner.FullConfig( ++ this.normal, ++ this.ominous, ++ this.targetCooldownLength, ++ requiredPlayerRange ++ ); ++ } ++ ++ public TrialSpawner.FullConfig overrideConfigs(final Holder normal, final Holder ominous) { ++ return new TrialSpawner.FullConfig( ++ normal, ++ ominous, ++ this.targetCooldownLength, ++ this.requiredPlayerRange ++ ); ++ } ++ // Paper end - trial spawner API - withers + } + + public interface StateAccessor { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java.patch similarity index 76% rename from paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch rename to paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java.patch index b8359650d1..e9c7b1566a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java.patch @@ -1,6 +1,6 @@ ---- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -+++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerData.java -@@ -197,7 +_,7 @@ +--- a/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java ++++ b/net/minecraft/world/level/block/entity/trialspawner/TrialSpawnerStateData.java +@@ -185,7 +_,7 @@ mob.dropPreservedEquipment(level); } @@ -8,4 +8,4 @@ + entity.remove(Entity.RemovalReason.DISCARDED, org.bukkit.event.entity.EntityRemoveEvent.Cause.DESPAWN); // CraftBukkit - Add bukkit remove cause; } }); - if (!spawner.getOminousConfig().spawnPotentialsDefinition().isEmpty()) { + if (!spawner.ominousConfig().spawnPotentialsDefinition().isEmpty()) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java.patch index 024d2b4bdc..15447e6128 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java +++ b/net/minecraft/world/level/block/entity/vault/VaultBlockEntity.java -@@ -260,7 +_,12 @@ +@@ -257,7 +_,12 @@ if (!list.isEmpty()) { player.awardStat(Stats.ITEM_USED.get(stack.getItem())); stack.consume(config.keyItem().getCount(), player); @@ -14,7 +14,7 @@ serverData.addToRewardedPlayers(player); sharedData.updateConnectedPlayersWithinRange(level, pos, serverData, config, config.deactivationRange()); } -@@ -269,8 +_,30 @@ +@@ -266,8 +_,30 @@ } static void setVaultState(ServerLevel level, BlockPos pos, BlockState oldState, BlockState newState, VaultConfig config, VaultSharedData sharedData) { @@ -47,7 +47,7 @@ level.setBlock(pos, newState, 3); vaultState.onTransition(level, pos, vaultState1, config, sharedData, newState.getValue(VaultBlock.OMINOUS)); } -@@ -282,6 +_,11 @@ +@@ -279,6 +_,11 @@ ItemStack randomDisplayItemFromLootTable = getRandomDisplayItemFromLootTable( level, pos, config.overrideLootTableToDisplay().orElse(config.lootTable()) ); @@ -59,7 +59,7 @@ sharedData.setDisplayItem(randomDisplayItemFromLootTable); } } -@@ -304,10 +_,24 @@ +@@ -301,10 +_,24 @@ VaultSharedData sharedData, List itemsToEject ) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch index 7eeba3cf94..c83366549b 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java +++ b/net/minecraft/world/level/block/piston/PistonMovingBlockEntity.java -@@ -39,7 +_,7 @@ +@@ -38,7 +_,7 @@ private static final boolean DEFAULT_EXTENDING = false; private static final boolean DEFAULT_SOURCE = false; private BlockState movedState = DEFAULT_BLOCK_STATE; @@ -9,7 +9,7 @@ private boolean extending = false; private boolean isSourcePiston = false; private static final ThreadLocal NOCLIP = ThreadLocal.withInitial(() -> null); -@@ -310,7 +_,7 @@ +@@ -309,7 +_,7 @@ if (level.getBlockState(pos).is(Blocks.MOVING_PISTON)) { BlockState blockState = Block.updateFromNeighbourShapes(blockEntity.movedState, level, pos); if (blockState.isAir()) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch index 9b18db1f71..54c605cdde 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ChunkAccess.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ChunkAccess.java +++ b/net/minecraft/world/level/chunk/ChunkAccess.java -@@ -64,7 +_,7 @@ +@@ -65,7 +_,7 @@ protected final ShortList[] postProcessing; private volatile boolean unsaved; private volatile boolean isLightCorrect; @@ -9,7 +9,7 @@ private long inhabitedTime; @Nullable @Deprecated -@@ -82,6 +_,11 @@ +@@ -83,6 +_,11 @@ public final Map blockEntities = new Object2ObjectOpenHashMap<>(); protected final LevelHeightAccessor levelHeightAccessor; protected final LevelChunkSection[] sections; @@ -21,7 +21,7 @@ public ChunkAccess( ChunkPos chunkPos, -@@ -92,7 +_,8 @@ +@@ -93,7 +_,8 @@ @Nullable LevelChunkSection[] sections, @Nullable BlendingData blendingData ) { @@ -31,7 +31,7 @@ this.upgradeData = upgradeData; this.levelHeightAccessor = levelHeightAccessor; this.sections = new LevelChunkSection[levelHeightAccessor.getSectionsCount()]; -@@ -109,6 +_,7 @@ +@@ -110,6 +_,7 @@ } replaceMissingSections(biomeRegistry, this.sections); @@ -39,7 +39,7 @@ } private static void replaceMissingSections(Registry biomeRegistry, LevelChunkSection[] sections) { -@@ -123,6 +_,8 @@ +@@ -124,6 +_,8 @@ return GameEventListenerRegistry.NOOP; } @@ -48,7 +48,7 @@ @Nullable public BlockState setBlockState(BlockPos pos, BlockState state) { return this.setBlockState(pos, state, 3); -@@ -278,6 +_,7 @@ +@@ -275,6 +_,7 @@ public boolean tryMarkSaved() { if (this.unsaved) { this.unsaved = false; @@ -56,7 +56,7 @@ return true; } else { return false; -@@ -285,7 +_,7 @@ +@@ -282,7 +_,7 @@ } public boolean isUnsaved() { @@ -65,7 +65,7 @@ } public abstract ChunkStatus getPersistedStatus(); -@@ -451,6 +_,22 @@ +@@ -448,6 +_,22 @@ throw new ReportedException(crashReport); } } diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch index f6a2d24db0..bc6ff86f1c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/LevelChunk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/LevelChunk.java +++ b/net/minecraft/world/level/chunk/LevelChunk.java -@@ -77,7 +_,7 @@ +@@ -79,7 +_,7 @@ }; private final Map tickersInLevel = Maps.newHashMap(); public boolean loaded; @@ -9,7 +9,7 @@ @Nullable private Supplier fullStatus; @Nullable -@@ -86,6 +_,14 @@ +@@ -88,6 +_,14 @@ private final LevelChunkTicks blockTicks; private final LevelChunkTicks fluidTicks; private LevelChunk.UnsavedListener unsavedListener = chunkPos -> {}; @@ -24,7 +24,7 @@ public LevelChunk(Level level, ChunkPos pos) { this(level, pos, UpgradeData.EMPTY, new LevelChunkTicks<>(), new LevelChunkTicks<>(), 0L, null, null, null); -@@ -103,7 +_,7 @@ +@@ -105,7 +_,7 @@ @Nullable BlendingData blendingData ) { super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); @@ -33,7 +33,7 @@ this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>(); for (Heightmap.Types types : Heightmap.Types.values()) { -@@ -155,6 +_,10 @@ +@@ -157,6 +_,10 @@ this.skyLightSources = chunk.skyLightSources; this.setLightCorrect(chunk.isLightCorrect()); this.markUnsaved(); @@ -44,7 +44,7 @@ } public void setUnsavedListener(LevelChunk.UnsavedListener unsavedListener) { -@@ -163,6 +_,12 @@ +@@ -165,6 +_,12 @@ unsavedListener.setUnsaved(this.chunkPos); } } @@ -57,7 +57,7 @@ @Override public void markUnsaved() { -@@ -196,8 +_,28 @@ +@@ -198,8 +_,28 @@ : super.getListenerRegistry(sectionY); } @@ -86,7 +86,7 @@ int x = pos.getX(); int y = pos.getY(); int z = pos.getZ(); -@@ -232,28 +_,42 @@ +@@ -234,28 +_,42 @@ } } @@ -131,7 +131,7 @@ } @Nullable -@@ -313,7 +_,7 @@ +@@ -315,7 +_,7 @@ if (!section.getBlockState(i, i1, i2).is(block)) { return null; } else { @@ -140,7 +140,7 @@ state.onPlace(this.level, pos, blockState, flag1); } -@@ -367,7 +_,12 @@ +@@ -369,7 +_,12 @@ @Nullable public BlockEntity getBlockEntity(BlockPos pos, LevelChunk.EntityCreationType creationType) { @@ -154,7 +154,7 @@ if (blockEntity == null) { CompoundTag compoundTag = this.pendingBlockEntities.remove(pos); if (compoundTag != null) { -@@ -421,7 +_,13 @@ +@@ -424,7 +_,13 @@ BlockPos blockPos = blockEntity.getBlockPos(); BlockState blockState = this.getBlockState(blockPos); if (!blockState.hasBlockEntity()) { @@ -169,7 +169,7 @@ } else { BlockState blockState1 = blockEntity.getBlockState(); if (blockState != blockState1) { -@@ -469,6 +_,11 @@ +@@ -472,6 +_,11 @@ public void removeBlockEntity(BlockPos pos) { if (this.isInLevel()) { BlockEntity blockEntity = this.blockEntities.remove(pos); @@ -181,7 +181,7 @@ if (blockEntity != null) { if (this.level instanceof ServerLevel serverLevel) { this.removeGameEventListener(blockEntity, serverLevel); -@@ -511,6 +_,65 @@ +@@ -514,6 +_,65 @@ } } @@ -247,7 +247,7 @@ public boolean isEmpty() { return false; } -@@ -719,23 +_,24 @@ +@@ -726,23 +_,24 @@ if (this.blockEntity.getType().isValid(blockState)) { this.ticker.tick(LevelChunk.this.level, this.blockEntity.getBlockPos(), blockState, this.blockEntity); this.loggedInvalidBlockState = false; diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/PalettedContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/PalettedContainer.java.patch index 360faa2856..dc581e6c3a 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/PalettedContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/PalettedContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/PalettedContainer.java +++ b/net/minecraft/world/level/chunk/PalettedContainer.java -@@ -30,14 +_,14 @@ +@@ -29,14 +_,14 @@ public final IdMap registry; private volatile PalettedContainer.Data data; private final PalettedContainer.Strategy strategy; @@ -18,7 +18,7 @@ } public static Codec> codecRW(IdMap registry, Codec codec, PalettedContainer.Strategy strategy, T value) { -@@ -99,7 +_,7 @@ +@@ -98,7 +_,7 @@ } @Override @@ -27,7 +27,7 @@ PalettedContainer.Data data = this.data; PalettedContainer.Data data1 = this.createOrReuseData(data, bits); data1.copyFrom(data.palette, data.storage); -@@ -107,7 +_,7 @@ +@@ -106,7 +_,7 @@ return data1.palette.idFor(objectAdded); } @@ -36,7 +36,7 @@ this.acquire(); Object var5; -@@ -130,7 +_,7 @@ +@@ -129,7 +_,7 @@ return this.data.palette.valueFor(andSet); } @@ -45,7 +45,7 @@ this.acquire(); try { -@@ -163,7 +_,7 @@ +@@ -162,7 +_,7 @@ set.forEach(id -> consumer.accept(palette.valueFor(id))); } @@ -54,7 +54,7 @@ this.acquire(); try { -@@ -178,7 +_,7 @@ +@@ -177,7 +_,7 @@ } @Override @@ -63,7 +63,7 @@ this.acquire(); try { -@@ -226,7 +_,7 @@ +@@ -225,7 +_,7 @@ } @Override diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch index e3d51ebf1f..d05906e13e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/ProtoChunk.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/ProtoChunk.java +++ b/net/minecraft/world/level/chunk/ProtoChunk.java -@@ -85,14 +_,33 @@ +@@ -90,14 +_,33 @@ return new ChunkAccess.PackedTicks(this.blockTicks.pack(gametime), this.fluidTicks.pack(gametime)); } diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch index 4f624eb72b..d963210594 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java +++ b/net/minecraft/world/level/chunk/status/ChunkStatusTasks.java -@@ -35,7 +_,7 @@ +@@ -40,7 +_,7 @@ WorldGenContext worldGenContext, ChunkStep step, StaticCache2D cache, ChunkAccess chunk ) { ServerLevel serverLevel = worldGenContext.level(); @@ -9,15 +9,15 @@ worldGenContext.generator() .createStructures( serverLevel.registryAccess(), -@@ -198,7 +_,58 @@ +@@ -207,7 +_,58 @@ - public static void postLoadProtoChunk(ServerLevel level, List entityTags) { - if (!entityTags.isEmpty()) { -- level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD)); + public static void postLoadProtoChunk(ServerLevel level, ValueInput.ValueInputList input) { + if (!input.isEmpty()) { +- level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD)); - } - } + // CraftBukkit start - these are spawned serialized (DefinedStructure) and we don't call an add event below at the moment due to ordering complexities -+ level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(entityTags, level, EntitySpawnReason.LOAD).filter((entity) -> { ++ level.addWorldGenChunkEntities(EntityType.loadEntitiesRecursive(input, level, EntitySpawnReason.LOAD).filter((entity) -> { + boolean needsRemoval = false; + net.minecraft.server.dedicated.DedicatedServer server = level.getCraftServer().getServer(); + if (!level.getChunkSource().spawnFriendlies && (entity instanceof net.minecraft.world.entity.animal.Animal || entity instanceof net.minecraft.world.entity.animal.WaterAnimal)) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch index 239c1f8ff6..38bdc3df49 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/ChunkStorage.java.patch @@ -17,7 +17,7 @@ + // CraftBukkit end ) { int version = getVersion(chunkData); - if (version == SharedConstants.getCurrentVersion().getDataVersion().getVersion()) { + if (version == SharedConstants.getCurrentVersion().dataVersion().version()) { return chunkData; } else { try { diff --git a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch index be691f9e81..51d6def59c 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/chunk/storage/SerializableChunkData.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java +++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java -@@ -91,6 +_,7 @@ +@@ -93,6 +_,7 @@ List entities, List blockEntities, CompoundTag structureData @@ -8,7 +8,7 @@ ) { public static final Codec> BLOCK_STATE_CODEC = PalettedContainer.codecRW( Block.BLOCK_STATE_REGISTRY, BlockState.CODEC, PalettedContainer.Strategy.SECTION_STATES, Blocks.AIR.defaultBlockState() -@@ -109,12 +_,38 @@ +@@ -111,12 +_,38 @@ public static final String BLOCK_LIGHT_TAG = "BlockLight"; public static final String SKY_LIGHT_TAG = "SkyLight"; @@ -26,7 +26,7 @@ + // Paper end - guard against serializing mismatching coordinates + + // Paper start - Do not let the server load chunks from newer versions -+ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().getDataVersion().getVersion(); ++ private static final int CURRENT_DATA_VERSION = net.minecraft.SharedConstants.getCurrentVersion().dataVersion().version(); + private static final boolean JUST_CORRUPT_IT = Boolean.getBoolean("Paper.ignoreWorldDataVersion"); + // Paper end - Do not let the server load chunks from newer versions + @@ -48,7 +48,7 @@ long longOr = tag.getLongOr("LastUpdate", 0L); long longOr1 = tag.getLongOr("InhabitedTime", 0L); ChunkStatus chunkStatus = tag.read("Status", ChunkStatus.CODEC).orElse(ChunkStatus.EMPTY); -@@ -154,7 +_,7 @@ +@@ -156,7 +_,7 @@ ListTag listOrEmpty2 = tag.getListOrEmpty("sections"); List list5 = new ArrayList<>(listOrEmpty2.size()); Registry registry = registries.lookupOrThrow(Registries.BIOME); @@ -57,7 +57,7 @@ for (int i2 = 0; i2 < listOrEmpty2.size(); i2++) { Optional compound = listOrEmpty2.getCompound(i2); -@@ -174,7 +_,7 @@ +@@ -176,7 +_,7 @@ Block.BLOCK_STATE_REGISTRY, Blocks.AIR.defaultBlockState(), PalettedContainer.Strategy.SECTION_STATES ) ); @@ -66,7 +66,7 @@ .map( compoundTag1 -> codec.parse(NbtOps.INSTANCE, compoundTag1) .promotePartial(string -> logErrors(chunkPos, byteOr, string)) -@@ -215,6 +_,7 @@ +@@ -217,6 +_,7 @@ list3, list4, compoundOrEmpty @@ -74,7 +74,7 @@ ); } } -@@ -292,6 +_,12 @@ +@@ -294,6 +_,12 @@ } } @@ -87,7 +87,7 @@ chunkAccess.setLightCorrect(this.lightCorrect); EnumSet set = EnumSet.noneOf(Heightmap.Types.class); -@@ -346,6 +_,12 @@ +@@ -348,6 +_,12 @@ ); } @@ -100,7 +100,7 @@ public static SerializableChunkData copyOf(ServerLevel level, ChunkAccess chunk) { if (!chunk.canBeSerialized()) { throw new IllegalArgumentException("Chunk can't be serialized: " + chunk); -@@ -404,6 +_,12 @@ +@@ -406,6 +_,12 @@ CompoundTag compoundTag = packStructureData( StructurePieceSerializationContext.fromLevel(level), pos, chunk.getAllStarts(), chunk.getAllReferences() ); @@ -113,7 +113,7 @@ return new SerializableChunkData( level.registryAccess().lookupOrThrow(Registries.BIOME), pos, -@@ -423,6 +_,7 @@ +@@ -425,6 +_,7 @@ list2, list1, compoundTag @@ -121,7 +121,7 @@ ); } } -@@ -489,6 +_,11 @@ +@@ -491,6 +_,11 @@ this.heightmaps.forEach((types, longs) -> compoundTag2.put(types.getSerializationKey(), new LongArrayTag(longs))); compoundTag.put("Heightmaps", compoundTag2); compoundTag.put("structures", this.structureData); @@ -133,7 +133,7 @@ return compoundTag; } -@@ -562,6 +_,12 @@ +@@ -572,6 +_,12 @@ } else { StructureStart structureStart = StructureStart.loadStaticStart(context, compoundOrEmpty.getCompoundOrEmpty(string), seed); if (structureStart != null) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch index b7f4e172fb..62e3e6784e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/entity/PersistentEntitySectionManager.java.patch @@ -141,7 +141,7 @@ @@ -231,14 +_,20 @@ } - private void processPendingLoads() { + public void processPendingLoads() { + org.spigotmc.AsyncCatcher.catchOp("Entity chunk process pending loads"); // Paper ChunkEntities chunkEntities; while ((chunkEntities = this.loadingInbox.poll()) != null) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch index 9f34fb9376..abb7e7cc89 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/StructurePiece.java.patch @@ -12,11 +12,12 @@ FluidState fluidState = level.getFluidState(worldPos); if (!fluidState.isEmpty()) { level.scheduleTick(worldPos, fluidState.getType(), 0); -@@ -193,6 +_,39 @@ +@@ -193,6 +_,48 @@ } } + // CraftBukkit start ++ private static final org.slf4j.Logger LOGGER = com.mojang.logging.LogUtils.getLogger(); + protected boolean placeCraftBlockEntity(ServerLevelAccessor levelAccessor, BlockPos pos, org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState, int flags) { + if (levelAccessor instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess && transformerAccess.canTransformBlocks()) { + return transformerAccess.setCraftBlock(pos, craftBlockEntityState, flags); @@ -25,7 +26,15 @@ + boolean result = levelAccessor.setBlock(pos, craftBlockEntityState.getHandle(), flags); + BlockEntity blockEntity = levelAccessor.getBlockEntity(pos); + if (blockEntity != null) { -+ blockEntity.loadWithComponents(craftBlockEntityState.getSnapshotNBT(), levelAccessor.registryAccess()); ++ try (final net.minecraft.util.ProblemReporter.ScopedCollector problemReporter = new net.minecraft.util.ProblemReporter.ScopedCollector( ++ () -> "StructurePieceTranformers@" + pos.toShortString(), LOGGER ++ )) { ++ blockEntity.loadWithComponents(net.minecraft.world.level.storage.TagValueInput.create( ++ problemReporter, ++ levelAccessor.registryAccess(), ++ craftBlockEntityState.getSnapshotNBT() ++ )); ++ } + } + return result; + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch index 0ae5165235..21be4ecfcd 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java +++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java -@@ -73,6 +_,10 @@ +@@ -79,6 +_,10 @@ public final List entityInfoList = Lists.newArrayList(); private Vec3i size = Vec3i.ZERO; private String author = "?"; @@ -11,7 +11,7 @@ public Vec3i getSize() { return this.size; -@@ -247,6 +_,19 @@ +@@ -255,6 +_,19 @@ if (this.palettes.isEmpty()) { return false; } else { @@ -31,83 +31,83 @@ List list = settings.getRandomPalette(this.palettes, offset).blocks(); if ((!list.isEmpty() || !settings.isIgnoreEntities() && !this.entityInfoList.isEmpty()) && this.size.getX() >= 1 -@@ -272,6 +_,21 @@ - serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820); - } +@@ -282,6 +_,21 @@ + serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820); + } -+ // CraftBukkit start -+ if (structureTransformer != null) { -+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null); -+ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState entityState) { -+ entityState.loadData(structureBlockInfo.nbt); -+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable craftLootable) { -+ craftLootable.setSeed(random.nextLong()); ++ // CraftBukkit start ++ if (structureTransformer != null) { ++ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null); ++ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState entityState) { ++ entityState.loadData(structureBlockInfo.nbt); ++ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable craftLootable) { ++ craftLootable.setSeed(random.nextLong()); ++ } + } ++ craftBlockState = structureTransformer.transformCraftState(craftBlockState); ++ blockState = craftBlockState.getHandle(); ++ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null)); + } -+ craftBlockState = structureTransformer.transformCraftState(craftBlockState); -+ blockState = craftBlockState.getHandle(); -+ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null)); -+ } -+ // CraftBukkit end ++ // CraftBukkit end + - if (serverLevel.setBlock(blockPos, blockState, flags)) { - i = Math.min(i, blockPos.getX()); - i1 = Math.min(i1, blockPos.getY()); -@@ -283,7 +_,7 @@ - if (structureBlockInfo.nbt != null) { - BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos); - if (blockEntity != null) { -- if (blockEntity instanceof RandomizableContainer) { -+ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above - structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong()); - } + if (serverLevel.setBlock(blockPos, blockState, flags)) { + i = Math.min(i, blockPos.getX()); + i1 = Math.min(i1, blockPos.getY()); +@@ -293,7 +_,7 @@ + if (structureBlockInfo.nbt != null) { + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos); + if (blockEntity != null) { +- if (blockEntity instanceof RandomizableContainer) { ++ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above + structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong()); + } -@@ -366,7 +_,11 @@ - if (pair1.getSecond() != null) { - BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4); - if (blockEntity != null) { -- blockEntity.setChanged(); -+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock -+ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) { -+ blockEntity.setChanged(); -+ } -+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock +@@ -380,7 +_,11 @@ + if (pair1.getSecond() != null) { + BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4); + if (blockEntity != null) { +- blockEntity.setChanged(); ++ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock ++ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) { ++ blockEntity.setChanged(); ++ } ++ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock + } } } - } -@@ -374,7 +_,7 @@ +@@ -388,7 +_,7 @@ - if (!settings.isIgnoreEntities()) { - this.placeEntities( -- serverLevel, -+ wrappedAccess, // CraftBukkit - offset, - settings.getMirror(), - settings.getRotation(), -@@ -488,14 +_,17 @@ - ); + if (!settings.isIgnoreEntities()) { + this.placeEntities( +- serverLevel, ++ wrappedAccess, // CraftBukkit + offset, + settings.getMirror(), + settings.getRotation(), +@@ -499,14 +_,17 @@ + }); } } + } - private static Optional createEntityIgnoreException(ServerLevelAccessor level, CompoundTag tag) { + private static Optional createEntityIgnoreException(ProblemReporter problemReporter, ServerLevelAccessor level, CompoundTag tag) { - try { -- return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE); -- } catch (Exception var3) { +- return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE); +- } catch (Exception var4) { - return Optional.empty(); - } + // CraftBukkit start + // try { -+ return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation -+ // } catch (Exception var3) { ++ return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation ++ // } catch (Exception var4) { + // return Optional.empty(); + // } + // CraftBukkit end } public Vec3i getSize(Rotation rotation) { -@@ -688,6 +_,11 @@ +@@ -699,6 +_,11 @@ tag.put("entities", listTag3); tag.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ())); @@ -119,7 +119,7 @@ return NbtUtils.addCurrentDataVersion(tag); } -@@ -718,6 +_,11 @@ +@@ -729,6 +_,11 @@ .ifPresent(compoundTag1 -> this.entityInfoList.add(new StructureTemplate.StructureEntityInfo(vec3, blockPos, compoundTag1))); } ); @@ -131,7 +131,7 @@ } private void loadPalette(HolderGetter blockGetter, ListTag paletteTag, ListTag blocksTag) { -@@ -817,7 +_,7 @@ +@@ -828,7 +_,7 @@ public static final class Palette { private final List blocks; diff --git a/paper-server/patches/sources/net/minecraft/world/level/portal/PortalShape.java.patch b/paper-server/patches/sources/net/minecraft/world/level/portal/PortalShape.java.patch index 89e1525889..85e23ecea4 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/portal/PortalShape.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/portal/PortalShape.java.patch @@ -140,7 +140,7 @@ BlockPos.betweenClosed(this.bottomLeft, this.bottomLeft.relative(Direction.UP, this.height - 1).relative(this.rightDir, this.width - 1)) + .forEach(pos -> this.blocks.setBlock(pos, blockState, 18)); + org.bukkit.event.world.PortalCreateEvent event = new org.bukkit.event.world.PortalCreateEvent((java.util.List) (java.util.List) this.blocks.getSnapshotBlocks(), bworld, (entity == null) ? null : entity.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.FIRE); -+ level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event); ++ level.getMinecraftWorld().getServer().server.getPluginManager().callEvent(event); // todo the list is not really mutable here unlike other call and the portal frame is included + + if (event.isCancelled()) { + return false; diff --git a/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch b/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch index b65e02e918..4780b51094 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/portal/TeleportTransition.java.patch @@ -59,22 +59,13 @@ } public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) { -- this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, false, false, Set.of(), postTeleportTransition); +- this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition); + // CraftBukkit start + this(level, entity, postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause.UNKNOWN); + } + public TeleportTransition(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition, org.bukkit.event.player.PlayerTeleportEvent.TeleportCause cause) { -+ this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition, cause); // Paper - MC-200092 - fix first spawn pos yaw being ignored ++ this(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, false, false, Set.of(), postTeleportTransition, cause); + // CraftBukkit end } private static void playPortalSound(Entity entity) { -@@ -57,7 +_,7 @@ - } - - public static TeleportTransition missingRespawnBlock(ServerLevel level, Entity entity, TeleportTransition.PostTeleportTransition postTeleportTransition) { -- return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, 0.0F, 0.0F, true, false, Set.of(), postTeleportTransition); -+ return new TeleportTransition(level, findAdjustedSharedSpawnPos(level, entity), Vec3.ZERO, level.getSharedSpawnAngle(), 0.0F, true, false, Set.of(), postTeleportTransition); // Paper - MC-200092 - fix spawn pos yaw being ignored - } - - private static Vec3 findAdjustedSharedSpawnPos(ServerLevel level, Entity entity) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch index 6a336da5f5..96aefe7f52 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/PlayerDataStorage.java.patch @@ -1,19 +1,19 @@ --- a/net/minecraft/world/level/storage/PlayerDataStorage.java +++ b/net/minecraft/world/level/storage/PlayerDataStorage.java -@@ -31,6 +_,7 @@ +@@ -32,6 +_,7 @@ } public void save(Player player) { + if (org.spigotmc.SpigotConfig.disablePlayerDataSaving) return; // Spigot - try { - CompoundTag compoundTag = player.saveWithoutId(new CompoundTag()); - Path path = this.playerDir.toPath(); -@@ -40,30 +_,46 @@ + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), LOGGER)) { + TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector, player.registryAccess()); + player.saveWithoutId(tagValueOutput); +@@ -43,30 +_,46 @@ Path path3 = path.resolve(player.getStringUUID() + ".dat_old"); Util.safeReplaceFile(path2, path1, path3); - } catch (Exception var7) { + } catch (Exception var11) { - LOGGER.warn("Failed to save player data for {}", player.getName().getString()); -+ LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), var7); // Paper - Print exception ++ LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), var11); // Paper - Print exception } } @@ -64,13 +64,13 @@ } } -@@ -71,16 +_,40 @@ +@@ -74,17 +_,40 @@ } - public Optional load(Player player) { + public Optional load(Player player, ProblemReporter problemReporter) { - Optional optional = this.load(player, ".dat"); + // CraftBukkit start -+ return this.load(player.getName().getString(), player.getStringUUID()).map((tag) -> { ++ return this.load(player.getName().getString(), player.getStringUUID(), problemReporter).map((tag) -> { + if (player instanceof net.minecraft.server.level.ServerPlayer serverPlayer) { + org.bukkit.craftbukkit.entity.CraftPlayer craftPlayer = serverPlayer.getBukkitEntity(); + // Only update first played if it is older than the one we have @@ -80,12 +80,13 @@ + } + } + -+ player.load(tag); // From below -+ return tag; ++ ValueInput valueInput = TagValueInput.create(problemReporter, player.registryAccess(), tag); ++ player.load(valueInput); // From below ++ return valueInput; + }); + } + -+ public Optional load(String name, String uuid) { ++ public Optional load(String name, String uuid, ProblemReporter problemReporter) { + // CraftBukkit end + Optional optional = this.load(name, uuid, ".dat"); // CraftBukkit if (optional.isEmpty()) { @@ -97,9 +98,10 @@ + return optional.or(() -> this.load(name, uuid, ".dat_old")).map(compoundTag -> { // CraftBukkit int dataVersion = NbtUtils.getDataVersion(compoundTag, -1); compoundTag = DataFixTypes.PLAYER.updateToCurrentVersion(this.fixerUpper, compoundTag, dataVersion); -- player.load(compoundTag); -+ // player.load(compoundTag); // CraftBukkit - handled above - return compoundTag; +- ValueInput valueInput = TagValueInput.create(problemReporter, player.registryAccess(), compoundTag); +- player.load(valueInput); +- return valueInput; ++ return compoundTag; // CraftBukkit - handled above }); } + diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueInput.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueInput.java.patch new file mode 100644 index 0000000000..b53963635f --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueInput.java.patch @@ -0,0 +1,18 @@ +--- a/net/minecraft/world/level/storage/TagValueInput.java ++++ b/net/minecraft/world/level/storage/TagValueInput.java +@@ -37,6 +_,15 @@ + this.input = input; + } + ++ // Paper start - utility methods ++ public static ValueInput createGlobal( ++ final ProblemReporter problemReporter, ++ final CompoundTag compoundTag ++ ) { ++ return create(problemReporter, net.minecraft.server.MinecraftServer.getServer().registryAccess(), compoundTag); ++ } ++ // Paper end - utility methods ++ + public static ValueInput create(ProblemReporter problemReporter, HolderLookup.Provider lookup, CompoundTag input) { + return new TagValueInput(problemReporter, new ValueInputContextHelper(lookup, NbtOps.INSTANCE), input); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueOutput.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueOutput.java.patch new file mode 100644 index 0000000000..4d29ca83ee --- /dev/null +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/TagValueOutput.java.patch @@ -0,0 +1,26 @@ +--- a/net/minecraft/world/level/storage/TagValueOutput.java ++++ b/net/minecraft/world/level/storage/TagValueOutput.java +@@ -24,6 +_,23 @@ + this.output = tag; + } + ++ // Paper start - utility methods ++ public static TagValueOutput createWrappingGlobal( ++ final ProblemReporter problemReporter, ++ final CompoundTag compoundTag ++ ) { ++ return new TagValueOutput(problemReporter, NbtOps.INSTANCE, compoundTag); ++ } ++ ++ public static TagValueOutput createWrappingWithContext( ++ final ProblemReporter problemReporter, ++ final HolderLookup.Provider lookup, ++ final CompoundTag compoundTag ++ ) { ++ return new TagValueOutput(problemReporter, lookup.createSerializationContext(NbtOps.INSTANCE), compoundTag); ++ } ++ // Paper end - utility methods ++ + public static TagValueOutput createWithContext(ProblemReporter problemReporter, HolderLookup.Provider lookup) { + return new TagValueOutput(problemReporter, lookup.createSerializationContext(NbtOps.INSTANCE), new CompoundTag()); + } diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootDataType.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootDataType.java.patch index 87eb699603..521ff0103e 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootDataType.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootDataType.java.patch @@ -1,16 +1,16 @@ --- a/net/minecraft/world/level/storage/loot/LootDataType.java +++ b/net/minecraft/world/level/storage/loot/LootDataType.java -@@ -31,9 +_,14 @@ +@@ -32,9 +_,14 @@ } private static LootDataType.Validator createLootTableValidator() { - return (context, key, value) -> value.validate( -- context.setContextKeySet(value.getParamSet()).enterElement("{" + key.registry() + "/" + key.location() + "}", key) +- context.setContextKeySet(value.getParamSet()).enterElement(new ProblemReporter.RootElementPathElement(key), key) - ); + // CraftBukkit start + return (context, key, value) -> { + value.validate( -+ context.setContextKeySet(value.getParamSet()).enterElement("{" + key.registry() + "/" + key.location() + "}", key) ++ context.setContextKeySet(value.getParamSet()).enterElement(new ProblemReporter.RootElementPathElement(key), key) + ); + value.craftLootTable = new org.bukkit.craftbukkit.CraftLootTable(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(key.location()), value); + // CraftBukkit end diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch index c93c7dddda..e94a2298f5 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/LootTable.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/LootTable.java +++ b/net/minecraft/world/level/storage/loot/LootTable.java -@@ -52,6 +_,7 @@ +@@ -53,6 +_,7 @@ private final List pools; private final List functions; private final BiFunction compositeFunction; @@ -8,7 +8,7 @@ LootTable(ContextKeySet paramSet, Optional randomSequence, List pools, List functions) { this.paramSet = paramSet; -@@ -62,9 +_,10 @@ +@@ -63,9 +_,10 @@ } public static Consumer createStackSplitter(ServerLevel level, Consumer output) { @@ -20,7 +20,7 @@ output.accept(itemStack); } else { int count = itemStack.getCount(); -@@ -145,9 +_,22 @@ +@@ -146,9 +_,22 @@ } public void fill(Container container, LootParams params, long seed) { diff --git a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch index baa99f7a0b..03a917ef41 100644 --- a/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch +++ b/paper-server/patches/sources/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java.patch @@ -1,6 +1,6 @@ --- a/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java +++ b/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java -@@ -32,6 +_,10 @@ +@@ -33,6 +_,10 @@ ); } }; @@ -11,7 +11,7 @@ protected LootPoolSingletonContainer(int weight, int quality, List conditions, List functions) { super(conditions); -@@ -126,7 +_,31 @@ +@@ -127,7 +_,31 @@ protected abstract class EntryBase implements LootPoolEntry { @Override public int getWeight(float luck) { diff --git a/paper-server/patches/unapplied/0015-Rewrite-dataconverter-system.patch b/paper-server/patches/unapplied/0015-Rewrite-dataconverter-system.patch index cd20ceb478..9d17eab4b4 100644 --- a/paper-server/patches/unapplied/0015-Rewrite-dataconverter-system.patch +++ b/paper-server/patches/unapplied/0015-Rewrite-dataconverter-system.patch @@ -29346,10 +29346,10 @@ index 0000000000000000000000000000000000000000..62c0f4073aff301bf5b3187e0d4446fd +} diff --git a/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java b/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java new file mode 100644 -index 0000000000000000000000000000000000000000..40da70d5cf584a9730f9fe81c355cf8513fba475 +index 0000000000000000000000000000000000000000..9fab2371790596ab57298fe28b8983d85210c6d9 --- /dev/null +++ b/ca/spottedleaf/dataconverter/util/CommandArgumentUpgrader.java -@@ -0,0 +1,592 @@ +@@ -0,0 +1,597 @@ +package ca.spottedleaf.dataconverter.util; + +import ca.spottedleaf.dataconverter.minecraft.MCDataConverter; @@ -29908,6 +29908,11 @@ index 0000000000000000000000000000000000000000..40da70d5cf584a9730f9fe81c355cf85 + ) { + return Optional.of(new HolderLookup.RegistryLookup() { + @Override ++ public Optional getValueForCopying(final ResourceKey resourceKey) { ++ return Optional.empty(); ++ } ++ ++ @Override + public ResourceKey> key() { + return registryRef; + } diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAmethystCluster.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAmethystCluster.java index d931bea60c..503d8eaa10 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAmethystCluster.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAmethystCluster.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.AmethystCluster; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftAmethystCluster extends CraftBlockData implements AmethystCluster { private static final EnumProperty FACING = AmethystClusterBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAnvil.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAnvil.java index 9523eb7419..9a7e2a75b3 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAnvil.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAnvil.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftAnvil extends CraftBlockData implements Directional { private static final EnumProperty FACING = AnvilBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAttachedStem.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAttachedStem.java index d5f2f41bba..81e2dc3809 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAttachedStem.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftAttachedStem.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftAttachedStem extends CraftBlockData implements Directional { private static final EnumProperty FACING = AttachedStemBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBambooStalk.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBambooStalk.java index 2dac138e38..e876dfe2ff 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBambooStalk.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBambooStalk.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Bamboo; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBambooStalk extends CraftBlockData implements Bamboo { private static final IntegerProperty AGE = BambooStalkBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBanner.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBanner.java index f6d39e3e50..ba6ac7c221 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBanner.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBanner.java @@ -11,7 +11,7 @@ import org.bukkit.block.data.Rotatable; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBanner extends CraftBlockData implements Rotatable { private static final IntegerProperty ROTATION = BannerBlock.ROTATION; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java index 67428ff047..166156690b 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrel.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Barrel; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBarrel extends CraftBlockData implements Barrel { private static final EnumProperty FACING = BarrelBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrier.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrier.java index f3a1a2ebef..6b9b9018e6 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrier.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBarrier.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBarrier extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = BarrierBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralFan.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralFan.java index ba47dc86a9..bec35a528f 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralFan.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralFan.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBaseCoralFan extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = BaseCoralFanBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralPlant.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralPlant.java index b5ba21b329..7078be46dc 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralPlant.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralPlant.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBaseCoralPlant extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = BaseCoralPlantBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralWallFan.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralWallFan.java index fc818c4ca0..919632894c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralWallFan.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBaseCoralWallFan.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.CoralWallFan; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBaseCoralWallFan extends CraftBlockData implements CoralWallFan { private static final EnumProperty FACING = BaseCoralWallFanBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBed.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBed.java index 9b03035bc5..cf04e57e2c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBed.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBed.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Bed; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBed extends CraftBlockData implements Bed { private static final EnumProperty FACING = BedBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeehive.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeehive.java index 758e17b22b..d9e15ca7fb 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeehive.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeehive.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Beehive; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBeehive extends CraftBlockData implements Beehive { private static final EnumProperty FACING = BeehiveBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeetroot.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeetroot.java index aff49f95de..5f6d137b90 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeetroot.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBeetroot.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBeetroot extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = BeetrootBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBell.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBell.java index d4f1ee3726..ed4f6a7918 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBell.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBell.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Bell; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBell extends CraftBlockData implements Bell { private static final EnumProperty ATTACHMENT = BellBlock.ATTACHMENT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleaf.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleaf.java index a097689fcf..350f1c4a29 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleaf.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleaf.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.BigDripleaf; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBigDripleaf extends CraftBlockData implements BigDripleaf { private static final EnumProperty FACING = BigDripleafBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleafStem.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleafStem.java index 46f6663386..9b4dc0d05a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleafStem.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBigDripleafStem.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Dripleaf; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBigDripleafStem extends CraftBlockData implements Dripleaf { private static final EnumProperty FACING = BigDripleafStemBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java index 4fb939d053..ca51dd6f2c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBlastFurnace.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Furnace; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBlastFurnace extends CraftBlockData implements Furnace { private static final EnumProperty FACING = BlastFurnaceBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrewingStand.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrewingStand.java index 0d1a9b20c4..3d51fca456 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrewingStand.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrewingStand.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.BrewingStand; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBrewingStand extends CraftBlockData implements BrewingStand { private static final BooleanProperty[] HAS_BOTTLE = BrewingStandBlock.HAS_BOTTLE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrushable.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrushable.java index a6d25ef59b..47d15f5c96 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrushable.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBrushable.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Brushable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBrushable extends CraftBlockData implements Brushable { private static final IntegerProperty DUSTED = BlockStateProperties.DUSTED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBubbleColumn.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBubbleColumn.java index 48cd35fb6a..42fe4ef913 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBubbleColumn.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftBubbleColumn.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.BubbleColumn; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftBubbleColumn extends CraftBlockData implements BubbleColumn { private static final BooleanProperty DRAG_DOWN = BubbleColumnBlock.DRAG_DOWN; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftButton.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftButton.java index de870c63e7..fedca3f5fd 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftButton.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftButton.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Switch; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftButton extends CraftBlockData implements Switch { private static final EnumProperty FACE = ButtonBlock.FACE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCactus.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCactus.java index 6a41d3d0f2..8bbf4d4194 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCactus.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCactus.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCactus extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = CactusBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCake.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCake.java index e889abe725..fc9ace7efe 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCake.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCake.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Cake; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCake extends CraftBlockData implements Cake { private static final IntegerProperty BITES = CakeBlock.BITES; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCalibratedSculkSensor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCalibratedSculkSensor.java index ea2a71a6e7..940ce38c13 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCalibratedSculkSensor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCalibratedSculkSensor.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.CalibratedSculkSensor; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCalibratedSculkSensor extends CraftBlockData implements CalibratedSculkSensor { private static final EnumProperty FACING = CalibratedSculkSensorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java index 05d85edb15..3131a36f9a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCampfire.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Campfire; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCampfire extends CraftBlockData implements Campfire { private static final EnumProperty FACING = CampfireBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java index db1ce7c458..90019bd2f4 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Candle; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCandle extends CraftBlockData implements Candle { private static final IntegerProperty CANDLES = CandleBlock.CANDLES; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandleCake.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandleCake.java index 103b39b0b0..b9cb5b4db9 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandleCake.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCandleCake.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Lightable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCandleCake extends CraftBlockData implements Lightable { private static final BooleanProperty LIT = CandleCakeBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarrot.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarrot.java index 50a113f01d..51c1bbf788 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarrot.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarrot.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCarrot extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = CarrotBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarvedPumpkin.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarvedPumpkin.java index 0cdaee616f..39b8c2a27a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarvedPumpkin.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCarvedPumpkin.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCarvedPumpkin extends CraftBlockData implements Directional { private static final EnumProperty FACING = CarvedPumpkinBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVines.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVines.java index 66d271e6c7..32f3891dec 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVines.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVines.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.CaveVines; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCaveVines extends CraftBlockData implements CaveVines { private static final IntegerProperty AGE = CaveVinesBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVinesPlant.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVinesPlant.java index ca2074cc8d..a59daa6110 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVinesPlant.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCaveVinesPlant.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.CaveVinesPlant; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCaveVinesPlant extends CraftBlockData implements CaveVinesPlant { private static final BooleanProperty BERRIES = CaveVinesPlantBlock.BERRIES; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCeilingHangingSign.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCeilingHangingSign.java index 80151fbd5b..f2cac88be5 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCeilingHangingSign.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCeilingHangingSign.java @@ -12,7 +12,7 @@ import org.bukkit.block.data.type.HangingSign; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCeilingHangingSign extends CraftBlockData implements HangingSign { private static final BooleanProperty ATTACHED = CeilingHangingSignBlock.ATTACHED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChain.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChain.java index 8885f26ce1..45ac52f7b3 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChain.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChain.java @@ -12,7 +12,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.type.Chain; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftChain extends CraftBlockData implements Chain { private static final EnumProperty AXIS = ChainBlock.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChest.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChest.java index f598e7218f..1380a7f37b 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChest.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChest.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Chest; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftChest extends CraftBlockData implements Chest { private static final EnumProperty FACING = ChestBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChiseledBookShelf.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChiseledBookShelf.java index fa4118e181..dd59d821e8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChiseledBookShelf.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChiseledBookShelf.java @@ -15,7 +15,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.ChiseledBookshelf; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftChiseledBookShelf extends CraftBlockData implements ChiseledBookshelf { private static final EnumProperty HORIZONTAL_FACING = BlockStateProperties.HORIZONTAL_FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusFlower.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusFlower.java index 7aaca089ac..36b052298d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusFlower.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusFlower.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftChorusFlower extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = ChorusFlowerBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusPlant.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusPlant.java index 860eb36a8c..376ffe9c6a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusPlant.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftChorusPlant.java @@ -15,7 +15,7 @@ import org.bukkit.block.data.MultipleFacing; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftChorusPlant extends CraftBlockData implements MultipleFacing { private static final Map PROPERTY_BY_DIRECTION = ChorusPlantBlock.PROPERTY_BY_DIRECTION.entrySet().stream() .collect(Collectors.toMap(entry -> CraftBlock.notchToBlockFace(entry.getKey()), entry -> entry.getValue())); diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCocoa.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCocoa.java index b185a1127f..32485fc811 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCocoa.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCocoa.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Cocoa; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCocoa extends CraftBlockData implements Cocoa { private static final IntegerProperty AGE = CocoaBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCommandBlock.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCommandBlock.java index ba8fa0b364..ab31b91103 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCommandBlock.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCommandBlock.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.CommandBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCommandBlock extends CraftBlockData implements CommandBlock { private static final BooleanProperty CONDITIONAL = net.minecraft.world.level.block.CommandBlock.CONDITIONAL; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComparator.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComparator.java index 3354b67e6f..3623954574 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComparator.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComparator.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Comparator; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftComparator extends CraftBlockData implements Comparator { private static final EnumProperty FACING = ComparatorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java index b74562f568..5b8ad1ca09 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Levelled; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftComposter extends CraftBlockData implements Levelled { private static final IntegerProperty LEVEL = ComposterBlock.LEVEL; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftConduit.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftConduit.java index e4d0cb5cd2..2d3bdcfc4c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftConduit.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftConduit.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftConduit extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = ConduitBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCopperBulb.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCopperBulb.java index 53de51d7ee..a358e9a8fc 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCopperBulb.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCopperBulb.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.CopperBulb; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCopperBulb extends CraftBlockData implements CopperBulb { private static final BooleanProperty LIT = CopperBulbBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralFan.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralFan.java index 332901a606..3cecbbbc98 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralFan.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralFan.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCoralFan extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = CoralFanBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralPlant.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralPlant.java index 2c2ea21cf0..7495a4d299 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralPlant.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralPlant.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCoralPlant extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = CoralPlantBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralWallFan.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralWallFan.java index 4500d844a7..0bddb6c75d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralWallFan.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCoralWallFan.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.CoralWallFan; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCoralWallFan extends CraftBlockData implements CoralWallFan { private static final EnumProperty FACING = CoralWallFanBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrafter.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrafter.java index c639553a47..4c2cd8f77f 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrafter.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrafter.java @@ -11,7 +11,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.type.Crafter; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCrafter extends CraftBlockData implements Crafter { private static final BooleanProperty CRAFTING = CrafterBlock.CRAFTING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCreakingHeart.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCreakingHeart.java index ea51c9a969..5702570d62 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCreakingHeart.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCreakingHeart.java @@ -13,7 +13,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.type.CreakingHeart; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCreakingHeart extends CraftBlockData implements CreakingHeart { private static final EnumProperty AXIS = CreakingHeartBlock.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrop.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrop.java index 3693f5adbf..55b06d8add 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrop.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftCrop.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftCrop extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = CropBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDaylightDetector.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDaylightDetector.java index 7c676ccc1c..91fb07b52d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDaylightDetector.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDaylightDetector.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.DaylightDetector; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDaylightDetector extends CraftBlockData implements DaylightDetector { private static final BooleanProperty INVERTED = DaylightDetectorBlock.INVERTED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java index e2aecaa8c3..59bf9c5fbb 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDecoratedPot.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.DecoratedPot; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDecoratedPot extends CraftBlockData implements DecoratedPot { private static final BooleanProperty CRACKED = DecoratedPotBlock.CRACKED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDetectorRail.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDetectorRail.java index 95ee8f4ffa..bea473fb45 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDetectorRail.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDetectorRail.java @@ -11,7 +11,7 @@ import net.minecraft.world.level.block.state.properties.RailShape; import org.bukkit.block.data.type.RedstoneRail; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDetectorRail extends CraftBlockData implements RedstoneRail { private static final BooleanProperty POWERED = DetectorRailBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDispenser.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDispenser.java index c93733f7bc..a0152f23d1 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDispenser.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDispenser.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Dispenser; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDispenser extends CraftBlockData implements Dispenser { private static final EnumProperty FACING = DispenserBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoor.java index 3b71b22ebb..99987f559b 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoor.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Door; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDoor extends CraftBlockData implements Door { private static final EnumProperty FACING = DoorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoublePlant.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoublePlant.java index 2b98b17b1e..50246e9bac 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoublePlant.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDoublePlant.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.Bisected; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDoublePlant extends CraftBlockData implements Bisected { private static final EnumProperty HALF = DoublePlantBlock.HALF; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDriedGhast.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDriedGhast.java new file mode 100644 index 0000000000..8d9c25c483 --- /dev/null +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDriedGhast.java @@ -0,0 +1,69 @@ +package org.bukkit.craftbukkit.block.impl; + +import com.google.common.base.Preconditions; +import io.papermc.paper.generated.GeneratedFrom; +import java.util.Set; +import net.minecraft.core.Direction; +import net.minecraft.world.level.block.DriedGhastBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.block.state.properties.BooleanProperty; +import net.minecraft.world.level.block.state.properties.EnumProperty; +import net.minecraft.world.level.block.state.properties.IntegerProperty; +import org.bukkit.block.BlockFace; +import org.bukkit.block.data.type.DriedGhast; +import org.bukkit.craftbukkit.block.data.CraftBlockData; + +@GeneratedFrom("1.21.6-rc1") +public class CraftDriedGhast extends CraftBlockData implements DriedGhast { + private static final EnumProperty FACING = DriedGhastBlock.FACING; + + private static final IntegerProperty HYDRATION_LEVEL = DriedGhastBlock.HYDRATION_LEVEL; + + private static final BooleanProperty WATERLOGGED = DriedGhastBlock.WATERLOGGED; + + public CraftDriedGhast(BlockState state) { + super(state); + } + + @Override + public BlockFace getFacing() { + return this.get(FACING, BlockFace.class); + } + + @Override + public void setFacing(final BlockFace blockFace) { + Preconditions.checkArgument(blockFace != null, "blockFace cannot be null!"); + Preconditions.checkArgument(blockFace.isCartesian() && blockFace.getModY() == 0, "Invalid face, only cartesian horizontal face are allowed for this property!"); + this.set(FACING, blockFace); + } + + @Override + public Set getFaces() { + return this.getValues(FACING, BlockFace.class); + } + + @Override + public int getHydration() { + return this.get(HYDRATION_LEVEL); + } + + @Override + public void setHydration(final int hydration) { + this.set(HYDRATION_LEVEL, hydration); + } + + @Override + public int getMaximumHydration() { + return HYDRATION_LEVEL.max; + } + + @Override + public boolean isWaterlogged() { + return this.get(WATERLOGGED); + } + + @Override + public void setWaterlogged(final boolean waterlogged) { + this.set(WATERLOGGED, waterlogged); + } +} diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDropper.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDropper.java index 08695cf5ab..4602b76fb2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDropper.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftDropper.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Dispenser; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftDropper extends CraftBlockData implements Dispenser { private static final EnumProperty FACING = DropperBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndPortalFrame.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndPortalFrame.java index 88b8fe7c16..72372070b6 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndPortalFrame.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndPortalFrame.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.EndPortalFrame; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftEndPortalFrame extends CraftBlockData implements EndPortalFrame { private static final BooleanProperty HAS_EYE = EndPortalFrameBlock.HAS_EYE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndRod.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndRod.java index ba790faf3e..7bf7ce6f41 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndRod.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEndRod.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftEndRod extends CraftBlockData implements Directional { private static final EnumProperty FACING = EndRodBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEnderChest.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEnderChest.java index b119c63fda..c377645c53 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEnderChest.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftEnderChest.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.EnderChest; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftEnderChest extends CraftBlockData implements EnderChest { private static final EnumProperty FACING = EnderChestBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFarm.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFarm.java index 88b7c7b5b8..3f90718e4d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFarm.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFarm.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Farmland; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFarm extends CraftBlockData implements Farmland { private static final IntegerProperty MOISTURE = FarmBlock.MOISTURE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFence.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFence.java index b67a02dd12..c3a5176f6a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFence.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFence.java @@ -15,7 +15,7 @@ import org.bukkit.block.data.type.Fence; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFence extends CraftBlockData implements Fence { private static final BooleanProperty WATERLOGGED = FenceBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFenceGate.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFenceGate.java index d84ebcb7f8..a3d02c3ba2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFenceGate.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFenceGate.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Gate; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFenceGate extends CraftBlockData implements Gate { private static final EnumProperty FACING = FenceGateBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFire.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFire.java index a148145fb8..20d5d331eb 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFire.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFire.java @@ -16,7 +16,7 @@ import org.bukkit.block.data.type.Fire; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFire extends CraftBlockData implements Fire { private static final IntegerProperty AGE = FireBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFlowerBed.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFlowerBed.java index 0f82214df9..9c0367e0a2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFlowerBed.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFlowerBed.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.FlowerBed; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFlowerBed extends CraftBlockData implements FlowerBed { private static final EnumProperty FACING = FlowerBedBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFrostedIce.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFrostedIce.java index fd83ea6d33..36f03ecfa4 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFrostedIce.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFrostedIce.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFrostedIce extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = FrostedIceBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java index d9c72086dc..fd5c36e9e0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftFurnace.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Furnace; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftFurnace extends CraftBlockData implements Furnace { private static final EnumProperty FACING = FurnaceBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlazedTerracotta.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlazedTerracotta.java index d21a3824c9..9d301cfb0f 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlazedTerracotta.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlazedTerracotta.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftGlazedTerracotta extends CraftBlockData implements Directional { private static final EnumProperty FACING = GlazedTerracottaBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlowLichen.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlowLichen.java index ae2a5f8f30..b825ef316a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlowLichen.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGlowLichen.java @@ -15,17 +15,17 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.GlowLichen; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftGlowLichen extends CraftBlockData implements GlowLichen { private static final BooleanProperty WATERLOGGED = GlowLichenBlock.WATERLOGGED; private static final Map PROPERTY_BY_DIRECTION = Map.of( BlockFace.DOWN, BlockStateProperties.DOWN, - BlockFace.UP, BlockStateProperties.UP, + BlockFace.EAST, BlockStateProperties.EAST, BlockFace.NORTH, BlockStateProperties.NORTH, BlockFace.SOUTH, BlockStateProperties.SOUTH, - BlockFace.WEST, BlockStateProperties.WEST, - BlockFace.EAST, BlockStateProperties.EAST + BlockFace.UP, BlockStateProperties.UP, + BlockFace.WEST, BlockStateProperties.WEST ); public CraftGlowLichen(BlockState state) { diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrass.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrass.java index f614805483..45f1b6272e 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrass.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrass.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Snowable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftGrass extends CraftBlockData implements Snowable { private static final BooleanProperty SNOWY = GrassBlock.SNOWY; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java index d19c28380f..b997b27983 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftGrindstone.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Grindstone; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftGrindstone extends CraftBlockData implements Grindstone { private static final EnumProperty FACE = GrindstoneBlock.FACE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingMoss.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingMoss.java index a600ff8dcf..bb3031b922 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingMoss.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingMoss.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.HangingMoss; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHangingMoss extends CraftBlockData implements HangingMoss { private static final BooleanProperty TIP = HangingMossBlock.TIP; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingRoots.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingRoots.java index b5936e57ac..014014d839 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingRoots.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHangingRoots.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHangingRoots extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = BlockStateProperties.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHay.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHay.java index c33a505f1f..92bffe00c8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHay.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHay.java @@ -11,7 +11,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.Orientable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHay extends CraftBlockData implements Orientable { private static final EnumProperty AXIS = HayBlock.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHeavyCore.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHeavyCore.java index 2d59f73476..a43924df7b 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHeavyCore.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHeavyCore.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHeavyCore extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = HeavyCoreBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHopper.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHopper.java index a2a3b8177b..c8177f0a9d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHopper.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHopper.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Hopper; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHopper extends CraftBlockData implements Hopper { private static final BooleanProperty ENABLED = HopperBlock.ENABLED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHugeMushroom.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHugeMushroom.java index 5318419eb9..e4972a16b6 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHugeMushroom.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftHugeMushroom.java @@ -14,15 +14,15 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.MultipleFacing; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftHugeMushroom extends CraftBlockData implements MultipleFacing { private static final Map PROPERTY_BY_DIRECTION = Map.of( BlockFace.DOWN, HugeMushroomBlock.DOWN, - BlockFace.UP, HugeMushroomBlock.UP, + BlockFace.EAST, HugeMushroomBlock.EAST, BlockFace.NORTH, HugeMushroomBlock.NORTH, BlockFace.SOUTH, HugeMushroomBlock.SOUTH, - BlockFace.WEST, HugeMushroomBlock.WEST, - BlockFace.EAST, HugeMushroomBlock.EAST + BlockFace.UP, HugeMushroomBlock.UP, + BlockFace.WEST, HugeMushroomBlock.WEST ); public CraftHugeMushroom(BlockState state) { diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftInfestedRotatedPillar.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftInfestedRotatedPillar.java index 976576ecad..fbf53e6a2c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftInfestedRotatedPillar.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftInfestedRotatedPillar.java @@ -11,7 +11,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.Orientable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftInfestedRotatedPillar extends CraftBlockData implements Orientable { private static final EnumProperty AXIS = BlockStateProperties.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftIronBars.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftIronBars.java index 88805c241c..b43f2678d8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftIronBars.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftIronBars.java @@ -15,7 +15,7 @@ import org.bukkit.block.data.type.Fence; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftIronBars extends CraftBlockData implements Fence { private static final BooleanProperty WATERLOGGED = IronBarsBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java index bfa66201d0..16cbb64871 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJigsaw.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.type.Jigsaw; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftJigsaw extends CraftBlockData implements Jigsaw { private static final EnumProperty ORIENTATION = JigsawBlock.ORIENTATION; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJukebox.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJukebox.java index 0883d213ef..508df6a714 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJukebox.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftJukebox.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.Jukebox; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftJukebox extends CraftBlockData implements Jukebox { private static final BooleanProperty HAS_RECORD = JukeboxBlock.HAS_RECORD; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftKelp.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftKelp.java index 720370327e..1d726703af 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftKelp.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftKelp.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftKelp extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = KelpBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLadder.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLadder.java index 01ca00b1a9..563515c0bd 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLadder.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLadder.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Ladder; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLadder extends CraftBlockData implements Ladder { private static final EnumProperty FACING = LadderBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java index 1f9acabeb3..0a2bdbce81 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLantern.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.Lantern; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLantern extends CraftBlockData implements Lantern { private static final BooleanProperty HANGING = LanternBlock.HANGING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java index 9b77f34483..e41c4b6555 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Levelled; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLayeredCauldron extends CraftBlockData implements Levelled { private static final IntegerProperty LEVEL = LayeredCauldronBlock.LEVEL; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLeafLitter.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLeafLitter.java index 86178e0638..18e9c5412a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLeafLitter.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLeafLitter.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.LeafLitter; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLeafLitter extends CraftBlockData implements LeafLitter { private static final EnumProperty FACING = LeafLitterBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java index ac0235f235..36df7c34c8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLectern.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Lectern; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLectern extends CraftBlockData implements Lectern { private static final EnumProperty FACING = LecternBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLever.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLever.java index 3e8531763e..068f04ea28 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLever.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLever.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Switch; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLever extends CraftBlockData implements Switch { private static final EnumProperty FACE = LeverBlock.FACE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLight.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLight.java index 7f90294b48..ef600ef70e 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLight.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLight.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Light; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLight extends CraftBlockData implements Light { private static final IntegerProperty LEVEL = LightBlock.LEVEL; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLightningRod.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLightningRod.java index b6653f2f4f..87f6a4f370 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLightningRod.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLightningRod.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.LightningRod; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLightningRod extends CraftBlockData implements LightningRod { private static final EnumProperty FACING = LightningRodBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLiquid.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLiquid.java index 4d7ff9b2d7..237c4efd38 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLiquid.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLiquid.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Levelled; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLiquid extends CraftBlockData implements Levelled { private static final IntegerProperty LEVEL = LiquidBlock.LEVEL; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java index a13b2bc3cf..cb892a861c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftLoom.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftLoom extends CraftBlockData implements Directional { private static final EnumProperty FACING = LoomBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java index b6375028c0..70c4e16eab 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveLeaves.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Leaves; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMangroveLeaves extends CraftBlockData implements Leaves { private static final IntegerProperty DISTANCE = MangroveLeavesBlock.DISTANCE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangrovePropagule.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangrovePropagule.java index 577d04d4d2..2a51c141f0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangrovePropagule.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangrovePropagule.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.MangrovePropagule; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMangrovePropagule extends CraftBlockData implements MangrovePropagule { private static final IntegerProperty AGE = MangrovePropaguleBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveRoots.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveRoots.java index 2949bfad2d..d7db66c8e8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveRoots.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMangroveRoots.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMangroveRoots extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = MangroveRootsBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMossyCarpet.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMossyCarpet.java index a2d3967064..813763b129 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMossyCarpet.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMossyCarpet.java @@ -14,7 +14,7 @@ import org.bukkit.block.data.type.MossyCarpet; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMossyCarpet extends CraftBlockData implements MossyCarpet { private static final BooleanProperty BASE = MossyCarpetBlock.BASE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMovingPiston.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMovingPiston.java index 6d5da6e40e..eb2b5623f5 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMovingPiston.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMovingPiston.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.TechnicalPiston; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMovingPiston extends CraftBlockData implements TechnicalPiston { private static final EnumProperty FACING = MovingPistonBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMultiface.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMultiface.java index 73070fd11a..b39fe8c665 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMultiface.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMultiface.java @@ -15,17 +15,17 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.ResinClump; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMultiface extends CraftBlockData implements ResinClump { private static final BooleanProperty WATERLOGGED = MultifaceBlock.WATERLOGGED; private static final Map PROPERTY_BY_DIRECTION = Map.of( BlockFace.DOWN, BlockStateProperties.DOWN, - BlockFace.UP, BlockStateProperties.UP, + BlockFace.EAST, BlockStateProperties.EAST, BlockFace.NORTH, BlockStateProperties.NORTH, BlockFace.SOUTH, BlockStateProperties.SOUTH, - BlockFace.WEST, BlockStateProperties.WEST, - BlockFace.EAST, BlockStateProperties.EAST + BlockFace.UP, BlockStateProperties.UP, + BlockFace.WEST, BlockStateProperties.WEST ); public CraftMultiface(BlockState state) { diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMycelium.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMycelium.java index d05536eb51..469f42459d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMycelium.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftMycelium.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Snowable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftMycelium extends CraftBlockData implements Snowable { private static final BooleanProperty SNOWY = MyceliumBlock.SNOWY; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherPortal.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherPortal.java index 9c1887d2db..2eca5e1983 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherPortal.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherPortal.java @@ -11,7 +11,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.Orientable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftNetherPortal extends CraftBlockData implements Orientable { private static final EnumProperty AXIS = NetherPortalBlock.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherWart.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherWart.java index 46c53c871f..820923b800 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherWart.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNetherWart.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftNetherWart extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = NetherWartBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNoteBlock.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNoteBlock.java index 42397ac3fb..843599dde2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNoteBlock.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftNoteBlock.java @@ -12,7 +12,7 @@ import org.bukkit.Note; import org.bukkit.block.data.type.NoteBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftNoteBlock extends CraftBlockData implements NoteBlock { private static final EnumProperty INSTRUMENT = net.minecraft.world.level.block.NoteBlock.INSTRUMENT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftObserver.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftObserver.java index 65a9cddbfa..2b9676a9b1 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftObserver.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftObserver.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Observer; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftObserver extends CraftBlockData implements Observer { private static final EnumProperty FACING = ObserverBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPiglinWallSkull.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPiglinWallSkull.java index d801e81f65..9f4b928e1e 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPiglinWallSkull.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPiglinWallSkull.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallSkull; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPiglinWallSkull extends CraftBlockData implements WallSkull { private static final EnumProperty FACING = PiglinWallSkullBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonBase.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonBase.java index ac3f52745f..f610caf249 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonBase.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonBase.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Piston; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPistonBase extends CraftBlockData implements Piston { private static final BooleanProperty EXTENDED = PistonBaseBlock.EXTENDED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonHead.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonHead.java index c6a91e8f18..4be494cb7a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonHead.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPistonHead.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.PistonHead; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPistonHead extends CraftBlockData implements PistonHead { private static final EnumProperty FACING = PistonHeadBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPitcherCrop.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPitcherCrop.java index 644ba700f0..6e3dde21ad 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPitcherCrop.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPitcherCrop.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.PitcherCrop; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPitcherCrop extends CraftBlockData implements PitcherCrop { private static final IntegerProperty AGE = PitcherCropBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerHead.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerHead.java index 5c24036358..1c3bacde69 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerHead.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerHead.java @@ -12,7 +12,7 @@ import org.bukkit.block.data.type.Skull; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPlayerHead extends CraftBlockData implements Skull { private static final BooleanProperty POWERED = PlayerHeadBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerWallHead.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerWallHead.java index 7511a2a4be..8fe4b4b4b1 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerWallHead.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPlayerWallHead.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallSkull; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPlayerWallHead extends CraftBlockData implements WallSkull { private static final EnumProperty FACING = PlayerWallHeadBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPointedDripstone.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPointedDripstone.java index 15e157cab7..f929d8afda 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPointedDripstone.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPointedDripstone.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.PointedDripstone; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPointedDripstone extends CraftBlockData implements PointedDripstone { private static final EnumProperty THICKNESS = PointedDripstoneBlock.THICKNESS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPotato.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPotato.java index 8d7cdbe6bb..c39ac771e0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPotato.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPotato.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPotato extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = PotatoBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPoweredRail.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPoweredRail.java index 709020b70b..8b982a0556 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPoweredRail.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPoweredRail.java @@ -11,7 +11,7 @@ import net.minecraft.world.level.block.state.properties.RailShape; import org.bukkit.block.data.type.RedstoneRail; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPoweredRail extends CraftBlockData implements RedstoneRail { private static final BooleanProperty POWERED = PoweredRailBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPressurePlate.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPressurePlate.java index 75121f1f5e..79159ba1b8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPressurePlate.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftPressurePlate.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Powerable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftPressurePlate extends CraftBlockData implements Powerable { private static final BooleanProperty POWERED = PressurePlateBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRail.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRail.java index b511c458d4..f89db9c673 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRail.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRail.java @@ -11,7 +11,7 @@ import net.minecraft.world.level.block.state.properties.RailShape; import org.bukkit.block.data.Rail; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRail extends CraftBlockData implements Rail { private static final EnumProperty SHAPE = RailBlock.SHAPE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneOre.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneOre.java index 848755668c..3461599215 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneOre.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneOre.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Lightable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRedStoneOre extends CraftBlockData implements Lightable { private static final BooleanProperty LIT = RedStoneOreBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneWire.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneWire.java index e807adf199..e0608e564b 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneWire.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedStoneWire.java @@ -16,7 +16,7 @@ import org.bukkit.block.data.type.RedstoneWire; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRedStoneWire extends CraftBlockData implements RedstoneWire { private static final IntegerProperty POWER = RedStoneWireBlock.POWER; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneLamp.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneLamp.java index 397d53839b..a0dc9ddf6c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneLamp.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneLamp.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Lightable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRedstoneLamp extends CraftBlockData implements Lightable { private static final BooleanProperty LIT = RedstoneLampBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneTorch.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneTorch.java index 9f5ff81c2a..d16f306986 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneTorch.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneTorch.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Lightable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRedstoneTorch extends CraftBlockData implements Lightable { private static final BooleanProperty LIT = RedstoneTorchBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneWallTorch.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneWallTorch.java index 6e26120552..b9e232a1fa 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneWallTorch.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRedstoneWallTorch.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.RedstoneWallTorch; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRedstoneWallTorch extends CraftBlockData implements RedstoneWallTorch { private static final EnumProperty FACING = RedstoneWallTorchBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRepeater.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRepeater.java index 38fbc4b470..950877887c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRepeater.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRepeater.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Repeater; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRepeater extends CraftBlockData implements Repeater { private static final IntegerProperty DELAY = RepeaterBlock.DELAY; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRespawnAnchor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRespawnAnchor.java index c89fd9b1d6..1c4a2b78b2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRespawnAnchor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRespawnAnchor.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.RespawnAnchor; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRespawnAnchor extends CraftBlockData implements RespawnAnchor { private static final IntegerProperty CHARGE = RespawnAnchorBlock.CHARGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRotatedPillar.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRotatedPillar.java index 36586e124c..e6ef408860 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRotatedPillar.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftRotatedPillar.java @@ -11,7 +11,7 @@ import org.bukkit.Axis; import org.bukkit.block.data.Orientable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftRotatedPillar extends CraftBlockData implements Orientable { private static final EnumProperty AXIS = RotatedPillarBlock.AXIS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSapling.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSapling.java index 9f445b1cce..8993cb2cd9 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSapling.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSapling.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Sapling; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSapling extends CraftBlockData implements Sapling { private static final IntegerProperty STAGE = SaplingBlock.STAGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java index 52508b7481..e5e5d6c41c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftScaffolding.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Scaffolding; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftScaffolding extends CraftBlockData implements Scaffolding { private static final BooleanProperty BOTTOM = ScaffoldingBlock.BOTTOM; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkCatalyst.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkCatalyst.java index ebbf253283..f6aae50683 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkCatalyst.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkCatalyst.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.SculkCatalyst; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSculkCatalyst extends CraftBlockData implements SculkCatalyst { private static final BooleanProperty PULSE = SculkCatalystBlock.PULSE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkSensor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkSensor.java index f9a64ea65f..d89e16d34c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkSensor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkSensor.java @@ -11,7 +11,7 @@ import net.minecraft.world.level.block.state.properties.SculkSensorPhase; import org.bukkit.block.data.type.SculkSensor; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSculkSensor extends CraftBlockData implements SculkSensor { private static final IntegerProperty POWER = SculkSensorBlock.POWER; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkShrieker.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkShrieker.java index f8e10eaf24..1378823ef0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkShrieker.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkShrieker.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.SculkShrieker; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSculkShrieker extends CraftBlockData implements SculkShrieker { private static final BooleanProperty CAN_SUMMON = SculkShriekerBlock.CAN_SUMMON; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkVein.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkVein.java index 2d43475c8c..ed3603efd6 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkVein.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSculkVein.java @@ -15,17 +15,17 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.SculkVein; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSculkVein extends CraftBlockData implements SculkVein { private static final BooleanProperty WATERLOGGED = SculkVeinBlock.WATERLOGGED; private static final Map PROPERTY_BY_DIRECTION = Map.of( BlockFace.DOWN, BlockStateProperties.DOWN, - BlockFace.UP, BlockStateProperties.UP, + BlockFace.EAST, BlockStateProperties.EAST, BlockFace.NORTH, BlockStateProperties.NORTH, BlockFace.SOUTH, BlockStateProperties.SOUTH, - BlockFace.WEST, BlockStateProperties.WEST, - BlockFace.EAST, BlockStateProperties.EAST + BlockFace.UP, BlockStateProperties.UP, + BlockFace.WEST, BlockStateProperties.WEST ); public CraftSculkVein(BlockState state) { diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSeaPickle.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSeaPickle.java index 3c008c76a4..48bcfc88c1 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSeaPickle.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSeaPickle.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.SeaPickle; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSeaPickle extends CraftBlockData implements SeaPickle { private static final IntegerProperty PICKLES = SeaPickleBlock.PICKLES; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftShulkerBox.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftShulkerBox.java index b5836e4d8c..c345e8c865 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftShulkerBox.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftShulkerBox.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftShulkerBox extends CraftBlockData implements Directional { private static final EnumProperty FACING = ShulkerBoxBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSkull.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSkull.java index 5057f8a7d1..adb8d62586 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSkull.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSkull.java @@ -12,7 +12,7 @@ import org.bukkit.block.data.type.Skull; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSkull extends CraftBlockData implements Skull { private static final BooleanProperty POWERED = SkullBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSlab.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSlab.java index 325c8c6986..4832e2f182 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSlab.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSlab.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.state.properties.SlabType; import org.bukkit.block.data.type.Slab; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSlab extends CraftBlockData implements Slab { private static final EnumProperty TYPE = SlabBlock.TYPE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmallDripleaf.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmallDripleaf.java index 551649ab30..a51ca8cfd9 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmallDripleaf.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmallDripleaf.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.SmallDripleaf; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSmallDripleaf extends CraftBlockData implements SmallDripleaf { private static final EnumProperty FACING = SmallDripleafBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java index 82897a7d17..9a1b81a532 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSmoker.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Furnace; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSmoker extends CraftBlockData implements Furnace { private static final EnumProperty FACING = SmokerBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnifferEgg.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnifferEgg.java index d9fbac6b9d..92de83262f 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnifferEgg.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnifferEgg.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Hatchable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSnifferEgg extends CraftBlockData implements Hatchable { private static final IntegerProperty HATCH = SnifferEggBlock.HATCH; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowLayer.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowLayer.java index 6f98633d15..1935c66e11 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowLayer.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowLayer.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Snow; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSnowLayer extends CraftBlockData implements Snow { private static final IntegerProperty LAYERS = SnowLayerBlock.LAYERS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowyDirt.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowyDirt.java index 351882623f..2ba9836c29 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowyDirt.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSnowyDirt.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Snowable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSnowyDirt extends CraftBlockData implements Snowable { private static final BooleanProperty SNOWY = SnowyDirtBlock.SNOWY; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStainedGlassPane.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStainedGlassPane.java index becbc7ab52..6cc6fa74c0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStainedGlassPane.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStainedGlassPane.java @@ -15,7 +15,7 @@ import org.bukkit.block.data.type.GlassPane; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStainedGlassPane extends CraftBlockData implements GlassPane { private static final BooleanProperty WATERLOGGED = StainedGlassPaneBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStair.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStair.java index 456bf31f13..c146946738 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStair.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStair.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Stairs; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStair extends CraftBlockData implements Stairs { private static final EnumProperty FACING = StairBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStandingSign.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStandingSign.java index 849b50aee5..a50bf2293c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStandingSign.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStandingSign.java @@ -12,7 +12,7 @@ import org.bukkit.block.data.type.Sign; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStandingSign extends CraftBlockData implements Sign { private static final IntegerProperty ROTATION = StandingSignBlock.ROTATION; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStem.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStem.java index c84c62a1db..5cfd483ac0 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStem.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStem.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStem extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = StemBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java index 5fd2f6357f..c8c8d477a8 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStonecutter.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStonecutter extends CraftBlockData implements Directional { private static final EnumProperty FACING = StonecutterBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStructureBlock.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStructureBlock.java index b30cfa5823..c953b4580a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStructureBlock.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftStructureBlock.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.StructureMode; import org.bukkit.block.data.type.StructureBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftStructureBlock extends CraftBlockData implements StructureBlock { private static final EnumProperty MODE = net.minecraft.world.level.block.StructureBlock.MODE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSugarCane.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSugarCane.java index df66c18a0d..422a630eae 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSugarCane.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSugarCane.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSugarCane extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = SugarCaneBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java index 6259d5b554..4ba6c8a628 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftSweetBerryBush.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftSweetBerryBush extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = SweetBerryBushBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallFlower.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallFlower.java index 7e3b634c66..9620ca5d6c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallFlower.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallFlower.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.Bisected; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTallFlower extends CraftBlockData implements Bisected { private static final EnumProperty HALF = TallFlowerBlock.HALF; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallSeagrass.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallSeagrass.java index cac15af902..57252978a9 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallSeagrass.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTallSeagrass.java @@ -9,7 +9,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.Bisected; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTallSeagrass extends CraftBlockData implements Bisected { private static final EnumProperty HALF = TallSeagrassBlock.HALF; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTarget.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTarget.java index b2967918f3..0d59bc487d 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTarget.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTarget.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.AnaloguePowerable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTarget extends CraftBlockData implements AnaloguePowerable { private static final IntegerProperty OUTPUT_POWER = BlockStateProperties.POWER; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTestBlock.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTestBlock.java index c388896072..355e16b629 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTestBlock.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTestBlock.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.TestBlockMode; import org.bukkit.block.data.type.TestBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTestBlock extends CraftBlockData implements TestBlock { private static final EnumProperty MODE = net.minecraft.world.level.block.TestBlock.MODE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTintedParticleLeaves.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTintedParticleLeaves.java index 397dcfb762..15a4d42804 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTintedParticleLeaves.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTintedParticleLeaves.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Leaves; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTintedParticleLeaves extends CraftBlockData implements Leaves { private static final IntegerProperty DISTANCE = TintedParticleLeavesBlock.DISTANCE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTnt.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTnt.java index 525fa7e69c..ba89c1b5cd 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTnt.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTnt.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.TNT; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTnt extends CraftBlockData implements TNT { private static final BooleanProperty UNSTABLE = TntBlock.UNSTABLE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTorchflowerCrop.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTorchflowerCrop.java index 22274f2d84..775cdde4cf 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTorchflowerCrop.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTorchflowerCrop.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTorchflowerCrop extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = TorchflowerCropBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrapDoor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrapDoor.java index 791656ef9e..c5b40aa684 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrapDoor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrapDoor.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.TrapDoor; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTrapDoor extends CraftBlockData implements TrapDoor { private static final EnumProperty FACING = TrapDoorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrappedChest.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrappedChest.java index 0231159734..0ef4da84d1 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrappedChest.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrappedChest.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Chest; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTrappedChest extends CraftBlockData implements Chest { private static final EnumProperty FACING = TrappedChestBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrialSpawner.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrialSpawner.java index 90ca1ce3f0..250bf432ae 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrialSpawner.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTrialSpawner.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.state.properties.EnumProperty; import org.bukkit.block.data.type.TrialSpawner; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTrialSpawner extends CraftBlockData implements TrialSpawner { private static final BooleanProperty OMINOUS = TrialSpawnerBlock.OMINOUS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWire.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWire.java index 855f3324f8..00d212fcf7 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWire.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWire.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Tripwire; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTripWire extends CraftBlockData implements Tripwire { private static final BooleanProperty ATTACHED = TripWireBlock.ATTACHED; @@ -23,10 +23,10 @@ public class CraftTripWire extends CraftBlockData implements Tripwire { private static final BooleanProperty POWERED = TripWireBlock.POWERED; private static final Map PROPERTY_BY_DIRECTION = Map.of( - BlockFace.WEST, TripWireBlock.WEST, BlockFace.EAST, TripWireBlock.EAST, BlockFace.NORTH, TripWireBlock.NORTH, - BlockFace.SOUTH, TripWireBlock.SOUTH + BlockFace.SOUTH, TripWireBlock.SOUTH, + BlockFace.WEST, TripWireBlock.WEST ); public CraftTripWire(BlockState state) { diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWireHook.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWireHook.java index 069f59fa0b..06882ca55a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWireHook.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTripWireHook.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.TripwireHook; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTripWireHook extends CraftBlockData implements TripwireHook { private static final BooleanProperty ATTACHED = TripWireHookBlock.ATTACHED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTurtleEgg.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTurtleEgg.java index 1448ffdbd4..29bf07b635 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTurtleEgg.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTurtleEgg.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.TurtleEgg; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTurtleEgg extends CraftBlockData implements TurtleEgg { private static final IntegerProperty EGGS = TurtleEggBlock.EGGS; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTwistingVines.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTwistingVines.java index f56ee736b3..3bbad68dec 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTwistingVines.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftTwistingVines.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftTwistingVines extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = TwistingVinesBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftUntintedParticleLeaves.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftUntintedParticleLeaves.java index 1f7204ac3c..4151f126f3 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftUntintedParticleLeaves.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftUntintedParticleLeaves.java @@ -8,7 +8,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.type.Leaves; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftUntintedParticleLeaves extends CraftBlockData implements Leaves { private static final IntegerProperty DISTANCE = UntintedParticleLeavesBlock.DISTANCE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVault.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVault.java index c9ec607618..e2c7fd5723 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVault.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVault.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Vault; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftVault extends CraftBlockData implements Vault { private static final EnumProperty FACING = VaultBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVine.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVine.java index c4a86206a3..4e6dcf183f 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVine.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftVine.java @@ -15,7 +15,7 @@ import org.bukkit.block.data.MultipleFacing; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftVine extends CraftBlockData implements MultipleFacing { private static final Map PROPERTY_BY_DIRECTION = VineBlock.PROPERTY_BY_DIRECTION.entrySet().stream() .collect(Collectors.toMap(entry -> CraftBlock.notchToBlockFace(entry.getKey()), entry -> entry.getValue())); diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWall.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWall.java index d553f03bbe..80bd3e8033 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWall.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWall.java @@ -14,7 +14,7 @@ import org.bukkit.block.data.type.Wall; import org.bukkit.craftbukkit.block.CraftBlock; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWall extends CraftBlockData implements Wall { private static final BooleanProperty UP = WallBlock.UP; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallBanner.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallBanner.java index af32e2e2fc..1f5d7542a3 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallBanner.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallBanner.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWallBanner extends CraftBlockData implements Directional { private static final EnumProperty FACING = WallBannerBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallHangingSign.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallHangingSign.java index 96d666be43..b3367095b2 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallHangingSign.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallHangingSign.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallHangingSign; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWallHangingSign extends CraftBlockData implements WallHangingSign { private static final EnumProperty FACING = WallHangingSignBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSign.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSign.java index 3583a7d91a..46d054b266 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSign.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSign.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallSign; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWallSign extends CraftBlockData implements WallSign { private static final EnumProperty FACING = WallSignBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSkull.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSkull.java index 5852d57bb3..83be91101a 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSkull.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallSkull.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallSkull; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWallSkull extends CraftBlockData implements WallSkull { private static final EnumProperty FACING = WallSkullBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallTorch.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallTorch.java index 3ec8724d15..5eefdea88c 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallTorch.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWallTorch.java @@ -11,7 +11,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.Directional; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWallTorch extends CraftBlockData implements Directional { private static final EnumProperty FACING = WallTorchBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWaterloggedTransparent.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWaterloggedTransparent.java index 7a7187169c..705487de2e 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWaterloggedTransparent.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWaterloggedTransparent.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWaterloggedTransparent extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = WaterloggedTransparentBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperBulb.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperBulb.java index fb67d3fa37..4996a49bb5 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperBulb.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperBulb.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.type.CopperBulb; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperBulb extends CraftBlockData implements CopperBulb { private static final BooleanProperty LIT = WeatheringCopperBulbBlock.LIT; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperDoor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperDoor.java index 460fb7a257..5643bf94a4 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperDoor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperDoor.java @@ -14,7 +14,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Door; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperDoor extends CraftBlockData implements Door { private static final EnumProperty FACING = WeatheringCopperDoorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperGrate.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperGrate.java index 7671dcc3d3..45e408f3fc 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperGrate.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperGrate.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.BooleanProperty; import org.bukkit.block.data.Waterlogged; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperGrate extends CraftBlockData implements Waterlogged { private static final BooleanProperty WATERLOGGED = WeatheringCopperGrateBlock.WATERLOGGED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperSlab.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperSlab.java index f049c773a7..be482779bc 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperSlab.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperSlab.java @@ -10,7 +10,7 @@ import net.minecraft.world.level.block.state.properties.SlabType; import org.bukkit.block.data.type.Slab; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperSlab extends CraftBlockData implements Slab { private static final EnumProperty TYPE = WeatheringCopperSlabBlock.TYPE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperStair.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperStair.java index b9274d9e87..b4b06fac47 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperStair.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperStair.java @@ -13,7 +13,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.Stairs; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperStair extends CraftBlockData implements Stairs { private static final EnumProperty FACING = WeatheringCopperStairBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperTrapDoor.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperTrapDoor.java index ee5af42a87..2fa18eb598 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperTrapDoor.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeatheringCopperTrapDoor.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.TrapDoor; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeatheringCopperTrapDoor extends CraftBlockData implements TrapDoor { private static final EnumProperty FACING = WeatheringCopperTrapDoorBlock.FACING; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeepingVines.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeepingVines.java index 7f6a0c21d2..7c20a6f5af 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeepingVines.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeepingVines.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.Ageable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeepingVines extends CraftBlockData implements Ageable { private static final IntegerProperty AGE = WeepingVinesBlock.AGE; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeightedPressurePlate.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeightedPressurePlate.java index aa614ef862..778560c624 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeightedPressurePlate.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWeightedPressurePlate.java @@ -7,7 +7,7 @@ import net.minecraft.world.level.block.state.properties.IntegerProperty; import org.bukkit.block.data.AnaloguePowerable; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWeightedPressurePlate extends CraftBlockData implements AnaloguePowerable { private static final IntegerProperty POWER = WeightedPressurePlateBlock.POWER; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherSkull.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherSkull.java index 711d97c62a..882053d513 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherSkull.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherSkull.java @@ -12,7 +12,7 @@ import org.bukkit.block.data.type.Skull; import org.bukkit.craftbukkit.block.data.CraftBlockData; import org.bukkit.util.Vector; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWitherSkull extends CraftBlockData implements Skull { private static final BooleanProperty POWERED = WitherSkullBlock.POWERED; diff --git a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherWallSkull.java b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherWallSkull.java index 13d51eaa09..faae729967 100644 --- a/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherWallSkull.java +++ b/paper-server/src/generated/java/org/bukkit/craftbukkit/block/impl/CraftWitherWallSkull.java @@ -12,7 +12,7 @@ import org.bukkit.block.BlockFace; import org.bukkit.block.data.type.WallSkull; import org.bukkit.craftbukkit.block.data.CraftBlockData; -@GeneratedFrom("1.21.5") +@GeneratedFrom("1.21.6-rc1") public class CraftWitherWallSkull extends CraftBlockData implements WallSkull { private static final EnumProperty FACING = WitherWallSkullBlock.FACING; diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java index 9fd2c43d2c..25779c8710 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java @@ -1,17 +1,17 @@ package com.destroystokyo.paper.entity; import com.google.common.base.Preconditions; +import java.util.ArrayList; +import java.util.List; +import javax.annotation.Nonnull; +import javax.annotation.Nullable; +import net.minecraft.world.level.pathfinder.Node; +import net.minecraft.world.level.pathfinder.Path; import org.bukkit.Location; import org.bukkit.craftbukkit.entity.CraftLivingEntity; import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Mob; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; -import net.minecraft.world.level.pathfinder.Node; -import net.minecraft.world.level.pathfinder.Path; -import java.util.ArrayList; -import java.util.List; public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder { @@ -23,7 +23,7 @@ public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinde @Override public Mob getEntity() { - return (Mob) entity.getBukkitEntity(); + return (Mob) this.entity.getBukkitEntity(); } public void setHandle(net.minecraft.world.entity.Mob entity) { diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java index a786d75794..9e32cbb266 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/MobGoalHelper.java @@ -1,189 +1,211 @@ package com.destroystokyo.paper.entity.ai; import com.destroystokyo.paper.entity.RangedEntity; -import com.google.common.collect.BiMap; -import com.google.common.collect.HashBiMap; +import com.google.common.base.CaseFormat; import io.papermc.paper.entity.SchoolableFish; import io.papermc.paper.util.ObfHelper; +import it.unimi.dsi.fastutil.ints.Int2BooleanFunction; import java.lang.reflect.Constructor; +import java.lang.reflect.Modifier; +import java.util.Arrays; +import java.util.Comparator; import java.util.EnumSet; import java.util.HashMap; -import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; +import net.minecraft.Util; import net.minecraft.world.entity.ai.goal.Goal; import net.minecraft.world.entity.monster.RangedAttackMob; +import org.apache.commons.lang3.math.NumberUtils; import org.bukkit.NamespacedKey; import org.bukkit.entity.*; public class MobGoalHelper { - private static final BiMap deobfuscationMap = HashBiMap.create(); - private static final Map, Class> entityClassCache = new HashMap<>(); - private static final Map, Class> bukkitMap = new HashMap<>(); - - static final Set ignored = new HashSet<>(); - - static { - // TODO these kinda should be checked on each release, in case obfuscation changes - deobfuscationMap.put("abstract_skeleton_1", "abstract_skeleton_melee"); - - ignored.add("goal_selector_1"); - ignored.add("goal_selector_2"); - ignored.add("selector_1"); - ignored.add("selector_2"); - ignored.add("wrapped"); - + private static final Map, Class> GENERIC_TYPE_CACHE = new HashMap<>(); + public static final Map, Class> BUKKIT_BRIDGE = Util.make(new LinkedHashMap<>(), map -> { // - // Start generate - MobGoalHelper#bukkitMap - // @GeneratedFrom 1.21.5 - bukkitMap.put(net.minecraft.world.entity.Mob.class, Mob.class); - bukkitMap.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class); - bukkitMap.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class); - bukkitMap.put(net.minecraft.world.entity.animal.Animal.class, Animals.class); - bukkitMap.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class); - bukkitMap.put(net.minecraft.world.entity.animal.Bee.class, Bee.class); - bukkitMap.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cat.class, Cat.class); - bukkitMap.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class); - bukkitMap.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cod.class, Cod.class); - bukkitMap.put(net.minecraft.world.entity.animal.Cow.class, Cow.class); - bukkitMap.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class); - bukkitMap.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class); - bukkitMap.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class); - bukkitMap.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class); - bukkitMap.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class); - bukkitMap.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class); - bukkitMap.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); - bukkitMap.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); - bukkitMap.put(net.minecraft.world.entity.FlyingMob.class, Flying.class); - bukkitMap.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); - bukkitMap.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); - bukkitMap.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class); - bukkitMap.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class); - bukkitMap.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class); - bukkitMap.put(net.minecraft.world.entity.animal.camel.Camel.class, Camel.class); - bukkitMap.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class); - bukkitMap.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class); - bukkitMap.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class); - bukkitMap.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class); - bukkitMap.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class); - bukkitMap.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class); - bukkitMap.put(net.minecraft.world.entity.monster.Monster.class, Monster.class); - bukkitMap.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); - bukkitMap.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class); - bukkitMap.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class); - bukkitMap.put(net.minecraft.world.entity.animal.Panda.class, Panda.class); - bukkitMap.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class); - bukkitMap.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); - bukkitMap.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class); - bukkitMap.put(net.minecraft.world.entity.animal.Pig.class, Pig.class); - bukkitMap.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class); - bukkitMap.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class); - bukkitMap.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class); - bukkitMap.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class); - bukkitMap.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class); - bukkitMap.put(net.minecraft.world.entity.raid.Raider.class, Raider.class); - bukkitMap.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class); - bukkitMap.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class); - bukkitMap.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class); - bukkitMap.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class); - bukkitMap.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class); - bukkitMap.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.Stray.class, Stray.class); - bukkitMap.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class); - bukkitMap.put(net.minecraft.world.entity.monster.Slime.class, Slime.class); - bukkitMap.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class); - bukkitMap.put(net.minecraft.world.entity.monster.Spider.class, Spider.class); - bukkitMap.put(net.minecraft.world.entity.animal.Squid.class, Squid.class); - bukkitMap.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class); - bukkitMap.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class); - bukkitMap.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class); - bukkitMap.put(net.minecraft.world.entity.monster.Vex.class, Vex.class); - bukkitMap.put(net.minecraft.world.entity.npc.Villager.class, Villager.class); - bukkitMap.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class); - bukkitMap.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class); - bukkitMap.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class); - bukkitMap.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class); - bukkitMap.put(net.minecraft.world.entity.monster.Witch.class, Witch.class); - bukkitMap.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class); - bukkitMap.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class); - bukkitMap.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class); - bukkitMap.put(net.minecraft.world.entity.monster.Husk.class, Husk.class); - bukkitMap.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class); - bukkitMap.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class); - bukkitMap.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class); - bukkitMap.put(net.minecraft.world.entity.monster.Strider.class, Strider.class); - bukkitMap.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class); - bukkitMap.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class); - bukkitMap.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class); - bukkitMap.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class); - bukkitMap.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class); - bukkitMap.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class); - bukkitMap.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class); - bukkitMap.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class); - bukkitMap.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class); - bukkitMap.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class); - bukkitMap.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class); - bukkitMap.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class); - bukkitMap.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class); - bukkitMap.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); - bukkitMap.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class); - // End generate - MobGoalHelper#bukkitMap + // Start generate - MobGoalHelper#BUKKIT_BRIDGE + // @GeneratedFrom 1.21.6-rc1 + map.put(net.minecraft.world.entity.Mob.class, Mob.class); + map.put(net.minecraft.world.entity.AgeableMob.class, Ageable.class); + map.put(net.minecraft.world.entity.ambient.AmbientCreature.class, Ambient.class); + map.put(net.minecraft.world.entity.animal.Animal.class, Animals.class); + map.put(net.minecraft.world.entity.ambient.Bat.class, Bat.class); + map.put(net.minecraft.world.entity.animal.Bee.class, Bee.class); + map.put(net.minecraft.world.entity.monster.Blaze.class, Blaze.class); + map.put(net.minecraft.world.entity.animal.Cat.class, Cat.class); + map.put(net.minecraft.world.entity.monster.CaveSpider.class, CaveSpider.class); + map.put(net.minecraft.world.entity.animal.Chicken.class, Chicken.class); + map.put(net.minecraft.world.entity.animal.Cod.class, Cod.class); + map.put(net.minecraft.world.entity.animal.Cow.class, Cow.class); + map.put(net.minecraft.world.entity.PathfinderMob.class, Creature.class); + map.put(net.minecraft.world.entity.monster.Creeper.class, Creeper.class); + map.put(net.minecraft.world.entity.animal.Dolphin.class, Dolphin.class); + map.put(net.minecraft.world.entity.monster.Drowned.class, Drowned.class); + map.put(net.minecraft.world.entity.boss.enderdragon.EnderDragon.class, EnderDragon.class); + map.put(net.minecraft.world.entity.monster.EnderMan.class, Enderman.class); + map.put(net.minecraft.world.entity.monster.Endermite.class, Endermite.class); + map.put(net.minecraft.world.entity.monster.Evoker.class, Evoker.class); + map.put(net.minecraft.world.entity.animal.AbstractFish.class, Fish.class); + map.put(net.minecraft.world.entity.animal.AbstractSchoolingFish.class, SchoolableFish.class); + map.put(net.minecraft.world.entity.animal.Fox.class, Fox.class); + map.put(net.minecraft.world.entity.monster.Ghast.class, Ghast.class); + map.put(net.minecraft.world.entity.monster.Giant.class, Giant.class); + map.put(net.minecraft.world.entity.animal.AbstractGolem.class, Golem.class); + map.put(net.minecraft.world.entity.monster.Guardian.class, Guardian.class); + map.put(net.minecraft.world.entity.monster.ElderGuardian.class, ElderGuardian.class); + map.put(net.minecraft.world.entity.animal.horse.Horse.class, Horse.class); + map.put(net.minecraft.world.entity.animal.horse.AbstractHorse.class, AbstractHorse.class); + map.put(net.minecraft.world.entity.animal.horse.AbstractChestedHorse.class, ChestedHorse.class); + map.put(net.minecraft.world.entity.animal.horse.Donkey.class, Donkey.class); + map.put(net.minecraft.world.entity.animal.horse.Mule.class, Mule.class); + map.put(net.minecraft.world.entity.animal.horse.SkeletonHorse.class, SkeletonHorse.class); + map.put(net.minecraft.world.entity.animal.horse.ZombieHorse.class, ZombieHorse.class); + map.put(net.minecraft.world.entity.animal.camel.Camel.class, Camel.class); + map.put(net.minecraft.world.entity.monster.AbstractIllager.class, Illager.class); + map.put(net.minecraft.world.entity.monster.Illusioner.class, Illusioner.class); + map.put(net.minecraft.world.entity.monster.SpellcasterIllager.class, Spellcaster.class); + map.put(net.minecraft.world.entity.animal.IronGolem.class, IronGolem.class); + map.put(net.minecraft.world.entity.animal.horse.Llama.class, Llama.class); + map.put(net.minecraft.world.entity.animal.horse.TraderLlama.class, TraderLlama.class); + map.put(net.minecraft.world.entity.monster.MagmaCube.class, MagmaCube.class); + map.put(net.minecraft.world.entity.monster.Monster.class, Monster.class); + map.put(net.minecraft.world.entity.monster.PatrollingMonster.class, Raider.class); + map.put(net.minecraft.world.entity.animal.MushroomCow.class, MushroomCow.class); + map.put(net.minecraft.world.entity.animal.Ocelot.class, Ocelot.class); + map.put(net.minecraft.world.entity.animal.Panda.class, Panda.class); + map.put(net.minecraft.world.entity.animal.Parrot.class, Parrot.class); + map.put(net.minecraft.world.entity.animal.ShoulderRidingEntity.class, Parrot.class); + map.put(net.minecraft.world.entity.monster.Phantom.class, Phantom.class); + map.put(net.minecraft.world.entity.animal.Pig.class, Pig.class); + map.put(net.minecraft.world.entity.monster.ZombifiedPiglin.class, PigZombie.class); + map.put(net.minecraft.world.entity.monster.Pillager.class, Pillager.class); + map.put(net.minecraft.world.entity.animal.PolarBear.class, PolarBear.class); + map.put(net.minecraft.world.entity.animal.Pufferfish.class, PufferFish.class); + map.put(net.minecraft.world.entity.animal.Rabbit.class, Rabbit.class); + map.put(net.minecraft.world.entity.raid.Raider.class, Raider.class); + map.put(net.minecraft.world.entity.monster.Ravager.class, Ravager.class); + map.put(net.minecraft.world.entity.animal.Salmon.class, Salmon.class); + map.put(net.minecraft.world.entity.animal.sheep.Sheep.class, Sheep.class); + map.put(net.minecraft.world.entity.monster.Shulker.class, Shulker.class); + map.put(net.minecraft.world.entity.monster.Silverfish.class, Silverfish.class); + map.put(net.minecraft.world.entity.monster.Skeleton.class, Skeleton.class); + map.put(net.minecraft.world.entity.monster.AbstractSkeleton.class, AbstractSkeleton.class); + map.put(net.minecraft.world.entity.monster.Stray.class, Stray.class); + map.put(net.minecraft.world.entity.monster.WitherSkeleton.class, WitherSkeleton.class); + map.put(net.minecraft.world.entity.monster.Slime.class, Slime.class); + map.put(net.minecraft.world.entity.animal.SnowGolem.class, Snowman.class); + map.put(net.minecraft.world.entity.monster.Spider.class, Spider.class); + map.put(net.minecraft.world.entity.animal.Squid.class, Squid.class); + map.put(net.minecraft.world.entity.TamableAnimal.class, Tameable.class); + map.put(net.minecraft.world.entity.animal.TropicalFish.class, TropicalFish.class); + map.put(net.minecraft.world.entity.animal.Turtle.class, Turtle.class); + map.put(net.minecraft.world.entity.monster.Vex.class, Vex.class); + map.put(net.minecraft.world.entity.npc.Villager.class, Villager.class); + map.put(net.minecraft.world.entity.npc.AbstractVillager.class, AbstractVillager.class); + map.put(net.minecraft.world.entity.npc.WanderingTrader.class, WanderingTrader.class); + map.put(net.minecraft.world.entity.monster.Vindicator.class, Vindicator.class); + map.put(net.minecraft.world.entity.animal.WaterAnimal.class, WaterMob.class); + map.put(net.minecraft.world.entity.monster.Witch.class, Witch.class); + map.put(net.minecraft.world.entity.boss.wither.WitherBoss.class, Wither.class); + map.put(net.minecraft.world.entity.animal.wolf.Wolf.class, Wolf.class); + map.put(net.minecraft.world.entity.monster.Zombie.class, Zombie.class); + map.put(net.minecraft.world.entity.monster.Husk.class, Husk.class); + map.put(net.minecraft.world.entity.monster.ZombieVillager.class, ZombieVillager.class); + map.put(net.minecraft.world.entity.monster.hoglin.Hoglin.class, Hoglin.class); + map.put(net.minecraft.world.entity.monster.piglin.Piglin.class, Piglin.class); + map.put(net.minecraft.world.entity.monster.piglin.AbstractPiglin.class, PiglinAbstract.class); + map.put(net.minecraft.world.entity.monster.piglin.PiglinBrute.class, PiglinBrute.class); + map.put(net.minecraft.world.entity.monster.Strider.class, Strider.class); + map.put(net.minecraft.world.entity.monster.Zoglin.class, Zoglin.class); + map.put(net.minecraft.world.entity.GlowSquid.class, GlowSquid.class); + map.put(net.minecraft.world.entity.animal.axolotl.Axolotl.class, Axolotl.class); + map.put(net.minecraft.world.entity.animal.goat.Goat.class, Goat.class); + map.put(net.minecraft.world.entity.animal.frog.Frog.class, Frog.class); + map.put(net.minecraft.world.entity.animal.frog.Tadpole.class, Tadpole.class); + map.put(net.minecraft.world.entity.monster.warden.Warden.class, Warden.class); + map.put(net.minecraft.world.entity.animal.allay.Allay.class, Allay.class); + map.put(net.minecraft.world.entity.animal.sniffer.Sniffer.class, Sniffer.class); + map.put(net.minecraft.world.entity.monster.breeze.Breeze.class, Breeze.class); + map.put(net.minecraft.world.entity.animal.armadillo.Armadillo.class, Armadillo.class); + map.put(net.minecraft.world.entity.monster.Bogged.class, Bogged.class); + map.put(net.minecraft.world.entity.monster.creaking.Creaking.class, Creaking.class); + map.put(net.minecraft.world.entity.animal.AgeableWaterCreature.class, Squid.class); + map.put(net.minecraft.world.entity.animal.AbstractCow.class, AbstractCow.class); + map.put(net.minecraft.world.entity.animal.HappyGhast.class, HappyGhast.class); + // End generate - MobGoalHelper#BUKKIT_BRIDGE // - } + }); + + // TODO these kinda should be checked on each release, in case nested classes changes + private static final Map NESTED_CLASS_NAMES = Util.make(new HashMap<>(), map -> { + map.put("AbstractSkeleton$1", "AbstractSkeletonMelee"); + + // remove duplicate + map.put("TraderLlama$TraderLlamaDefendWanderingTraderGoal", "TraderLlamaDefendWanderingTraderGoal"); + map.put("AbstractIllager$RaiderOpenDoorGoal", "RaiderOpenDoorGoal"); + + // weird enderman case + map.put("EnderMan.EndermanFreezeWhenLookedAt", "EndermanFreezeWhenLookedAt"); + map.put("EnderMan.EndermanLeaveBlockGoal", "EndermanLeaveBlockGoal"); + map.put("EnderMan.EndermanTakeBlockGoal", "EndermanTakeBlockGoal"); + map.put("EnderMan.EndermanLookForPlayerGoal", "EndermanLookForPlayerGoal"); + }); + + private static final Set> NO_SPECIFIER = Set.of( + Mob.class, + Creature.class, + Animals.class, + RangedEntity.class, + Tameable.class, + Monster.class, + PufferFish.class // weird case + ); + + private static String getPathName(Class type, Class holderClass, String name) { + String pathName = name.substring(name.lastIndexOf('.') + 1); + boolean needRename = false; - public static String getUsableName(Class clazz) { - String name = io.papermc.paper.util.MappingEnvironment.reobf() ? ObfHelper.INSTANCE.deobfClassName(clazz.getName()) : clazz.getName(); - name = name.substring(name.lastIndexOf(".") + 1); - boolean flag = false; // inner classes - if (name.contains("$")) { - String cut = name.substring(name.indexOf("$") + 1); - if (cut.length() <= 2) { - name = name.replace("Entity", ""); - name = name.replace("$", "_"); - flag = true; - } else { - // mapped, wooo - name = cut; + int firstInnerDelimiter = pathName.indexOf('$'); + if (firstInnerDelimiter != -1) { + String innerClassNames = pathName.substring(firstInnerDelimiter + 1); + for (String innerClassName : innerClassNames.split("\\$")) { + if (NumberUtils.isDigits(innerClassName)) { + needRename = true; + break; + } + } + if (!needRename && !NESTED_CLASS_NAMES.containsKey(pathName)) { + pathName = innerClassNames; } } - name = name.replace("TargetGoal", ""); - name = name.replace("Goal", ""); - StringBuilder sb = new StringBuilder(); - for (char c : name.toCharArray()) { - if (c >= 'A' && c <= 'Z') { - sb.append("_"); - sb.append(Character.toLowerCase(c)); - } else { - sb.append(c); + + if (!NESTED_CLASS_NAMES.containsKey(pathName)) { + if (needRename) { + throw new IllegalStateException("need to map " + name + " (" + pathName + ")"); } - } - name = sb.toString(); - name = name.replaceFirst("_", ""); - - if (flag && !deobfuscationMap.containsKey(name.toLowerCase(java.util.Locale.ROOT)) && !ignored.contains(name)) { - System.out.println("need to map " + clazz.getName() + " (" + name.toLowerCase(java.util.Locale.ROOT) + ")"); + String prefix = null; + if (!NO_SPECIFIER.contains(type)) { + prefix = type.getSimpleName(); + } else if (!net.minecraft.world.entity.Mob.class.isAssignableFrom(holderClass)) { + prefix = holderClass.getSimpleName(); + } + if (prefix != null && !pathName.startsWith(prefix)) { + pathName = prefix + pathName; + } + } else { + pathName = NESTED_CLASS_NAMES.get(pathName); } - // did we rename this key? - return deobfuscationMap.getOrDefault(name, name); + pathName = pathName.replace("TargetGoal", ""); // replace last? reverse search? + pathName = pathName.replace("Goal", ""); + pathName = pathName.replace("Abstract", ""); + pathName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, pathName); + + return pathName; } public static EnumSet vanillaToPaper(Goal goal) { @@ -197,20 +219,13 @@ public class MobGoalHelper { } public static GoalType vanillaToPaper(Goal.Flag type) { - switch (type) { - case MOVE: - return GoalType.MOVE; - case LOOK: - return GoalType.LOOK; - case JUMP: - return GoalType.JUMP; - case UNKNOWN_BEHAVIOR: - return GoalType.UNKNOWN_BEHAVIOR; - case TARGET: - return GoalType.TARGET; - default: - throw new IllegalArgumentException("Unknown vanilla mob goal type " + type.name()); - } + return switch (type) { + case MOVE -> GoalType.MOVE; + case LOOK -> GoalType.LOOK; + case JUMP -> GoalType.JUMP; + case UNKNOWN_BEHAVIOR -> GoalType.UNKNOWN_BEHAVIOR; + case TARGET -> GoalType.TARGET; + }; } public static EnumSet paperToVanilla(EnumSet types) { @@ -222,41 +237,57 @@ public class MobGoalHelper { } public static Goal.Flag paperToVanilla(GoalType type) { - switch (type) { - case MOVE: - return Goal.Flag.MOVE; - case LOOK: - return Goal.Flag.LOOK; - case JUMP: - return Goal.Flag.JUMP; - case UNKNOWN_BEHAVIOR: - return Goal.Flag.UNKNOWN_BEHAVIOR; - case TARGET: - return Goal.Flag.TARGET; - default: - throw new IllegalArgumentException("Unknown paper mob goal type " + type.name()); - } + return switch (type) { + case MOVE -> Goal.Flag.MOVE; + case LOOK -> Goal.Flag.LOOK; + case JUMP -> Goal.Flag.JUMP; + case UNKNOWN_BEHAVIOR -> Goal.Flag.UNKNOWN_BEHAVIOR; + case TARGET -> Goal.Flag.TARGET; + }; } public static GoalKey getKey(Class goalClass) { - String name = getUsableName(goalClass); - if (ignored.contains(name)) { - //noinspection unchecked - return (GoalKey) GoalKey.of(Mob.class, NamespacedKey.minecraft(name)); + Class type = getGenericType(goalClass); + + String name = goalClass.getName(); + if (io.papermc.paper.util.MappingEnvironment.reobf()) { + name = ObfHelper.INSTANCE.deobfClassName(name); } - return GoalKey.of(getEntity(goalClass), NamespacedKey.minecraft(name)); + + Class holderClass = getTopLevelClass(goalClass); + name = getPathName(type, holderClass, name); + return GoalKey.of(type, NamespacedKey.minecraft(name)); } - public static Class getEntity(Class goalClass) { + private static final Int2BooleanFunction[] VISIBILITY_SEARCH_STEP = { + Modifier::isPublic, + Modifier::isProtected, + mod -> (mod & 0b111) == 0, // package-private + Modifier::isPrivate, + }; + + private static final Comparator> VISIBILITY_ORDER = Comparator.comparingInt(constructor -> { + int mod = constructor.getModifiers(); + for (int i = 0; i < VISIBILITY_SEARCH_STEP.length; i++) { + Int2BooleanFunction visibility = VISIBILITY_SEARCH_STEP[i]; + if (visibility.test(mod)) { + return i; + } + } + throw new UnsupportedOperationException("Unknown visibility: " + mod); + }); + + private static Class getGenericType(Class goalClass) { //noinspection unchecked - return (Class) entityClassCache.computeIfAbsent(goalClass, key -> { - for (Constructor ctor : key.getDeclaredConstructors()) { - for (int i = 0; i < ctor.getParameterCount(); i++) { - Class param = ctor.getParameterTypes()[i]; - if (net.minecraft.world.entity.Mob.class.isAssignableFrom(param)) { + return (Class) GENERIC_TYPE_CACHE.computeIfAbsent(goalClass, key -> { + Constructor[] constructors = key.getDeclaredConstructors(); + Arrays.sort(constructors, VISIBILITY_ORDER); + for (Constructor constructor : constructors) { + for (Class paramType : constructor.getParameterTypes()) { + if (net.minecraft.world.entity.Mob.class.isAssignableFrom(paramType)) { //noinspection unchecked - return toBukkitClass((Class) param); - } else if (RangedAttackMob.class.isAssignableFrom(param)) { + return toBukkitClass((Class) paramType); + } else if (RangedAttackMob.class.isAssignableFrom(paramType)) { return RangedEntity.class; } } @@ -265,10 +296,24 @@ public class MobGoalHelper { }); } - public static Class toBukkitClass(Class nmsClass) { - Class bukkitClass = bukkitMap.get(nmsClass); + private static Class getTopLevelClass(Class clazz) { + Class topLevelClass = clazz; + Class upperClass = clazz; + + while(true) { + upperClass = upperClass.getEnclosingClass(); + if (upperClass == null) { + return topLevelClass; + } + + topLevelClass = upperClass; + } + } + + public static Class toBukkitClass(Class internalClass) { + Class bukkitClass = BUKKIT_BRIDGE.get(internalClass); if (bukkitClass == null) { - throw new RuntimeException("Can't figure out applicable bukkit entity for nms entity " + nmsClass); // maybe just return Mob? + throw new RuntimeException("Can't figure out applicable bukkit entity for internal entity " + internalClass); // maybe just return Mob? } return bukkitClass; } diff --git a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperGoal.java b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperGoal.java index 74d172166b..c57612f097 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperGoal.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/entity/ai/PaperGoal.java @@ -21,41 +21,45 @@ public class PaperGoal implements com.destroystokyo.paper.entity. } public Goal getHandle() { - return handle; + return this.handle; } @Override public boolean shouldActivate() { - return handle.canUse(); + return this.handle.canUse(); } @Override public boolean shouldStayActive() { - return handle.canContinueToUse(); + return this.handle.canContinueToUse(); } @Override public void start() { - handle.start(); + this.handle.start(); } @Override public void stop() { - handle.stop(); + this.handle.stop(); } @Override public void tick() { - handle.tick(); + this.handle.tick(); } @Override public GoalKey getKey() { - return key; + return this.key; } @Override public EnumSet getTypes() { - return types; + return this.types; + } + + public String toString() { + return this.key.toString(); } } diff --git a/paper-server/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java b/paper-server/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java index ee21a40f72..901a538fde 100644 --- a/paper-server/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java +++ b/paper-server/src/main/java/com/destroystokyo/paper/loottable/PaperLootableInventoryData.java @@ -1,5 +1,7 @@ package com.destroystokyo.paper.loottable; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import io.papermc.paper.configuration.WorldConfiguration; import io.papermc.paper.configuration.type.DurationOrDisabled; import java.util.HashMap; @@ -14,6 +16,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.world.RandomizableContainer; import net.minecraft.world.entity.vehicle.ContainerEntity; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import org.bukkit.entity.Player; import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.Nullable; @@ -164,53 +168,38 @@ public class PaperLootableInventoryData { private static final String NUM_REFILLS = "numRefills"; private static final String LOOTED_PLAYERS = "lootedPlayers"; - public void loadNbt(final CompoundTag base) { - final Optional compOpt = base.getCompound(ROOT); - if (compOpt.isEmpty()) { - return; - } - CompoundTag comp = compOpt.get(); - this.lastFill = comp.getLongOr(LAST_FILL, -1); - this.nextRefill = comp.getLongOr(NEXT_REFILL, -1); - this.numRefills = comp.getIntOr(NUM_REFILLS, 0); - final ListTag list = comp.getListOrEmpty(LOOTED_PLAYERS); - final int size = list.size(); - if (size > 0) { - this.lootedPlayers = new HashMap<>(list.size()); - } - for (int i = 0; i < size; i++) { - list.getCompound(i).ifPresent(tag -> { - tag.read("UUID", UUIDUtil.CODEC).ifPresent(uuid -> { - this.lootedPlayers.put(uuid, tag.getLongOr("Time", 0)); - }); - }); + public void loadNbt(final ValueInput input) { + final ValueInput data = input.childOrEmpty(ROOT); + this.lastFill = data.getLongOr(LAST_FILL, -1); + this.nextRefill = data.getLongOr(NEXT_REFILL, -1); + this.numRefills = data.getIntOr(NUM_REFILLS, 0); + final ValueInput.TypedInputList list = data.listOrEmpty(LOOTED_PLAYERS, SerializedLootedPlayerEntry.CODEC); + if (!list.isEmpty()) { + this.lootedPlayers = new HashMap<>(); + list.forEach(serializedLootedPlayerEntry -> lootedPlayers.put(serializedLootedPlayerEntry.uuid, serializedLootedPlayerEntry.time)); } } - public void saveNbt(final CompoundTag base) { - final CompoundTag comp = new CompoundTag(); + public void saveNbt(final ValueOutput output) { + final ValueOutput data = output.child(ROOT); if (this.nextRefill != -1) { - comp.putLong(NEXT_REFILL, this.nextRefill); + data.putLong(NEXT_REFILL, this.nextRefill); } if (this.lastFill != -1) { - comp.putLong(LAST_FILL, this.lastFill); + data.putLong(LAST_FILL, this.lastFill); } if (this.numRefills != 0) { - comp.putInt(NUM_REFILLS, this.numRefills); + data.putInt(NUM_REFILLS, this.numRefills); } if (this.lootedPlayers != null && !this.lootedPlayers.isEmpty()) { - final ListTag list = new ListTag(); + final ValueOutput.TypedOutputList list = data.list(LOOTED_PLAYERS, SerializedLootedPlayerEntry.CODEC); for (final Map.Entry entry : this.lootedPlayers.entrySet()) { - final CompoundTag cmp = new CompoundTag(); - cmp.store("UUID", UUIDUtil.CODEC, entry.getKey()); - cmp.putLong("Time", entry.getValue()); - list.add(cmp); + list.add(new SerializedLootedPlayerEntry(entry.getKey(), entry.getValue())); } - comp.put(LOOTED_PLAYERS, list); } - if (!comp.isEmpty()) { - base.put(ROOT, comp); + if (data.isEmpty()) { + output.discard(ROOT); } } @@ -242,4 +231,14 @@ public class PaperLootableInventoryData { @Nullable Long getLastLooted(final UUID player) { return this.lootedPlayers != null ? this.lootedPlayers.get(player) : null; } + + record SerializedLootedPlayerEntry(UUID uuid, long time) { + public static final Codec CODEC = RecordCodecBuilder.create( + instance -> instance.group( + UUIDUtil.CODEC.fieldOf("UUID").forGetter(SerializedLootedPlayerEntry::uuid), + Codec.LONG.optionalFieldOf("Time", 0L).forGetter(SerializedLootedPlayerEntry::time) + ) + .apply(instance, SerializedLootedPlayerEntry::new) + ); + } } diff --git a/paper-server/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java b/paper-server/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java index 790bad0494..74ffdc823e 100644 --- a/paper-server/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/ServerBuildInfoImpl.java @@ -45,8 +45,8 @@ public record ServerBuildInfoImpl( .orElse(BRAND_PAPER_ID), getManifestAttribute(manifest, ATTRIBUTE_BRAND_NAME) .orElse(BRAND_PAPER_NAME), - SharedConstants.getCurrentVersion().getId(), - SharedConstants.getCurrentVersion().getName(), + SharedConstants.getCurrentVersion().id(), + SharedConstants.getCurrentVersion().name(), getManifestAttribute(manifest, ATTRIBUTE_BUILD_NUMBER) .map(Integer::parseInt) .map(OptionalInt::of) diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java index 90a604cfc2..91292cfcda 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/APICommandMeta.java @@ -10,10 +10,10 @@ import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; @NullMarked -public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List aliases, @Nullable String helpCommandNamespace, boolean serverSideOnly) { +public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String description, List aliases, @Nullable String helpCommandNamespace) { public APICommandMeta(final @Nullable PluginMeta pluginMeta, final @Nullable String description) { - this(pluginMeta, description, Collections.emptyList(), null, false); + this(pluginMeta, description, Collections.emptyList(), null); } public APICommandMeta { @@ -26,6 +26,6 @@ public record APICommandMeta(@Nullable PluginMeta pluginMeta, @Nullable String d } public APICommandMeta withAliases(List registeredAliases) { - return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace, this.serverSideOnly); + return new APICommandMeta(this.pluginMeta, this.description, List.copyOf(registeredAliases), this.helpCommandNamespace); } } diff --git a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java index 84fab94f38..af480008ad 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java +++ b/paper-server/src/main/java/io/papermc/paper/command/brigadier/PaperCommands.java @@ -95,7 +95,7 @@ public class PaperCommands implements Commands, PaperRegistrar registerWithFlagsInternal(final @Nullable PluginMeta pluginMeta, final String namespace, final @Nullable String helpNamespaceOverride, final LiteralCommandNode node, final @Nullable String description, final Collection aliases, final Set flags) { - final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride, flags.contains(CommandRegistrationFlag.SERVER_ONLY)); + final APICommandMeta meta = new APICommandMeta(pluginMeta, description, List.of(), helpNamespaceOverride); final String literal = node.getLiteral(); final LiteralCommandNode pluginLiteral = PaperBrigadier.copyLiteral(namespace + ":" + literal, node); diff --git a/paper-server/src/main/java/io/papermc/paper/command/subcommands/MobcapsCommand.java b/paper-server/src/main/java/io/papermc/paper/command/subcommands/MobcapsCommand.java index d3b39d88a7..950e709a7b 100644 --- a/paper-server/src/main/java/io/papermc/paper/command/subcommands/MobcapsCommand.java +++ b/paper-server/src/main/java/io/papermc/paper/command/subcommands/MobcapsCommand.java @@ -162,7 +162,7 @@ public final class MobcapsCommand implements PaperSubcommand { } final ServerPlayer serverPlayer = ((CraftPlayer) player).getHandle(); - final ServerLevel level = serverPlayer.serverLevel(); + final ServerLevel level = serverPlayer.level(); if (!level.paperConfig().entities.spawning.perPlayerMobSpawns) { sender.sendMessage(Component.text("Use '/paper mobcaps' for worlds where per-player mob spawning is disabled.", NamedTextColor.RED)); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java index 37d04c589a..1249be9e90 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/DataComponentAdapters.java @@ -184,7 +184,6 @@ public final class DataComponentAdapters { register(DataComponents.RABBIT_VARIANT, nms -> Rabbit.Type.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.Rabbit.Variant.byId(api.ordinal())); register(DataComponents.PIG_VARIANT, CraftPig.CraftVariant::minecraftHolderToBukkit, CraftPig.CraftVariant::bukkitToMinecraftHolder); register(DataComponents.COW_VARIANT, CraftCow.CraftVariant::minecraftHolderToBukkit, CraftCow.CraftVariant::bukkitToMinecraftHolder); - // TODO: We should probably find a better pattern for handling this which retains the EitherHolder, this does kinda suck in terms of exposure, however register(DataComponents.CHICKEN_VARIANT, nms -> CraftChicken.CraftVariant.minecraftHolderToBukkit(nms.unwrap(CraftRegistry.getMinecraftRegistry()).orElseThrow()), api -> new EitherHolder<>(CraftChicken.CraftVariant.bukkitToMinecraftHolder(api))); register(DataComponents.FROG_VARIANT, CraftFrog.CraftVariant::minecraftHolderToBukkit, CraftFrog.CraftVariant::bukkitToMinecraftHolder); register(DataComponents.HORSE_VARIANT, nms -> Horse.Color.values()[nms.ordinal()], api -> net.minecraft.world.entity.animal.horse.Variant.byId(api.ordinal())); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java index c4d48a6dcb..578da88d07 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/ItemComponentTypesBridgesImpl.java @@ -3,13 +3,13 @@ package io.papermc.paper.datacomponent.item; import com.destroystokyo.paper.profile.PlayerProfile; import com.google.common.base.Preconditions; import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; import io.papermc.paper.registry.tag.TagKey; import io.papermc.paper.text.Filtered; import net.kyori.adventure.key.Key; import net.kyori.adventure.util.TriState; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.world.item.component.OminousBottleAmplifier; import org.bukkit.JukeboxSong; @@ -171,11 +171,11 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr } @Override - public UseRemainder useRemainder(final ItemStack itemStack) { - Preconditions.checkArgument(itemStack != null, "Item cannot be null"); - Preconditions.checkArgument(!itemStack.isEmpty(), "Remaining item cannot be empty!"); + public UseRemainder useRemainder(final ItemStack stack) { + Preconditions.checkArgument(stack != null, "Item cannot be null"); + Preconditions.checkArgument(!stack.isEmpty(), "Remaining item cannot be empty!"); return new PaperUseRemainder( - new net.minecraft.world.item.component.UseRemainder(CraftItemStack.asNMSCopy(itemStack)) + new net.minecraft.world.item.component.UseRemainder(CraftItemStack.asNMSCopy(stack)) ); } @@ -203,7 +203,7 @@ public final class ItemComponentTypesBridgesImpl implements ItemComponentTypesBr @Override public Repairable repairable(final RegistryKeySet types) { return new PaperRepairable(new net.minecraft.world.item.enchantment.Repairable( - PaperRegistrySets.convertToNms(Registries.ITEM, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), types) + PaperRegistrySets.convertToNms(Registries.ITEM, Conversions.global().lookup(), types) )); } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java index b4b9df9d85..7d8ae6b3a3 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperBlocksAttacks.java @@ -8,13 +8,13 @@ import io.papermc.paper.datacomponent.item.blocksattacks.PaperDamageReduction; import io.papermc.paper.datacomponent.item.blocksattacks.PaperItemDamageFunction; import io.papermc.paper.registry.PaperRegistries; import io.papermc.paper.registry.tag.TagKey; -import java.util.ArrayList; import java.util.List; import java.util.Optional; +import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.kyori.adventure.key.Key; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.damage.DamageType; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; public record PaperBlocksAttacks( net.minecraft.world.item.component.BlocksAttacks impl @@ -65,7 +65,7 @@ public record PaperBlocksAttacks( private float blockDelaySeconds; private float disableCooldownScale = 1.0F; - private List damageReductions = new ArrayList<>(); + private List damageReductions = new ObjectArrayList<>(); private ItemDamageFunction itemDamage = new PaperItemDamageFunction(net.minecraft.world.item.component.BlocksAttacks.ItemDamageFunction.DEFAULT); private @Nullable TagKey bypassedBy; private @Nullable Key blockSound; @@ -87,11 +87,16 @@ public record PaperBlocksAttacks( @Override public Builder addDamageReduction(final DamageReduction reduction) { - Preconditions.checkArgument(reduction.horizontalBlockingAngle() >= 0, "horizontalBlockingAngle must be non-negative, was %s", reduction.horizontalBlockingAngle()); this.damageReductions.add(reduction); return this; } + @Override + public Builder damageReductions(final List reductions) { + this.damageReductions = new ObjectArrayList<>(reductions); + return this; + } + @Override public Builder itemDamage(final ItemDamageFunction function) { this.itemDamage = function; @@ -105,30 +110,24 @@ public record PaperBlocksAttacks( } @Override - public Builder blockSound(@Nullable final Key sound) { + public Builder blockSound(final @Nullable Key sound) { this.blockSound = sound; return this; } @Override - public Builder disableSound(@Nullable final Key sound) { + public Builder disableSound(final @Nullable Key sound) { this.disableSound = sound; return this; } - @Override - public Builder damageReductions(final List reductions) { - this.damageReductions = new ArrayList<>(reductions); - return this; - } - @Override public BlocksAttacks build() { return new PaperBlocksAttacks(new net.minecraft.world.item.component.BlocksAttacks( this.blockDelaySeconds, this.disableCooldownScale, this.damageReductions.stream().map(damageReduction -> ((PaperDamageReduction) damageReduction).getHandle()).toList(), - ((PaperItemDamageFunction) itemDamage).getHandle(), + ((PaperItemDamageFunction) this.itemDamage).getHandle(), Optional.ofNullable(this.bypassedBy).map(PaperRegistries::toNms), Optional.ofNullable(this.blockSound).map(PaperAdventure::resolveSound), Optional.ofNullable(this.disableSound).map(PaperAdventure::resolveSound) diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java index 0bc2bad71d..a73d9117f8 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperConsumable.java @@ -4,7 +4,7 @@ import com.google.common.base.Preconditions; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect; import io.papermc.paper.datacomponent.item.consumable.ItemUseAnimation; -import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffects; +import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffect; import io.papermc.paper.util.MCUtil; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; @@ -49,7 +49,7 @@ public record PaperConsumable( @Override public @Unmodifiable List consumeEffects() { - return MCUtil.transformUnmodifiable(this.impl.onConsumeEffects(), PaperConsumableEffects::fromNms); + return MCUtil.transformUnmodifiable(this.impl.onConsumeEffects(), PaperConsumableEffect::fromNms); } @Override @@ -98,14 +98,14 @@ public record PaperConsumable( @Override public Builder addEffect(final ConsumeEffect effect) { - this.effects.add(PaperConsumableEffects.toNms(effect)); + this.effects.add(PaperConsumableEffect.toNms(effect)); return this; } @Override public Builder addEffects(final List effects) { for (final ConsumeEffect effect : effects) { - this.effects.add(PaperConsumableEffects.toNms(effect)); + this.effects.add(PaperConsumableEffect.toNms(effect)); } return this; } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java index 798e45d3b3..e643b5db9d 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperDeathProtection.java @@ -1,7 +1,7 @@ package io.papermc.paper.datacomponent.item; import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect; -import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffects; +import io.papermc.paper.datacomponent.item.consumable.PaperConsumableEffect; import io.papermc.paper.util.MCUtil; import java.util.ArrayList; import java.util.List; @@ -19,7 +19,7 @@ public record PaperDeathProtection( @Override public @Unmodifiable List deathEffects() { - return MCUtil.transformUnmodifiable(this.impl.deathEffects(), PaperConsumableEffects::fromNms); + return MCUtil.transformUnmodifiable(this.impl.deathEffects(), PaperConsumableEffect::fromNms); } static final class BuilderImpl implements Builder { @@ -28,14 +28,14 @@ public record PaperDeathProtection( @Override public Builder addEffect(final ConsumeEffect effect) { - this.effects.add(PaperConsumableEffects.toNms(effect)); + this.effects.add(PaperConsumableEffect.toNms(effect)); return this; } @Override public Builder addEffects(final List effects) { for (final ConsumeEffect effect : effects) { - this.effects.add(PaperConsumableEffects.toNms(effect)); + this.effects.add(PaperConsumableEffect.toNms(effect)); } return this; } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java index 2f4d593e9d..3ead3fbaf9 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperEquippable.java @@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; import java.util.Optional; @@ -20,7 +21,7 @@ import org.bukkit.craftbukkit.CraftEquipmentSlot; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.entity.EntityType; import org.bukkit.inventory.EquipmentSlot; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.jspecify.annotations.Nullable; public record PaperEquippable( net.minecraft.world.item.equipment.Equippable impl @@ -82,6 +83,16 @@ public record PaperEquippable( return this.impl.equipOnInteract(); } + @Override + public boolean canBeSheared() { + return this.impl.canBeSheared(); + } + + @Override + public Key shearSound() { + return PaperAdventure.asAdventure(this.impl.shearingSound().value().location()); + } + @Override public Builder toBuilder() { return new BuilderImpl(this.slot()) @@ -92,7 +103,9 @@ public record PaperEquippable( .dispensable(this.dispensable()) .swappable(this.swappable()) .damageOnHurt(this.damageOnHurt()) - .equipOnInteract(this.equipOnInteract()); + .equipOnInteract(this.equipOnInteract()) + .shearSound(this.shearSound()) + .canBeSheared(this.canBeSheared()); } @@ -107,6 +120,8 @@ public record PaperEquippable( private boolean swappable = true; private boolean damageOnHurt = true; private boolean equipOnInteract; + private boolean canBeSheared = false; + private Holder shearSound = BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP); BuilderImpl(final EquipmentSlot equipmentSlot) { this.equipmentSlot = CraftEquipmentSlot.getNMS(equipmentSlot); @@ -137,7 +152,7 @@ public record PaperEquippable( @Override public Builder allowedEntities(final @Nullable RegistryKeySet allowedEntities) { this.allowedEntities = Optional.ofNullable(allowedEntities) - .map((set) -> PaperRegistrySets.convertToNms(Registries.ENTITY_TYPE, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), set)); + .map((set) -> PaperRegistrySets.convertToNms(Registries.ENTITY_TYPE, Conversions.global().lookup(), set)); return this; } @@ -165,6 +180,18 @@ public record PaperEquippable( return this; } + @Override + public Builder canBeSheared(final boolean canBeSheared) { + this.canBeSheared = canBeSheared; + return this; + } + + @Override + public Builder shearSound(final Key shearSound) { + this.shearSound = PaperAdventure.resolveSound(shearSound); + return this; + } + @Override public Equippable build() { return new PaperEquippable( @@ -177,7 +204,9 @@ public record PaperEquippable( this.dispensable, this.swappable, this.damageOnHurt, - this.equipOnInteract + this.equipOnInteract, + this.canBeSheared, + this.shearSound ) ); } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java index ab62515fa8..705f5a4f1d 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAdventurePredicate.java @@ -2,13 +2,13 @@ package io.papermc.paper.datacomponent.item; import io.papermc.paper.block.BlockPredicate; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.util.MCUtil; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; import java.util.Optional; import net.minecraft.advancements.critereon.DataComponentMatchers; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import org.bukkit.craftbukkit.util.Handleable; @@ -25,6 +25,7 @@ public record PaperItemAdventurePredicate( public net.minecraft.world.item.AdventureModePredicate getHandle() { return this.impl; } + @Override public List predicates() { return convert(this.impl); @@ -37,7 +38,7 @@ public record PaperItemAdventurePredicate( @Override public ItemAdventurePredicate.Builder addPredicate(final BlockPredicate predicate) { this.predicates.add(new net.minecraft.advancements.critereon.BlockPredicate(Optional.ofNullable(predicate.blocks()).map( - blocks -> PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), blocks) + blocks -> PaperRegistrySets.convertToNms(Registries.BLOCK, Conversions.global().lookup(), blocks) ), Optional.empty(), Optional.empty(), DataComponentMatchers.ANY)); // TODO DataComponentMatchers return this; } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java index bcefa86747..b3142e9661 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemArmorTrim.java @@ -26,6 +26,7 @@ public record PaperItemArmorTrim( BuilderImpl(final ArmorTrim armorTrim) { this.armorTrim = armorTrim; } + @Override public ItemArmorTrim.Builder armorTrim(final ArmorTrim armorTrim) { this.armorTrim = armorTrim; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java index fdc1b73b22..d9970e0a2b 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemAttributeModifiers.java @@ -1,6 +1,8 @@ package io.papermc.paper.datacomponent.item; import com.google.common.base.Preconditions; +import io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplay; +import io.papermc.paper.datacomponent.item.attribute.PaperAttributeModifierDisplay; import io.papermc.paper.util.MCUtil; import it.unimi.dsi.fastutil.objects.ObjectArrayList; import java.util.List; @@ -21,7 +23,8 @@ public record PaperItemAttributeModifiers( private static List convert(final net.minecraft.world.item.component.ItemAttributeModifiers nmsModifiers) { return MCUtil.transformUnmodifiable(nmsModifiers.modifiers(), nms -> new PaperEntry( CraftAttribute.minecraftHolderToBukkit(nms.attribute()), - CraftAttributeInstance.convert(nms.modifier(), nms.slot()) + CraftAttributeInstance.convert(nms.modifier(), nms.slot()), + PaperAttributeModifierDisplay.fromNms(nms.display()) )); } @@ -35,7 +38,7 @@ public record PaperItemAttributeModifiers( return convert(this.impl); } - public record PaperEntry(Attribute attribute, AttributeModifier modifier) implements ItemAttributeModifiers.Entry { + public record PaperEntry(Attribute attribute, AttributeModifier modifier, AttributeModifierDisplay display) implements ItemAttributeModifiers.Entry { } static final class BuilderImpl implements ItemAttributeModifiers.Builder { @@ -43,12 +46,7 @@ public record PaperItemAttributeModifiers( private final List entries = new ObjectArrayList<>(); @Override - public Builder addModifier(final Attribute attribute, final AttributeModifier modifier) { - return this.addModifier(attribute, modifier, modifier.getSlotGroup()); - } - - @Override - public ItemAttributeModifiers.Builder addModifier(final Attribute attribute, final AttributeModifier modifier, final EquipmentSlotGroup equipmentSlotGroup) { + public ItemAttributeModifiers.Builder addModifier(final Attribute attribute, final AttributeModifier modifier, final EquipmentSlotGroup equipmentSlotGroup, final AttributeModifierDisplay display) { Preconditions.checkArgument( this.entries.stream().noneMatch(e -> e.modifier().id().equals(CraftNamespacedKey.toMinecraft(modifier.getKey())) && e.attribute().is(CraftNamespacedKey.toMinecraft(attribute.getKey())) @@ -60,7 +58,8 @@ public record PaperItemAttributeModifiers( this.entries.add(new net.minecraft.world.item.component.ItemAttributeModifiers.Entry( CraftAttribute.bukkitToMinecraftHolder(attribute), CraftAttributeInstance.convert(modifier), - CraftEquipmentSlot.getNMSGroup(equipmentSlotGroup) + CraftEquipmentSlot.getNMSGroup(equipmentSlotGroup), + PaperAttributeModifierDisplay.toNms(display) )); return this; } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java index 2c4ecc2d5f..fe86d636f6 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemContainerContents.java @@ -48,7 +48,7 @@ public record PaperItemContainerContents( this.items.size() + stacks.size() ); MCUtil.addAndConvert(this.items, stacks, stack -> { - Preconditions.checkArgument(stack != null, "Cannot pass null itemstacks!"); + Preconditions.checkArgument(stack != null, "Cannot pass null item!"); return CraftItemStack.asNMSCopy(stack); }); return this; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java index 31625a0e4a..2bb8166347 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperItemTool.java @@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item; import com.google.common.base.Preconditions; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; import io.papermc.paper.util.MCUtil; @@ -10,12 +11,11 @@ import java.util.Collection; import java.util.List; import java.util.Optional; import net.kyori.adventure.util.TriState; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import org.bukkit.block.BlockType; import org.bukkit.craftbukkit.util.Handleable; -import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.Nullable; public record PaperItemTool( net.minecraft.world.item.component.Tool impl @@ -85,7 +85,7 @@ public record PaperItemTool( @Override public Builder addRule(final Rule rule) { this.rules.add(new net.minecraft.world.item.component.Tool.Rule( - PaperRegistrySets.convertToNms(Registries.BLOCK, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), rule.blocks()), + PaperRegistrySets.convertToNms(Registries.BLOCK, Conversions.global().lookup(), rule.blocks()), Optional.ofNullable(rule.speed()), Optional.ofNullable(rule.correctForDrops().toBoolean()) )); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java index d1ddcc17db..cc74da9489 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperPotionContents.java @@ -14,8 +14,8 @@ import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionType; -import org.checkerframework.checker.nullness.qual.Nullable; import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.Nullable; public record PaperPotionContents( net.minecraft.world.item.alchemy.PotionContents impl diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java index 7583a7efb4..3a5aed0cc8 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperResolvableProfile.java @@ -13,8 +13,10 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; import net.minecraft.util.StringUtil; import org.bukkit.craftbukkit.util.Handleable; -import org.checkerframework.checker.nullness.qual.Nullable; +import org.intellij.lang.annotations.Pattern; +import org.intellij.lang.annotations.Subst; import org.jetbrains.annotations.Unmodifiable; +import org.jspecify.annotations.Nullable; public record PaperResolvableProfile( net.minecraft.world.item.component.ResolvableProfile impl diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperUseCooldown.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperUseCooldown.java index 1aeab920fa..b5e2e73874 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperUseCooldown.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/PaperUseCooldown.java @@ -28,7 +28,6 @@ public record PaperUseCooldown( .orElse(null); } - static final class BuilderImpl implements Builder { private final float seconds; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplayBridgeImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplayBridgeImpl.java new file mode 100644 index 0000000000..7980e0fd9b --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/AttributeModifierDisplayBridgeImpl.java @@ -0,0 +1,25 @@ +package io.papermc.paper.datacomponent.item.attribute; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.ComponentLike; +import net.minecraft.world.item.component.ItemAttributeModifiers; +import org.jspecify.annotations.NullMarked; + +@NullMarked +public class AttributeModifierDisplayBridgeImpl implements AttributeModifierDisplayBridge { + + @Override + public AttributeModifierDisplay.Default reset() { + return new PaperDefaultDisplay(new ItemAttributeModifiers.Display.Default()); + } + + @Override + public AttributeModifierDisplay.Hidden hidden() { + return new PaperHiddenDisplay(new ItemAttributeModifiers.Display.Hidden()); + } + + @Override + public AttributeModifierDisplay.OverrideText override(final ComponentLike text) { + return new PaperOverrideTextDisplay(new ItemAttributeModifiers.Display.OverrideText(PaperAdventure.asVanilla(text.asComponent()))); + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperAttributeModifierDisplay.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperAttributeModifierDisplay.java new file mode 100644 index 0000000000..f4fd301823 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperAttributeModifierDisplay.java @@ -0,0 +1,24 @@ +package io.papermc.paper.datacomponent.item.attribute; + +import net.minecraft.world.item.component.ItemAttributeModifiers; +import org.bukkit.craftbukkit.util.Handleable; + +public interface PaperAttributeModifierDisplay extends Handleable { + + static AttributeModifierDisplay fromNms(ItemAttributeModifiers.Display display) { + return switch (display) { + case ItemAttributeModifiers.Display.Default def -> new PaperDefaultDisplay(def); + case ItemAttributeModifiers.Display.Hidden hidden -> new PaperHiddenDisplay(hidden); + case ItemAttributeModifiers.Display.OverrideText override -> new PaperOverrideTextDisplay(override); + default -> throw new UnsupportedOperationException("Don't know how to convert " + display.getClass()); + }; + } + + static ItemAttributeModifiers.Display toNms(AttributeModifierDisplay display) { + if (display instanceof PaperAttributeModifierDisplay modifierDisplay) { + return modifierDisplay.getHandle(); + } else { + throw new UnsupportedOperationException("Must implement handleable!"); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperDefaultDisplay.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperDefaultDisplay.java new file mode 100644 index 0000000000..c75b9020f7 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperDefaultDisplay.java @@ -0,0 +1,13 @@ +package io.papermc.paper.datacomponent.item.attribute; + +import net.minecraft.world.item.component.ItemAttributeModifiers; + +public record PaperDefaultDisplay( + ItemAttributeModifiers.Display.Default impl +) implements AttributeModifierDisplay.Default, PaperAttributeModifierDisplay { + + @Override + public ItemAttributeModifiers.Display.Default getHandle() { + return this.impl; + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperHiddenDisplay.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperHiddenDisplay.java new file mode 100644 index 0000000000..ba74db6a7c --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperHiddenDisplay.java @@ -0,0 +1,13 @@ +package io.papermc.paper.datacomponent.item.attribute; + +import net.minecraft.world.item.component.ItemAttributeModifiers; + +public record PaperHiddenDisplay( + ItemAttributeModifiers.Display.Hidden impl +) implements AttributeModifierDisplay.Hidden, PaperAttributeModifierDisplay { + + @Override + public ItemAttributeModifiers.Display.Hidden getHandle() { + return this.impl; + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperOverrideTextDisplay.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperOverrideTextDisplay.java new file mode 100644 index 0000000000..41b2fa5e39 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/PaperOverrideTextDisplay.java @@ -0,0 +1,20 @@ +package io.papermc.paper.datacomponent.item.attribute; + +import io.papermc.paper.adventure.PaperAdventure; +import net.kyori.adventure.text.Component; +import net.minecraft.world.item.component.ItemAttributeModifiers; + +public record PaperOverrideTextDisplay( + ItemAttributeModifiers.Display.OverrideText impl +) implements AttributeModifierDisplay.OverrideText, PaperAttributeModifierDisplay { + + @Override + public Component text() { + return PaperAdventure.asAdventure(this.impl.component()); + } + + @Override + public ItemAttributeModifiers.Display.OverrideText getHandle() { + return this.impl; + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/package-info.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/package-info.java new file mode 100644 index 0000000000..52a88bc096 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/attribute/package-info.java @@ -0,0 +1,7 @@ +/** + * Relating to attribute modifier display for components. + */ +@NullMarked +package io.papermc.paper.datacomponent.item.attribute; + +import org.jspecify.annotations.NullMarked; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java index 865563be36..bb8bf4d3ad 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/BlocksAttacksBridgeImpl.java @@ -1,9 +1,7 @@ package io.papermc.paper.datacomponent.item.blocksattacks; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; -@ApiStatus.Internal @NullMarked public class BlocksAttacksBridgeImpl implements BlocksAttacksBridge { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java index 7da287938e..7fae3d05cd 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperDamageReduction.java @@ -2,6 +2,7 @@ package io.papermc.paper.datacomponent.item.blocksattacks; import com.google.common.base.Preconditions; import io.papermc.paper.registry.RegistryKey; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; import net.minecraft.core.HolderSet; @@ -9,7 +10,7 @@ import net.minecraft.core.registries.Registries; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.damage.DamageType; import org.checkerframework.checker.index.qual.Positive; -import org.jetbrains.annotations.Nullable; +import org.jspecify.annotations.Nullable; import java.util.Optional; public record PaperDamageReduction( @@ -44,19 +45,19 @@ public record PaperDamageReduction( static final class BuilderImpl implements Builder { private Optional> type = Optional.empty(); - private float horizontalBlockingAngle = 90f; - private float base = 0; - private float factor = 0; + private float horizontalBlockingAngle = 90.0F; + private float base = 0.0F; + private float factor = 1.0F; @Override public Builder type(final @Nullable RegistryKeySet type) { this.type = Optional.ofNullable(type) - .map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider, set)); + .map((set) -> PaperRegistrySets.convertToNms(Registries.DAMAGE_TYPE, Conversions.global().lookup(), set)); return this; } @Override - public Builder horizontalBlockingAngle(@Positive final float horizontalBlockingAngle) { + public Builder horizontalBlockingAngle(final @Positive float horizontalBlockingAngle) { Preconditions.checkArgument(horizontalBlockingAngle > 0, "horizontalBlockingAngle must be positive and not zero, was %s", horizontalBlockingAngle); this.horizontalBlockingAngle = horizontalBlockingAngle; return this; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java index 515eec1599..e41dd17405 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/blocksattacks/PaperItemDamageFunction.java @@ -1,6 +1,7 @@ package io.papermc.paper.datacomponent.item.blocksattacks; import com.google.common.base.Preconditions; +import net.minecraft.world.item.component.BlocksAttacks; import org.bukkit.craftbukkit.util.Handleable; import org.checkerframework.checker.index.qual.NonNegative; @@ -35,12 +36,12 @@ public record PaperItemDamageFunction( static final class BuilderImpl implements Builder { - private float threshold; - private float base; - private float factor; + private float threshold = BlocksAttacks.ItemDamageFunction.DEFAULT.threshold(); + private float base = BlocksAttacks.ItemDamageFunction.DEFAULT.base(); + private float factor = BlocksAttacks.ItemDamageFunction.DEFAULT.factor(); @Override - public Builder threshold(@NonNegative final float threshold) { + public Builder threshold(final @NonNegative float threshold) { Preconditions.checkArgument(threshold >= 0, "threshold must be non-negative, was %s", threshold); this.threshold = threshold; return this; diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java index eab1883d69..e6d4358f4c 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/ConsumableTypesBridgeImpl.java @@ -3,20 +3,18 @@ package io.papermc.paper.datacomponent.item.consumable; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; import java.util.ArrayList; import java.util.List; import net.kyori.adventure.key.Key; -import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import org.bukkit.craftbukkit.potion.CraftPotionUtil; import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffectType; -import org.jetbrains.annotations.ApiStatus; import org.jspecify.annotations.NullMarked; -@ApiStatus.Internal @NullMarked public class ConsumableTypesBridgeImpl implements ConsumableTypesBridge { @@ -35,7 +33,7 @@ public class ConsumableTypesBridgeImpl implements ConsumableTypesBridge { public ConsumeEffect.RemoveStatusEffects removeStatusEffects(final RegistryKeySet effectTypes) { return new PaperRemoveStatusEffects( new net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect( - PaperRegistrySets.convertToNms(Registries.MOB_EFFECT, BuiltInRegistries.BUILT_IN_CONVERSIONS.lookup(), effectTypes) + PaperRegistrySets.convertToNms(Registries.MOB_EFFECT, Conversions.global().lookup(), effectTypes) ) ); } diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java index 0d2a4ba560..9b81970b53 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperApplyStatusEffects.java @@ -9,7 +9,7 @@ import static io.papermc.paper.util.MCUtil.transformUnmodifiable; public record PaperApplyStatusEffects( ApplyStatusEffectsConsumeEffect impl -) implements ConsumeEffect.ApplyStatusEffects, PaperConsumableEffectImpl { +) implements ConsumeEffect.ApplyStatusEffects, PaperConsumableEffect { @Override public List effects() { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperClearAllStatusEffects.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperClearAllStatusEffects.java index 2afcbbbeb4..554887b232 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperClearAllStatusEffects.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperClearAllStatusEffects.java @@ -1,8 +1,10 @@ package io.papermc.paper.datacomponent.item.consumable; +import net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect; + public record PaperClearAllStatusEffects( net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect impl -) implements ConsumeEffect.ClearAllStatusEffects, PaperConsumableEffectImpl { +) implements ConsumeEffect.ClearAllStatusEffects, PaperConsumableEffect { @Override public net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect getHandle() { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffects.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffect.java similarity index 69% rename from paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffects.java rename to paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffect.java index ff07939ef0..a75e7fd6de 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffects.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffect.java @@ -2,16 +2,15 @@ package io.papermc.paper.datacomponent.item.consumable; import net.minecraft.world.item.consume_effects.ApplyStatusEffectsConsumeEffect; import net.minecraft.world.item.consume_effects.ClearAllStatusEffectsConsumeEffect; +import net.minecraft.world.item.consume_effects.ConsumeEffect; import net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect; import net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect; import net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect; +import org.bukkit.craftbukkit.util.Handleable; -public final class PaperConsumableEffects { +public interface PaperConsumableEffect extends Handleable { - private PaperConsumableEffects() { - } - - public static ConsumeEffect fromNms(net.minecraft.world.item.consume_effects.ConsumeEffect consumable) { + static io.papermc.paper.datacomponent.item.consumable.ConsumeEffect fromNms(net.minecraft.world.item.consume_effects.ConsumeEffect consumable) { return switch (consumable) { case ApplyStatusEffectsConsumeEffect effect -> new PaperApplyStatusEffects(effect); case ClearAllStatusEffectsConsumeEffect effect -> new PaperClearAllStatusEffects(effect); @@ -22,8 +21,8 @@ public final class PaperConsumableEffects { }; } - public static net.minecraft.world.item.consume_effects.ConsumeEffect toNms(ConsumeEffect effect) { - if (effect instanceof PaperConsumableEffectImpl consumableEffect) { + static net.minecraft.world.item.consume_effects.ConsumeEffect toNms(io.papermc.paper.datacomponent.item.consumable.ConsumeEffect effect) { + if (effect instanceof PaperConsumableEffect consumableEffect) { return consumableEffect.getHandle(); } else { throw new UnsupportedOperationException("Must implement handleable!"); diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffectImpl.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffectImpl.java deleted file mode 100644 index 05ede1d3f5..0000000000 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperConsumableEffectImpl.java +++ /dev/null @@ -1,7 +0,0 @@ -package io.papermc.paper.datacomponent.item.consumable; - -import net.minecraft.world.item.consume_effects.ConsumeEffect; -import org.bukkit.craftbukkit.util.Handleable; - -public interface PaperConsumableEffectImpl extends Handleable { -} diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperPlaySound.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperPlaySound.java index 26a8ee292b..552883b544 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperPlaySound.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperPlaySound.java @@ -6,7 +6,7 @@ import net.minecraft.world.item.consume_effects.PlaySoundConsumeEffect; public record PaperPlaySound( PlaySoundConsumeEffect impl -) implements ConsumeEffect.PlaySound, PaperConsumableEffectImpl { +) implements ConsumeEffect.PlaySound, PaperConsumableEffect { @Override public Key sound() { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperRemoveStatusEffects.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperRemoveStatusEffects.java index 20e09c6eba..2188938fe1 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperRemoveStatusEffects.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperRemoveStatusEffects.java @@ -3,11 +3,12 @@ package io.papermc.paper.datacomponent.item.consumable; import io.papermc.paper.registry.RegistryKey; import io.papermc.paper.registry.set.PaperRegistrySets; import io.papermc.paper.registry.set.RegistryKeySet; +import net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect; import org.bukkit.potion.PotionEffectType; public record PaperRemoveStatusEffects( net.minecraft.world.item.consume_effects.RemoveStatusEffectsConsumeEffect impl -) implements ConsumeEffect.RemoveStatusEffects, PaperConsumableEffectImpl { +) implements ConsumeEffect.RemoveStatusEffects, PaperConsumableEffect { @Override public RegistryKeySet removeEffects() { diff --git a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperTeleportRandomly.java b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperTeleportRandomly.java index c21889e998..265001be1c 100644 --- a/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperTeleportRandomly.java +++ b/paper-server/src/main/java/io/papermc/paper/datacomponent/item/consumable/PaperTeleportRandomly.java @@ -1,8 +1,10 @@ package io.papermc.paper.datacomponent.item.consumable; +import net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect; + public record PaperTeleportRandomly( net.minecraft.world.item.consume_effects.TeleportRandomlyConsumeEffect impl -) implements ConsumeEffect.TeleportRandomly, PaperConsumableEffectImpl { +) implements ConsumeEffect.TeleportRandomly, PaperConsumableEffect { @Override public float diameter() { return this.impl.diameter(); diff --git a/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java index bed83c5897..493914c8d1 100644 --- a/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java +++ b/paper-server/src/main/java/io/papermc/paper/entity/activation/ActivationType.java @@ -1,12 +1,13 @@ package io.papermc.paper.entity.activation; import net.minecraft.world.entity.Entity; -import net.minecraft.world.entity.FlyingMob; import net.minecraft.world.entity.PathfinderMob; import net.minecraft.world.entity.ambient.AmbientCreature; import net.minecraft.world.entity.animal.AgeableWaterCreature; import net.minecraft.world.entity.animal.WaterAnimal; import net.minecraft.world.entity.monster.Enemy; +import net.minecraft.world.entity.monster.Ghast; +import net.minecraft.world.entity.monster.Phantom; import net.minecraft.world.entity.npc.Villager; import net.minecraft.world.entity.raid.Raider; import net.minecraft.world.phys.AABB; @@ -33,7 +34,7 @@ public enum ActivationType { return ActivationType.WATER; } else if (entity instanceof Villager) { return ActivationType.VILLAGER; - } else if (entity instanceof FlyingMob && entity instanceof Enemy) { + } else if (entity instanceof Ghast || entity instanceof Phantom) { // TODO: some kind of better distinction here? return ActivationType.FLYING_MONSTER; } else if (entity instanceof Raider) { return ActivationType.RAIDER; diff --git a/paper-server/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java b/paper-server/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java index 3e82ea07ca..792ef37481 100644 --- a/paper-server/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java +++ b/paper-server/src/main/java/io/papermc/paper/plugin/manager/PaperPluginInstanceManager.java @@ -320,7 +320,6 @@ class PaperPluginInstanceManager { } - // TODO: Implement event part in future patch (paper patch move up, this patch is lower) private void handlePluginException(String msg, Throwable ex, Plugin plugin) { Bukkit.getServer().getLogger().log(Level.SEVERE, msg, ex); this.pluginManager.callEvent(new com.destroystokyo.paper.event.server.ServerExceptionEvent(new com.destroystokyo.paper.exception.ServerPluginEnableDisableException(msg, ex, plugin))); diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java index 16b27434f2..a45afdefed 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistries.java @@ -12,8 +12,10 @@ import io.papermc.paper.registry.data.PaperDamageTypeRegistryEntry; import io.papermc.paper.registry.data.PaperEnchantmentRegistryEntry; import io.papermc.paper.registry.data.PaperFrogVariantRegistryEntry; import io.papermc.paper.registry.data.PaperGameEventRegistryEntry; +import io.papermc.paper.registry.data.PaperJukeboxSongRegistryEntry; import io.papermc.paper.registry.data.PaperPaintingVariantRegistryEntry; import io.papermc.paper.registry.data.PaperPigVariantRegistryEntry; +import io.papermc.paper.registry.data.PaperSoundEventRegistryEntry; import io.papermc.paper.registry.data.PaperWolfVariantRegistryEntry; import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntryMeta; @@ -95,7 +97,7 @@ public final class PaperRegistries { static { REGISTRY_ENTRIES = List.of( // Start generate - RegistryDefinitions - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 // built-in start(Registries.GAME_EVENT, RegistryKey.GAME_EVENT).craft(GameEvent.class, CraftGameEvent::new).writable(PaperGameEventRegistryEntry.PaperBuilder::new), start(Registries.STRUCTURE_TYPE, RegistryKey.STRUCTURE_TYPE).craft(StructureType.class, CraftStructureType::new).build(), @@ -108,7 +110,7 @@ public final class PaperRegistries { start(Registries.MENU, RegistryKey.MENU).craft(MenuType.class, CraftMenuType::new).build(), start(Registries.ATTRIBUTE, RegistryKey.ATTRIBUTE).craft(Attribute.class, CraftAttribute::new).serializationUpdater(FieldRename.ATTRIBUTE_RENAME).build(), start(Registries.FLUID, RegistryKey.FLUID).craft(Fluid.class, CraftFluid::new).build(), - start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new, true).build(), + start(Registries.SOUND_EVENT, RegistryKey.SOUND_EVENT).craft(Sound.class, CraftSound::new, true).create(PaperSoundEventRegistryEntry.PaperBuilder::new, RegistryEntryMeta.RegistryModificationApiSupport.NONE), start(Registries.DATA_COMPONENT_TYPE, RegistryKey.DATA_COMPONENT_TYPE).craft(DataComponentTypes.class, PaperDataComponentType::of).build(), // data-driven @@ -120,9 +122,9 @@ public final class PaperRegistries { start(Registries.WOLF_VARIANT, RegistryKey.WOLF_VARIANT).craft(Wolf.Variant.class, CraftWolf.CraftVariant::new).writable(PaperWolfVariantRegistryEntry.PaperBuilder::new).delayed(), start(Registries.WOLF_SOUND_VARIANT, RegistryKey.WOLF_SOUND_VARIANT).craft(Wolf.SoundVariant.class, CraftWolf.CraftSoundVariant::new).build(), start(Registries.ENCHANTMENT, RegistryKey.ENCHANTMENT).craft(Enchantment.class, CraftEnchantment::new).serializationUpdater(FieldRename.ENCHANTMENT_RENAME).writable(PaperEnchantmentRegistryEntry.PaperBuilder::new).delayed(), - start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).build().delayed(), + start(Registries.JUKEBOX_SONG, RegistryKey.JUKEBOX_SONG).craft(JukeboxSong.class, CraftJukeboxSong::new).writable(PaperJukeboxSongRegistryEntry.PaperBuilder::new).delayed(), start(Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN).craft(PatternType.class, CraftPatternType::new, true).writable(PaperBannerPatternRegistryEntry.PaperBuilder::new).delayed(), - start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new, true).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), + start(Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT).craft(Art.class, CraftArt::new).writable(PaperPaintingVariantRegistryEntry.PaperBuilder::new).delayed(), start(Registries.INSTRUMENT, RegistryKey.INSTRUMENT).craft(MusicInstrument.class, CraftMusicInstrument::new, true).build().delayed(), start(Registries.CAT_VARIANT, RegistryKey.CAT_VARIANT).craft(Cat.Type.class, CraftCat.CraftType::new).writable(PaperCatTypeRegistryEntry.PaperBuilder::new).delayed(), start(Registries.FROG_VARIANT, RegistryKey.FROG_VARIANT).craft(Frog.Variant.class, CraftFrog.CraftVariant::new).writable(PaperFrogVariantRegistryEntry.PaperBuilder::new).delayed(), diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java index e96c28cecc..28b4e81375 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryAccess.java @@ -97,12 +97,12 @@ public class PaperRegistryAccess implements RegistryAccess { return registry; } - public void registerReloadableRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry) { - this.registerRegistry(resourceKey, registry, true); + public void registerReloadableRegistry(final net.minecraft.core.Registry registry) { + this.registerRegistry(registry, true); } - public void registerRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry) { - this.registerRegistry(resourceKey, registry, false); + public void registerRegistry(final net.minecraft.core.Registry registry) { + this.registerRegistry(registry, false); } public void lockReferenceHolders(final ResourceKey> resourceKey) { @@ -115,8 +115,8 @@ public class PaperRegistryAccess implements RegistryAccess { } @SuppressWarnings("unchecked") // this method should be called right after any new MappedRegistry instances are created to later be used by the server. - private > void registerRegistry(final ResourceKey> resourceKey, final net.minecraft.core.Registry registry, final boolean replace) { - final RegistryEntry entry = PaperRegistries.getEntry(resourceKey); + private > void registerRegistry(final net.minecraft.core.Registry registry, final boolean replace) { + final RegistryEntry entry = PaperRegistries.getEntry(registry.key()); if (entry == null) { // skip registries that don't have API entries return; } @@ -129,7 +129,7 @@ public class PaperRegistryAccess implements RegistryAccess { // if the registry holder is delayed, and the entry is marked as "delayed", then load the holder with the CraftRegistry instance that wraps the actual nms Registry. ((RegistryHolder.Delayed) registryHolder).loadFrom(delayedEntry, registry); } else { - throw new IllegalArgumentException(resourceKey + " has already been created"); + throw new IllegalArgumentException(registry.key() + " has already been created"); } } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java index e83a6336bb..712b88b423 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryBuilderFactory.java @@ -2,19 +2,28 @@ package io.papermc.paper.registry; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.registry.data.util.Conversions; +import java.util.Optional; import java.util.function.Function; -import net.minecraft.resources.ResourceLocation; +import net.minecraft.core.Registry; +import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.jspecify.annotations.Nullable; public class PaperRegistryBuilderFactory> implements RegistryBuilderFactory { // TODO remove Keyed + private final ResourceKey> registryKey; private final Conversions conversions; private final PaperRegistryBuilder.Filler builderFiller; - private final Function existingValueGetter; + private final Function, Optional> existingValueGetter; private @Nullable B builder; - public PaperRegistryBuilderFactory(final Conversions conversions, final PaperRegistryBuilder.Filler builderFiller, final Function existingValueGetter) { + public PaperRegistryBuilderFactory( + final ResourceKey> registryKey, + final Conversions conversions, + final PaperRegistryBuilder.Filler builderFiller, + final Function, Optional> existingValueGetter + ) { + this.registryKey = registryKey; this.conversions = conversions; this.builderFiller = builderFiller; this.existingValueGetter = existingValueGetter; @@ -42,10 +51,10 @@ public class PaperRegistryBuilderFactory key) { this.validate(); - final M existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(key)); - if (existing == null) { + final Optional existing = this.existingValueGetter.apply(PaperAdventure.asVanilla(this.registryKey, key)); + if (existing.isEmpty()) { throw new IllegalArgumentException("Key " + key + " doesn't exist"); } - return this.builder = this.builderFiller.fill(this.conversions, existing); + return this.builder = this.builderFiller.fill(this.conversions, existing.get()); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java index 540aaa0964..65339315be 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/PaperRegistryListenerManager.java @@ -10,11 +10,12 @@ import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEventType; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.entry.RegistryEntry; import io.papermc.paper.registry.entry.RegistryEntryMeta; +import io.papermc.paper.registry.event.RegistryEntryAddEvent; import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; import io.papermc.paper.registry.event.RegistryEventMap; import io.papermc.paper.registry.event.RegistryEventProvider; -import io.papermc.paper.registry.event.RegistryFreezeEvent; -import io.papermc.paper.registry.event.RegistryFreezeEventImpl; +import io.papermc.paper.registry.event.RegistryComposeEventImpl; +import io.papermc.paper.registry.event.RegistryComposeEvent; import io.papermc.paper.registry.event.type.RegistryEntryAddEventType; import io.papermc.paper.registry.event.type.RegistryEntryAddEventTypeImpl; import io.papermc.paper.registry.event.type.RegistryLifecycleEventType; @@ -37,7 +38,7 @@ public class PaperRegistryListenerManager { public static final PaperRegistryListenerManager INSTANCE = new PaperRegistryListenerManager(); public final RegistryEventMap valueAddEventTypes = new RegistryEventMap("value add"); - public final RegistryEventMap freezeEventTypes = new RegistryEventMap("freeze"); + public final RegistryEventMap composeEventType = new RegistryEventMap("compose"); private PaperRegistryListenerManager() { } @@ -60,7 +61,7 @@ public class PaperRegistryListenerManager { * For {@link Registry#register(Registry, ResourceKey, Object)} */ public M registerWithListeners(final Registry registry, final ResourceKey key, final M nms) { - return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, PaperRegistryListenerManager::registerWithInstance, BuiltInRegistries.BUILT_IN_CONVERSIONS); + return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, PaperRegistryListenerManager::registerWithInstance, BuiltInRegistries.STATIC_ACCESS_CONVERSIONS); } /** @@ -74,7 +75,7 @@ public class PaperRegistryListenerManager { * For {@link Registry#registerForHolder(Registry, ResourceKey, Object)} */ public Holder.Reference registerForHolderWithListeners(final Registry registry, final ResourceKey key, final M nms) { - return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, WritableRegistry::register, BuiltInRegistries.BUILT_IN_CONVERSIONS); + return this.registerWithListeners(registry, key, nms, RegistrationInfo.BUILT_IN, WritableRegistry::register, BuiltInRegistries.STATIC_ACCESS_CONVERSIONS); } public void registerWithListeners( @@ -157,28 +158,28 @@ public class PaperRegistryListenerManager { public > void runFreezeListeners(final ResourceKey> resourceKey, final Conversions conversions) { final RegistryEntry entry = PaperRegistries.getEntry(resourceKey); - if (entry == null || !entry.meta().modificationApiSupport().canAdd() || !this.freezeEventTypes.hasHandlers(entry.apiKey())) { + if (entry == null || !entry.meta().modificationApiSupport().canAdd() || !this.composeEventType.hasHandlers(entry.apiKey())) { return; } final RegistryEntryMeta.Buildable writableEntry = (RegistryEntryMeta.Buildable) entry.meta(); final WritableCraftRegistry writableRegistry = PaperRegistryAccess.instance().getWritableRegistry(entry.apiKey()); - final RegistryFreezeEventImpl event = writableEntry.createFreezeEvent(writableRegistry, conversions); - LifecycleEventRunner.INSTANCE.callEvent(this.freezeEventTypes.getEventType(entry.apiKey()), event); + final RegistryComposeEventImpl event = writableEntry.createPostLoadEvent(writableRegistry, conversions); + LifecycleEventRunner.INSTANCE.callEvent(this.composeEventType.getEventType(entry.apiKey()), event); } public > RegistryEntryAddEventType getRegistryValueAddEventType(final RegistryEventProvider type) { final RegistryEntry entry = PaperRegistries.getEntry(type.registryKey()); if (entry == null || !entry.meta().modificationApiSupport().canModify()) { - throw new IllegalArgumentException(type.registryKey() + " does not support RegistryEntryAddEvent"); + throw new IllegalArgumentException(type.registryKey() + " does not support " + RegistryEntryAddEvent.class.getSimpleName()); } return this.valueAddEventTypes.getOrCreate(type.registryKey(), RegistryEntryAddEventTypeImpl::new); } - public > LifecycleEventType.Prioritizable> getRegistryFreezeEventType(final RegistryEventProvider type) { + public > LifecycleEventType.Prioritizable> getRegistryComposeEventType(final RegistryEventProvider type) { final RegistryEntry entry = PaperRegistries.getEntry(type.registryKey()); if (entry == null || !entry.meta().modificationApiSupport().canAdd()) { - throw new IllegalArgumentException(type.registryKey() + " does not support RegistryFreezeEvent"); + throw new IllegalArgumentException(type.registryKey() + " does not support " + RegistryComposeEvent.class.getSimpleName()); } - return this.freezeEventTypes.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new); + return this.composeEventType.getOrCreate(type.registryKey(), RegistryLifecycleEventType::new); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java index a294ec37b6..9e8672c705 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/WritableCraftRegistry.java @@ -31,7 +31,7 @@ public class WritableCraftRegistry key, final Consumer> value, final Conversions conversions) { final ResourceKey resourceKey = PaperRegistries.toNms(key); this.registry.validateWrite(resourceKey); - final PaperRegistryBuilderFactory builderFactory = new PaperRegistryBuilderFactory<>(conversions, this.meta.builderFiller(), this.registry.temporaryUnfrozenMap::get); + final PaperRegistryBuilderFactory builderFactory = new PaperRegistryBuilderFactory<>(this.registry.key(), conversions, this.meta.builderFiller(), this.registry::getValueForCopying); value.accept(builderFactory); PaperRegistryListenerManager.INSTANCE.registerWithListeners( this.registry, diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java index e0d23b3dc5..dbde5b9913 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/InlinedRegistryBuilderProviderImpl.java @@ -1,34 +1,4 @@ package io.papermc.paper.registry.data; -import com.google.common.base.Preconditions; -import io.papermc.paper.registry.PaperRegistries; -import io.papermc.paper.registry.PaperRegistryBuilder; -import io.papermc.paper.registry.PaperRegistryBuilderFactory; -import io.papermc.paper.registry.RegistryBuilderFactory; -import io.papermc.paper.registry.data.util.Conversions; -import io.papermc.paper.registry.entry.RegistryEntryMeta; -import java.util.function.Consumer; -import net.minecraft.core.Holder; -import net.minecraft.core.Registry; -import net.minecraft.core.registries.Registries; -import net.minecraft.resources.ResourceKey; -import org.bukkit.Art; -import org.bukkit.Keyed; -import org.bukkit.craftbukkit.CraftRegistry; - -@SuppressWarnings("BoundedWildcard") public final class InlinedRegistryBuilderProviderImpl implements InlinedRegistryBuilderProvider { - - private static > A create(final ResourceKey> registryKey, final Consumer> value) { - final RegistryEntryMeta.Buildable buildableMeta = PaperRegistries.getBuildableMeta(registryKey); - Preconditions.checkArgument(buildableMeta.registryTypeMapper().supportsDirectHolders(), "Registry type mapper must support direct holders"); - final PaperRegistryBuilderFactory builderFactory = new PaperRegistryBuilderFactory<>(Conversions.global(), buildableMeta.builderFiller(), CraftRegistry.getMinecraftRegistry(buildableMeta.mcKey())::getValue); - value.accept(builderFactory); - return buildableMeta.registryTypeMapper().createBukkit(Holder.direct(builderFactory.requireBuilder().build())); - } - - @Override - public Art createPaintingVariant(final Consumer> value) { - return create(Registries.PAINTING_VARIANT, value::accept); - } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperJukeboxSongRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperJukeboxSongRegistryEntry.java new file mode 100644 index 0000000000..7e8764436d --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperJukeboxSongRegistryEntry.java @@ -0,0 +1,121 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.RegistryBuilderFactory; +import io.papermc.paper.registry.TypedKey; +import io.papermc.paper.registry.data.util.Conversions; +import io.papermc.paper.registry.holder.PaperRegistryHolders; +import io.papermc.paper.registry.holder.RegistryHolder; +import java.util.OptionalInt; +import java.util.function.Consumer; +import net.minecraft.core.Holder; +import net.minecraft.core.registries.Registries; +import net.minecraft.network.chat.Component; +import net.minecraft.sounds.SoundEvent; +import net.minecraft.world.item.JukeboxSong; +import net.minecraft.world.level.redstone.Redstone; +import org.bukkit.Sound; +import org.checkerframework.checker.index.qual.Positive; +import org.jetbrains.annotations.Range; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asArgumentMinExclusive; +import static io.papermc.paper.registry.data.util.Checks.asArgumentRange; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +public class PaperJukeboxSongRegistryEntry implements JukeboxSongRegistryEntry { + + protected final Conversions conversions; + protected @Nullable Holder soundEvent; + protected @Nullable Component description; + protected @Nullable Float lengthInSeconds; + protected OptionalInt comparatorOutput = OptionalInt.empty(); + + public PaperJukeboxSongRegistryEntry(final Conversions conversions, final @Nullable JukeboxSong internal) { + this.conversions = conversions; + + if (internal == null) { + return; + } + this.soundEvent = internal.soundEvent(); + this.description = internal.description(); + this.lengthInSeconds = internal.lengthInSeconds(); + this.comparatorOutput = OptionalInt.of(internal.comparatorOutput()); + } + + @Override + public RegistryHolder soundEvent() { + final Holder current = asConfigured(this.soundEvent, "soundEvent"); + return PaperRegistryHolders.create(current, e -> new PaperSoundEventRegistryEntry(this.conversions, e)); + } + + @Override + public net.kyori.adventure.text.Component description() { + return this.conversions.asAdventure(asConfigured(this.description, "description")); + } + + @Override + public float lengthInSeconds() { + return asConfigured(this.lengthInSeconds, "lengthInSeconds"); + } + + @Override + public int comparatorOutput() { + return asConfigured(this.comparatorOutput, "comparatorOutput"); + } + + public static final class PaperBuilder extends PaperJukeboxSongRegistryEntry implements JukeboxSongRegistryEntry.Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable JukeboxSong internal) { + super(conversions, internal); + } + + @Override + public JukeboxSongRegistryEntry.Builder soundEvent(final TypedKey soundEvent) { + this.soundEvent = this.conversions.getReferenceHolder(PaperRegistries.toNms(asArgument(soundEvent, "soundEvent"))); + return this; + } + + @Override + public JukeboxSongRegistryEntry.Builder soundEvent(final Consumer> soundEvent) { + this.soundEvent = this.conversions.createHolderFromBuilder(Registries.SOUND_EVENT, asArgument(soundEvent, "soundEvent")); + return this; + } + + @Override + public Builder soundEvent(final RegistryHolder soundEvent) { + this.soundEvent = PaperRegistryHolders.convert(soundEvent, this.conversions); + return this; + } + + @Override + public JukeboxSongRegistryEntry.Builder description(final net.kyori.adventure.text.Component description) { + this.description = this.conversions.asVanilla(asArgument(description, "description")); + return this; + } + + @Override + public JukeboxSongRegistryEntry.Builder lengthInSeconds(final @Positive float lengthInSeconds) { + this.lengthInSeconds = asArgumentMinExclusive(lengthInSeconds, "lengthInSeconds", 0); + return this; + } + + @Override + public JukeboxSongRegistryEntry.Builder comparatorOutput(final @Range(from = 0, to = 15) int comparatorOutput) { + this.comparatorOutput = OptionalInt.of(asArgumentRange(comparatorOutput, "comparatorOutput", Redstone.SIGNAL_MIN, Redstone.SIGNAL_MAX)); + return this; + } + + @Override + public JukeboxSong build() { + return new JukeboxSong( + asConfigured(this.soundEvent, "soundEvent"), + asConfigured(this.description, "description"), + this.lengthInSeconds(), + this.comparatorOutput() + ); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/PaperSoundEventRegistryEntry.java b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperSoundEventRegistryEntry.java new file mode 100644 index 0000000000..9590faa0c6 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/PaperSoundEventRegistryEntry.java @@ -0,0 +1,69 @@ +package io.papermc.paper.registry.data; + +import io.papermc.paper.adventure.PaperAdventure; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.data.util.Conversions; +import java.util.Optional; +import net.kyori.adventure.key.Key; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.sounds.SoundEvent; +import org.bukkit.Sound; +import org.jspecify.annotations.Nullable; + +import static io.papermc.paper.registry.data.util.Checks.asArgument; +import static io.papermc.paper.registry.data.util.Checks.asConfigured; + +/** + * Not actually used for modifying {@link net.minecraft.core.registries.Registries#SOUND_EVENT} + * but for creating direct holders for other registries and direct {@link org.bukkit.craftbukkit.CraftSound}s. + */ +public class PaperSoundEventRegistryEntry implements SoundEventRegistryEntry { + + protected final Conversions conversions; + protected @Nullable ResourceLocation location; + protected @Nullable Float fixedRange; + + public PaperSoundEventRegistryEntry(final Conversions conversions, final @Nullable SoundEvent soundEvent) { + this.conversions = conversions; + if (soundEvent == null) { + return; + } + + this.location = soundEvent.location(); + this.fixedRange = soundEvent.fixedRange().orElse(null); + } + + @Override + public Key location() { + return PaperAdventure.asAdventure(asConfigured(this.location, "location")); + } + + @Override + public @Nullable Float fixedRange() { + return this.fixedRange; + } + + public static final class PaperBuilder extends PaperSoundEventRegistryEntry implements SoundEventRegistryEntry.Builder, PaperRegistryBuilder { + + public PaperBuilder(final Conversions conversions, final @Nullable SoundEvent soundEvent) { + super(conversions, soundEvent); + } + + @Override + public SoundEventRegistryEntry.Builder location(final Key location) { + this.location = PaperAdventure.asVanilla(asArgument(location, "location")); + return this; + } + + @Override + public SoundEventRegistryEntry.Builder fixedRange(final @Nullable Float fixedRange) { + this.fixedRange = fixedRange; + return this; + } + + @Override + public SoundEvent build() { + return new SoundEvent(asConfigured(this.location, "location"), Optional.ofNullable(this.fixedRange)); + } + } +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Checks.java b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Checks.java index 9d61fad398..24067e2445 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Checks.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Checks.java @@ -40,6 +40,13 @@ public final class Checks { return value; } + public static float asArgumentMinExclusive(final float value, final String field, final float min) { + if (value <= min) { + throw new IllegalArgumentException("argument " + field + " must be (" + min + ",+inf)"); + } + return value; + } + private Checks() { } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java index b6a9fd509a..710286a19f 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/data/util/Conversions.java @@ -4,13 +4,20 @@ import com.google.common.base.Preconditions; import com.mojang.serialization.JavaOps; import io.papermc.paper.adventure.PaperAdventure; import io.papermc.paper.adventure.WrapperAwareSerializer; -import java.util.Optional; +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.PaperRegistryBuilder; +import io.papermc.paper.registry.PaperRegistryBuilderFactory; import io.papermc.paper.registry.data.client.ClientTextureAsset; +import io.papermc.paper.registry.entry.RegistryEntryMeta; +import java.util.function.Consumer; import net.kyori.adventure.text.Component; +import net.minecraft.core.Holder; +import net.minecraft.core.HolderLookup; import net.minecraft.core.Registry; import net.minecraft.core.RegistryAccess; import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; +import org.bukkit.Keyed; import org.bukkit.craftbukkit.CraftRegistry; import org.jetbrains.annotations.Contract; import org.jspecify.annotations.Nullable; @@ -22,15 +29,7 @@ public class Conversions { if (globalInstance == null) { final RegistryAccess globalAccess = CraftRegistry.getMinecraftRegistry(); Preconditions.checkState(globalAccess != null, "Global registry access is not available"); - globalInstance = new Conversions(new RegistryOps.RegistryInfoLookup() { - @Override - public Optional> lookup(final ResourceKey> registryRef) { - final Registry registry = globalAccess.lookupOrThrow(registryRef); - return Optional.of( - new RegistryOps.RegistryInfo<>(registry, registry, registry.registryLifecycle()) - ); - } - }); + globalInstance = new Conversions(new RegistryOps.HolderLookupAdapter(globalAccess)); } return globalInstance; } @@ -47,6 +46,10 @@ public class Conversions { return this.lookup; } + public Holder.Reference getReferenceHolder(final ResourceKey key) { + return this.lookup.lookup(key.registryKey()).orElseThrow().getter().getOrThrow(key); + } + @Contract("null -> null; !null -> !null") public net.minecraft.network.chat.@Nullable Component asVanilla(final @Nullable Component adventure) { if (adventure == null) return null; @@ -70,4 +73,33 @@ public class Conversions { PaperAdventure.asVanilla(clientTextureAsset.texturePath()) ); } + + private static > RegistryEntryMeta.Buildable getDirectHolderBuildableMeta(final ResourceKey> registryKey) { + final RegistryEntryMeta.Buildable buildableMeta = PaperRegistries.getBuildableMeta(registryKey); + Preconditions.checkArgument(buildableMeta.registryTypeMapper().supportsDirectHolders(), "Registry type mapper must support direct holders"); + return buildableMeta; + } + + public > A createApiInstanceFromBuilder(final ResourceKey> registryKey, final Consumer> value) { + final RegistryEntryMeta.Buildable meta = getDirectHolderBuildableMeta(registryKey); + final PaperRegistryBuilderFactory builderFactory = this.createRegistryBuilderFactory(registryKey, meta); + value.accept(builderFactory); + return meta.registryTypeMapper().createBukkit(Holder.direct(builderFactory.requireBuilder().build())); + } + + public > Holder createHolderFromBuilder(final ResourceKey> registryKey, final Consumer> value) { + final RegistryEntryMeta.Buildable meta = getDirectHolderBuildableMeta(registryKey); + final PaperRegistryBuilderFactory builderFactory = this.createRegistryBuilderFactory(registryKey, meta); + value.accept(builderFactory); + return Holder.direct(builderFactory.requireBuilder().build()); + } + + private > PaperRegistryBuilderFactory createRegistryBuilderFactory( + final ResourceKey> registryKey, + final RegistryEntryMeta.Buildable buildableMeta + ) { + final HolderLookup.RegistryLookup lookupForBuilders = this.lookup.lookupForValueCopyViaBuilders().lookupOrThrow(registryKey); + return new PaperRegistryBuilderFactory<>(registryKey, this, buildableMeta.builderFiller(), lookupForBuilders::getValueForCopying); + } + } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java index 57a46cc901..04bdb095ae 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryBuilder.java @@ -89,7 +89,7 @@ public class RegistryEntryBuilder { // TODO remove Keyed return this.create(filler, WRITABLE); } - private > RegistryEntry create(final PaperRegistryBuilder.Filler filler, final RegistryEntryMeta.RegistryModificationApiSupport support) { + public > RegistryEntry create(final PaperRegistryBuilder.Filler filler, final RegistryEntryMeta.RegistryModificationApiSupport support) { return new RegistryEntryImpl<>(new RegistryEntryMeta.Buildable<>(this.mcKey, this.apiKey, this.classToPreload, this.minecraftToBukkit, this.serializationUpdater, filler, support)); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java index be3ec5863f..f606c523f6 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/entry/RegistryEntryMeta.java @@ -7,7 +7,7 @@ import io.papermc.paper.registry.TypedKey; import io.papermc.paper.registry.WritableCraftRegistry; import io.papermc.paper.registry.data.util.Conversions; import io.papermc.paper.registry.event.RegistryEntryAddEventImpl; -import io.papermc.paper.registry.event.RegistryFreezeEventImpl; +import io.papermc.paper.registry.event.RegistryComposeEventImpl; import java.util.function.BiFunction; import java.util.function.Supplier; import net.minecraft.core.MappedRegistry; @@ -106,8 +106,8 @@ public sealed interface RegistryEntryMeta permits RegistryEn return new RegistryEntryAddEventImpl<>(key, initialBuilder, this.apiKey(), conversions); } - public RegistryFreezeEventImpl createFreezeEvent(final WritableCraftRegistry writableRegistry, final Conversions conversions) { - return new RegistryFreezeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions); + public RegistryComposeEventImpl createPostLoadEvent(final WritableCraftRegistry writableRegistry, final Conversions conversions) { + return new RegistryComposeEventImpl<>(this.apiKey(), writableRegistry.createApiWritableRegistry(conversions), conversions); } @Override diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEventImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java similarity index 94% rename from paper-server/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEventImpl.java rename to paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java index 1b45802f9a..1ceb822b41 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryFreezeEventImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryComposeEventImpl.java @@ -12,7 +12,7 @@ import net.minecraft.core.HolderSet; import net.minecraft.resources.RegistryOps; import org.bukkit.Keyed; -public record RegistryFreezeEventImpl>( +public record RegistryComposeEventImpl>( RegistryKey registryKey, WritableRegistry registry, Conversions conversions diff --git a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProviderImpl.java index 34c842ffa3..02390a7df5 100644 --- a/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/registry/event/RegistryEventTypeProviderImpl.java @@ -18,7 +18,7 @@ public class RegistryEventTypeProviderImpl implements RegistryEventTypeProvider } @Override - public > LifecycleEventType.Prioritizable> registryFreeze(final RegistryEventProvider type) { - return PaperRegistryListenerManager.INSTANCE.getRegistryFreezeEventType(type); + public > LifecycleEventType.Prioritizable> registryCompose(final RegistryEventProvider type) { + return PaperRegistryListenerManager.INSTANCE.getRegistryComposeEventType(type); } } diff --git a/paper-server/src/main/java/io/papermc/paper/registry/holder/InlinedRegistryHolderImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/holder/InlinedRegistryHolderImpl.java new file mode 100644 index 0000000000..4a3c017ade --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/holder/InlinedRegistryHolderImpl.java @@ -0,0 +1,8 @@ +package io.papermc.paper.registry.holder; + +import net.minecraft.core.Holder; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +record InlinedRegistryHolderImpl(ENTRY entry, Holder.Direct holder) implements RegistryHolder.Inlined { +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/holder/PaperRegistryHolders.java b/paper-server/src/main/java/io/papermc/paper/registry/holder/PaperRegistryHolders.java new file mode 100644 index 0000000000..15536e07d6 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/holder/PaperRegistryHolders.java @@ -0,0 +1,26 @@ +package io.papermc.paper.registry.holder; + +import io.papermc.paper.registry.PaperRegistries; +import io.papermc.paper.registry.data.util.Conversions; +import java.util.function.Function; +import net.minecraft.core.Holder; + +public final class PaperRegistryHolders { + + public static RegistryHolder create(final Holder holder, final Function entryCreator) { + return switch (holder) { + case final Holder.Direct direct -> new InlinedRegistryHolderImpl<>(entryCreator.apply(direct.value()), direct); + case final Holder.Reference reference -> new ReferenceRegistryHolderImpl<>(PaperRegistries.fromNms(reference.key())); + default -> throw new IllegalArgumentException("Unsupported holder type: " + holder.getClass().getName()); + }; + } + + public static Holder convert(final RegistryHolder holder, final Conversions conversions) { + return switch (holder) { + case final RegistryHolder.Reference ref -> conversions.getReferenceHolder(PaperRegistries.toNms(ref.key())); + case final RegistryHolder.Inlined inlined -> ((InlinedRegistryHolderImpl) inlined).holder(); + }; + } + + private PaperRegistryHolders() {} +} diff --git a/paper-server/src/main/java/io/papermc/paper/registry/holder/ReferenceRegistryHolderImpl.java b/paper-server/src/main/java/io/papermc/paper/registry/holder/ReferenceRegistryHolderImpl.java new file mode 100644 index 0000000000..976907d272 --- /dev/null +++ b/paper-server/src/main/java/io/papermc/paper/registry/holder/ReferenceRegistryHolderImpl.java @@ -0,0 +1,8 @@ +package io.papermc.paper.registry.holder; + +import io.papermc.paper.registry.TypedKey; +import org.jetbrains.annotations.ApiStatus; + +@ApiStatus.Internal +record ReferenceRegistryHolderImpl(TypedKey key) implements RegistryHolder.Reference { +} diff --git a/paper-server/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java b/paper-server/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java index 58ba269c53..2de9d79441 100644 --- a/paper-server/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java +++ b/paper-server/src/main/java/io/papermc/paper/world/flag/PaperFeatureFlagProviderImpl.java @@ -21,7 +21,7 @@ public class PaperFeatureFlagProviderImpl implements FeatureFlagProvider { public static final BiMap FLAGS = ImmutableBiMap.of( // Start generate - PaperFeatureFlagProviderImpl#FLAGS - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 FeatureFlag.MINECART_IMPROVEMENTS, FeatureFlags.MINECART_IMPROVEMENTS, FeatureFlag.REDSTONE_EXPERIMENTS, FeatureFlags.REDSTONE_EXPERIMENTS, FeatureFlag.TRADE_REBALANCE, FeatureFlags.TRADE_REBALANCE, diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java index 43ae147ae1..54ab8a0b50 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java @@ -10,11 +10,14 @@ import java.util.Map; import java.util.UUID; import net.minecraft.core.GlobalPos; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.protocol.game.ClientboundTagQueryPacket; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.players.UserWhiteListEntry; import net.minecraft.stats.ServerStatsCounter; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.level.storage.PlayerDataStorage; +import net.minecraft.world.level.storage.TagValueOutput; import net.minecraft.world.phys.Vec2; import net.minecraft.world.phys.Vec3; import org.bukkit.BanEntry; @@ -196,7 +199,8 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa } private CompoundTag getData() { - return this.storage.load(this.profile.getName(), this.profile.getId().toString()).orElse(null); + // This method does not use the problem reporter + return this.storage.load(this.profile.getName(), this.profile.getId().toString(), ProblemReporter.DISCARDING).orElse(null); } private CompoundTag getBukkitData() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java index 1775eb659e..0a10f49ee4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java @@ -198,7 +198,6 @@ public abstract class CraftRegionAccessor implements RegionAccessor { BlockPos pos = CraftLocation.toBlockPosition(location); BlockStateListPopulator populator = new BlockStateListPopulator(this.getHandle()); boolean result = this.generateTree(populator, this.getHandle().getMinecraftWorld().getChunkSource().getGenerator(), pos, new RandomSourceWrapper(random), treeType); - populator.refreshTiles(); populator.placeSomeBlocks(predicate == null ? ($ -> true) : predicate); return result; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java index 408c561661..4b08d061c6 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftRegistry.java @@ -205,7 +205,8 @@ public class CraftRegistry implements Registry { return cached; } - final Optional> holderOptional = this.minecraftRegistry.get(CraftNamespacedKey.toMinecraft(namespacedKey)); + // Important to use the ResourceKey "get" method below because it will work before registry is frozen + final Optional> holderOptional = this.minecraftRegistry.get(MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey)); final Holder.Reference holder; if (holderOptional.isPresent()) { holder = holderOptional.get(); @@ -215,12 +216,9 @@ public class CraftRegistry implements Registry { // to create something to fill the API constant fields, so we create a dummy reference holder. holder = Holder.Reference.createStandAlone(this.invalidHolderOwner, MCUtil.toResourceKey(this.minecraftRegistry.key(), namespacedKey)); } else { - holder = null; - } - final B bukkit = this.createBukkit(holder); - if (bukkit == null) { return null; } + final B bukkit = this.createBukkit(holder); this.cache.put(namespacedKey, bukkit); @@ -250,10 +248,6 @@ public class CraftRegistry implements Registry { } public B createBukkit(Holder minecraft) { - if (minecraft == null) { - return null; - } - return this.minecraftToBukkit.createBukkit(minecraft); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java index 5ce9304f7c..e5612f8ccc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftStatistic.java @@ -21,7 +21,7 @@ import org.bukkit.entity.EntityType; public enum CraftStatistic { // Start generate - CraftStatisticCustom - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 ANIMALS_BRED(Stats.ANIMALS_BRED), AVIATE_ONE_CM(Stats.AVIATE_ONE_CM), BELL_RING(Stats.BELL_RING), @@ -46,6 +46,7 @@ public enum CraftStatistic { CAULDRON_FILLED(Stats.FILL_CAULDRON), FISH_CAUGHT(Stats.FISH_CAUGHT), FLY_ONE_CM(Stats.FLY_ONE_CM), + HAPPY_GHAST_ONE_CM(Stats.HAPPY_GHAST_ONE_CM), HORSE_ONE_CM(Stats.HORSE_ONE_CM), DISPENSER_INSPECTED(Stats.INSPECT_DISPENSER), DROPPER_INSPECTED(Stats.INSPECT_DROPPER), @@ -99,7 +100,7 @@ public enum CraftStatistic { WALK_UNDER_WATER_ONE_CM(Stats.WALK_UNDER_WATER_ONE_CM), // End generate - CraftStatisticCustom // Start generate - CraftStatisticType - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 BREAK_ITEM(ResourceLocation.withDefaultNamespace("broken")), CRAFT_ITEM(ResourceLocation.withDefaultNamespace("crafted")), DROP(ResourceLocation.withDefaultNamespace("dropped")), diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index aae378697b..7990382df4 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1,5 +1,7 @@ package org.bukkit.craftbukkit; +import ca.spottedleaf.moonrise.common.list.ReferenceList; +import ca.spottedleaf.moonrise.common.util.CoordinateUtils; import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.mojang.datafixers.util.Pair; @@ -12,6 +14,7 @@ import io.papermc.paper.raytracing.PositionedRayTraceConfigurationBuilderImpl; import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap; import java.io.File; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.HashMap; @@ -19,6 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.PrimitiveIterator; import java.util.Random; import java.util.Set; import java.util.UUID; @@ -40,6 +44,7 @@ import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ChunkHolder; import net.minecraft.server.level.ChunkMap; import net.minecraft.server.level.DistanceManager; +import net.minecraft.server.level.ServerChunkCache; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.TicketType; @@ -243,7 +248,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public BiomeProvider vanillaBiomeProvider() { - net.minecraft.server.level.ServerChunkCache serverCache = this.getHandle().chunkSource; + ServerChunkCache serverCache = this.getHandle().chunkSource; final net.minecraft.world.level.chunk.ChunkGenerator gen = serverCache.getGenerator(); net.minecraft.world.level.biome.BiomeSource biomeSource; @@ -421,8 +426,21 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public Chunk[] getLoadedChunks() { - List chunks = ca.spottedleaf.moonrise.common.PlatformHooks.get().getVisibleChunkHolders(this.world); // Paper - return chunks.stream().map(ChunkHolder::getFullChunkNow).filter(Objects::nonNull).map(CraftChunk::new).toArray(Chunk[]::new); + ServerChunkCache serverChunkCache = this.getHandle().chunkSource; + ReferenceList chunks = new ReferenceList<>(new Chunk[serverChunkCache.fullChunks.size()]); + + for (PrimitiveIterator.OfLong iterator = serverChunkCache.fullChunks.keyIterator(); iterator.hasNext();) { + long chunk = iterator.nextLong(); + chunks.add(new CraftChunk(this.world, CoordinateUtils.getChunkX(chunk), CoordinateUtils.getChunkZ(chunk))); + } + + Chunk[] raw = chunks.getRawDataUnchecked(); + int size = chunks.size(); + if (raw.length == size) { + // always true when on main + return raw; + } + return Arrays.copyOf(raw, size); } @Override @@ -631,7 +649,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { Set chunks = new HashSet<>(); for (long coord : this.getHandle().getForceLoadedChunks()) { - chunks.add(this.getChunkAt(ChunkPos.getX(coord), ChunkPos.getZ(coord))); + chunks.add(new CraftChunk(this.getHandle(), ChunkPos.getX(coord), ChunkPos.getZ(coord))); } return Collections.unmodifiableCollection(chunks); @@ -828,7 +846,7 @@ public class CraftWorld extends CraftRegionAccessor implements World { CraftPlayer cp = (CraftPlayer) p; if (cp.getHandle().connection == null) continue; - cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().serverLevel().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); + cp.getHandle().connection.send(new ClientboundSetTimePacket(cp.getHandle().level().getGameTime(), cp.getHandle().getPlayerTime(), cp.getHandle().relativeTime && cp.getHandle().level().getGameRules().getBoolean(GameRules.RULE_DAYLIGHT))); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java b/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java index a11fc64b49..7675acdca2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/Main.java @@ -3,16 +3,16 @@ package org.bukkit.craftbukkit; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; -import java.util.Arrays; import java.util.Calendar; import java.util.Date; -import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import joptsimple.OptionParser; import joptsimple.OptionSet; import joptsimple.util.PathConverter; +import static java.util.Arrays.asList; + public class Main { public static final java.time.Instant BOOT_TIME = java.time.Instant.now(); // Paper - track initial start time public static boolean useJline = true; @@ -25,41 +25,40 @@ public class Main { // Paper end - Reset loggers after shutdown public static void main(String[] args) { - // Todo: Installation script if (System.getProperty("jdk.nio.maxCachedBufferSize") == null) System.setProperty("jdk.nio.maxCachedBufferSize", "262144"); // Paper - cap per-thread NIO cache size; https://www.evanjones.ca/java-bytebuffer-leak.html OptionParser parser = new OptionParser() { { - this.acceptsAll(Main.asList("?", "help"), "Show the help"); + this.acceptsAll(asList("?", "help"), "Show the help"); - this.acceptsAll(Main.asList("c", "config"), "Properties file to use") + this.acceptsAll(asList("c", "config"), "Properties file to use") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("server.properties")) .describedAs("Properties file"); - this.acceptsAll(Main.asList("P", "plugins"), "Plugin directory to use") + this.acceptsAll(asList("P", "plugins"), "Plugin directory to use") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("plugins")) .describedAs("Plugin directory"); - this.acceptsAll(Main.asList("h", "host", "server-ip"), "Host to listen on") + this.acceptsAll(asList("h", "host", "server-ip"), "Host to listen on") .withRequiredArg() .ofType(String.class) .describedAs("Hostname or IP"); - this.acceptsAll(Main.asList("W", "world-dir", "universe", "world-container"), "World container") + this.acceptsAll(asList("W", "world-dir", "universe", "world-container"), "World container") .withRequiredArg() .ofType(File.class) .defaultsTo(new File(".")) .describedAs("Directory containing worlds"); - this.acceptsAll(Main.asList("w", "world", "level-name"), "World name") + this.acceptsAll(asList("w", "world", "level-name"), "World name") .withRequiredArg() .ofType(String.class) .describedAs("World name"); - this.acceptsAll(Main.asList("p", "port", "server-port"), "Port to listen on") + this.acceptsAll(asList("p", "port", "server-port"), "Port to listen on") .withRequiredArg() .ofType(Integer.class) .describedAs("Port"); @@ -73,99 +72,99 @@ public class Main { .withRequiredArg() .withValuesConvertedBy(new PathConverter()); - this.acceptsAll(Main.asList("o", "online-mode"), "Whether to use online authentication") + this.acceptsAll(asList("o", "online-mode"), "Whether to use online authentication") .withRequiredArg() .ofType(Boolean.class) .describedAs("Authentication"); - this.acceptsAll(Main.asList("s", "size", "max-players"), "Maximum amount of players") + this.acceptsAll(asList("s", "size", "max-players"), "Maximum amount of players") .withRequiredArg() .ofType(Integer.class) .describedAs("Server size"); - this.acceptsAll(Main.asList("d", "date-format"), "Format of the date to display in the console (for log entries)") + this.acceptsAll(asList("d", "date-format"), "Format of the date to display in the console (for log entries)") .withRequiredArg() .ofType(SimpleDateFormat.class) .describedAs("Log date format"); - this.acceptsAll(Main.asList("log-pattern"), "Specfies the log filename pattern") + this.accepts("log-pattern", "Specfies the log filename pattern") .withRequiredArg() .ofType(String.class) .defaultsTo("server.log") .describedAs("Log filename"); - this.acceptsAll(Main.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)") + this.accepts("log-limit", "Limits the maximum size of the log file (0 = unlimited)") .withRequiredArg() .ofType(Integer.class) .defaultsTo(0) .describedAs("Max log size"); - this.acceptsAll(Main.asList("log-count"), "Specified how many log files to cycle through") + this.accepts("log-count", "Specified how many log files to cycle through") .withRequiredArg() .ofType(Integer.class) .defaultsTo(1) .describedAs("Log count"); - this.acceptsAll(Main.asList("log-append"), "Whether to append to the log file") + this.accepts("log-append", "Whether to append to the log file") .withRequiredArg() .ofType(Boolean.class) .defaultsTo(true) .describedAs("Log append"); - this.acceptsAll(Main.asList("log-strip-color"), "Strips color codes from log file"); + this.accepts("log-strip-color", "Strips color codes from log file"); - this.acceptsAll(Main.asList("b", "bukkit-settings"), "File for bukkit settings") + this.acceptsAll(asList("b", "bukkit-settings"), "File for bukkit settings") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("bukkit.yml")) .describedAs("Yml file"); - this.acceptsAll(Main.asList("C", "commands-settings"), "File for command settings") + this.acceptsAll(asList("C", "commands-settings"), "File for command settings") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("commands.yml")) .describedAs("Yml file"); - this.acceptsAll(Main.asList("forceUpgrade"), "Whether to force a world upgrade"); - this.acceptsAll(Main.asList("eraseCache"), "Whether to force cache erase during world upgrade"); - this.acceptsAll(Main.asList("recreateRegionFiles"), "Whether to recreate region files during world upgrade"); + this.accepts("forceUpgrade", "Whether to force a world upgrade"); + this.accepts("eraseCache", "Whether to force cache erase during world upgrade"); + this.accepts("recreateRegionFiles", "Whether to recreate region files during world upgrade"); this.accepts("safeMode", "Loads level with vanilla datapack only"); // Paper - this.acceptsAll(Main.asList("nogui"), "Disables the graphical console"); + this.accepts("nogui", "Disables the graphical console"); - this.acceptsAll(Main.asList("nojline"), "Disables jline and emulates the vanilla console"); + this.accepts("nojline", "Disables jline and emulates the vanilla console"); - this.acceptsAll(Main.asList("noconsole"), "Disables the console"); + this.accepts("noconsole", "Disables the console"); - this.acceptsAll(Main.asList("v", "version"), "Show the CraftBukkit Version"); + this.acceptsAll(asList("v", "version"), "Show the CraftBukkit Version"); - this.acceptsAll(Main.asList("demo"), "Demo mode"); + this.accepts("demo", "Demo mode"); - this.acceptsAll(Main.asList("initSettings"), "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option + this.accepts("initSettings", "Only create configuration files and then exit"); // SPIGOT-5761: Add initSettings option - this.acceptsAll(Main.asList("S", "spigot-settings"), "File for spigot settings") + this.acceptsAll(asList("S", "spigot-settings"), "File for spigot settings") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("spigot.yml")) .describedAs("Yml file"); - acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings") + this.acceptsAll(asList("paper-dir", "paper-settings-directory"), "Directory for Paper settings") .withRequiredArg() .ofType(File.class) .defaultsTo(new File(io.papermc.paper.configuration.PaperConfigurations.CONFIG_DIR)) .describedAs("Config directory"); - acceptsAll(asList("paper", "paper-settings"), "File for Paper settings") + this.acceptsAll(asList("paper", "paper-settings"), "File for Paper settings") .withRequiredArg() .ofType(File.class) .defaultsTo(new File("paper.yml")) .describedAs("Yml file"); - acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.") + this.acceptsAll(asList("add-plugin", "add-extra-plugin-jar"), "Specify paths to extra plugin jars to be loaded in addition to those in the plugins folder. This argument can be specified multiple times, once for each extra plugin jar path.") .withRequiredArg() .ofType(File.class) .defaultsTo(new File[] {}) .describedAs("Jar file"); - acceptsAll(asList("server-name"), "Name of the server") + this.accepts("server-name", "Name of the server") .withRequiredArg() .ofType(String.class) .defaultsTo("Unknown Server") @@ -246,8 +245,4 @@ public class Main { } } } - - private static List asList(String... params) { - return Arrays.asList(params); - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java index 61fa3b04f2..c00a267eaa 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CapturedBlockState.java @@ -40,10 +40,7 @@ public final class CapturedBlockState extends CraftBlockState { @Override public boolean place(int flags) { boolean result = super.place(flags); - - if (result) { - this.addBees(); - } + this.addBees(); return result; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java index c025b0225f..b25b1d3652 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBiome.java @@ -7,7 +7,6 @@ import org.bukkit.NamespacedKey; import org.bukkit.block.Biome; import org.bukkit.craftbukkit.CraftRegistry; import org.jetbrains.annotations.ApiStatus; -import org.jetbrains.annotations.NotNull; import org.jspecify.annotations.NullMarked; import org.jspecify.annotations.Nullable; import java.util.Objects; @@ -61,17 +60,17 @@ public class CraftBiome extends OldEnumHolderable extends CraftBlockState implements TileState { // Paper - revert upstream's revert of the block state changes + private static final Logger LOGGER = LogUtils.getLogger(); + private final T blockEntity; private final T snapshot; public boolean snapshotDisabled; // Paper @@ -67,10 +74,6 @@ public abstract class CraftBlockEntityState extends Craft this.loadData(state.getSnapshotNBT()); } - public void refreshSnapshot() { - this.load(this.blockEntity); - } - private RegistryAccess getRegistryAccess() { LevelAccessor worldHandle = this.getWorldHandle(); return (worldHandle != null) ? worldHandle.registryAccess() : CraftRegistry.getMinecraftRegistry(); @@ -97,14 +100,22 @@ public abstract class CraftBlockEntityState extends Craft // Loads the specified data into the snapshot BlockEntity. public void loadData(CompoundTag tag) { - this.snapshot.loadWithComponents(tag, this.getRegistryAccess()); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER + )) { + this.snapshot.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag)); + } this.load(this.snapshot); } // copies the BlockEntity-specific data, retains the position private void copyData(T from, T to) { CompoundTag tag = from.saveWithFullMetadata(this.getRegistryAccess()); - to.loadWithComponents(tag, this.getRegistryAccess()); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER + )) { + to.loadWithComponents(TagValueInput.create(problemReporter, this.getRegistryAccess(), tag)); + } } // gets the wrapped BlockEntity @@ -143,13 +154,21 @@ public abstract class CraftBlockEntityState extends Craft // Paper start - properly save blockentity itemstacks public CompoundTag getSnapshotCustomNbtOnly() { this.applyTo(this.snapshot); - final CompoundTag nbt = this.snapshot.saveCustomOnly(this.getRegistryAccess()); - this.snapshot.removeComponentsFromTag(nbt); - if (!nbt.isEmpty()) { - // have to include the "id" if it's going to have block entity data - this.snapshot.saveId(nbt); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "CraftBlockEntityState@" + getPosition().toShortString(), LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWrappingWithContext( + problemReporter, + this.getRegistryAccess(), + this.snapshot.saveCustomOnly(this.getRegistryAccess()) + ); + this.snapshot.removeComponentsFromTag(output); + if (!output.isEmpty()) { + // have to include the "id" if it's going to have block entity data + this.snapshot.saveId(output); + } + return output.buildResult(); } - return nbt; } // Paper end @@ -183,15 +202,14 @@ public abstract class CraftBlockEntityState extends Craft @Override public boolean place(int flags) { - if (super.place(flags)) { - this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> { - this.applyTo((T) blockEntity); - blockEntity.setChanged(); - }); - return true; - } + boolean result = super.place(flags); - return false; + this.getWorldHandle().getBlockEntity(this.getPosition(), this.blockEntity.getType()).ifPresent(blockEntity -> { + this.applyTo((T) blockEntity); + blockEntity.setChanged(); + }); + + return result; } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java index 2338e7c115..cc5028cebc 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java @@ -85,7 +85,7 @@ public final class CraftBlockStates { static { // Start generate - CraftBlockEntityStates - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 register(BlockEntityType.BANNER, CraftBanner.class, CraftBanner::new); register(BlockEntityType.BARREL, CraftBarrel.class, CraftBarrel::new); register(BlockEntityType.BEACON, CraftBeacon.class, CraftBeacon::new); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java index b7352ab040..21443c9cbb 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftConduit.java @@ -2,7 +2,9 @@ package org.bukkit.craftbukkit.block; import java.util.ArrayList; import java.util.Collection; +import net.minecraft.Optionull; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.level.block.entity.ConduitBlockEntity; import net.minecraft.world.phys.AABB; import org.bukkit.Location; @@ -83,7 +85,7 @@ public class CraftConduit extends CraftBlockEntityState impl return false; } - net.minecraft.world.entity.LivingEntity currentTarget = conduit.destroyTarget; + EntityReference currentTarget = conduit.destroyTarget; if (target == null) { if (currentTarget == null) { @@ -91,17 +93,22 @@ public class CraftConduit extends CraftBlockEntityState impl } conduit.destroyTarget = null; - conduit.destroyTargetUUID = null; } else { if (currentTarget != null && target.getUniqueId().equals(currentTarget.getUUID())) { return false; } - conduit.destroyTarget = ((CraftLivingEntity) target).getHandle(); - conduit.destroyTargetUUID = target.getUniqueId(); + conduit.destroyTarget = new EntityReference<>(((CraftLivingEntity) target).getHandle()); } - ConduitBlockEntity.updateDestroyTarget(conduit.getLevel(), this.getPosition(), this.data, conduit.effectBlocks, conduit, false); + ConduitBlockEntity.updateAndAttackTarget( + conduit.getLevel().getMinecraftWorld(), + this.getPosition(), + this.data, + conduit, + conduit.effectBlocks.size() >= ConduitBlockEntity.MIN_KILL_SIZE, + false + ); return true; } @@ -112,14 +119,17 @@ public class CraftConduit extends CraftBlockEntityState impl return null; } - net.minecraft.world.entity.LivingEntity nmsEntity = conduit.destroyTarget; - return (nmsEntity != null) ? (LivingEntity) nmsEntity.getBukkitEntity() : null; + final net.minecraft.world.entity.LivingEntity nmsEntity = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class); + return nmsEntity == null ? null : nmsEntity.getBukkitLivingEntity(); } @Override public boolean hasTarget() { ConduitBlockEntity conduit = (ConduitBlockEntity) this.getBlockEntityFromWorld(); - return conduit != null && conduit.destroyTarget != null && conduit.destroyTarget.isAlive(); + if (conduit == null) return false; + + final net.minecraft.world.entity.LivingEntity destroyTarget = EntityReference.get(conduit.destroyTarget, this.getWorldHandle().getMinecraftWorld(), net.minecraft.world.entity.LivingEntity.class); + return destroyTarget != null && destroyTarget.isAlive(); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java index 7f1b758e50..9f20a8543b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java @@ -8,8 +8,10 @@ import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; +import net.minecraft.core.RegistryAccess; import net.minecraft.nbt.CompoundTag; import net.minecraft.util.InclusiveRange; +import net.minecraft.util.ProblemReporter; import net.minecraft.util.RandomSource; import net.minecraft.util.random.Weighted; import net.minecraft.util.random.WeightedList; @@ -17,6 +19,8 @@ import net.minecraft.world.entity.EquipmentTable; import net.minecraft.world.level.BaseSpawner; import net.minecraft.world.level.SpawnData; import net.minecraft.world.level.block.entity.SpawnerBlockEntity; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.ValueInput; import org.bukkit.Location; import org.bukkit.World; import org.bukkit.block.CreatureSpawner; @@ -46,8 +50,11 @@ public class CraftCreatureSpawner extends CraftBlockEntityState> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn()); - return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> "spawner@" + getLocation(), LOGGER)) { + ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.entityToSpawn()); + Optional> type = net.minecraft.world.entity.EntityType.by(valueInput); + return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + } } @Override @@ -175,9 +182,12 @@ public class CraftCreatureSpawner extends CraftBlockEntityState "spawner@" + getLocation(), LOGGER)) { + ValueInput valueInput = TagValueInput.create(scopedCollector, this.getInternalWorld().registryAccess(), spawnData.getEntityToSpawn()); + Optional> type = net.minecraft.world.entity.EntityType.by(valueInput); - Optional> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn()); - return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null); + return type.map(CraftEntityType::minecraftToBukkit).map(CraftEntityType::bukkitToString).orElse(null); + } } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java index ca61c1c130..b652f93063 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java @@ -46,8 +46,8 @@ public abstract class CraftFurnace extends @Override public void setBurnTime(short burnTime) { this.getSnapshot().litTimeRemaining = burnTime; - // SPIGOT-844: Allow lighting and relighting using this API - this.data = this.data.setValue(AbstractFurnaceBlock.LIT, burnTime > 0); + this.data = this.data.trySetValue(AbstractFurnaceBlock.LIT, burnTime > 0); + // only try, block data might have changed to something different that would not allow this property } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java index 069d22e4aa..238fc32103 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/CraftTrialSpawner.java @@ -7,7 +7,7 @@ import java.util.UUID; import net.minecraft.core.Holder; import net.minecraft.world.level.block.TrialSpawnerBlock; import net.minecraft.world.level.block.entity.TrialSpawnerBlockEntity; -import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerData; +import net.minecraft.world.level.block.entity.trialspawner.TrialSpawnerStateData; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.World; @@ -23,8 +23,8 @@ public class CraftTrialSpawner extends CraftBlockEntityState> type = net.minecraft.world.entity.EntityType.by(this.spawnPotentialsDefinition.unwrap().get(0).value().getEntityToSpawn()); - return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "TrialSpawnerConfiguration@" + snapshot.getBlockPos().toShortString(), LOGGER + )) { + Optional> type = net.minecraft.world.entity.EntityType.by( + TagValueInput.createGlobal( + problemReporter, + this.spawnPotentialsDefinition.unwrap().getFirst().value().getEntityToSpawn() + ) + ); + return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + } } @Override @@ -74,7 +91,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration Preconditions.checkArgument(entityType != EntityType.UNKNOWN, "Can't spawn EntityType %s from mob spawners!", entityType); SpawnData data = new SpawnData(); - data.getEntityToSpawn().putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString()); + data.getEntityToSpawn().putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(CraftEntityType.bukkitToMinecraft(entityType)).toString()); this.getTrialData().nextSpawnData = Optional.of(data); this.spawnPotentialsDefinition = WeightedList.of(data); } @@ -121,7 +138,7 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration @Override public int getDelay() { - return this.ticksBetweenSpawn; + return this.ticksBetweenSpawn; } @Override @@ -287,16 +304,16 @@ public class CraftTrialSpawnerConfiguration implements TrialSpawnerConfiguration @Override public int getRequiredPlayerRange() { - return this.snapshot.trialSpawner.getRequiredPlayerRange(); + return this.snapshot.trialSpawner.getRequiredPlayerRange(); } @Override public void setRequiredPlayerRange(int requiredPlayerRange) { - this.snapshot.trialSpawner.requiredPlayerRange = requiredPlayerRange; + this.snapshot.trialSpawner.config = this.snapshot.trialSpawner.config.overrideRequiredPlayerRange(requiredPlayerRange); } - private TrialSpawnerData getTrialData() { - return this.snapshot.getTrialSpawner().getData(); + private TrialSpawnerStateData getTrialData() { + return this.snapshot.getTrialSpawner().getStateData(); } protected TrialSpawnerConfig toMinecraft() { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java index 34a2e07dab..6ea7d087ac 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java @@ -362,7 +362,7 @@ public class CraftBlockData implements BlockData { static { // // Start generate - CraftBlockData#MAP - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 register(net.minecraft.world.level.block.AmethystClusterBlock.class, org.bukkit.craftbukkit.block.impl.CraftAmethystCluster::new); register(net.minecraft.world.level.block.AnvilBlock.class, org.bukkit.craftbukkit.block.impl.CraftAnvil::new); register(net.minecraft.world.level.block.AttachedStemBlock.class, org.bukkit.craftbukkit.block.impl.CraftAttachedStem::new); @@ -418,6 +418,7 @@ public class CraftBlockData implements BlockData { register(net.minecraft.world.level.block.DispenserBlock.class, org.bukkit.craftbukkit.block.impl.CraftDispenser::new); register(net.minecraft.world.level.block.DoorBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoor::new); register(net.minecraft.world.level.block.DoublePlantBlock.class, org.bukkit.craftbukkit.block.impl.CraftDoublePlant::new); + register(net.minecraft.world.level.block.DriedGhastBlock.class, org.bukkit.craftbukkit.block.impl.CraftDriedGhast::new); register(net.minecraft.world.level.block.DropperBlock.class, org.bukkit.craftbukkit.block.impl.CraftDropper::new); register(net.minecraft.world.level.block.EndPortalFrameBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndPortalFrame::new); register(net.minecraft.world.level.block.EndRodBlock.class, org.bukkit.craftbukkit.block.impl.CraftEndRod::new); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java index 8244b7eaca..46902cbbaa 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java @@ -1,5 +1,8 @@ package org.bukkit.craftbukkit.entity; +import net.minecraft.Optionull; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityReference; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Projectile; @@ -76,7 +79,7 @@ public abstract class AbstractProjectile extends CraftEntity implements Projecti @Override public java.util.UUID getOwnerUniqueId() { - return this.getHandle().ownerUUID; + return Optionull.map(this.getHandle().owner, EntityReference::getUUID); } // Paper end - More projectile API } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java index 1249a5324e..ab9747ba5e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java @@ -139,7 +139,11 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac @Override public void setRearing(boolean rearing) { - this.getHandle().setForceStanding(rearing); + if (rearing) { + this.getHandle().setStanding(Integer.MAX_VALUE); + } else { + this.getHandle().clearStanding(); + } } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java index 9bd90d0589..adde52d936 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java @@ -2,6 +2,8 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import java.util.UUID; +import net.minecraft.Optionull; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.entity.animal.Animal; import org.bukkit.Material; import org.bukkit.craftbukkit.CraftServer; @@ -22,12 +24,12 @@ public class CraftAnimals extends CraftAgeable implements Animals { @Override public UUID getBreedCause() { - return this.getHandle().loveCause; + return Optionull.map(this.getHandle().loveCause, EntityReference::getUUID); } @Override public void setBreedCause(UUID uuid) { - this.getHandle().loveCause = uuid; + this.getHandle().loveCause = uuid == null ? null : new EntityReference<>(uuid); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java index 30dea480db..aa5afe124a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftAreaEffectCloud.java @@ -3,9 +3,11 @@ package org.bukkit.craftbukkit.entity; import com.google.common.collect.ImmutableList; import java.util.List; import java.util.Optional; +import net.minecraft.Optionull; import net.minecraft.core.Holder; import net.minecraft.world.effect.MobEffect; import net.minecraft.world.effect.MobEffectInstance; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.item.alchemy.PotionContents; import org.bukkit.Color; import org.bukkit.Particle; @@ -115,7 +117,7 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud @Override public void setParticle(Particle particle, T data) { - this.getHandle().setParticle(CraftParticle.createParticleParam(particle, data)); + this.getHandle().setCustomParticle(CraftParticle.createParticleParam(particle, data)); } @Override @@ -226,13 +228,12 @@ public class CraftAreaEffectCloud extends CraftEntity implements AreaEffectCloud // Paper start - owner API @Override public java.util.UUID getOwnerUniqueId() { - return this.getHandle().ownerUUID; + return Optionull.map(this.getHandle().owner, EntityReference::getUUID); } @Override public void setOwnerUniqueId(final java.util.UUID ownerUuid) { - this.getHandle().setOwner(null); - this.getHandle().ownerUUID = ownerUuid; + this.getHandle().owner = ownerUuid == null ? null : new EntityReference<>(ownerUuid); } // Paper end } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java index 2b52654e8f..e7aa85589b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmadillo.java @@ -18,7 +18,7 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo { @Override public State getState() { - return CraftArmadillo.stateToBukkit(this.getHandle().getState()); + return State.valueOf(this.getHandle().getState().name()); } @Override @@ -37,22 +37,4 @@ public class CraftArmadillo extends CraftAnimals implements Armadillo { this.getHandle().lastHurtByMob = null; // Clear this memory to not have the sensor trigger rollUp instantly for damaged armadillo this.getHandle().getBrain().setMemoryWithExpiry(MemoryModuleType.DANGER_DETECTED_RECENTLY, true, ArmadilloState.UNROLLING.animationDuration()); } - - public static State stateToBukkit(ArmadilloState state) { - return switch (state) { - case IDLE -> State.IDLE; - case ROLLING -> State.ROLLING; - case SCARED -> State.SCARED; - case UNROLLING -> State.UNROLLING; - }; - } - - public static ArmadilloState stateToNMS(State state) { - return switch (state) { - case State.IDLE -> ArmadilloState.IDLE; - case State.ROLLING -> ArmadilloState.ROLLING; - case State.SCARED -> ArmadilloState.SCARED; - case State.UNROLLING -> ArmadilloState.UNROLLING; - }; - } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java index e8371e5153..ac3550c65c 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java @@ -72,7 +72,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getBodyPose() { - return CraftArmorStand.fromNMS(this.getHandle().bodyPose); + return CraftArmorStand.fromNMS(this.getHandle().getBodyPose()); } @Override @@ -82,7 +82,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getLeftArmPose() { - return CraftArmorStand.fromNMS(this.getHandle().leftArmPose); + return CraftArmorStand.fromNMS(this.getHandle().getLeftArmPose()); } @Override @@ -92,7 +92,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getRightArmPose() { - return CraftArmorStand.fromNMS(this.getHandle().rightArmPose); + return CraftArmorStand.fromNMS(this.getHandle().getRightArmPose()); } @Override @@ -102,7 +102,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getLeftLegPose() { - return CraftArmorStand.fromNMS(this.getHandle().leftLegPose); + return CraftArmorStand.fromNMS(this.getHandle().getLeftLegPose()); } @Override @@ -112,7 +112,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getRightLegPose() { - return CraftArmorStand.fromNMS(this.getHandle().rightLegPose); + return CraftArmorStand.fromNMS(this.getHandle().getRightLegPose()); } @Override @@ -122,7 +122,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public EulerAngle getHeadPose() { - return CraftArmorStand.fromNMS(this.getHandle().headPose); + return CraftArmorStand.fromNMS(this.getHandle().getHeadPose()); } @Override @@ -293,7 +293,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getBodyRotations() { - return fromNMSRotations(this.getHandle().bodyPose); + return fromNMSRotations(this.getHandle().getBodyPose()); } @Override @@ -303,7 +303,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getLeftArmRotations() { - return fromNMSRotations(this.getHandle().leftArmPose); + return fromNMSRotations(this.getHandle().getLeftArmPose()); } @Override @@ -313,7 +313,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getRightArmRotations() { - return fromNMSRotations(this.getHandle().rightArmPose); + return fromNMSRotations(this.getHandle().getRightArmPose()); } @Override @@ -323,7 +323,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getLeftLegRotations() { - return fromNMSRotations(this.getHandle().leftLegPose); + return fromNMSRotations(this.getHandle().getLeftLegPose()); } @Override @@ -333,7 +333,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getRightLegRotations() { - return fromNMSRotations(this.getHandle().rightLegPose); + return fromNMSRotations(this.getHandle().getRightLegPose()); } @Override @@ -343,7 +343,7 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand { @Override public io.papermc.paper.math.Rotations getHeadRotations() { - return fromNMSRotations(this.getHandle().headPose); + return fromNMSRotations(this.getHandle().getHeadPose()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java index 7feea819b2..4348da60ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java @@ -1,6 +1,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; +import net.minecraft.Optionull; import net.minecraft.world.entity.projectile.EyeOfEnder; import net.minecraft.world.item.Items; import org.bukkit.Location; @@ -22,7 +23,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal { @Override public Location getTargetLocation() { - return new Location(this.getWorld(), this.getHandle().tx, this.getHandle().ty, this.getHandle().tz, this.getHandle().getYRot(), this.getHandle().getXRot()); + return Optionull.map(this.getHandle().target, target -> CraftLocation.toBukkit(target, this.getWorld(), this.getHandle().getYRot(), this.getHandle().getXRot())); } @Override @@ -35,7 +36,7 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal { public void setTargetLocation(Location location, boolean update) { // Paper end - Change EnderEye target without changing other things Preconditions.checkArgument(this.getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds"); - this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper - Change EnderEye target without changing other things + this.getHandle().signalTo(CraftLocation.toVec3(location), update); // Paper - Change EnderEye target without changing other things } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 3b41a37f85..a41f481a1e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -5,6 +5,7 @@ import com.google.common.base.Preconditions; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Lists; +import com.mojang.logging.LogUtils; import io.papermc.paper.datacomponent.DataComponentType; import io.papermc.paper.entity.TeleportFlag; import java.util.HashSet; @@ -15,7 +16,6 @@ import io.papermc.paper.entity.LookAnchor; import java.util.concurrent.CompletableFuture; import net.kyori.adventure.util.TriState; import net.minecraft.nbt.CompoundTag; -import net.minecraft.nbt.Tag; import net.minecraft.network.chat.Component; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ChunkMap; @@ -24,12 +24,16 @@ import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.level.TicketType; import net.minecraft.server.network.ServerPlayerConnection; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.boss.EnderDragonPart; import net.minecraft.world.entity.boss.enderdragon.EnderDragon; import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.level.portal.TeleportTransition; +import net.minecraft.world.level.storage.TagValueOutput; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.Vec3; import org.bukkit.EntityEffect; @@ -73,8 +77,12 @@ import org.bukkit.util.Vector; import net.md_5.bungee.api.chat.BaseComponent; // Spigot import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; public abstract class CraftEntity implements org.bukkit.entity.Entity { + + private static final Logger LOGGER = LogUtils.getLogger(); + private static PermissibleBase perm; private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry(); @@ -979,12 +987,19 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { @Override public String getAsString() { - CompoundTag tag = new CompoundTag(); - if (!this.getHandle().saveAsPassenger(tag, false, true, true)) { - return null; - } + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "Entity#toString", LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWithContext( + problemReporter, + this.getHandle().registryAccess() + ); + if (!this.getHandle().saveAsPassenger(output, false, true, true)) { + return null; + } - return tag.toString(); + return output.buildResult().toString(); + } } @Override @@ -1012,32 +1027,40 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { } private Entity copy(net.minecraft.world.level.Level level) { - CompoundTag compoundTag = new CompoundTag(); - this.getHandle().saveAsPassenger(compoundTag, false, true, true); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "Entity#copy", LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWithContext(problemReporter, level.registryAccess()); + this.getHandle().saveAsPassenger(output, false, true, true); - return net.minecraft.world.entity.EntityType.loadEntityRecursive(compoundTag, level, EntitySpawnReason.LOAD, java.util.function.Function.identity()); + return net.minecraft.world.entity.EntityType.loadEntityRecursive(output.buildResult(), level, EntitySpawnReason.LOAD, java.util.function.Function.identity()); + } } - public void storeBukkitValues(CompoundTag c) { + public void storeBukkitValues(ValueOutput output) { if (!this.persistentDataContainer.isEmpty()) { - c.put("BukkitValues", this.persistentDataContainer.toTagCompound()); + output.store("BukkitValues", CompoundTag.CODEC, this.persistentDataContainer.toTagCompound()); } } - public void readBukkitValues(CompoundTag c) { - Tag base = c.get("BukkitValues"); - if (base instanceof CompoundTag) { - this.persistentDataContainer.putAll((CompoundTag) base); - } + public void readBukkitValues(ValueInput input) { + input.read("BukkitValues", CompoundTag.CODEC).ifPresent(this.persistentDataContainer::putAll); } protected CompoundTag save() { - CompoundTag tag = new CompoundTag(); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "Entity#save", LOGGER + )) { + final TagValueOutput tagValueOutput = TagValueOutput.createWithContext( + problemReporter, + this.getHandle().registryAccess() + ); - tag.putString(Entity.ID_TAG, this.getHandle().getEncodeId()); // todo NPE? - this.getHandle().saveWithoutId(tag); + tagValueOutput.putString(Entity.TAG_ID, this.getHandle().getEncodeId(true)); + this.getHandle().saveWithoutId(tagValueOutput); - return tag; + return tagValueOutput.buildResult(); + } } // re-sends the spawn entity packet to updated values which cannot be updated otherwise diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java index 2575f068dc..e20e446e43 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityFactory.java @@ -2,14 +2,19 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.logging.LogUtils; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.TagParser; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.EntityType; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.entity.EntityFactory; import org.bukkit.entity.EntitySnapshot; +import org.slf4j.Logger; public class CraftEntityFactory implements EntityFactory { + private static final Logger LOGGER = LogUtils.getLogger(); private static final CraftEntityFactory instance; static { @@ -30,7 +35,12 @@ public class CraftEntityFactory implements EntityFactory { throw new IllegalArgumentException("Could not parse Entity: " + input, e); } - EntityType type = EntityType.by(tag).orElse(null); + final EntityType type; + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "createEntitySnapshot", LOGGER + )) { + type = EntityType.by(TagValueInput.createGlobal(problemReporter, tag)).orElse(null); + } if (type == null) { throw new IllegalArgumentException("Could not parse Entity: " + input); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java index 59ef331b2f..b3228adb70 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntitySnapshot.java @@ -2,16 +2,25 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import java.util.function.Function; +import com.mojang.logging.LogUtils; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.EntitySpawnReason; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.Location; import org.bukkit.World; +import org.bukkit.craftbukkit.CraftRegistry; import org.bukkit.craftbukkit.CraftWorld; import org.bukkit.entity.Entity; import org.bukkit.entity.EntitySnapshot; import org.bukkit.entity.EntityType; +import org.slf4j.Logger; public class CraftEntitySnapshot implements EntitySnapshot { + + private static final Logger LOGGER = LogUtils.getLogger(); + private final CompoundTag data; private final EntityType type; @@ -55,7 +64,11 @@ public class CraftEntitySnapshot implements EntitySnapshot { } Preconditions.checkArgument(internal != null, "Error creating new entity."); // This should only fail if the stored CompoundTag is malformed. - internal.load(this.data); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "EntitySnapshot#createEntity", LOGGER + )) { + internal.load(TagValueInput.createGlobal(problemReporter, this.data)); + } return internal; } @@ -65,12 +78,19 @@ public class CraftEntitySnapshot implements EntitySnapshot { } public static CraftEntitySnapshot create(CraftEntity entity) { - CompoundTag tag = new CompoundTag(); - if (!entity.getHandle().saveAsPassenger(tag, false, false, false)) { - return null; - } + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "create@" + entity.getUniqueId(), LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWithContext( + problemReporter, + CraftRegistry.getMinecraftRegistry() + ); + if (!entity.getHandle().saveAsPassenger(output, false, false, false)) { + return null; + } - return new CraftEntitySnapshot(tag, entity.getType()); + return new CraftEntitySnapshot(output.buildResult(), entity.getType()); + } } public static CraftEntitySnapshot create(CompoundTag tag, EntityType type) { @@ -82,7 +102,13 @@ public class CraftEntitySnapshot implements EntitySnapshot { } public static CraftEntitySnapshot create(CompoundTag tag) { - EntityType type = net.minecraft.world.entity.EntityType.by(tag).map(CraftEntityType::minecraftToBukkit).orElse(null); - return CraftEntitySnapshot.create(tag, type); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "create", LOGGER + )) { + EntityType type = net.minecraft.world.entity.EntityType.by( + TagValueInput.createGlobal(problemReporter, tag) + ).map(CraftEntityType::minecraftToBukkit).orElse(null); + return CraftEntitySnapshot.create(tag, type); + } } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java index aa44cd6cc4..d0ab356492 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftEntityTypes.java @@ -106,6 +106,7 @@ import org.bukkit.entity.GlowSquid; import org.bukkit.entity.Goat; import org.bukkit.entity.Guardian; import org.bukkit.entity.Hanging; +import org.bukkit.entity.HappyGhast; import org.bukkit.entity.Hoglin; import org.bukkit.entity.Horse; import org.bukkit.entity.Husk; @@ -352,6 +353,7 @@ public final class CraftEntityTypes { register(new EntityTypeData<>(EntityType.BREEZE, Breeze.class, CraftBreeze::new, createLiving(net.minecraft.world.entity.EntityType.BREEZE))); register(new EntityTypeData<>(EntityType.ARMADILLO, Armadillo.class, CraftArmadillo::new, createLiving(net.minecraft.world.entity.EntityType.ARMADILLO))); register(new EntityTypeData<>(EntityType.CREAKING, Creaking.class, CraftCreaking::new, createLiving(net.minecraft.world.entity.EntityType.CREAKING))); + register(new EntityTypeData<>(EntityType.HAPPY_GHAST, HappyGhast.class, CraftHappyGhast::new, createLiving(net.minecraft.world.entity.EntityType.HAPPY_GHAST))); Function dragonFunction = createLiving(net.minecraft.world.entity.EntityType.ENDER_DRAGON); register(new EntityTypeData<>(EntityType.ENDER_DRAGON, EnderDragon.class, CraftEnderDragon::new, spawnData -> { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java deleted file mode 100644 index 974ed7be3f..0000000000 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.bukkit.craftbukkit.entity; - -import net.minecraft.world.entity.FlyingMob; -import org.bukkit.craftbukkit.CraftServer; -import org.bukkit.entity.Flying; - -public class CraftFlying extends CraftMob implements Flying { - - public CraftFlying(CraftServer server, FlyingMob entity) { - super(server, entity); - } - - @Override - public FlyingMob getHandle() { - return (FlyingMob) this.entity; - } -} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java index 7ae83ee68f..9f699fdbd2 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java @@ -3,7 +3,7 @@ package org.bukkit.craftbukkit.entity; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Ghast; -public class CraftGhast extends CraftFlying implements Ghast, CraftEnemy { +public class CraftGhast extends CraftMob implements Ghast, CraftEnemy { public CraftGhast(CraftServer server, net.minecraft.world.entity.monster.Ghast entity) { super(server, entity); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHappyGhast.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHappyGhast.java new file mode 100644 index 0000000000..e0408e6114 --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHappyGhast.java @@ -0,0 +1,10 @@ +package org.bukkit.craftbukkit.entity; + +import org.bukkit.craftbukkit.CraftServer; +import org.bukkit.entity.HappyGhast; + +public class CraftHappyGhast extends CraftAnimals implements HappyGhast { + public CraftHappyGhast(final CraftServer server, final net.minecraft.world.entity.animal.HappyGhast entity) { + super(server, entity); + } +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index 934eb5c668..8fba3cbac5 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -8,6 +8,7 @@ import java.util.Collection; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; +import com.mojang.logging.LogUtils; import io.papermc.paper.adventure.PaperAdventure; import net.kyori.adventure.key.Key; import net.minecraft.core.BlockPos; @@ -18,11 +19,13 @@ import net.minecraft.network.protocol.game.ClientboundOpenScreenPacket; import net.minecraft.network.protocol.game.ServerboundContainerClosePacket; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.level.ServerPlayer; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.MenuProvider; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.HumanoidArm; +import net.minecraft.world.entity.TamableAnimal; import net.minecraft.world.entity.item.ItemEntity; import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.projectile.FireworkRocketEntity; @@ -38,6 +41,7 @@ import net.minecraft.world.level.block.BedBlock; import net.minecraft.world.level.block.Blocks; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.GameMode; import org.bukkit.Location; import org.bukkit.Material; @@ -78,9 +82,11 @@ import org.bukkit.permissions.PermissionAttachmentInfo; import org.bukkit.plugin.Plugin; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { + private static final Logger LOGGER = LogUtils.getLogger(); private CraftInventoryPlayer inventory; private final CraftInventory enderChest; protected final PermissibleBase perm = new PermissibleBase(this); @@ -175,7 +181,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { return null; } - net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).server.getLevel(respawnConfig.dimension()); + net.minecraft.server.level.ServerLevel level = ((ServerPlayer) this.getHandle()).getServer().getLevel(respawnConfig.dimension()); if (level == null) { return null; } @@ -769,8 +775,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public org.bukkit.entity.Entity getShoulderEntityLeft() { if (!this.getHandle().getShoulderEntityLeft().isEmpty()) { - Optional shoulder = EntityType.create(this.getHandle().getShoulderEntityLeft(), this.getHandle().level(), EntitySpawnReason.LOAD); - return shoulder.map(Entity::getBukkitEntity).orElse(null); + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) { + return EntityType.create( + TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityLeft()), + this.getHandle().level(), + EntitySpawnReason.LOAD + ).map(Entity::getBukkitEntity).orElse(null); + } } return null; @@ -778,6 +789,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public void setShoulderEntityLeft(org.bukkit.entity.Entity entity) { + if (entity != null) { + Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey()); + } this.getHandle().setShoulderEntityLeft(entity == null ? new CompoundTag() : ((CraftEntity) entity).save()); if (entity != null) { entity.remove(); @@ -787,8 +801,13 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public org.bukkit.entity.Entity getShoulderEntityRight() { if (!this.getHandle().getShoulderEntityRight().isEmpty()) { - Optional shoulder = EntityType.create(this.getHandle().getShoulderEntityRight(), this.getHandle().level(), EntitySpawnReason.LOAD); - return shoulder.map(Entity::getBukkitEntity).orElse(null); + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(this.getHandle().problemPath(), LOGGER)) { + return EntityType.create( + TagValueInput.create(scopedCollector.forChild(() -> ".shoulder"), this.getHandle().registryAccess(), this.getHandle().getShoulderEntityRight()), + this.getHandle().level(), + EntitySpawnReason.LOAD + ).map(Entity::getBukkitEntity).orElse(null); + } } return null; @@ -796,6 +815,9 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { @Override public void setShoulderEntityRight(org.bukkit.entity.Entity entity) { + if (entity != null) { + Preconditions.checkArgument(((CraftEntity) entity).getHandle().getType().canSerialize(), "Cannot set entity of type %s as a shoulder entity", entity.getType().getKey()); + } this.getHandle().setShoulderEntityRight(entity == null ? new CompoundTag() : ((CraftEntity) entity).save()); if (entity != null) { entity.remove(); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java index ca656d97a0..33a0e5de4b 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java @@ -1,7 +1,9 @@ package org.bukkit.craftbukkit.entity; -import java.util.UUID; import com.google.common.base.Preconditions; +import java.util.UUID; +import net.minecraft.Optionull; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.entity.item.ItemEntity; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.inventory.CraftItemStack; @@ -136,11 +138,11 @@ public class CraftItem extends CraftEntity implements Item { @Override public void setThrower(UUID uuid) { - this.getHandle().thrower = uuid; + this.getHandle().thrower = uuid == null ? null : new EntityReference<>(uuid); } @Override public UUID getThrower() { - return this.getHandle().thrower; + return Optionull.map(this.getHandle().thrower, EntityReference::getUUID); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java index 704635f202..c353cb4ad8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java @@ -4,10 +4,12 @@ import com.google.common.base.Preconditions; import java.util.Collection; import java.util.List; import java.util.Optional; +import net.minecraft.util.ProblemReporter; import net.minecraft.util.RandomSource; import net.minecraft.util.random.WeightedList; import net.minecraft.world.entity.vehicle.MinecartSpawner; import net.minecraft.world.level.SpawnData; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.block.spawner.SpawnRule; import org.bukkit.block.spawner.SpawnerEntry; import org.bukkit.craftbukkit.CraftServer; @@ -34,8 +36,14 @@ public class CraftMinecartMobSpawner extends CraftMinecart implements SpawnerMin return null; } - Optional> type = net.minecraft.world.entity.EntityType.by(spawnData.getEntityToSpawn()); - return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "getSpawnedType@" + this.getUniqueId(), LOGGER + )) { + Optional> type = net.minecraft.world.entity.EntityType.by( + TagValueInput.create(problemReporter, getHandle().registryAccess(), spawnData.getEntityToSpawn()) + ); + return type.map(CraftEntityType::minecraftToBukkit).orElse(null); + } } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java index ffeb5adc0c..cabdcbef0e 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java @@ -7,7 +7,7 @@ import org.bukkit.craftbukkit.util.CraftLocation; import org.bukkit.entity.Phantom; import java.util.UUID; -public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy { +public class CraftPhantom extends CraftMob implements Phantom, CraftEnemy { public CraftPhantom(CraftServer server, net.minecraft.world.entity.monster.Phantom entity) { super(server, entity); @@ -50,7 +50,6 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy { @Override public void setAnchorLocation(Location location) { - com.google.common.base.Preconditions.checkArgument(location != null, "location cannot be null"); this.getHandle().anchorPoint = location == null ? null : CraftLocation.toBlockPosition(location); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java index 1db6276ae7..144623d4ef 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java @@ -106,6 +106,7 @@ import net.minecraft.server.level.ServerPlayer; import net.minecraft.server.network.ServerGamePacketListenerImpl; import net.minecraft.server.players.UserWhiteListEntry; import net.minecraft.sounds.SoundEvent; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ai.attributes.AttributeInstance; import net.minecraft.world.entity.ai.attributes.Attributes; @@ -120,6 +121,8 @@ import net.minecraft.world.level.border.BorderChangeListener; import net.minecraft.world.level.saveddata.maps.MapDecoration; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; +import net.minecraft.world.level.storage.ValueInput; +import net.minecraft.world.level.storage.ValueOutput; import org.bukkit.BanEntry; import org.bukkit.BanList; import org.bukkit.Bukkit; @@ -1530,7 +1533,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { @Override public void loadData() { - this.server.getHandle().playerIo.load(this.getHandle()); + this.server.getHandle().playerIo.load(this.getHandle(), ProblemReporter.DISCARDING); } @Override @@ -1560,7 +1563,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { final ServerPlayer.RespawnConfig respawnConfig = this.getHandle().getRespawnConfig(); if (respawnConfig == null) return null; - final ServerLevel world = this.getHandle().server.getLevel(respawnConfig.dimension()); + final ServerLevel world = this.getHandle().getServer().getLevel(respawnConfig.dimension()); if (world == null) return null; if (!loadLocationAndValidate) { @@ -1885,7 +1888,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ()); final int possibleDurabilityFromXp = net.minecraft.world.item.enchantment.EnchantmentHelper.modifyDurabilityToRepairFromXp( - handle.serverLevel(), itemstack, amount + handle.level(), itemstack, amount ); int i = Math.min(possibleDurabilityFromXp, itemstack.getDamageValue()); final int consumedExperience = i > 0 ? i * amount / possibleDurabilityFromXp : possibleDurabilityFromXp; // Paper - taken from ExperienceOrb#repairPlayerItems + prevent division by 0 @@ -2234,11 +2237,11 @@ public class CraftPlayer extends CraftHumanEntity implements Player { ServerGamePacketListenerImpl connection = handle.connection; // Respawn the player then update their position and selected slot - ServerLevel level = handle.serverLevel(); + ServerLevel level = handle.level(); connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(handle.createCommonSpawnInfo(level), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA)); handle.onUpdateAbilities(); connection.internalTeleport(net.minecraft.world.entity.PositionMoveRotation.of(this.getHandle()), java.util.Collections.emptySet()); - net.minecraft.server.players.PlayerList playerList = handle.server.getPlayerList(); + net.minecraft.server.players.PlayerList playerList = handle.getServer().getPlayerList(); playerList.sendPlayerPermissionLevel(handle, false); playerList.sendLevelInfo(handle, level); playerList.sendAllPlayerInfo(handle); @@ -2351,9 +2354,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player { } // Paper end - getLastPlayed replacement API - public void readExtraData(CompoundTag tag) { + public void readExtraData(ValueInput input) { this.hasPlayedBefore = true; - tag.getCompound("bukkit").ifPresent(data -> { + input.child("bukkit").ifPresent(data -> { this.firstPlayed = data.getLongOr("firstPlayed", 0); this.lastPlayed = data.getLongOr("lastPlayed", 0); @@ -2366,14 +2369,10 @@ public class CraftPlayer extends CraftHumanEntity implements Player { }); } - public void setExtraData(CompoundTag tag) { + public void setExtraData(ValueOutput output) { this.lastSaveTime = System.currentTimeMillis(); // Paper - if (!tag.contains("bukkit")) { - tag.put("bukkit", new CompoundTag()); - } - - CompoundTag data = tag.getCompoundOrEmpty("bukkit"); + ValueOutput data = output.child("bukkit"); ServerPlayer handle = this.getHandle(); data.putInt("newExp", handle.newExp); data.putInt("newTotalExp", handle.newTotalExp); @@ -2385,11 +2384,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { data.putString("lastKnownName", handle.getScoreboardName()); // Paper start - persist for use in offline save data - if (!tag.contains("Paper")) { - tag.put("Paper", new CompoundTag()); - } - - CompoundTag paper = tag.getCompoundOrEmpty("Paper"); + ValueOutput paper = output.child("Paper"); paper.putLong("LastLogin", handle.loginTime); paper.putLong("LastSeen", System.currentTimeMillis()); // Paper end @@ -3016,7 +3011,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player { public void updateCommands() { if (this.getHandle().connection == null) return; - this.getHandle().server.getCommands().sendCommands(this.getHandle()); + this.getHandle().getServer().getCommands().sendCommands(this.getHandle()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java index eea78db7f1..4a62bd61ad 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.entity; +import net.minecraft.world.entity.EntityReference; import net.minecraft.world.entity.item.PrimedTnt; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.entity.Entity; @@ -57,7 +58,7 @@ public class CraftTNTPrimed extends CraftEntity implements TNTPrimed { @Override public void setSource(Entity source) { if (source instanceof LivingEntity) { - this.getHandle().owner = ((CraftLivingEntity) source).getHandle(); + this.getHandle().owner = new EntityReference<>(((CraftLivingEntity) source).getHandle()); } else { this.getHandle().owner = null; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java index 227640d34d..f561b45a20 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/entity/CraftVex.java @@ -2,6 +2,7 @@ package org.bukkit.craftbukkit.entity; import com.google.common.base.Preconditions; import net.minecraft.core.BlockPos; +import net.minecraft.world.entity.EntityReference; import org.bukkit.Location; import org.bukkit.craftbukkit.CraftServer; import org.bukkit.craftbukkit.util.CraftLocation; @@ -20,13 +21,13 @@ public class CraftVex extends CraftMonster implements Vex { @Override public org.bukkit.entity.Mob getSummoner() { - net.minecraft.world.entity.Mob owner = getHandle().getOwner(); + net.minecraft.world.entity.Mob owner = this.getHandle().getOwner(); return owner != null ? (org.bukkit.entity.Mob) owner.getBukkitEntity() : null; } @Override public void setSummoner(org.bukkit.entity.Mob summoner) { - getHandle().setOwner(summoner == null ? null : ((CraftMob) summoner).getHandle()); + this.getHandle().owner = summoner == null ? null : new EntityReference<>(((CraftMob) summoner).getHandle()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 9774c9c72a..c5daefa565 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -27,6 +27,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.effect.MobEffectInstance; import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.Leashable; import net.minecraft.world.entity.Mob; import net.minecraft.world.entity.animal.AbstractFish; import net.minecraft.world.entity.animal.AbstractGolem; @@ -881,7 +882,7 @@ public class CraftEventFactory { public static PlayerDeathEvent callPlayerDeathEvent(ServerPlayer victim, DamageSource damageSource, List drops, net.kyori.adventure.text.Component deathMessage, boolean showDeathMessages, boolean keepInventory) { CraftPlayer entity = victim.getBukkitEntity(); CraftDamageSource bukkitDamageSource = new CraftDamageSource(damageSource); - PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.serverLevel(), damageSource.getEntity()), 0, deathMessage, showDeathMessages); + PlayerDeathEvent event = new PlayerDeathEvent(entity, bukkitDamageSource, new io.papermc.paper.util.TransformingRandomAccessList<>(drops, Entity.DefaultDrop::stack, FROM_FUNCTION), victim.getExpReward(victim.level(), damageSource.getEntity()), 0, deathMessage, showDeathMessages); event.setKeepInventory(keepInventory); event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel populateFields(victim, event); // Paper - make cancellable @@ -1490,10 +1491,56 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(new PlayerRecipeBookSettingsChangeEvent(player.getBukkitEntity(), bukkitType, open, filter)); } - public static PlayerUnleashEntityEvent callPlayerUnleashEntityEvent(Entity entity, net.minecraft.world.entity.player.Player player, InteractionHand hand, boolean dropLeash) { + public static boolean handlePlayerUnleashEntityEvent( + final Leashable leashable, + final net.minecraft.world.entity.player.@Nullable Player player, + final @Nullable InteractionHand hand, + final boolean dropLeash, + final boolean resendState + ) { + if (!(leashable instanceof final Entity entity)) return true; + return handlePlayerUnleashEntityEvent(entity, player, hand, dropLeash, resendState); + } + + public static boolean handlePlayerUnleashEntityEvent( + final Entity entity, + final net.minecraft.world.entity.player.@Nullable Player player, + final @Nullable InteractionHand hand, + final boolean dropLeash, + final boolean resendState + ) { + if (player == null || hand == null) { + if (entity instanceof final Leashable leashable) { + if (dropLeash) leashable.dropLeash(); + else leashable.removeLeash(); + } + return true; + } + PlayerUnleashEntityEvent event = new PlayerUnleashEntityEvent(entity.getBukkitEntity(), (Player) player.getBukkitEntity(), CraftEquipmentSlot.getHand(hand), dropLeash); entity.level().getCraftServer().getPluginManager().callEvent(event); - return event; + if (event.isCancelled()) { + if (resendState && entity instanceof final Leashable leashable) { + ((ServerPlayer) player).connection.send(new net.minecraft.network.protocol.game.ClientboundSetEntityLinkPacket(entity, leashable.getLeashHolder())); + } + return false; + } + + if (entity instanceof final Leashable leashable) { + if (event.isDropLeash()) leashable.dropLeash(); + else leashable.removeLeash(); + } + return true; + } + + public static boolean handlePlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) { + if (!(leashed instanceof final Entity leashedEntity)) return false; + return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand).callEvent(); + } + + public static @Nullable PlayerLeashEntityEvent callPlayerLeashEntityEvent(Leashable leashed, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) { + if (!(leashed instanceof final Entity leashedEntity)) return null; + return callPlayerLeashEntityEvent(leashedEntity, leashHolder, player, hand); } public static PlayerLeashEntityEvent callPlayerLeashEntityEvent(Entity entity, Entity leashHolder, net.minecraft.world.entity.player.Player player, InteractionHand hand) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java index 3d3bf355b0..eb39073213 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java @@ -7,9 +7,11 @@ import java.util.Collection; import java.util.List; import java.util.Random; import java.util.function.Consumer; +import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.Holder; import net.minecraft.nbt.CompoundTag; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.ChunkPos; @@ -17,6 +19,7 @@ import net.minecraft.world.level.WorldGenLevel; import net.minecraft.world.level.chunk.ChunkAccess; import net.minecraft.world.level.chunk.ProtoChunk; import net.minecraft.world.level.chunk.status.ChunkStatus; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.HeightMap; import org.bukkit.Location; import org.bukkit.Material; @@ -30,9 +33,12 @@ import org.bukkit.entity.Entity; import org.bukkit.event.entity.CreatureSpawnEvent; import org.bukkit.generator.LimitedRegion; import org.bukkit.util.BoundingBox; +import org.slf4j.Logger; public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRegion { + private static final Logger LOGGER = LogUtils.getLogger(); + private final WeakReference weakAccess; private final int centerChunkX; private final int centerChunkZ; @@ -271,7 +277,16 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) { throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false)); } - getHandle().getBlockEntity(pos).loadWithComponents(((org.bukkit.craftbukkit.block.CraftBlockEntityState) state).getSnapshotNBT(), this.getHandle().registryAccess()); + + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "CraftLimitedRegion@" + pos.toShortString(), LOGGER + )) { + getHandle().getBlockEntity(pos).loadWithComponents(TagValueInput.create( + problemReporter, + this.getHandle().registryAccess(), + ((org.bukkit.craftbukkit.block.CraftBlockEntityState) state).getSnapshotNBT() + )); + } } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java index 9cf561d5bd..167c2c9a07 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAbstractHorse.java @@ -20,12 +20,12 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr @Override public ItemStack getSaddle() { - return this.getItem(HorseInventoryMenu.SLOT_SADDLE); // Paper + return this.getItem(HorseInventoryMenu.SLOT_SADDLE); } @Override public void setSaddle(ItemStack stack) { - this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack); // Paper + this.setItem(HorseInventoryMenu.SLOT_SADDLE, stack); } public Container getMainInventory() { @@ -88,14 +88,17 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr @Override public ItemStack getItem(final int index) { - if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) { - final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0); - return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); - } else if (index == HorseInventoryMenu.SLOT_SADDLE) { + if (index == HorseInventoryMenu.SLOT_SADDLE) { final net.minecraft.world.item.ItemStack item = this.getSaddleInventory().getItem(0); return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); + } else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) { + final net.minecraft.world.item.ItemStack item = this.getArmorInventory().getItem(0); + return item.isEmpty() ? null : CraftItemStack.asCraftMirror(item); } else { int shiftedIndex = index; + if (index > HorseInventoryMenu.SLOT_SADDLE) { + shiftedIndex--; + } if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) { shiftedIndex--; } @@ -107,16 +110,16 @@ public class CraftInventoryAbstractHorse extends CraftInventory implements Abstr @Override public void setItem(final int index, final ItemStack item) { - if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) { - this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item)); - } else if (index == HorseInventoryMenu.SLOT_SADDLE) { + if (index == HorseInventoryMenu.SLOT_SADDLE) { this.getSaddleInventory().setItem(0, CraftItemStack.asNMSCopy(item)); + } else if (index == HorseInventoryMenu.SLOT_BODY_ARMOR) { + this.getArmorInventory().setItem(0, CraftItemStack.asNMSCopy(item)); } else { int shiftedIndex = index; - if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) { + if (index > HorseInventoryMenu.SLOT_SADDLE) { shiftedIndex--; } - if (index > HorseInventoryMenu.SLOT_SADDLE) { + if (index > HorseInventoryMenu.SLOT_BODY_ARMOR) { shiftedIndex--; } this.getMainInventory().setItem(shiftedIndex, CraftItemStack.asNMSCopy(item)); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java index 5f200b260a..d8aae267a0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import java.util.List; import net.minecraft.network.protocol.game.ClientboundContainerSetSlotPacket; import net.minecraft.network.protocol.game.ClientboundSetHeldSlotPacket; +import net.minecraft.network.protocol.game.ClientboundSetPlayerInventoryPacket; import net.minecraft.server.level.ServerPlayer; import net.minecraft.world.entity.player.Inventory; import org.bukkit.craftbukkit.CraftEquipmentSlot; @@ -71,14 +72,25 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i @Override public void setItem(int index, ItemStack item) { // Paper start - Validate setItem index - if (index < 0 || index > 40) { - throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 40"); + if (index < 0 || index > 42) { + throw new ArrayIndexOutOfBoundsException("Index must be between 0 and 42"); } // Paper end - Validate setItem index super.setItem(index, item); if (this.getHolder() == null) return; + ServerPlayer player = ((CraftPlayer) this.getHolder()).getHandle(); if (player.connection == null) return; + // Of course, these are not part of the player inventory "menu" because these slots are not accessible. + // However they are technically part of the player inventory. + // This is a poor representation by this API, but basically instead send a player inventory update packet. + // This will allow updates to the player inventory rather than through the menu. + // TODO: This could be something worth cleaning up in the future. + if (index > 40) { + player.connection.send(new ClientboundSetPlayerInventoryPacket(index, CraftItemStack.asNMSCopy(item))); + return; + } + // PacketPlayOutSetSlot places the items differently than setItem() // // Between, and including, index 9 (the first index outside of the hotbar) and index 35 (the last index before @@ -123,11 +135,8 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i switch (slot) { case HAND -> this.setItemInMainHand(item); - case OFF_HAND, FEET, LEGS, CHEST, HEAD -> + case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE -> this.getInventory().equipment.set(CraftEquipmentSlot.getNMS(slot), CraftItemStack.asNMSCopy(item)); - case BODY -> throw new IllegalArgumentException("BODY is not valid for players!"); // Paper end - default -> - throw new IllegalArgumentException("Could not set slot " + slot + " - not a valid slot for PlayerInventory"); } } @@ -142,10 +151,7 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i return switch (slot) { case HAND -> this.getItemInMainHand(); - case OFF_HAND, FEET, LEGS, CHEST, HEAD -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot))); - case BODY -> throw new IllegalArgumentException("BODY is not valid for players!"); - default -> - throw new IllegalArgumentException("Could not get slot " + slot + " - not a valid slot for PlayerInventory"); + case OFF_HAND, FEET, LEGS, CHEST, HEAD, BODY, SADDLE -> CraftItemStack.asCraftMirror(this.getInventory().equipment.get(CraftEquipmentSlot.getNMS(slot))); }; } @@ -253,12 +259,12 @@ public class CraftInventoryPlayer extends CraftInventory implements org.bukkit.i @Override public ItemStack[] getExtraContents() { - return this.asCraftMirror(List.of(this.getInventory().equipment.get(net.minecraft.world.entity.EquipmentSlot.OFFHAND))); + return this.asCraftMirror(this.getInventory().getExtraContent()); } @Override public void setExtraContents(ItemStack[] items) { - this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 1); + this.setSlots(items, this.getInventory().getNonEquipmentItems().size() + this.getInventory().getArmorContents().size(), 3); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java index 753795106c..f896417d37 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java @@ -4,6 +4,7 @@ import com.google.common.base.Preconditions; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; import java.util.Optional; +import io.papermc.paper.registry.data.util.Conversions; import net.minecraft.commands.arguments.item.ItemParser; import net.minecraft.core.HolderSet; import net.minecraft.core.RegistryAccess; @@ -332,7 +333,7 @@ public final class CraftItemFactory implements ItemFactory { Optional.of( io.papermc.paper.registry.set.PaperRegistrySets.convertToNms( Registries.ENCHANTMENT, - net.minecraft.server.MinecraftServer.getServer().registryAccess().createSerializationContext(net.minecraft.nbt.NbtOps.INSTANCE).lookupProvider, + Conversions.global().lookup(), keySet ) ), diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java index 3dced8175a..3db36f2ec0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemMetas.java @@ -3,6 +3,7 @@ package org.bukkit.craftbukkit.inventory; import com.destroystokyo.paper.inventory.meta.ArmorStandMeta; import java.util.function.BiFunction; import net.minecraft.world.item.BannerItem; +import net.minecraft.world.item.BedItem; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.BundleItem; import net.minecraft.world.item.Item; @@ -247,7 +248,8 @@ public final class CraftItemMetas { || itemType == ItemType.SUSPICIOUS_GRAVEL || itemType == ItemType.CRAFTER || itemType == ItemType.TRIAL_SPAWNER || itemType == ItemType.VAULT || itemType == ItemType.CREAKING_HEART || itemType == ItemType.TEST_BLOCK - || itemType == ItemType.TEST_INSTANCE_BLOCK) { + || itemType == ItemType.TEST_INSTANCE_BLOCK || itemHandle instanceof BedItem + || itemType == ItemType.CONDUIT) { return CraftItemMetas.asType(CraftItemMetas.BLOCK_STATE_META_DATA); } if (itemType == ItemType.SHIELD) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java index 3b693cd8b1..a0a9b1c4f1 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java @@ -17,8 +17,10 @@ import net.minecraft.core.component.TypedDataComponent; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.NbtOps; import net.minecraft.nbt.Tag; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.item.component.CustomData; import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.DyeColor; import org.bukkit.Material; import org.bukkit.block.BlockState; @@ -144,12 +146,17 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta final BlockVector legacyPosition = SerializableMeta.getObject(BlockVector.class, map, "blockPosition", true); if (legacyPosition != null) { this.blockEntityTag = this.blockEntityTag.update(blockEntityTag -> { - if (blockEntityTag.isEmpty()) { - BlockEntity.addEntityType(blockEntityTag, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "blockEntityTag", LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWrappingWithContext(problemReporter, CraftRegistry.getMinecraftRegistry(), blockEntityTag); + if (blockEntityTag.isEmpty()) { + BlockEntity.addEntityType(output, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))); + } + output.putInt("x", legacyPosition.getBlockX()); + output.putInt("y", legacyPosition.getBlockY()); + output.putInt("z", legacyPosition.getBlockZ()); } - blockEntityTag.putInt("x", legacyPosition.getBlockX()); - blockEntityTag.putInt("y", legacyPosition.getBlockY()); - blockEntityTag.putInt("z", legacyPosition.getBlockZ()); }); } // Paper end - general item meta fixes - parse spigot legacy position and merge into block entity tag @@ -164,7 +171,14 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta final CompoundTag nbt = this.blockEntityTag.copyTag(); if (!nbt.isEmpty()) { if (nbt.getString("id").isEmpty()) { - BlockEntity.addEntityType(nbt, java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType()))); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "CraftMetaBlockState#apply", LOGGER + )) { + BlockEntity.addEntityType( + TagValueOutput.createWrappingWithContext(problemReporter, CraftRegistry.getMinecraftRegistry(), nbt), + java.util.Objects.requireNonNull(CraftBlockStates.getBlockEntityType(this.materialForBlockEntityType())) + ); + } } tag.put(CraftMetaBlockState.BLOCK_ENTITY_TAG, CustomData.of(nbt)); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java index 67e9e96d7c..eb21c7bf83 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBookSigned.java @@ -274,7 +274,6 @@ public class CraftMetaBookSigned extends CraftMetaItem implements BookMeta { return page > 0 && page <= this.getPageCount(); } - // TODO Expose this attribute in Bukkit? public boolean isResolved() { return this.resolved; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java index 228d191956..6708112d14 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java @@ -11,6 +11,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.google.common.collect.SetMultimap; import com.google.common.collect.Sets; +import com.mojang.logging.LogUtils; import com.mojang.serialization.DynamicOps; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; @@ -37,8 +38,6 @@ import java.util.Optional; import java.util.SequencedSet; import java.util.Set; import java.util.StringJoiner; -import java.util.logging.Level; -import java.util.logging.Logger; import it.unimi.dsi.fastutil.objects.ReferenceLinkedOpenHashSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; @@ -131,6 +130,7 @@ import org.bukkit.inventory.meta.components.UseCooldownComponent; import org.bukkit.inventory.meta.tags.CustomItemTagContainer; import org.bukkit.persistence.PersistentDataContainer; import org.bukkit.tag.DamageTypeTags; +import org.slf4j.Logger; /** * Children must include the following: @@ -158,6 +158,8 @@ import org.bukkit.tag.DamageTypeTags; // Important: ItemMeta needs to be the first interface see #applicableTo(Material) class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { + static final Logger LOGGER = LogUtils.getLogger(); + static class ItemMetaKey { @Retention(RetentionPolicy.SOURCE) @@ -750,7 +752,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { CompoundTag internalTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); this.deserializeInternal(internalTag, map); } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to read internal tag from object", ex); } } @@ -779,7 +781,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { } } } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to read unhandled tag for item", ex); } } @@ -809,7 +811,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { try { this.customTag = NbtIo.readCompressed(buf, NbtAccounter.unlimitedHeap()); } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to read custom tag for item", ex); } } } @@ -2238,7 +2240,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { NbtIo.writeCompressed(internal, buf); builder.put("internal", Base64.getEncoder().encodeToString(buf.toByteArray())); } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to write internal tag for item", ex); } } @@ -2258,7 +2260,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { NbtIo.writeCompressed((CompoundTag) unhandled, buf); builder.put("unhandled", Base64.getEncoder().encodeToString(buf.toByteArray())); } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to write unhandled tag for item", ex); } } @@ -2293,7 +2295,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta { NbtIo.writeCompressed(this.customTag, buf); builder.put("custom", Base64.getEncoder().encodeToString(buf.toByteArray())); } catch (IOException ex) { - Logger.getLogger(CraftMetaItem.class.getName()).log(Level.SEVERE, null, ex); + LOGGER.error("Failed to write custom tag for item", ex); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java index 05db0af608..49e3a8d391 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java @@ -323,11 +323,11 @@ class CraftMetaPotion extends CraftMetaItem implements PotionMeta { @Override @NotNull public Color computeEffectiveColor() { - if (hasColor()) return getColor(); + if (this.hasColor()) return this.getColor(); return Color.fromRGB( PotionContents.getColorOptional(Collections2.transform(getAllEffects(), CraftPotionUtil::fromBukkit)) - .orElse(PotionContents.BASE_POTION_COLOR) & 0xFFFFFF + .orElse(PotionContents.BASE_POTION_COLOR) & 0x00FFFFFF ); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java index 4f3a82ce29..2090613ef8 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/inventory/components/CraftEquippableComponent.java @@ -8,6 +8,7 @@ import java.util.Optional; import java.util.stream.Collectors; import net.minecraft.core.Holder; import net.minecraft.core.HolderSet; +import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.Registries; import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceLocation; @@ -74,7 +75,8 @@ public final class CraftEquippableComponent implements EquippableComponent { (dispensable != null) ? dispensable : true, (swappable != null) ? swappable : true, (damageOnHurt != null) ? damageOnHurt : true, - (equipOnInteract != null) ? equipOnInteract : false + (equipOnInteract != null) ? equipOnInteract : false, + false, BuiltInRegistries.SOUND_EVENT.wrapAsHolder(SoundEvents.SHEARS_SNIP) // TODO - 1.21.6 ); } @@ -115,7 +117,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setSlot(EquipmentSlot slot) { - this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(CraftEquipmentSlot.getNMS(slot), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -125,7 +127,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setEquipSound(Sound sound) { - this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), (sound != null) ? CraftSound.bukkitToMinecraftHolder(sound) : SoundEvents.ARMOR_EQUIP_GENERIC, this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -135,7 +137,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setModel(NamespacedKey key) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft).map((k) -> ResourceKey.create(EquipmentAssets.ROOT_ID, k)), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -145,7 +147,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setCameraOverlay(NamespacedKey key) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), Optional.ofNullable(key).map(CraftNamespacedKey::toMinecraft), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -157,7 +159,7 @@ public final class CraftEquippableComponent implements EquippableComponent { public void setAllowedEntities(EntityType entities) { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (entities != null) ? Optional.of(HolderSet.direct(CraftEntityType.bukkitToMinecraftHolder(entities))) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -165,7 +167,7 @@ public final class CraftEquippableComponent implements EquippableComponent { public void setAllowedEntities(Collection entities) { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (entities != null) ? Optional.of(HolderSet.direct(entities.stream().map(CraftEntityType::bukkitToMinecraftHolder).collect(Collectors.toList()))) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -175,7 +177,7 @@ public final class CraftEquippableComponent implements EquippableComponent { this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), (tag != null) ? Optional.of(((CraftEntityTag) tag).getHandle()) : Optional.empty(), - this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract() + this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound() ); } @@ -186,7 +188,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setDispensable(boolean dispensable) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), dispensable, this.handle.swappable(), this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -196,7 +198,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setSwappable(boolean swappable) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), swappable, this.handle.damageOnHurt(), this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -206,7 +208,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setDamageOnHurt(boolean damage) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract()); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), damage, this.handle.equipOnInteract(), this.handle.canBeSheared(), this.handle.shearingSound()); } @Override @@ -216,7 +218,7 @@ public final class CraftEquippableComponent implements EquippableComponent { @Override public void setEquipOnInteract(final boolean equip) { - this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip); + this.handle = new Equippable(this.handle.slot(), this.handle.equipSound(), this.handle.assetId(), this.handle.cameraOverlay(), this.handle.allowedEntities(), this.handle.dispensable(), this.handle.swappable(), this.handle.damageOnHurt(), equip, this.handle.canBeSheared(), this.handle.shearingSound()); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java index 7cc3f8edd8..1522c8fdb7 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionUtil.java @@ -15,7 +15,7 @@ public class CraftPotionUtil { private static final BiMap upgradeable = ImmutableBiMap.builder() // Start generate - CraftPotionUtil#upgradeable - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 .put(PotionType.HARMING, PotionType.STRONG_HARMING) .put(PotionType.HEALING, PotionType.STRONG_HEALING) .put(PotionType.LEAPING, PotionType.STRONG_LEAPING) @@ -29,7 +29,7 @@ public class CraftPotionUtil { .build(); private static final BiMap extendable = ImmutableBiMap.builder() // Start generate - CraftPotionUtil#extendable - // @GeneratedFrom 1.21.5 + // @GeneratedFrom 1.21.6-rc1 .put(PotionType.FIRE_RESISTANCE, PotionType.LONG_FIRE_RESISTANCE) .put(PotionType.INVISIBILITY, PotionType.LONG_INVISIBILITY) .put(PotionType.LEAPING, PotionType.LONG_LEAPING) diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/spawner/PaperSharedSpawnerLogic.java b/paper-server/src/main/java/org/bukkit/craftbukkit/spawner/PaperSharedSpawnerLogic.java index b1d08dc4c4..11c7990422 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/spawner/PaperSharedSpawnerLogic.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/spawner/PaperSharedSpawnerLogic.java @@ -2,29 +2,39 @@ package org.bukkit.craftbukkit.spawner; import com.google.common.base.Preconditions; import java.util.Optional; +import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; +import net.minecraft.core.RegistryAccess; import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.ListTag; +import net.minecraft.nbt.NbtUtils; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.BaseSpawner; +import net.minecraft.world.level.ChunkPos; import net.minecraft.world.level.Level; import net.minecraft.world.level.SpawnData; +import net.minecraft.world.level.chunk.ChunkAccess; +import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.craftbukkit.inventory.CraftItemStack; import org.bukkit.inventory.ItemStack; import org.bukkit.spawner.Spawner; +import org.slf4j.Logger; /** * A common parent interface for both the {@link org.bukkit.craftbukkit.block.CraftCreatureSpawner} and minecart mob spawner. */ public interface PaperSharedSpawnerLogic extends Spawner { + static final Logger LOGGER = LogUtils.getLogger(); + BaseSpawner getSpawner(); Level getInternalWorld(); BlockPos getInternalPosition(); - default boolean isActivated() { return this.getSpawner().isNearPlayer(this.getInternalWorld(), this.getInternalPosition()); } @@ -41,16 +51,20 @@ public interface PaperSharedSpawnerLogic extends Spawner { Preconditions.checkArgument(itemStack != null && !itemStack.getType().isAir(), "spawners cannot spawn air"); final net.minecraft.world.item.ItemStack item = CraftItemStack.asNMSCopy(itemStack); - final CompoundTag entity = new CompoundTag(); - entity.putString(Entity.ID_TAG, BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ITEM).toString()); - entity.put("Item", item.save(this.getInternalWorld().registryAccess())); - this.setNextSpawnData( - new net.minecraft.world.level.SpawnData( - entity, - java.util.Optional.empty(), - Optional.ofNullable(this.getSpawner().nextSpawnData).flatMap(SpawnData::equipment) - ) - ); + try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(() -> getSpawner().toString(), LOGGER)) { + TagValueOutput tagValueOutput = TagValueOutput.createWithContext(scopedCollector, this.getInternalWorld().registryAccess()); + tagValueOutput.putString(Entity.TAG_ID, BuiltInRegistries.ENTITY_TYPE.getKey(EntityType.ITEM).toString()); + tagValueOutput.store("Item", net.minecraft.world.item.ItemStack.CODEC, item); + + this.setNextSpawnData( + new net.minecraft.world.level.SpawnData( + tagValueOutput.buildResult(), + java.util.Optional.empty(), + Optional.ofNullable(this.getSpawner().nextSpawnData).flatMap(SpawnData::equipment) + ) + ); + } + } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java b/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java index 22bf130fcd..f4fca4614a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/structure/CraftStructure.java @@ -7,8 +7,10 @@ import java.util.Collections; import java.util.List; import java.util.Random; import java.util.stream.Collectors; +import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; +import net.minecraft.util.ProblemReporter; import net.minecraft.util.RandomSource; import net.minecraft.world.entity.EntitySpawnReason; import net.minecraft.world.entity.EntityType; @@ -19,6 +21,7 @@ import net.minecraft.world.level.block.Rotation; import net.minecraft.world.level.levelgen.structure.templatesystem.BlockRotProcessor; import net.minecraft.world.level.levelgen.structure.templatesystem.StructurePlaceSettings; import net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.Bukkit; import org.bukkit.Location; import org.bukkit.RegionAccessor; @@ -39,9 +42,12 @@ import org.bukkit.structure.Structure; import org.bukkit.util.BlockTransformer; import org.bukkit.util.BlockVector; import org.bukkit.util.EntityTransformer; +import org.slf4j.Logger; public class CraftStructure implements Structure { + private static final Logger LOGGER = LogUtils.getLogger(); + private final StructureTemplate structure; private final RegistryAccess registry; @@ -121,7 +127,7 @@ public class CraftStructure implements Structure { Preconditions.checkArgument(size != null, "BlockVector size cannot be null"); Preconditions.checkArgument(size.getBlockX() >= 1 && size.getBlockY() >= 1 && size.getBlockZ() >= 1, "Size must be at least 1x1x1 but was %sx%sx%s", size.getBlockX(), size.getBlockY(), size.getBlockZ()); - this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, Blocks.STRUCTURE_VOID); + this.structure.fillFromWorld(((CraftWorld) world).getHandle(), CraftLocation.toBlockPosition(origin), CraftBlockVector.toBlockPosition(size), includeEntities, List.of(Blocks.STRUCTURE_VOID)); } @Override @@ -133,10 +139,18 @@ public class CraftStructure implements Structure { public List getEntities() { List entities = new ArrayList<>(); for (StructureTemplate.StructureEntityInfo entity : this.structure.entityInfoList) { - EntityType.create(entity.nbt, ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(), EntitySpawnReason.STRUCTURE).ifPresent(dummyEntity -> { - dummyEntity.setPos(entity.pos.x, entity.pos.y, entity.pos.z); - entities.add(dummyEntity.getBukkitEntity()); - }); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "entity@" + entity.pos, LOGGER + )) { + EntityType.create( + TagValueInput.createGlobal(problemReporter, entity.nbt), + ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(), + EntitySpawnReason.STRUCTURE + ).ifPresent(dummyEntity -> { + dummyEntity.setPos(entity.pos.x, entity.pos.y, entity.pos.z); + entities.add(dummyEntity.getBukkitEntity()); + }); + } } return Collections.unmodifiableList(entities); } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/ApiVersion.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ApiVersion.java index 0a0292c2f3..4de7aa2a43 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/ApiVersion.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/ApiVersion.java @@ -17,7 +17,7 @@ public final class ApiVersion implements Comparable, Serializable { static { versions = new HashMap<>(); - CURRENT = getOrCreateVersion("1.21.5"); + CURRENT = getOrCreateVersion("1.21.6"); FLATTENING = getOrCreateVersion("1.13"); FIELD_NAME_PARITY = getOrCreateVersion("1.20.5"); ABSTRACT_COW = getOrCreateVersion("1.21.5"); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java index 86bd6549d7..be075a5d81 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java @@ -1,7 +1,6 @@ package org.bukkit.craftbukkit.util; import java.util.ArrayList; -import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -11,6 +10,7 @@ import net.minecraft.core.BlockPos; import net.minecraft.core.RegistryAccess; import net.minecraft.server.level.ServerLevel; import net.minecraft.util.RandomSource; +import net.minecraft.world.entity.Entity; import net.minecraft.world.level.LevelAccessor; import net.minecraft.world.level.block.EntityBlock; import net.minecraft.world.level.block.entity.BlockEntity; @@ -18,84 +18,86 @@ import net.minecraft.world.level.dimension.DimensionType; import net.minecraft.world.level.material.FluidState; import net.minecraft.world.level.storage.LevelData; import org.bukkit.block.BlockState; -import org.bukkit.craftbukkit.block.CraftBlock; -import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.block.CraftBlockStates; public class BlockStateListPopulator extends DummyGeneratorAccess { - private final LevelAccessor world; - private final Map dataMap = new HashMap<>(); - private final Map entityMap = new HashMap<>(); - private final LinkedHashMap blocks; - public BlockStateListPopulator(LevelAccessor world) { - this(world, new LinkedHashMap<>()); - } + private final LevelAccessor level; + private final Map blocks = new LinkedHashMap<>(); - private BlockStateListPopulator(LevelAccessor world, LinkedHashMap blocks) { - this.world = world; - this.blocks = blocks; + private List snapshots; + + public BlockStateListPopulator(LevelAccessor level) { + this.level = level; } @Override public net.minecraft.world.level.block.state.BlockState getBlockState(BlockPos pos) { - net.minecraft.world.level.block.state.BlockState state = this.dataMap.get(pos); - return (state != null) ? state : this.world.getBlockState(pos); + CapturedBlock block = this.blocks.get(pos); + return block != null ? block.state() : this.level.getBlockState(pos); } @Override public FluidState getFluidState(BlockPos pos) { - net.minecraft.world.level.block.state.BlockState state = this.dataMap.get(pos); - return (state != null) ? state.getFluidState() : this.world.getFluidState(pos); + CapturedBlock block = this.blocks.get(pos); + return block != null ? block.state().getFluidState() : this.level.getFluidState(pos); } @Override public BlockEntity getBlockEntity(BlockPos pos) { - // The contains is important to check for null values - if (this.entityMap.containsKey(pos)) { - return this.entityMap.get(pos); - } - - return this.world.getBlockEntity(pos); + CapturedBlock block = this.blocks.get(pos); + return block != null ? block.blockEntity() : this.level.getBlockEntity(pos); } @Override public boolean setBlock(BlockPos pos, net.minecraft.world.level.block.state.BlockState state, int flags, int recursionLeft) { pos = pos.immutable(); - // remove first to keep insertion order + // remove first to keep last updated order this.blocks.remove(pos); - this.dataMap.put(pos, state); - if (state.hasBlockEntity()) { - this.entityMap.put(pos, ((EntityBlock) state.getBlock()).newBlockEntity(pos, state)); + final BlockEntity newBlockEntity; + if (state.getBlock() instanceof EntityBlock entityBlock) { + // based on LevelChunk#setBlockState + BlockEntity currentBlockEntity = this.getBlockEntity(pos); + if (currentBlockEntity != null && currentBlockEntity.isValidBlockState(state)) { + newBlockEntity = currentBlockEntity; // previous block entity is still valid for this block state + currentBlockEntity.setBlockState(state); + } else { + newBlockEntity = entityBlock.newBlockEntity(pos, state); // create a new one when the block change + } } else { - this.entityMap.put(pos, null); + newBlockEntity = null; } - // use 'this' to ensure that the block state is the correct TileState - CraftBlockState snapshot = (CraftBlockState) CraftBlock.at(this, pos).getState(); - snapshot.setFlags(flags); - // set world handle to ensure that updated calls are done to the world and not to this populator - snapshot.setWorldHandle(this.world); - this.blocks.put(pos, snapshot); + this.blocks.put(pos, new CapturedBlock(state, flags, newBlockEntity)); + return true; + } + + @Override + public boolean destroyBlock(BlockPos pos, boolean dropBlock, Entity entity, int recursionLeft) { + net.minecraft.world.level.block.state.BlockState blockState = this.getBlockState(pos); + if (blockState.isAir()) { + return false; + } + + this.setBlock(pos, blockState.getFluidState().createLegacyBlock(), 3, recursionLeft); // capture block without the event return true; } @Override public ServerLevel getMinecraftWorld() { - return this.world.getMinecraftWorld(); + return this.level.getMinecraftWorld(); } - @Override - public ServerLevel getLevel() { - return this.getMinecraftWorld(); - } - - public void refreshTiles() { - for (CraftBlockState snapshot : this.blocks.values()) { - if (snapshot instanceof CraftBlockEntityState) { - ((CraftBlockEntityState) snapshot).refreshSnapshot(); - } + private void iterateSnapshots(Consumer callback) { + for (Map.Entry entry : this.blocks.entrySet()) { + CapturedBlock block = entry.getValue(); + CraftBlockState snapshot = CraftBlockStates.getBlockState( + this.getMinecraftWorld().getWorld(), entry.getKey(), block.state(), block.blockEntity() + ); + snapshot.setFlags(block.flags()); + callback.accept(snapshot); } } @@ -112,27 +114,38 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { } public void placeSomeBlocks(Consumer beforeRun, Predicate filter) { - for (CraftBlockState state : this.blocks.values()) { - if (filter.test(state)) { - beforeRun.accept(state); - state.place(state.getFlags()); + for (CraftBlockState snapshot : this.getSnapshotBlocks()) { + if (filter.test(snapshot)) { + beforeRun.accept(snapshot); + snapshot.place(snapshot.getFlags()); } } } public List getSnapshotBlocks() { - return new ArrayList<>(this.blocks.values()); + if (this.snapshots == null) { + List snapshots = new ArrayList<>(); + this.iterateSnapshots(snapshots::add); + this.snapshots = snapshots; + } + return snapshots; } // For tree generation + + @Override + public ServerLevel getLevel() { + return this.getMinecraftWorld(); + } + @Override public int getMinY() { - return this.world.getMinY(); + return this.level.getMinY(); } @Override public int getHeight() { - return this.world.getHeight(); + return this.level.getHeight(); } @Override @@ -147,29 +160,29 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { @Override public DimensionType dimensionType() { - return this.world.dimensionType(); + return this.level.dimensionType(); } @Override public RegistryAccess registryAccess() { - return this.world.registryAccess(); + return this.level.registryAccess(); } // Needed when a tree generates in water @Override public LevelData getLevelData() { - return this.world.getLevelData(); + return this.level.getLevelData(); } @Override public long nextSubTickCount() { - return this.world.nextSubTickCount(); + return this.level.nextSubTickCount(); } // SPIGOT-7966: Needed for some tree generations @Override public RandomSource getRandom() { - return this.world.getRandom(); + return this.level.getRandom(); } @Override @@ -179,22 +192,22 @@ public class BlockStateListPopulator extends DummyGeneratorAccess { } @Override - public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, BlockPos pos) { - return this.world.getHeightmapPos(heightmap, pos); + public BlockPos getHeightmapPos(net.minecraft.world.level.levelgen.Heightmap.Types heightmapType, BlockPos pos) { + return this.level.getHeightmapPos(heightmapType, pos); } @Override - public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmap, int x, int z) { - return this.world.getHeight(heightmap, x, z); + public int getHeight(net.minecraft.world.level.levelgen.Heightmap.Types heightmapType, int x, int z) { + return this.level.getHeight(heightmapType, x, z); } @Override public int getRawBrightness(BlockPos pos, int amount) { - return this.world.getRawBrightness(pos, amount); + return this.level.getRawBrightness(pos, amount); } @Override - public int getBrightness(net.minecraft.world.level.LightLayer lightLayer, BlockPos pos) { - return this.world.getBrightness(lightLayer, pos); + public int getBrightness(net.minecraft.world.level.LightLayer lightType, BlockPos pos) { + return this.level.getBrightness(lightType, pos); } } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CapturedBlock.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CapturedBlock.java new file mode 100644 index 0000000000..d1e0c0610b --- /dev/null +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CapturedBlock.java @@ -0,0 +1,10 @@ +package org.bukkit.craftbukkit.util; + +import net.minecraft.world.level.block.entity.BlockEntity; +import net.minecraft.world.level.block.state.BlockState; +import org.jspecify.annotations.NullMarked; +import org.jspecify.annotations.Nullable; + +@NullMarked +public record CapturedBlock(BlockState state, int flags, @Nullable BlockEntity blockEntity) { +} diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index 80835b5688..3f115c561f 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -2,6 +2,9 @@ package org.bukkit.craftbukkit.util; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap.Builder; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import java.net.URI; import java.util.ArrayList; @@ -11,6 +14,7 @@ import java.util.Map; import java.util.Optional; import java.util.regex.Matcher; import java.util.regex.Pattern; +import com.mojang.serialization.JsonOps; import net.md_5.bungee.api.chat.BaseComponent; import net.md_5.bungee.chat.ChatVersion; import net.md_5.bungee.chat.VersionedComponentSerializer; @@ -18,6 +22,7 @@ import com.mojang.serialization.JavaOps; import net.minecraft.ChatFormatting; import net.minecraft.network.chat.ClickEvent; import net.minecraft.network.chat.Component; +import net.minecraft.network.chat.ComponentSerialization; import net.minecraft.network.chat.MutableComponent; import net.minecraft.network.chat.Style; import net.minecraft.network.chat.TextColor; @@ -28,6 +33,7 @@ import org.bukkit.craftbukkit.CraftRegistry; public final class CraftChatMessage { + private static final Gson GSON = new GsonBuilder().disableHtmlEscaping().create(); private static final Map formatMap; static { @@ -223,7 +229,11 @@ public final class CraftChatMessage { } public static String toJSON(Component component) { - return Component.Serializer.toJson(component, CraftRegistry.getMinecraftRegistry()); + return GSON.toJson( + ComponentSerialization.CODEC + .encodeStart(CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE), component) + .getOrThrow(JsonParseException::new) + ); } public static String toJSONOrNull(Component component) { @@ -234,7 +244,10 @@ public final class CraftChatMessage { public static Component fromJSON(String jsonMessage) throws JsonParseException { // Note: This also parses plain Strings to text components. // Note: An empty message (empty, or only consisting of whitespace) results in null rather than a parse exception. - return Component.Serializer.fromJson(jsonMessage, CraftRegistry.getMinecraftRegistry()); + final JsonElement jsonElement = GSON.fromJson(jsonMessage, JsonElement.class); + return jsonElement == null ? null : ComponentSerialization.CODEC.parse( + CraftRegistry.getMinecraftRegistry().createSerializationContext(JsonOps.INSTANCE), jsonElement + ).getOrThrow(JsonParseException::new); } public static Component fromJSONOrNull(String jsonMessage) { diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java index a287ad5cce..c1aad9203a 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java @@ -4,12 +4,12 @@ import ca.spottedleaf.moonrise.common.PlatformHooks; import com.google.common.base.Preconditions; import com.google.common.collect.Multimap; import com.google.common.io.Files; -import com.google.gson.Gson; import com.google.gson.JsonElement; import com.google.gson.JsonParseException; import com.google.gson.JsonParser; import com.mojang.brigadier.StringReader; import com.mojang.brigadier.exceptions.CommandSyntaxException; +import com.mojang.logging.LogUtils; import com.mojang.serialization.Dynamic; import com.mojang.serialization.JsonOps; import io.papermc.paper.registry.RegistryKey; @@ -41,7 +41,7 @@ import net.minecraft.nbt.TagParser; import net.minecraft.resources.ResourceLocation; import net.minecraft.server.MinecraftServer; import net.minecraft.server.level.ServerLevel; -import net.minecraft.util.ExtraCodecs; +import net.minecraft.util.ProblemReporter; import net.minecraft.util.datafix.DataFixers; import net.minecraft.util.datafix.fixes.References; import net.minecraft.world.entity.player.Player; @@ -50,6 +50,8 @@ import net.minecraft.world.item.alchemy.Potion; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.storage.LevelResource; +import net.minecraft.world.level.storage.TagValueInput; +import net.minecraft.world.level.storage.TagValueOutput; import org.bukkit.Bukkit; import org.bukkit.Keyed; import org.bukkit.Material; @@ -82,9 +84,13 @@ import org.bukkit.material.MaterialData; import org.bukkit.plugin.InvalidPluginException; import org.bukkit.plugin.PluginDescriptionFile; import org.bukkit.potion.PotionType; +import org.slf4j.Logger; @SuppressWarnings("deprecation") public final class CraftMagicNumbers implements UnsafeValues { + + private static final Logger LOGGER = LogUtils.getLogger(); + public static final CraftMagicNumbers INSTANCE = new CraftMagicNumbers(); public static final boolean DISABLE_OLD_API_SUPPORT = Boolean.getBoolean("paper.disableOldApiSupport"); // Paper @@ -260,27 +266,17 @@ public final class CraftMagicNumbers implements UnsafeValues { } /** - * This string should be changed if the NMS mappings do. - * - * It has no meaning and should only be used as an equality check. Plugins - * which are sensitive to the NMS mappings may read it and refuse to load if - * it cannot be found or is different to the expected value. - * - * Remember: NMS is not supported API and may break at any time for any - * reason irrespective of this. There is often supported API to do the same - * thing as many common NMS usages. If not, you are encouraged to open a - * feature and/or pull request for consideration, or use a well abstracted - * third-party API such as ProtocolLib. - * - * @return string + * @deprecated in favor of {@link io.papermc.paper.ServerBuildInfo#minecraftVersionId()} + * Paper has used Mojang mappings since 1.20.5, and this method no longer returns a useful value. */ + @Deprecated(forRemoval = true, since = "1.21.6") public String getMappingsVersion() { - return "7ecad754373a5fbc43d381d7450c53a5"; + throw new UnsupportedOperationException("Use ServerBuildInfo#minecraftVersionId instead."); } @Override public int getDataVersion() { - return SharedConstants.getCurrentVersion().getDataVersion().getVersion(); + return SharedConstants.getCurrentVersion().dataVersion().version(); } @Override @@ -491,9 +487,14 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public byte[] serializeItem(ItemStack item) { Preconditions.checkNotNull(item, "null cannot be serialized"); - Preconditions.checkArgument(item.getType() != Material.AIR, "air cannot be serialized"); + Preconditions.checkArgument(!item.isEmpty(), "Empty itemstack cannot be serialized"); - return serializeNbtToBytes((CompoundTag) (item instanceof CraftItemStack ? ((CraftItemStack) item).handle : CraftItemStack.asNMSCopy(item)).save(MinecraftServer.getServer().registryAccess())); + return serializeNbtToBytes( + (CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart( + MinecraftServer.getServer().registryAccess().createSerializationContext(NbtOps.INSTANCE), + CraftItemStack.unwrap(item) + ).getOrThrow() + ); } @Override @@ -511,7 +512,9 @@ public final class CraftMagicNumbers implements UnsafeValues { if (compound.getStringOr("id", "minecraft:air").equals("minecraft:air")) { return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.EMPTY); } - return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.parse(CraftRegistry.getMinecraftRegistry(), compound).orElseThrow()); + return CraftItemStack.asCraftMirror(net.minecraft.world.item.ItemStack.CODEC.parse( + CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE), compound + ).getOrThrow()); } @Override @@ -519,7 +522,10 @@ public final class CraftMagicNumbers implements UnsafeValues { if (itemStack.isEmpty()) { return Map.of("id", "minecraft:air", SharedConstants.DATA_VERSION_TAG, this.getDataVersion(), "schema_version", 1); } - final CompoundTag tag = CraftItemStack.asNMSCopy(itemStack).save(CraftRegistry.getMinecraftRegistry()).asCompound().orElseThrow(); + final CompoundTag tag = (CompoundTag) net.minecraft.world.item.ItemStack.CODEC.encodeStart( + CraftRegistry.getMinecraftRegistry().createSerializationContext(NbtOps.INSTANCE), + CraftItemStack.asNMSCopy(itemStack) + ).getOrThrow(); NbtUtils.addCurrentDataVersion(tag); final Map ret = new LinkedHashMap<>(); @@ -677,21 +683,25 @@ public final class CraftMagicNumbers implements UnsafeValues { } }); - CompoundTag compound = new CompoundTag(); - if (serializePassangers) { - if (!nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization)) { - throw new IllegalArgumentException("Couldn't serialize entity"); - } - } else { - List pass = new ArrayList<>(nmsEntity.getPassengers()); - nmsEntity.passengers = com.google.common.collect.ImmutableList.of(); - boolean serialized = nmsEntity.saveAsPassenger(compound, true, includeNonSaveable, forceSerialization); - nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass); - if (!serialized) { - throw new IllegalArgumentException("Couldn't serialize entity"); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "serialiseEntity@" + entity.getUniqueId(), LOGGER + )) { + final TagValueOutput output = TagValueOutput.createWithContext(problemReporter, nmsEntity.registryAccess()); + if (serializePassangers) { + if (!nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization)) { + throw new IllegalArgumentException("Couldn't serialize entity"); + } + } else { + List pass = new ArrayList<>(nmsEntity.getPassengers()); + nmsEntity.passengers = com.google.common.collect.ImmutableList.of(); + boolean serialized = nmsEntity.saveAsPassenger(output, true, includeNonSaveable, forceSerialization); + nmsEntity.passengers = com.google.common.collect.ImmutableList.copyOf(pass); + if (!serialized) { + throw new IllegalArgumentException("Couldn't serialize entity"); + } } + return serializeNbtToBytes(output.buildResult()); } - return serializeNbtToBytes(compound); } @Override @@ -714,8 +724,18 @@ public final class CraftMagicNumbers implements UnsafeValues { // Generate a new UUID, so we don't have to worry about deserializing the same entity twice compound.remove("UUID"); } - net.minecraft.world.entity.Entity nmsEntity = net.minecraft.world.entity.EntityType.create(compound, world, net.minecraft.world.entity.EntitySpawnReason.LOAD) - .orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")); + + final net.minecraft.world.entity.Entity nmsEntity; + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "deserialiseEntity", LOGGER + )) { + nmsEntity = net.minecraft.world.entity.EntityType.create( + TagValueInput.create(problemReporter, world.registryAccess(), compound), + world, + net.minecraft.world.entity.EntitySpawnReason.LOAD + ).orElseThrow(() -> new IllegalArgumentException("An ID was not found for the data. Did you downgrade?")); + } + compound.getList("Passengers").ifPresent(passengers -> { for (final Tag tag : passengers) { if (!(tag instanceof final CompoundTag serializedPassenger)) { @@ -768,7 +788,7 @@ public final class CraftMagicNumbers implements UnsafeValues { @Override public int getProtocolVersion() { - return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion(); + return net.minecraft.SharedConstants.getCurrentVersion().protocolVersion(); } @Override diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java index d62940ba24..aed42b2113 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/TransformerGeneratorAccess.java @@ -1,20 +1,26 @@ package org.bukkit.craftbukkit.util; +import com.mojang.logging.LogUtils; import net.minecraft.core.BlockPos; +import net.minecraft.util.ProblemReporter; import net.minecraft.world.entity.Entity; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.entity.BlockEntity; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.structure.StructurePiece; import net.minecraft.world.level.material.FluidState; +import net.minecraft.world.level.storage.TagValueInput; import org.bukkit.craftbukkit.block.CraftBlockEntityState; import org.bukkit.craftbukkit.block.CraftBlockState; import org.bukkit.craftbukkit.block.CraftBlockStates; import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; import org.jetbrains.annotations.Nullable; +import org.slf4j.Logger; public class TransformerGeneratorAccess extends DelegatedGeneratorAccess { + private static final Logger LOGGER = LogUtils.getLogger(); + private CraftStructureTransformer structureTransformer; public void setStructureTransformer(CraftStructureTransformer structureTransformer) { @@ -60,7 +66,13 @@ public class TransformerGeneratorAccess extends DelegatedGeneratorAccess { } BlockEntity blockEntity = this.getBlockEntity(position); if (blockEntity != null && craftBlockState instanceof CraftBlockEntityState craftEntityState) { - blockEntity.loadWithComponents(craftEntityState.getSnapshotNBT(), this.registryAccess()); + try (final ProblemReporter.ScopedCollector problemReporter = new ProblemReporter.ScopedCollector( + () -> "TransformerGeneratorAccess@" + position.toShortString(), LOGGER + )) { + blockEntity.loadWithComponents(TagValueInput.create( + problemReporter, this.registryAccess(), craftEntityState.getSnapshotNBT() + )); + } } return result; } diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java index a38d464b47..de33ea0350 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/permissions/CommandPermissions.java @@ -31,8 +31,8 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "selector", "Allows the use of selectors", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "trigger", "Allows the use of the trigger command", PermissionDefault.TRUE, commands); // Paper start - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "attribute", "Allows the user to query, add, remove or set an entity attribute", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "advancement", "Allows the user to give, remove, or check player advancements", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "attribute", "Allows the user to query, add, remove or set an entity attribute", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban", "Allows the user to add players to the ban list", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ban-ip", "Allows the user to add ip address to the ban list", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "banlist", "Allows the user to display the ban list", PermissionDefault.OP, commands); @@ -44,6 +44,7 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "datapack", "Allows the user to control loaded data packs", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "debug", "Allows the user to start or stop a debugging session", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "deop", "Allows the user to revoke operator status from a player", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "dialog", "Allows the user to show dialogs", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "difficulty", "Allows the user to set the difficulty level", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "enchant", "Allows the user to enchant a player item", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "execute", "Allows the user to execute another command", PermissionDefault.OP, commands); @@ -52,6 +53,7 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "forceload", "Allows the user to force chunks to be constantly loaded or not", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "function", "Allows the user to run a function", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "gamerule", "Allows a user to set or query a game rule value", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "item", "Allows the user to replace items in inventories", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "jfr", "Allows a user to use the vanilla Java FlightRecorder profiling system", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "locate", "Allows the user to locate the closest structure", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "loot", "Allows the user to drop items from an inventory slot onto the ground", PermissionDefault.OP, commands); @@ -60,11 +62,14 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "pardon-ip", "Allows the user to remove entries from the ip address ban list", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "particle", "Allows the user to create particles", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "perf", "Allows the user to start/stop the vanilla performance metrics capture", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "place", "Allows the user to place features and structures", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "playsound", "Allows the user to play a sound", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ride", "Allows the user to use the /ride command to control passengers", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "random", "Allows the user to generate a random number", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "recipe", "Allows the user to give or take recipes", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "reload", "Allows the user to reload loot tables, advancements, and functions from disk", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "item", "Allows the user to replace items in inventories", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "return", "Allows the user to use the /return command", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "ride", "Allows the user to use the /ride command to control passengers", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "rotate", "Allows the user to change the rotation of entities", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-all", "Allows the user to save the server to disk", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-off", "Allows the user disable automatic server saves", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "save-on", "Allows the user enable automatic server saves", PermissionDefault.OP, commands); @@ -83,17 +88,15 @@ public final class CommandPermissions { DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "teammsg", "Allows the user to specify the message to send to team", PermissionDefault.TRUE, commands); // defaults to all players DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tellraw", "Allows the user to display a JSON message to players", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "test", "Allows the user to manage and execute GameTests", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "time", "Allows the user to change or query the world's game time", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "tick", "Allows the user to control the tick rate of the server", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "time", "Allows the user to change or query the world's game time", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "title", "Allows the user to manage screen titles", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "transfer", "Allows the user to transfer to another server", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "version", "Shows info related to the server version", PermissionDefault.OP, commands); + DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "waypoint", "Allows the managment of a waypoints on the server/locator bar", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "weather", "Allows the user to set the weather", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "whitelist", "Allows the user to manage the server whitelist", PermissionDefault.OP, commands); DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "worldborder", "Allows the user to manage the world border", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "place", "Allows the user to place features and structures", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "return", "Allows the user to use the /return command", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "random", "Allows the user to generate a random number", PermissionDefault.OP, commands); - DefaultPermissions.registerPermission(CommandPermissions.PREFIX + "rotate", "Allows the user to change the rotation of entities", PermissionDefault.OP, commands); // Paper end DefaultPermissions.registerPermission("minecraft.admin.command_feedback", "Receive command broadcasts when sendCommandFeedback is true", PermissionDefault.OP, commands); diff --git a/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplayBridge b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplayBridge new file mode 100644 index 0000000000..0cda3d90dc --- /dev/null +++ b/paper-server/src/main/resources/META-INF/services/io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplayBridge @@ -0,0 +1 @@ +io.papermc.paper.datacomponent.item.attribute.AttributeModifierDisplayBridgeImpl diff --git a/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta b/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta index 6cd8d64a4f..ad394b5c35 100644 --- a/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta +++ b/paper-server/src/main/resources/data/minecraft/datapacks/paper/pack.mcmeta @@ -1,6 +1,6 @@ { "pack": { "description": "Built-in Paper Datapack", - "pack_format": 71 + "pack_format": 80 } } diff --git a/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java b/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java new file mode 100644 index 0000000000..8c6292ea17 --- /dev/null +++ b/paper-server/src/test/java/io/papermc/paper/contract/StepBasedCollectorRunBeforeTest.java @@ -0,0 +1,38 @@ +package io.papermc.paper.contract; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.function.Consumer; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.InsideBlockEffectApplier.StepBasedCollector; +import net.minecraft.world.entity.InsideBlockEffectType; +import net.minecraft.world.entity.animal.Pig; +import org.bukkit.support.environment.AllFeatures; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.mockito.Mockito; + +/** + * Simple test ensuring that the {@link StepBasedCollector} executes calls to {@link StepBasedCollector#runBefore(InsideBlockEffectType, Consumer)} + * even if the effect is never registered. + *

+ * Paper relies on this implementation detail to perform some events, specifically + * - net.minecraft.world.level.block.LayeredCauldronBlock#entityInside + */ +@AllFeatures +public class StepBasedCollectorRunBeforeTest { + + @Test + public void testExecuteRunBeforeWithoutEffect() { + final StepBasedCollector stepBasedCollector = new StepBasedCollector(); + final AtomicBoolean triggered = new AtomicBoolean(false); + final Entity entity = Mockito.mock(Entity.class); + Mockito.when(entity.isAlive()).thenReturn(true); + + stepBasedCollector.runBefore(InsideBlockEffectType.EXTINGUISH, e -> triggered.set(true)); + stepBasedCollector.applyAndClear(entity); + + Assertions.assertTrue(triggered.get()); + } + +} diff --git a/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java b/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java index 7fa18dd100..8df17d82a3 100644 --- a/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java +++ b/paper-server/src/test/java/io/papermc/paper/registry/RegistryBuilderTest.java @@ -6,7 +6,6 @@ import io.papermc.paper.registry.entry.RegistryEntryMeta; import java.util.Map; import java.util.stream.Stream; import net.minecraft.core.Registry; -import net.minecraft.resources.RegistryOps; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.bukkit.support.RegistryHelper; @@ -32,7 +31,7 @@ class RegistryBuilderTest { void testEquality(final RegistryEntryMeta.Buildable registryEntry) { // TODO remove Keyed final Registry registry = RegistryHelper.getRegistry().lookupOrThrow(registryEntry.mcKey()); for (final Map.Entry, M> entry : registry.entrySet()) { - final M built = registryEntry.builderFiller().fill(new Conversions(new RegistryOps.HolderLookupAdapter(RegistryHelper.getRegistry())), entry.getValue()).build(); + final M built = registryEntry.builderFiller().fill(Conversions.global(), entry.getValue()).build(); assertEquals(entry.getValue(), built); } } diff --git a/paper-server/src/test/java/org/bukkit/ParticleTest.java b/paper-server/src/test/java/org/bukkit/ParticleTest.java index c47ce2e5d2..ba7cfbc2b1 100644 --- a/paper-server/src/test/java/org/bukkit/ParticleTest.java +++ b/paper-server/src/test/java/org/bukkit/ParticleTest.java @@ -193,7 +193,7 @@ public class ParticleTest { } private void testVibration(Particle bukkit, net.minecraft.core.particles.ParticleType minecraft) { - Vibration vibration = new Vibration(new Location(null, 3, 1, 4), new Vibration.Destination.BlockDestination(new Location(null, 1, 5, 9)), 265); + Vibration vibration = new Vibration(new Vibration.Destination.BlockDestination(new Location(null, 1, 5, 9)), 265); VibrationParticleOption param = this.createAndTest(bukkit, minecraft, vibration, VibrationParticleOption.class); assertEquals(265, param.getArrivalInTicks(), String.format(""" diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java index c27f37fd8a..6174b21c87 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java @@ -12,6 +12,8 @@ import net.minecraft.nbt.CompoundTag; import net.minecraft.world.item.BlockItem; import net.minecraft.world.item.Item; import net.minecraft.world.item.StandingAndWallBlockItem; +import net.minecraft.world.level.block.AbstractBannerBlock; +import net.minecraft.world.level.block.AbstractSkullBlock; import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.EntityBlock; import org.bukkit.Bukkit; @@ -174,9 +176,8 @@ public class ItemMetaTest { if (block != null) { ItemStack stack = CraftItemStack.asNewCraftStack(Item.byBlock(block)); - // Command blocks aren't unit testable atm - if (stack.getType() == Material.COMMAND_BLOCK || stack.getType() == Material.CHAIN_COMMAND_BLOCK || stack.getType() == Material.REPEATING_COMMAND_BLOCK) { - return; + if (block instanceof AbstractSkullBlock || block instanceof AbstractBannerBlock) { + continue; // those blocks have a special meta } ItemMeta meta = stack.getItemMeta(); diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/YamlSerializationTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/YamlSerializationTest.java index 6ecfd6209d..dbe967a470 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/YamlSerializationTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/inventory/YamlSerializationTest.java @@ -94,8 +94,8 @@ public class YamlSerializationTest { count: 1 components: minecraft:unbreakable: '{}' - minecraft:enchantments: '{"minecraft:sharpness":2}' minecraft:tooltip_display: '{hidden_components:["minecraft:enchantments","minecraft:unbreakable"]}' + minecraft:enchantments: '{"minecraft:sharpness":2}' schema_version: 1 """.formatted(Bukkit.getUnsafe().getDataVersion())); } diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java index 5ea4bc795e..9acd445a4c 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/legacy/LegacyTest.java @@ -137,6 +137,10 @@ public class LegacyTest { Material.RESIN_BRICK, Material.POTTED_OPEN_EYEBLOSSOM, Material.POTTED_CLOSED_EYEBLOSSOM, // 1.21.5 Material.WILDFLOWERS, Material.LEAF_LITTER, Material.TEST_BLOCK, Material.TEST_INSTANCE_BLOCK, Material.BUSH, Material.FIREFLY_BUSH, Material.SHORT_DRY_GRASS, Material.TALL_DRY_GRASS, Material.CACTUS_FLOWER, Material.BLUE_EGG, Material.BROWN_EGG, + // 1.21.6 + Material.BLACK_HARNESS, Material.BLUE_HARNESS, Material.BROWN_HARNESS, Material.CYAN_HARNESS, Material.DRIED_GHAST, Material.GRAY_HARNESS, Material.GREEN_HARNESS, Material.HAPPY_GHAST_SPAWN_EGG, Material.LIGHT_BLUE_HARNESS, Material.LIGHT_GRAY_HARNESS, + Material.LIME_HARNESS, Material.MAGENTA_HARNESS, Material.ORANGE_HARNESS, Material.PINK_HARNESS, Material.PURPLE_HARNESS, Material.RED_HARNESS, Material.WHITE_HARNESS, Material.YELLOW_HARNESS, + Material.MUSIC_DISC_TEARS, // Material.LEGACY_AIR, Material.LEGACY_DEAD_BUSH, Material.LEGACY_BURNING_FURNACE, Material.LEGACY_WALL_SIGN, Material.LEGACY_REDSTONE_TORCH_OFF, Material.LEGACY_SKULL, Material.LEGACY_REDSTONE_COMPARATOR_ON, Material.LEGACY_WALL_BANNER, Material.LEGACY_MONSTER_EGG)); diff --git a/paper-server/src/test/java/org/bukkit/craftbukkit/util/ApiVersionTest.java b/paper-server/src/test/java/org/bukkit/craftbukkit/util/ApiVersionTest.java index 495dde5586..99a60be337 100644 --- a/paper-server/src/test/java/org/bukkit/craftbukkit/util/ApiVersionTest.java +++ b/paper-server/src/test/java/org/bukkit/craftbukkit/util/ApiVersionTest.java @@ -69,9 +69,9 @@ public class ApiVersionTest { public void testCurrentVersionUpdated() { ApiVersion apiVersionOne = null; try { - apiVersionOne = ApiVersion.getOrCreateVersion(SharedConstants.getCurrentVersion().getName()); + apiVersionOne = ApiVersion.getOrCreateVersion(SharedConstants.getCurrentVersion().name()); } catch (IllegalArgumentException ex) { - if (!SharedConstants.getCurrentVersion().isStable()) { + if (!SharedConstants.getCurrentVersion().stable()) { return; } } diff --git a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java index 4027734993..f5d5b112ca 100644 --- a/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java +++ b/paper-server/src/test/java/org/bukkit/registry/RegistryConversionTest.java @@ -1,6 +1,7 @@ package org.bukkit.registry; import com.google.common.base.Joiner; +import io.papermc.paper.registry.RegistryAccess; import io.papermc.paper.registry.RegistryKey; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -9,12 +10,12 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.stream.Stream; import net.minecraft.resources.ResourceKey; import org.bukkit.Keyed; import org.bukkit.Registry; import org.bukkit.craftbukkit.util.Handleable; import org.bukkit.support.environment.AllFeatures; -import org.bukkit.support.provider.RegistryArgumentProvider; import org.bukkit.support.test.RegistriesTest; import org.junit.jupiter.api.MethodOrderer; import org.junit.jupiter.api.Order; @@ -43,6 +44,12 @@ public class RegistryConversionTest { private static final Set> IMPLEMENT_HANDLE_ABLE = new HashSet<>(); + public static Stream getValues(RegistryKey registryType) { // Paper + Registry registry = RegistryAccess.registryAccess().getRegistry(registryType); // Paper + return registry.stream().map(keyed -> (Handleable) keyed) + .map(handleAble -> Arguments.of(handleAble, handleAble.getHandle())); + } + @Order(1) @RegistriesTest public void testHandleableImplementation(io.papermc.paper.registry.RegistryKey type, Class clazz) { // Paper @@ -210,7 +217,7 @@ public class RegistryConversionTest { Map notMatching = new HashMap<>(); Method method = RegistryConversionTest.MINECRAFT_TO_BUKKIT_METHODS.get(clazz); - RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper + getValues(type).map(Arguments::get).forEach(arguments -> { // Paper Keyed bukkit = (Keyed) arguments[0]; Object minecraft = arguments[1]; @@ -241,7 +248,7 @@ public class RegistryConversionTest { Map notMatching = new HashMap<>(); Method method = RegistryConversionTest.BUKKIT_TO_MINECRAFT_METHODS.get(clazz); - RegistryArgumentProvider.getValues(type).map(Arguments::get).forEach(arguments -> { // Paper + getValues(type).map(Arguments::get).forEach(arguments -> { // Paper Keyed bukkit = (Keyed) arguments[0]; Object minecraft = arguments[1]; @@ -263,7 +270,7 @@ public class RegistryConversionTest { Joiner.on('\n').withKeyValueSeparator(" got: ").join(notMatching))); } - static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.PAINTING_VARIANT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT); // Paper + static final Set> IGNORE_FOR_DIRECT_HOLDER = Set.of(RegistryKey.TRIM_MATERIAL, RegistryKey.TRIM_PATTERN, RegistryKey.INSTRUMENT, RegistryKey.BANNER_PATTERN, RegistryKey.SOUND_EVENT); // Paper /** * Minecraft registry can return a default key / value diff --git a/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java b/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java deleted file mode 100644 index beb5fc9e72..0000000000 --- a/paper-server/src/test/java/org/bukkit/support/provider/RegistryArgumentProvider.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.bukkit.support.provider; - -import java.util.stream.Stream; -import org.bukkit.Bukkit; -import org.bukkit.Keyed; -import org.bukkit.Registry; -import org.bukkit.craftbukkit.util.Handleable; -import org.bukkit.support.test.RegistryTest; -import org.junit.jupiter.api.extension.ExtensionContext; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.ArgumentsProvider; -import org.junit.jupiter.params.support.AnnotationConsumer; - -public class RegistryArgumentProvider implements ArgumentsProvider, AnnotationConsumer { - - private Class registryType; - - @Override - public void accept(RegistryTest registryTest) { - this.registryType = registryTest.value(); - } - - @Override - public Stream provideArguments(ExtensionContext extensionContext) throws Exception { - return RegistryArgumentProvider.getValues(io.papermc.paper.registry.PaperRegistryAccess.byType(this.registryType)); // Paper - } - - public static Stream getValues(io.papermc.paper.registry.RegistryKey registryType) { // Paper - Registry registry = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(registryType); // Paper - return registry.stream().map(keyed -> (Handleable) keyed) - .map(handleAble -> Arguments.of(handleAble, handleAble.getHandle())); - } -} diff --git a/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java b/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java deleted file mode 100644 index 968c90214e..0000000000 --- a/paper-server/src/test/java/org/bukkit/support/test/RegistryTest.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.bukkit.support.test; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; -import org.bukkit.Keyed; -import org.bukkit.support.provider.RegistryArgumentProvider; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.ArgumentsSource; - -@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) -@Retention(RetentionPolicy.RUNTIME) -@ArgumentsSource(RegistryArgumentProvider.class) -@ParameterizedTest -public @interface RegistryTest { - - Class value(); -} diff --git a/settings.gradle.kts b/settings.gradle.kts index a5a070cae6..db2867ddc6 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,7 +8,7 @@ pluginManagement { } plugins { - id("org.gradle.toolchains.foojay-resolver-convention") version "0.9.0" + id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" } if (!file(".git").exists()) { diff --git a/test-plugin/build.gradle.kts b/test-plugin/build.gradle.kts index 9f7d9da599..af38ca2cf1 100644 --- a/test-plugin/build.gradle.kts +++ b/test-plugin/build.gradle.kts @@ -5,7 +5,10 @@ dependencies { } tasks.processResources { - val apiVersion = rootProject.providers.gradleProperty("mcVersion").get() + var apiVersion = rootProject.providers.gradleProperty("mcVersion").get() + // Bukkit api versioning does not support suffixed versions + apiVersion = apiVersion.substringBefore('-') + val props = mapOf( "version" to project.version, "apiversion" to "\"$apiVersion\"", diff --git a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/Registration.java b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/Registration.java index 035506a505..a45dcfc151 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/Registration.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/Registration.java @@ -8,7 +8,6 @@ import io.papermc.paper.command.brigadier.argument.ArgumentTypes; import io.papermc.paper.command.brigadier.argument.RegistryArgumentExtractor; import io.papermc.paper.command.brigadier.argument.range.DoubleRangeProvider; import io.papermc.paper.command.brigadier.argument.resolvers.FinePositionResolver; -import io.papermc.paper.math.FinePosition; import io.papermc.paper.plugin.bootstrap.BootstrapContext; import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager; import io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents; diff --git a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/ExampleAdminCommand.java b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/ExampleAdminCommand.java index 83f1ebb93e..5015bfbe46 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/ExampleAdminCommand.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/ExampleAdminCommand.java @@ -8,11 +8,9 @@ import io.papermc.paper.command.brigadier.argument.ArgumentTypes; import io.papermc.paper.command.brigadier.argument.resolvers.BlockPositionResolver; import io.papermc.paper.command.brigadier.argument.resolvers.selector.PlayerSelectorArgumentResolver; import io.papermc.paper.math.BlockPosition; -import io.papermc.testplugin.TestPlugin; import net.kyori.adventure.chat.ChatType; import net.kyori.adventure.text.Component; import org.bukkit.Bukkit; -import org.bukkit.block.Block; import org.bukkit.block.BlockState; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; @@ -109,9 +107,8 @@ public class ExampleAdminCommand { BlockState state = context.getArgument("block", BlockState.class); // TODO: better block state api here? :thinking: - Block block = context.getSource().getLocation().getWorld().getBlockAt(position.blockX(), position.blockY(), position.blockZ()); - block.setType(state.getType()); - block.setBlockData(state.getBlockData()); + state.copy(position.toLocation(context.getSource().getLocation().getWorld())) + .update(true); return 1; }) diff --git a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/IceCreamTypeArgument.java b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/IceCreamTypeArgument.java index 68df9e65a3..a40a9d3521 100644 --- a/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/IceCreamTypeArgument.java +++ b/test-plugin/src/main/java/io/papermc/testplugin/brigtests/example/IceCreamTypeArgument.java @@ -1,11 +1,9 @@ package io.papermc.testplugin.brigtests.example; -import com.mojang.brigadier.Message; import com.mojang.brigadier.arguments.ArgumentType; import com.mojang.brigadier.arguments.StringArgumentType; import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.exceptions.CommandSyntaxException; -import com.mojang.brigadier.exceptions.SimpleCommandExceptionType; import com.mojang.brigadier.suggestion.Suggestions; import com.mojang.brigadier.suggestion.SuggestionsBuilder; import io.papermc.paper.command.brigadier.MessageComponentSerializer; @@ -22,10 +20,8 @@ public class IceCreamTypeArgument implements CustomArgumentType.Converted