Compare commits

99 Commits

Author SHA1 Message Date
11b4356fb4 Merge remote-tracking branch 'upstream/main'
All checks were successful
SteamWarCI Build successful
2025-05-31 19:42:03 +02:00
2ba1675c75 Replace deprecated Thread#getId usage with Thread#threadId 2025-05-29 04:59:52 -07:00
6f315356b6 Add MCUtil#toLocation from Folia
Helper methods to convert NMS world/position to Bukkit Location
2025-05-29 04:58:00 -07:00
4765010083 Improve error messages when PluginRemapper fails to initialize (#12598) 2025-05-28 12:33:25 -07:00
a033e3b9ef Fix ancient player custom name converter
Who knows for how long it's been broken, but it only came up now given DataConverter isn't applied
Fixes #12565
Supersedes #12568
2025-05-25 09:24:49 +02:00
b9d6ba243c Expose more data for MusicInstrument (#12415) 2025-05-24 17:16:54 -04:00
84ee4249c9 Add Map filled event (#12574) 2025-05-24 22:45:32 +02:00
ee3b405316 Replace spigot check with generation check 2025-05-24 22:43:48 +02:00
b8fe22c9cd Do not call EntityRemoveEvent during worldgen (#12588)
Ports the follow commits from spigot to paper.
All credits to go the respective commit authors listed below.

CraftBukkit: 3b4fd5b321f4440a2b3a67f3945739b45e6e687f

By: md_5 <git@md-5.net>
2025-05-24 22:17:42 +02:00
220b57add4 Fixs and Improvements for EndermanEscapeEvent (#12570) 2025-05-24 21:53:02 +02:00
7774243d11 Add plugin details to zip file errors (#12580)
Helps debug classloading across plugin boundaries. Zip file errors
can be thrown for multiple reasons, and they are capable of
affecting other plugins' classloading.
2025-05-24 21:18:41 +02:00
a3909f5486 [ci skip] Fix bad format for jd @link (#12581) 2025-05-24 21:17:16 +02:00
3efaf477c4 Add API for client-side signs (#11903) 2025-05-24 21:16:23 +02:00
b70bca6b69 Revert "fix: Don't hardcode checks for translation registries (#12571)"
This reverts commit f303a076bc.
2025-05-23 21:29:51 +02:00
87349c317f Fix CombatTracker stale on death (#12562) 2025-05-21 18:19:08 +02:00
f303a076bc fix: Don't hardcode checks for translation registries (#12571)
Devs can register custom Translator instances, and we can use the new `#canTranslate` method to avoid having to iterate through the whole set of sources.
2025-05-21 18:19:00 +02:00
113b18ee08 Update paperweight and Gradle wrapper (#12573) 2025-05-19 17:34:49 -07:00
fa360aa836 Add some missing annotations and an incorrect one (#12204) 2025-05-18 18:31:49 -04:00
ce0fa4c438 Replace old version command with brigadier equivalent (#12502)
---------

Co-authored-by: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
2025-05-18 16:24:02 -04:00
6f73e62ecd Add getPickItemStack (#12552) 2025-05-18 20:42:14 +02:00
7171d29985 [ci skip] Mention CAN_PLACE/CAN_BREAK component in ItemMeta (#12559) 2025-05-18 19:49:57 +02:00
358786774c [ci skip] Fix format and mentions for ItemDamageFunction (#12560) 2025-05-18 13:23:52 -04:00
cc38032bee Deprecate TeleportCause CHORUS_FRUIT for CONSUMABLE_EFFECT (#12546) 2025-05-18 16:33:21 +02:00
f1dbed072c Implement BlocksAttack DamageReduction and ItemDamage (#12538) 2025-05-18 16:31:34 +02:00
28d7df75ac Backport HeroesOfTheVillage datafixer fix
Fixes #12515
2025-05-18 16:13:19 +02:00
c000b352ad fix(bukkit-brig-forwarding-map): Invert isEmpty method (#12555) 2025-05-18 09:12:59 +02:00
841d634230 Fix ItemStack#addUnsafeEnchantment ignored for missing enchantment component (#12549) 2025-05-17 16:13:08 +02:00
369ad1706b Cached tag parser for itemstack reading (#12547) 2025-05-17 13:42:51 +02:00
d683970d40 Add FishHookStateChangeEvent (#12165) 2025-05-15 20:17:32 +02:00
a25258190b Update mache 2025-05-11 22:28:25 +02:00
04ffca0b6b Also remove CraftPlayer methods 2025-05-09 14:55:41 +02:00
358e72ec0d Remove simplify remote item matching stuff for now
Twas broken for some time and I haven't had time to address it, this may be revisited later in a different way
2025-05-09 14:47:24 +02:00
d2ad2e668d Add missing EntityLookup#getAllMapped from Moonrise
Not used but the sources should remain synced.
2025-05-07 18:31:25 -07:00
6c3964d2f5 Properly save level data async (#12530)
Previously we added a parameter allowing for level data to be saved asynchronously which was then overriden by a vanilla parameter which does the opposite.

This reverts back to the previous behavior that we were doing before.

Co-authored-by: Warrior <50800980+Warriorrrr@users.noreply.github.com>
2025-05-07 17:34:58 -04:00
cbcf75a57c Update visual fire handling with TriState support (#12303)
Replaced the Boolean-based visual fire system with TriState for improved clarity and flexibility, enabling three distinct states: TRUE, FALSE, and NOT_SET. Deprecated older methods in favor of new ones and updated internal handling to reflect these changes. Adjusted serialization and deserialization logic to accommodate the new TriState implementation.
2025-05-07 23:33:41 +02:00
ab0253fecd Expand PlayerDeathEvent API (#12221) 2025-05-06 20:14:58 -04:00
e2da5d2f0a Registry API for supported Mob Variants (#12417)
---------

Co-authored-by: Bjarne Koll <git@lynxplay.dev>
2025-05-06 17:13:00 -04:00
753cff7c8a Improvements for Dump paper commands (#12512) 2025-05-06 16:45:17 -04:00
42a2a6c2b5 Supports the ability for commands to be registered internally (#12520) 2025-05-06 16:05:00 -04:00
c98cd65802 Add configuration interface to expose certain config values (#12273) 2025-05-03 16:33:25 -04:00
53d1d04ec5 Disable Item Obfuscation for entity related stacks (#12297) 2025-05-03 20:52:33 +02:00
88a3a87015 Configurable xp orb merge group count (#12503) 2025-05-03 20:51:19 +02:00
6f1f5b67e0 Fix ArmorStand items for canceled EntityDeathEvent (#12288)
Co-authored-by: Tamion <70228790+notTamion@users.noreply.github.com>
2025-05-02 23:19:15 +02:00
2bd84f6f0e Expand PotionMeta Api to allow getting effective potion colour and effects (#12390) 2025-05-02 22:31:39 +02:00
825685f82f Add PlayerPickBlockEvent and PlayerPickEntityEvent (#12425)
Extensions of the existing PlayerPickItemEvent that allow more fine grained access to relevant context, like the picked block or the entity.
2025-05-02 22:14:27 +02:00
1074237311 Pass correct draw strength for EntityShootBowEvent (#12308) 2025-05-02 16:05:50 -04:00
d637ae85dd Fix NoSuchElementException in EntityTransformEvent for slimes (#12510) 2025-05-02 21:15:58 +02:00
cb3ffd0b4a Don't store empty PDCs on raids 2025-05-02 20:02:34 +01:00
93246a0730 Fix errors when loading raid files without a PDC 2025-05-02 19:43:06 +01:00
51345a1cc8 Correct nullable fall location type 2025-05-02 18:57:18 +02:00
ec421715ed Add missing spaces back (#12508) 2025-05-02 07:39:46 +02:00
b9b3cd652e Use components instead of ChatColor in more places (#12507) 2025-05-02 02:11:25 +02:00
1acf3b3837 Infer block entity data in brigadier blockstate argument (#12197) 2025-05-01 16:08:41 +02:00
c9411bfb83 Fix min ItemStack amount check for asHoverEvent (#12505) 2025-05-01 16:00:23 +02:00
835b955913 Add a method on InventoryView to get the MenuType (#12193)
Since there is a new (better) way to create views for players using MenuType, it would be nice to also be able to get it back from InventoryView after creating.
2025-04-30 21:43:51 -04:00
0e9b94d533 Fix ItemStack amount issues with Chat Components (#12216) 2025-04-30 21:24:49 -04:00
bc3d946fdf Normalizes CraftEntity#toString/getHandle (#12170) 2025-04-30 21:21:04 -04:00
567f63ae34 Parity for respawn events (#11792) 2025-04-30 20:04:24 +02:00
2754d7c3b9 Add Throw EntityChangeBlockEvent for BrushableBlockEntity#brush (#12133) 2025-04-30 14:03:40 -04:00
5acfdd6af4 Fix save/load NaN Entity Motion (#12269) 2025-04-30 19:53:32 +02:00
cd4fe5b7d0 [ci skip] Drop non-applicable ATs (#12498) 2025-04-30 19:30:45 +02:00
e663f99982 Add combat tracker API (#11853) 2025-04-30 19:24:33 +02:00
646b80ca53 Fix unnecessary map data saves (#12296) 2025-04-30 11:51:13 -04:00
1e930763d2 Fix ipv6 loopback addresses being able to get connection throttled (#12155) 2025-04-30 11:50:18 -04:00
a74400d92c Update adventure to 4.21.0 (#12499) 2025-04-30 11:36:52 +02:00
d4be73c990 Merge remote-tracking branch 'upstream/main'
All checks were successful
SteamWarCI Build successful
2025-04-29 19:41:25 +02:00
a7a76c8fc7 Add methods for Armadillo (#12031) 2025-04-29 15:44:37 +02:00
fc0c371761 Fix handling of resultant crafting container from craftItemResult (#12307)
The result object of overhanging items is based upon a derived view
of the provided crafting slots, meaning that we need to consider this
when handing back the resultant slots.
2025-04-29 15:38:11 +02:00
9e873f50d3 Fix inconsistencies between offline/online spawn position getter (#11960) 2025-04-29 14:57:36 +02:00
02d20ff7eb Fix NPE in Server#getMap before worlds are loaded (#12492) 2025-04-28 21:22:33 +02:00
d1810f241c Allow Server#getDefaultGameMode before worlds are initialized (#12490) 2025-04-28 17:36:46 +02:00
1db3785307 [ci skip] improve javadoc for off-hand swaps through getHotbarButton (#12489) 2025-04-28 17:22:05 +02:00
952338b33e [ci skip] Add missing exception docs to Player#listPlayer (#12488) 2025-04-28 15:00:02 +02:00
b9d3147d3b Use correct placed block position for sound (#12410)
Previously the server attempted to compute the block placed by using the
BlockPlaceContext. This approach however fails on replacable blocks, as
the BlockPlaceContext computes this during its construction, which
happened after the actual world modification.

The commit reworks this approach and now stores metadata in the
InteractionResult which can later be read.
The diff is structured to allow for easy future expansion of the tracked
metadata.
2025-04-27 14:19:42 +02:00
f8fa4f6f5e Add method to retrieve FishHook (#12310) 2025-04-27 14:12:01 +02:00
b418321d85 Merge remote-tracking branch 'upstream/main'
All checks were successful
SteamWarCI Build successful
2025-04-27 01:51:28 +02:00
3e3b42cdf5 Update player chat session sync (#12382) 2025-04-26 23:26:20 +02:00
f86b435228 Add vault change state event (#12069) 2025-04-26 16:34:12 +02:00
deaccd2c42 [ci skip] Add file reference url to help.yml (#12481) 2025-04-26 16:01:06 +02:00
58f12b93f8 Merge pull request 'Reenable commands in Commands.java' (#2) from reenable-commands into main
All checks were successful
SteamWarCI Build successful
Reviewed-on: #2
Reviewed-by: Lixfel <lixfel@noreply.localhost>
2025-04-26 09:44:06 +02:00
284f5adefd Re-enabling WhitelistCommand.
All checks were successful
SteamWarCI Build successful
2025-04-26 09:43:24 +02:00
3222985e43 [ci skip] Rebuild patches 2025-04-25 20:06:10 +02:00
1cfc96bcf7 Add keyStream() API to registries (#12479) 2025-04-25 14:26:56 +02:00
3409e2d73f Mace was not included in the ENCHANTABLE MaterialSetTag (#12476) 2025-04-25 11:25:05 +02:00
ae512811db Add isSuffocating to Block and BlockState (#12445) 2025-04-25 10:48:24 +02:00
a211ac2ec5 Remove unused warning (#12478) 2025-04-25 10:46:06 +02:00
a112d37025 Fix horse_variant and tropical_fish_pattern (#12472) 2025-04-24 22:39:33 +02:00
6652bb7612 Reenable commands in Commands.java
All checks were successful
SteamWarCI Build successful
2025-04-24 18:31:12 +02:00
9cddf136d7 Fix portal create event block list (#12373) 2025-04-24 18:10:13 +02:00
767868ddbf Fix some components (#12457) 2025-04-24 16:57:20 +02:00
1410a22bb2 Fix passengers sending when riding players
Fixes #12468
2025-04-24 13:59:28 +02:00
d05bf33c05 Fix CI
All checks were successful
SteamWarCI Build successful
2025-04-23 22:46:58 +02:00
2b50a2ea07 Trigger Rebuild
Some checks failed
SteamWarCI Build failed
2025-04-23 22:43:42 +02:00
67a5148512 Trigger Rebuild
Some checks failed
SteamWarCI Build failed
2025-04-23 22:41:22 +02:00
a5269d76c0 Trigger Rebuild
Some checks failed
SteamWarCI Build failed
2025-04-23 22:35:18 +02:00
adc22129ae Trigger Rebuild
Some checks failed
SteamWarCI Build failed
2025-04-23 22:34:35 +02:00
cf7e54ea59 Trigger Rebuild
Some checks failed
SteamWarCI Build failed
2025-04-23 22:33:21 +02:00
5d6f544ed1 Merge branch 'update/1.21.4'
Some checks failed
SteamWarCI Build failed
2025-04-23 22:32:06 +02:00
cb9578f90f Merge pull request 'Update patches to latest 1.21.4' (#1) from update/1.21.4 into main
Some checks failed
SteamWarCI Build failed
Reviewed-on: #1
2025-04-23 22:27:10 +02:00
363 changed files with 4939 additions and 2119 deletions

View File

@ -17,13 +17,8 @@ public net.minecraft.commands.arguments.blocks.BlockInput tag
public net.minecraft.core.MappedRegistry validateWrite(Lnet/minecraft/resources/ResourceKey;)V
public net.minecraft.nbt.ListTag <init>(Ljava/util/List;)V
public net.minecraft.nbt.ListTag identifyRawElementType()B
public net.minecraft.nbt.TagParser readArrayTag()Lnet/minecraft/nbt/Tag;
public net.minecraft.nbt.TagParser type(Ljava/lang/String;)Lnet/minecraft/nbt/Tag;
public net.minecraft.network.Connection address
public net.minecraft.network.Connection channel
public net.minecraft.network.chat.HoverEvent$ItemStackInfo components
public net.minecraft.network.chat.HoverEvent$ItemStackInfo count
public net.minecraft.network.chat.HoverEvent$ItemStackInfo item
public net.minecraft.network.chat.TextColor name
public net.minecraft.network.chat.contents.TranslatableContents filterAllowedArguments(Ljava/lang/Object;)Lcom/mojang/serialization/DataResult;
public net.minecraft.network.chat.numbers.FixedFormat value
@ -108,14 +103,12 @@ public net.minecraft.server.level.ServerPlayer triggerDimensionChangeTriggers(Ln
public net.minecraft.server.level.ServerPlayer wardenSpawnTracker
public net.minecraft.server.level.ServerPlayer$RespawnPosAngle
public net.minecraft.server.level.ServerPlayerGameMode level
public net.minecraft.server.level.Ticket key
public net.minecraft.server.level.TicketType register(Ljava/lang/String;JZLnet/minecraft/server/level/TicketType$TicketUse;)Lnet/minecraft/server/level/TicketType;
public net.minecraft.server.network.ServerGamePacketListenerImpl isChatMessageIllegal(Ljava/lang/String;)Z
public net.minecraft.server.network.ServerLoginPacketListenerImpl authenticatedProfile
public net.minecraft.server.network.ServerLoginPacketListenerImpl connection
public net.minecraft.server.network.ServerLoginPacketListenerImpl state
public net.minecraft.server.network.ServerLoginPacketListenerImpl$State
public net.minecraft.server.packs.VanillaPackResourcesBuilder safeGetPath(Ljava/net/URI;)Ljava/nio/file/Path;
public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector
public net.minecraft.server.packs.repository.FolderRepositorySource$FolderPackDetector <init>(Lnet/minecraft/world/level/validation/DirectoryValidator;)V
public net.minecraft.server.packs.repository.Pack resources
@ -129,7 +122,6 @@ public net.minecraft.tags.TagEntry id
public net.minecraft.tags.TagEntry required
public net.minecraft.tags.TagEntry tag
public net.minecraft.util.datafix.fixes.BlockStateData register(ILcom/mojang/serialization/Dynamic;[Lcom/mojang/serialization/Dynamic;)V
public net.minecraft.util.datafix.fixes.EntityCustomNameToComponentFix fixCustomName(Lcom/mojang/serialization/DynamicOps;Ljava/lang/String;Ljava/lang/String;)Lcom/mojang/serialization/Dynamic;
public net.minecraft.util.datafix.fixes.ItemIdFix ITEM_NAMES
public net.minecraft.util.datafix.fixes.ItemSpawnEggFix ID_TO_ENTITY
public net.minecraft.world.BossEvent color
@ -138,6 +130,11 @@ public net.minecraft.world.BossEvent overlay
public net.minecraft.world.CompoundContainer container1
public net.minecraft.world.CompoundContainer container2
public net.minecraft.world.SimpleContainer items
public net.minecraft.world.damagesource.CombatTracker entries
public net.minecraft.world.damagesource.CombatTracker getMostSignificantFall()Lnet/minecraft/world/damagesource/CombatEntry;
public net.minecraft.world.damagesource.CombatTracker inCombat
public net.minecraft.world.damagesource.CombatTracker mob
public net.minecraft.world.damagesource.CombatTracker takingDamage
public net.minecraft.world.damagesource.DamageSource <init>(Lnet/minecraft/core/Holder;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/entity/Entity;Lnet/minecraft/world/phys/Vec3;)V
public net.minecraft.world.effect.MobEffect attributeModifiers
public net.minecraft.world.effect.MobEffect$AttributeTemplate
@ -198,7 +195,6 @@ public net.minecraft.world.entity.Entity getSwimSound()Lnet/minecraft/sounds/Sou
public net.minecraft.world.entity.Entity getSwimSplashSound()Lnet/minecraft/sounds/SoundEvent;
public net.minecraft.world.entity.Entity hasVisualFire
public net.minecraft.world.entity.Entity isAffectedByBlocks()Z
public net.minecraft.world.entity.Entity isInBubbleColumn()Z
public net.minecraft.world.entity.Entity isInRain()Z
public net.minecraft.world.entity.Entity isInvulnerableToBase(Lnet/minecraft/world/damagesource/DamageSource;)Z
public net.minecraft.world.entity.Entity onGround
@ -213,7 +209,6 @@ public net.minecraft.world.entity.Entity unsetRemoved()V
public net.minecraft.world.entity.Entity wasTouchingWater
public net.minecraft.world.entity.ExperienceOrb count
public net.minecraft.world.entity.ExperienceOrb setValue(I)V
public net.minecraft.world.entity.ExperienceOrb value
public net.minecraft.world.entity.GlowSquid setDarkTicks(I)V
public net.minecraft.world.entity.Interaction attack
public net.minecraft.world.entity.Interaction getHeight()F
@ -248,14 +243,10 @@ public net.minecraft.world.entity.LivingEntity lastHurtByMob
public net.minecraft.world.entity.LivingEntity lastHurtByMobTimestamp
public net.minecraft.world.entity.LivingEntity lastHurtByPlayer
public net.minecraft.world.entity.LivingEntity lastHurtByPlayerMemoryTime
public net.minecraft.world.entity.LivingEntity lastHurtByPlayerTime
public net.minecraft.world.entity.LivingEntity playSecondaryHurtSound(Lnet/minecraft/world/damagesource/DamageSource;)V
public net.minecraft.world.entity.LivingEntity setLivingEntityFlag(IZ)V
public net.minecraft.world.entity.LivingEntity useItemRemaining
public net.minecraft.world.entity.Mob armorDropChances
public net.minecraft.world.entity.Mob getAmbientSound()Lnet/minecraft/sounds/SoundEvent;
public net.minecraft.world.entity.Mob getEquipmentDropChance(Lnet/minecraft/world/entity/EquipmentSlot;)F
public net.minecraft.world.entity.Mob handDropChances
public net.minecraft.world.entity.Mob isSunBurnTick()Z
public net.minecraft.world.entity.Mob lootTable
public net.minecraft.world.entity.Mob lootTableSeed
@ -431,7 +422,6 @@ public net.minecraft.world.entity.npc.Villager setUnhappy()V
public net.minecraft.world.entity.npc.WanderingTrader getWanderTarget()Lnet/minecraft/core/BlockPos;
public net.minecraft.world.entity.player.Abilities flyingSpeed
public net.minecraft.world.entity.player.Abilities walkingSpeed
public net.minecraft.world.entity.player.Inventory compartments
public net.minecraft.world.entity.player.Inventory equipment
public net.minecraft.world.entity.player.Player DATA_PLAYER_MODE_CUSTOMISATION
public net.minecraft.world.entity.player.Player closeContainer()V
@ -492,7 +482,6 @@ public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaY
public net.minecraft.world.entity.projectile.ShulkerBullet targetDeltaZ
public net.minecraft.world.entity.projectile.SpectralArrow duration
public net.minecraft.world.entity.projectile.ThrowableItemProjectile getDefaultItem()Lnet/minecraft/world/item/Item;
public net.minecraft.world.entity.projectile.ThrownPotion isLingering()Z
public net.minecraft.world.entity.projectile.ThrownTrident dealtDamage
public net.minecraft.world.entity.projectile.windcharge.AbstractWindCharge explode(Lnet/minecraft/world/phys/Vec3;)V
public net.minecraft.world.entity.projectile.windcharge.BreezeWindCharge explode(Lnet/minecraft/world/phys/Vec3;)V
@ -522,6 +511,7 @@ public net.minecraft.world.flag.FeatureFlagRegistry names
public net.minecraft.world.food.FoodData exhaustionLevel
public net.minecraft.world.food.FoodData foodLevel
public net.minecraft.world.food.FoodData saturationLevel
public net.minecraft.world.inventory.AbstractContainerMenu menuType
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftSlots
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftStatus
public net.minecraft.world.inventory.AbstractContainerMenu quickcraftType
@ -558,7 +548,6 @@ public net.minecraft.world.item.context.UseOnContext <init>(Lnet/minecraft/world
public net.minecraft.world.item.crafting.RecipeManager recipes
public net.minecraft.world.item.crafting.RecipeMap byKey
public net.minecraft.world.item.crafting.RecipeMap byType
public net.minecraft.world.item.enchantment.ItemEnchantments showInTooltip
public net.minecraft.world.item.trading.MerchantOffer demand
public net.minecraft.world.item.trading.MerchantOffer result
public net.minecraft.world.item.trading.MerchantOffer specialPriceDiff
@ -777,7 +766,6 @@ public-f net.minecraft.world.inventory.AbstractContainerMenu lastSlots
public-f net.minecraft.world.inventory.AbstractContainerMenu remoteDataSlots
public-f net.minecraft.world.inventory.AbstractContainerMenu remoteSlots
public-f net.minecraft.world.inventory.AbstractContainerMenu slots
public-f net.minecraft.world.item.enchantment.ItemEnchantments$Mutable showInTooltip
public-f net.minecraft.world.item.trading.MerchantOffer baseCostA
public-f net.minecraft.world.item.trading.MerchantOffer costB
public-f net.minecraft.world.item.trading.MerchantOffer maxUses

View File

@ -2,7 +2,7 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
plugins {
id("io.papermc.paperweight.core") version "2.0.0-beta.16" apply false
id("io.papermc.paperweight.core") version "2.0.0-beta.17" apply false
}
subprojects {

Binary file not shown.

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

6
gradlew vendored
View File

@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM.
@ -205,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.
@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"
# Stop when "xargs" is not available.

4
gradlew.bat vendored
View File

@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end
@rem End local scope for the variables with windows NT shell

View File

@ -11,8 +11,7 @@ java {
val annotationsVersion = "26.0.2"
// Keep in sync with paper-server adventure-text-serializer-ansi dep
val adventureVersion = "4.21.0-mc1215-SNAPSHOT" // FIXME move to release asap
val adventureJavadocVersion = "4.20.0" // Fixme remove me
val adventureVersion = "4.21.0"
val bungeeCordChatVersion = "1.21-R0.2-deprecated+build.21"
val slf4jVersion = "2.0.16"
val log4jVersion = "2.24.1"
@ -58,15 +57,13 @@ dependencies {
exclude("com.google.guava", "guava")
}
// FIXME remove me when we are using a release again
val adventureGroup = "io.papermc.adventure"
apiAndDocs(platform("$adventureGroup:adventure-bom:$adventureVersion"))
apiAndDocs("$adventureGroup:adventure-api")
apiAndDocs("$adventureGroup:adventure-text-minimessage")
apiAndDocs("$adventureGroup:adventure-text-serializer-gson")
apiAndDocs("$adventureGroup:adventure-text-serializer-legacy")
apiAndDocs("$adventureGroup:adventure-text-serializer-plain")
apiAndDocs("$adventureGroup:adventure-text-logger-slf4j")
apiAndDocs(platform("net.kyori:adventure-bom:$adventureVersion"))
apiAndDocs("net.kyori:adventure-api")
apiAndDocs("net.kyori:adventure-text-minimessage")
apiAndDocs("net.kyori:adventure-text-serializer-gson")
apiAndDocs("net.kyori:adventure-text-serializer-legacy")
apiAndDocs("net.kyori:adventure-text-serializer-plain")
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
api("org.apache.maven:maven-resolver-provider:3.9.6") // make API dependency for Paper Plugins
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
@ -179,13 +176,13 @@ tasks.withType<Javadoc> {
"https://javadoc.io/doc/org.joml/joml/1.10.8/",
"https://www.javadoc.io/doc/com.google.code.gson/gson/2.11.0",
"https://jspecify.dev/docs/api/",
"https://jd.advntr.dev/api/$adventureJavadocVersion/",
"https://jd.advntr.dev/key/$adventureJavadocVersion/",
"https://jd.advntr.dev/text-minimessage/$adventureJavadocVersion/",
"https://jd.advntr.dev/text-serializer-gson/$adventureJavadocVersion/",
"https://jd.advntr.dev/text-serializer-legacy/$adventureJavadocVersion/",
"https://jd.advntr.dev/text-serializer-plain/$adventureJavadocVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureJavadocVersion/",
"https://jd.advntr.dev/api/$adventureVersion/",
"https://jd.advntr.dev/key/$adventureVersion/",
"https://jd.advntr.dev/text-minimessage/$adventureVersion/",
"https://jd.advntr.dev/text-serializer-gson/$adventureVersion/",
"https://jd.advntr.dev/text-serializer-legacy/$adventureVersion/",
"https://jd.advntr.dev/text-serializer-plain/$adventureVersion/",
"https://jd.advntr.dev/text-logger-slf4j/$adventureVersion/",
"https://javadoc.io/doc/org.slf4j/slf4j-api/$slf4jVersion/",
"https://logging.apache.org/log4j/2.x/javadoc/log4j-api/",
"https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3",

View File

@ -568,8 +568,8 @@ public class MaterialTags {
Material.FLINT_AND_STEEL, Material.CARROT_ON_A_STICK, Material.WARPED_FUNGUS_ON_A_STICK,
Material.BRUSH, Material.CARVED_PUMPKIN, Material.COMPASS, Material.SKELETON_SKULL,
Material.WITHER_SKELETON_SKULL, Material.PLAYER_HEAD, Material.ZOMBIE_HEAD,
Material.CREEPER_HEAD, Material.DRAGON_HEAD, Material.PIGLIN_HEAD)
.ensureSize("ENCHANTABLE", 75).lock();
Material.CREEPER_HEAD, Material.DRAGON_HEAD, Material.PIGLIN_HEAD, Material.MACE)
.ensureSize("ENCHANTABLE", 76).lock();
/**
* Covers the variants of raw ores.

View File

@ -27,7 +27,9 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
}
/**
* @return The reason the enderman is trying to escape
* Gets the reason the enderman is trying to escape.
*
* @return The reason
*/
public Reason getReason() {
return this.reason;
@ -42,7 +44,8 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
* Cancels the escape.
* <p>
* If this escape normally had resulted in damage avoidance such as indirect,
* the enderman will now take damage.
* the enderman will now take damage. However, this does not change the Enderman's
* innate immunities or damage behavior like arrows where the damage never happens.
*/
@Override
public void setCancelled(final boolean cancel) {
@ -76,7 +79,7 @@ public class EndermanEscapeEvent extends EntityEvent implements Cancellable {
*/
STARE,
/**
* Specific case for {@link #CRITICAL_HIT} where the enderman is taking rain damage
* Specific case for {@link #CRITICAL_HIT} where the enderman is taking damage by drowning (ex: rain)
*/
DROWN
}

View File

@ -1,9 +1,10 @@
package com.destroystokyo.paper.event.player;
import io.papermc.paper.event.player.AbstractRespawnEvent;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ -11,36 +12,31 @@ import org.jspecify.annotations.NullMarked;
* Fired after a player has respawned
*/
@NullMarked
public class PlayerPostRespawnEvent extends PlayerEvent {
public class PlayerPostRespawnEvent extends AbstractRespawnEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final Location respawnedLocation;
private final boolean isBedSpawn;
@ApiStatus.Internal
public PlayerPostRespawnEvent(final Player respawnPlayer, final Location respawnedLocation, final boolean isBedSpawn) {
super(respawnPlayer);
this.respawnedLocation = respawnedLocation;
this.isBedSpawn = isBedSpawn;
public PlayerPostRespawnEvent(
final Player respawnPlayer,
final Location respawnLocation,
final boolean isBedSpawn,
final boolean isAnchorSpawn,
final boolean missingRespawnBlock,
final PlayerRespawnEvent.RespawnReason respawnReason
) {
super(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, missingRespawnBlock, respawnReason);
}
/**
* Returns the location of the respawned player
* Returns the location of the respawned player.
*
* @return location of the respawned player
* @see #getRespawnLocation()
*/
@ApiStatus.Obsolete
public Location getRespawnedLocation() {
return this.respawnedLocation.clone();
}
/**
* Checks if the player respawned to their bed
*
* @return whether the player respawned to their bed
*/
public boolean isBedSpawn() {
return this.isBedSpawn;
return super.getRespawnLocation();
}
@Override

View File

@ -119,7 +119,7 @@ public class AsyncTabCompleteEvent extends Event implements Cancellable {
* the standard process of calling {@link Command#tabComplete(CommandSender, String, String[])}
* or current player names will not be called.
* <p>
* The passed collection will be cloned to a new {@code List}. You must call {{@link #getCompletions()}} to mutate from here
* The passed collection will be cloned to a new {@code List}. You must call {@link #getCompletions()} to mutate from here
*
* @param completions the new completions
*/

View File

@ -21,12 +21,24 @@ public interface VersionFetcher {
/**
* Gets the version message to cache and show to command senders.
*
* <p>NOTE: This is run in a new thread separate from that of the command processing thread</p>
* @return the message to show when requesting a version
* @apiNote This method may involve a web request which will block the executing thread
*/
Component getVersionMessage();
/**
* Gets the version message to cache and show to command senders.
*
* @param serverVersion the current version of the server (will match {@link Bukkit#getVersion()})
* @return the message to show when requesting a version
* @apiNote This method may involve a web request which will block the current thread
* @see #getVersionMessage()
* @deprecated {@code serverVersion} is not required
*/
Component getVersionMessage(String serverVersion);
@Deprecated
default Component getVersionMessage(String serverVersion) {
return getVersionMessage();
}
@ApiStatus.Internal
class DummyVersionFetcher implements VersionFetcher {
@ -37,7 +49,7 @@ public interface VersionFetcher {
}
@Override
public Component getVersionMessage(final String serverVersion) {
public Component getVersionMessage() {
Bukkit.getLogger().warning("Version provider has not been set, cannot check for updates!");
Bukkit.getLogger().info("Override the default implementation of org.bukkit.UnsafeValues#getVersionFetcher()");
new Throwable().printStackTrace();

View File

@ -1,10 +1,15 @@
package io.papermc.paper;
import io.papermc.paper.world.damagesource.CombatEntry;
import io.papermc.paper.world.damagesource.FallLocationType;
import net.kyori.adventure.util.Services;
import org.bukkit.block.Biome;
import org.bukkit.damage.DamageEffect;
import org.bukkit.damage.DamageSource;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Static bridge to the server internals.
@ -45,5 +50,28 @@ public interface InternalAPIBridge {
@Deprecated(forRemoval = true, since = "1.21.5")
@ApiStatus.ScheduledForRemoval(inVersion = "1.22")
Biome constructLegacyCustomBiome();
/**
* Creates a new combat entry.
* <p>
* The fall location and fall distance will be calculated from the entity's current state.
*
* @param entity entity
* @param damageSource damage source
* @param damage damage amount
* @return new combat entry
*/
CombatEntry createCombatEntry(LivingEntity entity, DamageSource damageSource, float damage);
/**
* Creates a new combat entry
*
* @param damageSource damage source
* @param damage damage amount
* @param fallLocationType fall location type
* @param fallDistance fall distance
* @return combat entry
*/
CombatEntry createCombatEntry(DamageSource damageSource, float damage, @Nullable FallLocationType fallLocationType, float fallDistance);
}

View File

@ -15,5 +15,9 @@ public enum CommandRegistrationFlag {
* @deprecated This is the default behavior now.
*/
@Deprecated(since = "1.21.4")
FLATTEN_ALIASES
FLATTEN_ALIASES,
/**
* Prevents this command from being sent to the client.
*/
SERVER_ONLY
}

View File

@ -0,0 +1,24 @@
package io.papermc.paper.configuration;
/**
* Represents the configuration settings for a server.
* <p>
* This interface doesn't aim to cover every possible server configuration
* option but focuses on selected critical settings and behaviors.
*/
public interface ServerConfiguration {
/**
* Gets whether the server is in online mode.
* <p>
* This method returns true if:
* <ul>
* <li>The server is in {@link org.bukkit.Server#getOnlineMode online mode},</li>
* <li>Velocity is enabled and configured to be in online mode, or</li>
* <li>BungeeCord is enabled and configured to be in online mode.</li>
* </ul>
*
* @return whether the server is in online mode or behind a proxy configured for online mode
*/
boolean isProxyOnlineMode();
}

View File

@ -367,7 +367,7 @@ public final class DataComponentTypes {
// 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> CHICKEN_VARIANT = valued("chicken/variant");
public static final DataComponentType.Valued<Frog.Variant> FROG_VARIANT = valued("frog/variant");
public static final DataComponentType.Valued<Horse.Style> HORSE_VARIANT = valued("horse/variant");
public static final DataComponentType.Valued<Horse.Color> HORSE_VARIANT = valued("horse/variant");
public static final DataComponentType.Valued<Art> PAINTING_VARIANT = valued("painting/variant");
public static final DataComponentType.Valued<Llama.Color> LLAMA_VARIANT = valued("llama/variant");
public static final DataComponentType.Valued<Axolotl.Variant> AXOLOTL_VARIANT = valued("axolotl/variant");

View File

@ -1,6 +1,8 @@
package io.papermc.paper.datacomponent.item;
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 net.kyori.adventure.key.Key;
import org.bukkit.damage.DamageType;
@ -8,8 +10,13 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.List;
// TODO
/**
* Holds block attacks to the holding player like Shield.
*
* @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
*/
@NullMarked
@ApiStatus.Experimental
@ApiStatus.NonExtendable
@ -20,19 +27,59 @@ public interface BlocksAttacks {
return ItemComponentTypesBridge.bridge().blocksAttacks();
}
/**
* Gets the amount of time (in seconds) that use must be held before successfully blocking attacks.
*
* @return the delay in seconds
*/
float blockDelaySeconds();
/**
* Gets the multiplier applied to the cooldown time for the item when attacked by a disabling attack (the multiplier for {@link Weapon#disableBlockingForSeconds()}).
* <br>
* If set to 0, this item can never be disabled by attacks.
*
* @return the multiplier for the cooldown time
*/
float disableCooldownScale();
//List<DamageReduction> damageReductions();
/**
* Gets a list of {@link DamageReduction} of how much damage should be blocked in a given attack.
*
* @return a list of damage reductions
*/
List<DamageReduction> damageReductions();
//ItemDamageFunction itemDamage();
/**
* Gets how much damage should be applied to the item from a given attack.
*
* @return the damage function
*/
ItemDamageFunction itemDamage();
@Nullable TagKey<DamageType> bypassedBy();
/**
* Gets the DamageType that can bypass the blocking.
*
* @return a damage type tag key, or null if there is no such tag key
*/
@Nullable
TagKey<DamageType> bypassedBy();
@Nullable Key blockSound();
/**
* Gets the key sound to play when an attack is successfully blocked.
*
* @return a key of the sound
*/
@Nullable
Key blockSound();
@Nullable Key disableSound();
/**
* 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();
/**
* Builder for {@link BlocksAttacks}.
@ -47,14 +94,14 @@ public interface BlocksAttacks {
@Contract(value = "_ -> this", mutates = "this")
Builder disableCooldownScale(float scale);
//@Contract(value = "_ -> this", mutates = "this")
//Builder addDamageReduction(DamageReduction reduction);
@Contract(value = "_ -> this", mutates = "this")
Builder addDamageReduction(DamageReduction reduction);
//@Contract(value = "_ -> this", mutates = "this")
//Builder damageReductions(List<DamageReduction> reductions);
@Contract(value = "_ -> this", mutates = "this")
Builder damageReductions(List<DamageReduction> reductions);
//@Contract(value = "_ -> this", mutates = "this")
//Builder itemDamage(ItemDamageFunction function);
@Contract(value = "_ -> this", mutates = "this")
Builder itemDamage(ItemDamageFunction function);
@Contract(value = "_ -> this", mutates = "this")
Builder bypassedBy(@Nullable TagKey<DamageType> bypassedBy);

View File

@ -60,6 +60,27 @@ public interface PotionContents {
@Contract(pure = true)
@Nullable String customName();
/**
* All effects that this component applies.
* <p>
* This is a combination of the base potion type and any custom effects.
*
* @return an unmodifiable list of all effects.
*/
@Contract(pure = true)
@Unmodifiable List<PotionEffect> allEffects();
/**
* Computes the effective colour of this potion contents component.
* <p>
* This blends all custom effects, or uses a default fallback colour.
* It may or may not have an alpha channel, used for tipped arrows.
*
* @return the effective colour this component would display with.
*/
@Contract(pure = true)
Color computeEffectiveColor();
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends DataComponentBuilder<PotionContents> {

View File

@ -0,0 +1,21 @@
package io.papermc.paper.datacomponent.item.blocksattacks;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import java.util.Optional;
import java.util.ServiceLoader;
@NullMarked
@ApiStatus.Internal
interface BlocksAttacksBridge {
Optional<BlocksAttacksBridge> BRIDGE = ServiceLoader.load(BlocksAttacksBridge.class).findFirst();
static BlocksAttacksBridge bridge() {
return BRIDGE.orElseThrow();
}
DamageReduction.Builder blocksAttacksDamageReduction();
ItemDamageFunction.Builder blocksAttacksItemDamageFunction();
}

View File

@ -0,0 +1,78 @@
package io.papermc.paper.datacomponent.item.blocksattacks;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import io.papermc.paper.registry.set.RegistryKeySet;
import org.bukkit.damage.DamageType;
import org.checkerframework.checker.index.qual.Positive;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Hold how much damage should be blocked in a given attack.
*
* @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
* @see io.papermc.paper.datacomponent.item.BlocksAttacks#damageReductions()
*/
@NullMarked
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface DamageReduction {
@Contract(value = "-> new", pure = true)
static DamageReduction.Builder damageReduction() {
return BlocksAttacksBridge.bridge().blocksAttacksDamageReduction();
}
/**
* The damage types to block.
*
* @return the set of damage type
*/
@Nullable
RegistryKeySet<DamageType> type();
/**
* Get the maximum angle between the users facing direction and the direction of the incoming attack to be blocked.
*
* @return the angle
*/
@Positive
float horizontalBlockingAngle();
/**
* Get the constant amount of damage to be blocked.
*
* @return the base
*/
float base();
/**
* Get the fraction of the dealt damage to be blocked.
*
* @return the factor
*/
float factor();
/**
* Builder for {@link DamageReduction}.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends DataComponentBuilder<DamageReduction> {
@Contract(value = "_ -> this", mutates = "this")
DamageReduction.Builder type(RegistryKeySet<DamageType> type);
@Contract(value = "_ -> this", mutates = "this")
DamageReduction.Builder horizontalBlockingAngle(@Positive float horizontalBlockingAngle);
@Contract(value = "_ -> this", mutates = "this")
DamageReduction.Builder base(float base);
@Contract(value = "_ -> this", mutates = "this")
DamageReduction.Builder factor(float factor);
}
}

View File

@ -0,0 +1,71 @@
package io.papermc.paper.datacomponent.item.blocksattacks;
import io.papermc.paper.datacomponent.DataComponentBuilder;
import org.checkerframework.checker.index.qual.NonNegative;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NullMarked;
/**
* Hold how much damage should be applied to the item from a given attack.
*
* @see io.papermc.paper.datacomponent.DataComponentTypes#BLOCKS_ATTACKS
* @see io.papermc.paper.datacomponent.item.BlocksAttacks#itemDamage()
*/
@NullMarked
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface ItemDamageFunction {
@Contract(value = "-> new", pure = true)
static ItemDamageFunction.Builder itemDamageFunction() {
return BlocksAttacksBridge.bridge().blocksAttacksItemDamageFunction();
}
/**
* Get the minimum amount of damage dealt by the attack before item damage is applied to the item.
*
* @return the threshold
*/
@NonNegative
float threshold();
/**
* Get the constant amount of damage applied to the item, if threshold is passed.
*
* @return the base
*/
float base();
/**
* Get the fraction of the dealt damage that should be applied to the item, if threshold is passed.
*
* @return the factor
*/
float factor();
/**
* Get the damage to apply for the item.
*
* @apiNote this doesn't apply enchantments like {@link org.bukkit.enchantments.Enchantment#UNBREAKING}
* @return the damage to apply
*/
int damageToApply(float damage);
/**
* Builder for {@link ItemDamageFunction}.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends DataComponentBuilder<ItemDamageFunction> {
@Contract(value = "_ -> this", mutates = "this")
ItemDamageFunction.Builder threshold(@NonNegative final float threshold);
@Contract(value = "_ -> this", mutates = "this")
ItemDamageFunction.Builder base(final float base);
@Contract(value = "_ -> this", mutates = "this")
ItemDamageFunction.Builder factor(final float factor);
}
}

View File

@ -0,0 +1,79 @@
package io.papermc.paper.event.block;
import com.google.common.base.Preconditions;
import org.bukkit.block.Block;
import org.bukkit.block.data.type.Vault;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.block.BlockEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Called when a vault block changes state.
*/
@NullMarked
public class VaultChangeStateEvent extends BlockEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final @Nullable Player player;
private final Vault.State currentState;
private final Vault.State newState;
private boolean cancelled = false;
@ApiStatus.Internal
public VaultChangeStateEvent(final Block vaultBlock, final @Nullable Player player, final Vault.State currentState, final Vault.State newState) {
super(vaultBlock);
this.player = player;
this.currentState = currentState;
this.newState = newState;
}
/**
* Gets the player associated with this state change, if applicable.
*
* @return The associated player, or {@code null} if not known.
*/
public @Nullable Player getPlayer() {
return this.player;
}
/**
* Gets the state the vault is currently in.
*
* @return The current vault state.
*/
public Vault.State getCurrentState() {
return currentState;
}
/**
* Gets the state the vault is attempting to transition to.
*
* @return The new vault state.
*/
public Vault.State getNewState() {
return newState;
}
@Override
public boolean isCancelled() {
return this.cancelled;
}
@Override
public void setCancelled(final boolean cancel) {
this.cancelled = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -0,0 +1,52 @@
package io.papermc.paper.event.entity;
import org.bukkit.entity.FishHook;
import org.bukkit.event.HandlerList;
import org.bukkit.event.entity.EntityEvent;
import org.bukkit.event.player.PlayerFishEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Called just before a {@link FishHook}'s {@link FishHook.HookState} is changed.
*
* <p>If you want to monitor a player's fishing state transition, you can use {@link PlayerFishEvent}.</p>
*/
@NullMarked
public final class FishHookStateChangeEvent extends EntityEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final FishHook.HookState newHookState;
@ApiStatus.Internal
public FishHookStateChangeEvent(final FishHook entity, final FishHook.HookState newHookState) {
super(entity);
this.newHookState = newHookState;
}
/**
* Get the <strong>new</strong> hook state of the {@link FishHook}.
*
* <p>Refer to {@link FishHook#getState()} to get the current hook state.</p>
*
* @return the <strong>new</strong> hook state
*/
public FishHook.HookState getNewHookState() {
return this.newHookState;
}
@Override
public FishHook getEntity() {
return (FishHook) super.getEntity();
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -0,0 +1,94 @@
package io.papermc.paper.event.packet;
import io.papermc.paper.math.BlockPosition;
import io.papermc.paper.math.Position;
import java.util.Collections;
import java.util.List;
import net.kyori.adventure.text.Component;
import org.bukkit.block.sign.Side;
import org.bukkit.entity.Player;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
/**
* Called when a client attempts to modify a sign, but the location at which the sign should be edited
* has not yet been checked for the existence of a real sign.
* <p>
* Cancelling this event will prevent further processing of the sign change, but needs further handling
* by the plugin as the client's local world might be in an inconsistent state.
*
* @see Player#openVirtualSign(Position, Side)
*/
@NullMarked
@ApiStatus.Experimental
public class UncheckedSignChangeEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private boolean cancel = false;
private final BlockPosition editedBlockPosition;
private final Side side;
private final List<Component> lines;
@ApiStatus.Internal
public UncheckedSignChangeEvent(
final Player editor,
final BlockPosition editedBlockPosition,
final Side side,
final List<Component> lines
) {
super(editor);
this.editedBlockPosition = editedBlockPosition;
this.side = side;
this.lines = lines;
}
/**
* Gets the location at which a potential sign was edited.
*
* @return location where the change happened
*/
public BlockPosition getEditedBlockPosition() {
return editedBlockPosition;
}
/**
* Gets which side of the sign was edited.
*
* @return {@link Side} that was edited
*/
public Side getSide() {
return side;
}
/**
* Gets the lines that the player has entered.
*
* @return the lines
*/
public @Unmodifiable List<Component> lines() {
return Collections.unmodifiableList(lines);
}
@Override
public boolean isCancelled() {
return cancel;
}
@Override
public void setCancelled(final boolean cancel) {
this.cancel = cancel;
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -0,0 +1,98 @@
package io.papermc.paper.event.player;
import com.google.common.collect.ImmutableSet;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.event.player.PlayerRespawnEvent;
import org.jetbrains.annotations.Unmodifiable;
import org.jspecify.annotations.NullMarked;
import java.util.Set;
@NullMarked
public abstract class AbstractRespawnEvent extends PlayerEvent {
protected Location respawnLocation;
private final boolean isBedSpawn;
private final boolean isAnchorSpawn;
private final boolean missingRespawnBlock;
private final PlayerRespawnEvent.RespawnReason respawnReason;
private final Set<PlayerRespawnEvent.RespawnFlag> respawnFlags;
protected AbstractRespawnEvent(
final Player respawnPlayer, final Location respawnLocation, final boolean isBedSpawn,
final boolean isAnchorSpawn, final boolean missingRespawnBlock, final PlayerRespawnEvent.RespawnReason respawnReason
) {
super(respawnPlayer);
this.respawnLocation = respawnLocation;
this.isBedSpawn = isBedSpawn;
this.isAnchorSpawn = isAnchorSpawn;
this.missingRespawnBlock = missingRespawnBlock;
this.respawnReason = respawnReason;
ImmutableSet.Builder<PlayerRespawnEvent.RespawnFlag> builder = ImmutableSet.builder();
if (respawnReason == PlayerRespawnEvent.RespawnReason.END_PORTAL) builder.add(PlayerRespawnEvent.RespawnFlag.END_PORTAL);
if (this.isBedSpawn) builder.add(PlayerRespawnEvent.RespawnFlag.BED_SPAWN);
if (this.isAnchorSpawn) builder.add(PlayerRespawnEvent.RespawnFlag.ANCHOR_SPAWN);
this.respawnFlags = builder.build();
}
/**
* Gets the current respawn location.
*
* @return the current respawn location
*/
public Location getRespawnLocation() {
return this.respawnLocation.clone();
}
/**
* Gets whether the respawn location is the player's bed.
*
* @return {@code true} if the respawn location is the player's bed
*/
public boolean isBedSpawn() {
return this.isBedSpawn;
}
/**
* Gets whether the respawn location is the player's respawn anchor.
*
* @return {@code true} if the respawn location is the player's respawn anchor
*/
public boolean isAnchorSpawn() {
return this.isAnchorSpawn;
}
/**
* Gets whether the player is missing a valid respawn block.
* <p>
* This will occur if the players respawn block is obstructed,
* or it is the first death after it was either destroyed or
* in case of a respawn anchor, ran out of charges.
*
* @return whether the player is missing a valid respawn block
*/
public boolean isMissingRespawnBlock() {
return this.missingRespawnBlock;
}
/**
* Gets the reason this respawn event was called.
*
* @return the reason the event was called
*/
public PlayerRespawnEvent.RespawnReason getRespawnReason() {
return this.respawnReason;
}
/**
* Gets the set of flags that apply to this respawn.
*
* @return an immutable set of the flags that apply to this respawn
* @deprecated in favour of {@link #getRespawnReason()}/{@link #isBedSpawn}/{@link #isAnchorSpawn()}
*/
@Deprecated
public @Unmodifiable Set<PlayerRespawnEvent.RespawnFlag> getRespawnFlags() {
return this.respawnFlags;
}
}

View File

@ -0,0 +1,63 @@
package io.papermc.paper.event.player;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
import org.bukkit.event.player.PlayerEvent;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NullMarked;
/**
* Called when a player creates a filled map by right-clicking an empty map.
*/
@NullMarked
public class PlayerMapFilledEvent extends PlayerEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final ItemStack originalItem;
private ItemStack createdMap;
@ApiStatus.Internal
public PlayerMapFilledEvent(final Player player, final ItemStack originalItem, final ItemStack createdMap) {
super(player);
this.originalItem = originalItem;
this.createdMap = createdMap;
}
/**
* Returns a copy of the empty map before it was consumed.
*
* @return cloned original item
*/
public ItemStack getOriginalItem() {
return this.originalItem.clone();
}
/**
* Returns a copy of the filled map which was created.
*
* @return cloned created map item
*/
public ItemStack getCreatedMap() {
return this.createdMap.clone();
}
/**
* Sets the filled map that will be created.
*
* @param createdMap map item
*/
public void setCreatedMap(final ItemStack createdMap) {
this.createdMap = createdMap.clone();
}
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}
}

View File

@ -0,0 +1,32 @@
package io.papermc.paper.event.player;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Event that is fired when a player uses the pick item functionality on a block
* (middle-clicking a block to get the appropriate item).
* After the handling of this event, the contents of the source and the target slot will be swapped,
* and the currently selected hotbar slot of the player will be set to the target slot.
*/
@NullMarked
public class PlayerPickBlockEvent extends PlayerPickItemEvent {
private final Block block;
@ApiStatus.Internal
public PlayerPickBlockEvent(final Player player, final Block block, final boolean includeData, final int targetSlot, final int sourceSlot) {
super(player, includeData, targetSlot, sourceSlot);
this.block = block;
}
/**
* Retrieves the block associated with this event.
*
* @return the block involved in the event
*/
public Block getBlock() {
return this.block;
}
}

View File

@ -0,0 +1,32 @@
package io.papermc.paper.event.player;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Event that is fired when a player uses the pick item functionality on an entity
* (middle-clicking an entity to get the appropriate item).
* After the handling of this event, the contents of the source and the target slot will be swapped,
* and the currently selected hotbar slot of the player will be set to the target slot.
*/
@NullMarked
public class PlayerPickEntityEvent extends PlayerPickItemEvent {
private final Entity entity;
@ApiStatus.Internal
public PlayerPickEntityEvent(final Player player, final Entity entity, final boolean includeData, final int targetSlot, final int sourceSlot) {
super(player, includeData, targetSlot, sourceSlot);
this.entity = entity;
}
/**
* Retrieves the entity associated with this event.
*
* @return the entity involved in the event
*/
public Entity getEntity() {
return this.entity;
}
}

View File

@ -10,27 +10,44 @@ import org.jetbrains.annotations.Range;
import org.jspecify.annotations.NullMarked;
/**
* Event that is fired when a player uses the pick item functionality (middle-clicking a block or entity to get the
* appropriate item). After the handling of this event, the contents of the source and the target slot will be swapped
* Event that is fired when a player uses the pick item functionality
* (middle-clicking a {@link PlayerPickBlockEvent block}
* or {@link PlayerPickEntityEvent entity} to get the appropriate item).
* After the handling of this event, the contents of the source and the target slot will be swapped,
* and the currently selected hotbar slot of the player will be set to the target slot.
*
* @see PlayerPickEntityEvent
* @see PlayerPickBlockEvent
*/
@NullMarked
public class PlayerPickItemEvent extends PlayerEvent implements Cancellable {
public abstract class PlayerPickItemEvent extends PlayerEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final boolean includeData;
private int targetSlot;
private int sourceSlot;
private boolean cancelled;
@ApiStatus.Internal
public PlayerPickItemEvent(final Player player, final int targetSlot, final int sourceSlot) {
protected PlayerPickItemEvent(final Player player, final boolean includeData, final int targetSlot, final int sourceSlot) {
super(player);
this.includeData = includeData;
this.targetSlot = targetSlot;
this.sourceSlot = sourceSlot;
}
/**
* Checks whether the player wants block/entity data included.
*
* @return {@code true} if data is included, otherwise {@code false}.
*/
public boolean isIncludeData() {
return includeData;
}
/**
* Returns the slot the item that is being picked goes into.
*

View File

@ -0,0 +1,45 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Cat;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Cat.Type} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface CatTypeRegistryEntry {
/**
* Provides the client texture asset of the cat type, which represents the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset clientTextureAsset();
/**
* A mutable builder for the {@link CatTypeRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #clientTextureAsset(ClientTextureAsset)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends CatTypeRegistryEntry, RegistryBuilder<Cat.Type> {
/**
* Sets the client texture asset of the cat type, which is the location of the texture to use.
*
* @param clientTextureAsset the client texture asset.
* @return this builder instance.
* @see CatTypeRegistryEntry#clientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder clientTextureAsset(ClientTextureAsset clientTextureAsset);
}
}

View File

@ -0,0 +1,78 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Chicken;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Chicken.Variant} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface ChickenVariantRegistryEntry {
/**
* The model of the chicken variant to render the configured texture on.
*/
enum Model {
/**
* The normal chicken model.
*/
NORMAL,
/**
* The cold chicken model.
*/
COLD,
}
/**
* Provides the client texture asset of the chicken variant, which represents the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset clientTextureAsset();
/**
* Provides the model of the chicken variant.
*
* @return the model.
*/
Model model();
/**
* A mutable builder for the {@link ChickenVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #clientTextureAsset(ClientTextureAsset)}</li>
* <li>{@link #model(Model)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends ChickenVariantRegistryEntry, RegistryBuilder<Chicken.Variant> {
/**
* Sets the client texture asset of the chicken variant, which is the location of the texture to use.
*
* @param clientTextureAsset the client texture asset.
* @return this builder instance.
* @see ChickenVariantRegistryEntry#clientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder clientTextureAsset(ClientTextureAsset clientTextureAsset);
/**
* Sets the model to use for this chicken variant.
*
* @param model the model.
* @return this builder instance.
* @see ChickenVariantRegistryEntry#model()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder model(Model model);
}
}

View File

@ -0,0 +1,83 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Cow;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Cow.Variant} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface CowVariantRegistryEntry {
/**
* The model of the cow variant to render the configured texture on.
*/
enum Model {
/**
* The normal cow model.
*/
NORMAL,
/**
* The cold cow model.
*/
COLD,
/**
* The warm cow model.
*/
WARM,
}
/**
* Provides the client texture asset of the cow variant, which represents the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset clientTextureAsset();
/**
* Provides the model of the cow variant.
*
* @return the model.
*/
Model model();
/**
* A mutable builder for the {@link CowVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #clientTextureAsset(ClientTextureAsset)}</li>
* <li>{@link #model(Model)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends CowVariantRegistryEntry, RegistryBuilder<Cow.Variant> {
/**
* Sets the client texture asset of the cow variant, which is the location of the texture to use.
*
* @param clientTextureAsset the client texture asset.
* @return this builder instance.
* @see CowVariantRegistryEntry#clientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder clientTextureAsset(ClientTextureAsset clientTextureAsset);
/**
* Sets the model to use for this cow variant.
*
* @param model the model.
* @return this builder instance.
* @see CowVariantRegistryEntry#model()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder model(Model model);
}
}

View File

@ -0,0 +1,45 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Frog;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Frog.Variant} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface FrogVariantRegistryEntry {
/**
* Provides the client texture asset of the frog variant, which represents the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset clientTextureAsset();
/**
* A mutable builder for the {@link FrogVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #clientTextureAsset(ClientTextureAsset)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends FrogVariantRegistryEntry, RegistryBuilder<Frog.Variant> {
/**
* Sets the client texture asset of the frog variant, which is the location of the texture to use.
*
* @param clientTextureAsset the client texture asset.
* @return this builder instance.
* @see FrogVariantRegistryEntry#clientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder clientTextureAsset(ClientTextureAsset clientTextureAsset);
}
}

View File

@ -0,0 +1,78 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Pig;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Pig.Variant} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface PigVariantRegistryEntry {
/**
* The model of the pig variant to render the configured texture on.
*/
enum Model {
/**
* The normal pig model.
*/
NORMAL,
/**
* The cold pig model.
*/
COLD,
}
/**
* Provides the client texture asset of the pig variant, which represents the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset clientTextureAsset();
/**
* Provides the model of the pig variant.
*
* @return the model.
*/
Model model();
/**
* A mutable builder for the {@link PigVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #clientTextureAsset(ClientTextureAsset)}</li>
* <li>{@link #model(Model)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends PigVariantRegistryEntry, RegistryBuilder<Pig.Variant> {
/**
* Sets the client texture asset of the pig variant, which is the location of the texture to use.
*
* @param clientTextureAsset the client texture asset.
* @return this builder instance.
* @see PigVariantRegistryEntry#clientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder clientTextureAsset(ClientTextureAsset clientTextureAsset);
/**
* Sets the model to use for this pig variant.
*
* @param model the model.
* @return this builder instance.
* @see PigVariantRegistryEntry#model()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder model(Model model);
}
}

View File

@ -0,0 +1,81 @@
package io.papermc.paper.registry.data;
import io.papermc.paper.registry.RegistryBuilder;
import io.papermc.paper.registry.data.client.ClientTextureAsset;
import org.bukkit.entity.Wolf;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific registry entry for the {@link Wolf.Variant} type.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface WolfVariantRegistryEntry {
/**
* Provides the client texture asset of the wolf variant for when it is angry, which is the location of the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset angryClientTextureAsset();
/**
* Provides the client texture asset of the wolf variant for when it is wild, which is the location of the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset wildClientTextureAsset();
/**
* Provides the client texture asset of the wolf variant for when it is tame, which is the location of the texture to use.
*
* @return the client texture asset.
*/
ClientTextureAsset tameClientTextureAsset();
/**
* A mutable builder for the {@link WolfVariantRegistryEntry} plugins may change in applicable registry events.
* <p>
* The following values are required for each builder:
* <ul>
* <li>{@link #angryClientTextureAsset(ClientTextureAsset)}</li>
* <li>{@link #wildClientTextureAsset(ClientTextureAsset)}</li>
* <li>{@link #tameClientTextureAsset(ClientTextureAsset)}</li>
* </ul>
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
interface Builder extends WolfVariantRegistryEntry, RegistryBuilder<Wolf.Variant> {
/**
* Sets the client texture asset of the wolf variant for when it is angry, which is the location of the texture to use.
*
* @param angryClientTextureAsset the client texture asset.
* @return this builder instance.
* @see WolfVariantRegistryEntry#angryClientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder angryClientTextureAsset(ClientTextureAsset angryClientTextureAsset);
/**
* Sets the client texture asset of the wolf variant for when it is wild, which is the location of the texture to use.
*
* @param wildClientTextureAsset the client texture asset.
* @return this builder instance.
* @see WolfVariantRegistryEntry#wildClientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder wildClientTextureAsset(ClientTextureAsset wildClientTextureAsset);
/**
* Sets the client texture asset of the wolf variant for when it is tame, which is the location of the texture to use.
*
* @param tameClientTextureAsset the client texture asset.
* @return this builder instance.
* @see WolfVariantRegistryEntry#tameClientTextureAsset()
*/
@Contract(value = "_ -> this", mutates = "this")
Builder tameClientTextureAsset(ClientTextureAsset tameClientTextureAsset);
}
}

View File

@ -0,0 +1,66 @@
package io.papermc.paper.registry.data.client;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.key.KeyPattern;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
/**
* A data-centric version-specific representation of a client texture asset, composed of an identifier and a path.
* Follows the same, version-specific, compatibility guarantees as the RegistryEntry types it is used in.
*/
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface ClientTextureAsset {
/**
* The identifier of the client texture asset, uniquely identifying the asset on the client.
*
* @return the identifier.
*/
Key identifier();
/**
* The path of the texture on the client, split into a namespace and a path/key.
*
* @return the texture path.
*/
Key texturePath();
/**
* Creates a new {@link ClientTextureAsset} with the specified identifier and texture path.
*
* @param identifier the unique identifier for the client texture asset.
* @param texturePath the path where the asset is located on the client.
* @return a new {@code ClientAsset} instance.
*/
@Contract("_,_ -> new")
static ClientTextureAsset clientTextureAsset(final Key identifier, final Key texturePath) {
return new ClientTextureAssetImpl(identifier, texturePath);
}
/**
* Creates a new {@link ClientTextureAsset} using the provided identifier and infers the texture path from it.
*
* @param identifier the unique identifier for the client texture asset.
* @return a new {@code ClientAsset} instance.
*/
@Contract("_ -> new")
static ClientTextureAsset clientTextureAsset(final Key identifier) {
return new ClientTextureAssetImpl(identifier, ClientTextureAssetImpl.pathFromIdentifier(identifier));
}
/**
* Creates a new {@link ClientTextureAsset} from the provided string-formatted {@link Key}
* and infers the texture path from it.
* <p>
* The identifier string must conform to the {@link KeyPattern} format.
*
* @param identifier the string representation of the asset's identifier.
* @return a new {@code ClientAsset} instance.
*/
@Contract("_ -> new")
static ClientTextureAsset clientTextureAsset(final @KeyPattern String identifier) {
return clientTextureAsset(Key.key(identifier));
}
}

View File

@ -0,0 +1,31 @@
package io.papermc.paper.registry.data.client;
import net.kyori.adventure.key.Key;
import org.intellij.lang.annotations.Subst;
import org.jspecify.annotations.NullMarked;
/**
* Package local implementation of the {@link ClientTextureAsset} type.
* Chosen over bridging into server internals as no internal types are required for this.
*/
@NullMarked
record ClientTextureAssetImpl(
Key identifier,
Key texturePath
) implements ClientTextureAsset {
/**
* Constructs the default asset path from the identifier of the asset.
* Mirrors internal logic in net.minecraft.core.ClientAsset
*
* @param identifier the identifier of the asset.
* @return the key/path of the asset.
*/
static Key pathFromIdentifier(@Subst("") final Key identifier) {
return Key.key(
identifier.namespace(),
"textures/" + identifier.value() + ".png"
);
}
}

View File

@ -2,15 +2,27 @@ package io.papermc.paper.registry.event;
import io.papermc.paper.registry.RegistryKey;
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
import io.papermc.paper.registry.data.CatTypeRegistryEntry;
import io.papermc.paper.registry.data.ChickenVariantRegistryEntry;
import io.papermc.paper.registry.data.CowVariantRegistryEntry;
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.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.block.banner.PatternType;
import org.bukkit.damage.DamageType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Cat;
import org.bukkit.entity.Chicken;
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;
@ -28,9 +40,15 @@ public final class RegistryEvents {
// @GeneratedFrom 1.21.5
public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT);
public static final RegistryEventProvider<DamageType, DamageTypeRegistryEntry.Builder> DAMAGE_TYPE = create(RegistryKey.DAMAGE_TYPE);
public static final RegistryEventProvider<Wolf.Variant, WolfVariantRegistryEntry.Builder> WOLF_VARIANT = create(RegistryKey.WOLF_VARIANT);
public static final RegistryEventProvider<Enchantment, EnchantmentRegistryEntry.Builder> ENCHANTMENT = create(RegistryKey.ENCHANTMENT);
public static final RegistryEventProvider<PatternType, BannerPatternRegistryEntry.Builder> BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN);
public static final RegistryEventProvider<Art, PaintingVariantRegistryEntry.Builder> PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT);
public static final RegistryEventProvider<Cat.Type, CatTypeRegistryEntry.Builder> CAT_VARIANT = create(RegistryKey.CAT_VARIANT);
public static final RegistryEventProvider<Frog.Variant, FrogVariantRegistryEntry.Builder> FROG_VARIANT = create(RegistryKey.FROG_VARIANT);
public static final RegistryEventProvider<Chicken.Variant, ChickenVariantRegistryEntry.Builder> CHICKEN_VARIANT = create(RegistryKey.CHICKEN_VARIANT);
public static final RegistryEventProvider<Cow.Variant, CowVariantRegistryEntry.Builder> COW_VARIANT = create(RegistryKey.COW_VARIANT);
public static final RegistryEventProvider<Pig.Variant, PigVariantRegistryEntry.Builder> PIG_VARIANT = create(RegistryKey.PIG_VARIANT);
// End generate - RegistryEvents
private RegistryEvents() {

View File

@ -0,0 +1,82 @@
package io.papermc.paper.world.damagesource;
import io.papermc.paper.InternalAPIBridge;
import org.bukkit.damage.DamageSource;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
/**
* Represents a combat entry
*/
@NullMarked
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface CombatEntry {
/**
* Gets the damage source.
*
* @return the damage source
*/
DamageSource getDamageSource();
/**
* Gets the amount of damage caused.
*
* @return the amount of damage caused
*/
float getDamage();
/**
* Gets the fall location type at the time of this damage.
*
* @return the fall location type
*/
@Nullable FallLocationType getFallLocationType();
/**
* Gets the fall distance at the time of this damage.
*
* @return the fall distance
*/
float getFallDistance();
/**
* Creates a new combat entry.
* <p>
* The fall location and fall distance will be calculated from the entity's current state.
*
* @param entity entity
* @param damageSource damage source
* @param damage damage amount
* @return combat entry
* @see #combatEntry(DamageSource, float, FallLocationType, float)
*/
static CombatEntry combatEntry(final LivingEntity entity, final DamageSource damageSource, final float damage) {
return InternalAPIBridge.get().createCombatEntry(entity, damageSource, damage);
}
/**
* Creates a new combat entry
*
* @param damageSource damage source
* @param damage damage amount
* @param fallLocationType fall location type
* @param fallDistance fall distance
* @return a new combat entry
* @see CombatTracker#calculateFallLocationType()
* @see Entity#getFallDistance()
*/
static CombatEntry combatEntry(
final DamageSource damageSource,
final float damage,
@Nullable final FallLocationType fallLocationType,
final float fallDistance
) {
return InternalAPIBridge.get().createCombatEntry(damageSource, damage, fallLocationType, fallDistance);
}
}

View File

@ -0,0 +1,110 @@
package io.papermc.paper.world.damagesource;
import net.kyori.adventure.text.Component;
import org.bukkit.entity.LivingEntity;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
import java.util.List;
/**
* Represents entity's combat tracker
*/
@NullMarked
@ApiStatus.Experimental
@ApiStatus.NonExtendable
public interface CombatTracker {
/**
* Gets the entity behind this combat tracker.
*
* @return the entity behind this combat tracker
*/
LivingEntity getEntity();
/**
* Gets the list of recorded combat entries.
* <p>
* The returned list is a copy, so any modifications
* to its contents won't affect this entity's
* combat history.
*
* @return the list of combat entries
* @see #setCombatEntries(List)
*/
List<CombatEntry> getCombatEntries();
/**
* Sets the entity's combat history.
* <p>
* Note that overriding the entity's combat history won't
* affect the entity's current or new combat state.
* Reset the current combat state and register new combat entries instead
* if you want the new history to affect the combat state.
*
* @param combatEntries combat entries
* @see #resetCombatState()
* @see #addCombatEntry(CombatEntry)
*/
void setCombatEntries(List<CombatEntry> combatEntries);
/**
* Calculates the most significant fall damage entry.
*
* @return the most significant fall damage entry
*/
@Nullable CombatEntry computeMostSignificantFall();
/**
* Checks whether the entity is in combat,
* i.e. has taken damage from an entity
* since the combat tracking has begun.
*
* @return whether the entity is in combat
*/
boolean isInCombat();
/**
* Checks whether the entity has started recording damage,
* i.e. its combat tracking is active.
*
* @return whether the entity has started recording damage
*/
boolean isTakingDamage();
/**
* Gets the last or current combat duration.
*
* @return the combat duration
* @see #isInCombat()
*/
int getCombatDuration();
/**
* Adds a new entry the pool of combat entries,
* updating the entity's combat state.
*
* @param combatEntry combat entry
*/
void addCombatEntry(CombatEntry combatEntry);
/**
* Constructs a death message based on the current combat history.
*
* @return a death message
*/
Component getDeathMessage();
/**
* Resets entity's combat state, clearing combat history.
*/
void resetCombatState();
/**
* Calculates the fall location type from the current entity's location.
*
* @return the fall location type
*/
@Nullable FallLocationType calculateFallLocationType();
}

View File

@ -0,0 +1,63 @@
package io.papermc.paper.world.damagesource;
import net.kyori.adventure.translation.Translatable;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Represents a type of location from which the entity fell.
*/
@NullMarked
@ApiStatus.Experimental
public sealed interface FallLocationType extends Translatable permits FallLocationTypeImpl {
/**
* Gets the fall location id.
*
* @return the fall location id
*/
String id();
/**
* Gets the translation key used for a fall death message
* caused by falling from this location
*
* @return the translation key
*/
@Override
String translationKey();
/**
* The entity was not within a special fall location.
*/
FallLocationType GENERIC = new FallLocationTypeImpl("generic");
/**
* The entity was within the ladder.
*/
FallLocationType LADDER = new FallLocationTypeImpl("ladder");
/**
* The entity was in vines.
*/
FallLocationType VINES = new FallLocationTypeImpl("vines");
/**
* The entity was in weeping wines.
*/
FallLocationType WEEPING_VINES = new FallLocationTypeImpl("weeping_vines");
/**
* The entity was in twisting vines.
*/
FallLocationType TWISTING_VINES = new FallLocationTypeImpl("twisting_vines");
/**
* The entity was in scaffolding.
*/
FallLocationType SCAFFOLDING = new FallLocationTypeImpl("scaffolding");
/**
* The entity was within some other climbable block.
*/
FallLocationType OTHER_CLIMBABLE = new FallLocationTypeImpl("other_climbable");
/**
* The entity was in water.
*/
FallLocationType WATER = new FallLocationTypeImpl("water");
}

View File

@ -0,0 +1,14 @@
package io.papermc.paper.world.damagesource;
import org.jspecify.annotations.NullMarked;
@NullMarked
record FallLocationTypeImpl(String id) implements FallLocationType {
@Override
public String translationKey() {
// Same as net.minecraft.world.damagesource.FallLocation#languageKey
return "death.fell.accident." + this.id;
}
}

View File

@ -14,6 +14,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Logger;
import io.papermc.paper.configuration.ServerConfiguration;
import net.kyori.adventure.text.Component;
import org.bukkit.Warning.WarningState;
import org.bukkit.advancement.Advancement;
@ -1435,6 +1436,15 @@ public final class Bukkit {
return server.getOnlineMode();
}
/**
* Retrieves the server configuration.
*
* @return the instance of ServerConfiguration containing the server's configuration details
*/
public static @NotNull ServerConfiguration getServerConfig() {
return server.getServerConfig();
}
/**
* Gets whether this server allows flying or not.
*

View File

@ -732,7 +732,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
/**
* Returns a copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ())
* @return A copy of this location except with y = getWorld().getHighestBlockYAt(this.getBlockX(), this.getBlockZ())
* @throws NullPointerException if {{@link #getWorld()}} is {@code null}
* @throws NullPointerException if {@link #getWorld()} is {@code null}
*/
@NotNull
public Location toHighestLocation() {

View File

@ -5,10 +5,12 @@ import io.papermc.paper.registry.RegistryAccess;
import io.papermc.paper.registry.RegistryKey;
import java.util.Collection;
import java.util.Collections;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import net.kyori.adventure.text.Component;
import org.jspecify.annotations.NullMarked;
import org.jspecify.annotations.Nullable;
public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable { // Paper - translation keys
@NullMarked
public abstract class MusicInstrument implements Keyed, net.kyori.adventure.translation.Translatable {
// Start generate - MusicInstrument
// @GeneratedFrom 1.21.5
@ -38,7 +40,7 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran
*/
@Nullable
@Deprecated(since = "1.20.1")
public static MusicInstrument getByKey(@NotNull NamespacedKey namespacedKey) {
public static MusicInstrument getByKey(final NamespacedKey namespacedKey) {
return Registry.INSTRUMENT.get(namespacedKey);
}
@ -48,25 +50,50 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran
* @return the memoryKeys
* @deprecated use {@link Registry#iterator()}.
*/
@NotNull
@Deprecated(since = "1.20.1")
public static Collection<MusicInstrument> values() {
return Collections.unmodifiableCollection(Lists.newArrayList(Registry.INSTRUMENT));
}
@NotNull
private static MusicInstrument getInstrument(@NotNull String key) {
private static MusicInstrument getInstrument(final String key) {
return RegistryAccess.registryAccess().getRegistry(RegistryKey.INSTRUMENT).getOrThrow(NamespacedKey.minecraft(key));
}
// Paper start - deprecate getKey
/**
* Gets the use duration of this music instrument.
*
* @return the duration expressed in seconds.
*/
public abstract float getDuration();
/**
* Gets the range of the sound.
*
* @return the range of the sound.
*/
public abstract float getRange();
/**
* Provides the description of this instrument as displayed to the client.
*
* @return the description component.
*/
public abstract Component description();
/**
* Gets the sound for this instrument.
*
* @return the sound
*/
public abstract Sound getSound();
/**
* @deprecated use {@link Registry#getKey(Keyed)}, {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)},
* and {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT}. MusicInstruments can exist without a key.
*/
@Deprecated(forRemoval = true, since = "1.20.5")
@Override
public abstract @NotNull NamespacedKey getKey();
public abstract NamespacedKey getKey();
/**
* @deprecated use {@link Registry#getKey(Keyed)}, {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)},
@ -78,15 +105,11 @@ public abstract class MusicInstrument implements Keyed, net.kyori.adventure.tran
return Keyed.super.key();
}
// Paper end - deprecate getKey
// Paper start - mark translation key as deprecated
/**
* @deprecated this method assumes that the instrument description
* always be a translatable component which is not guaranteed.
*/
@Override
@Deprecated(forRemoval = true)
public abstract @NotNull String translationKey();
// Paper end - mark translation key as deprecated
public abstract String translationKey();
}

View File

@ -287,13 +287,28 @@ public interface OfflinePlayer extends ServerOperator, AnimalTamer, Configuratio
// Paper end
/**
* Gets the Location where the player will spawn at, null if they
* Gets the Location where the player will spawn at, {@code null} if they
* don't have a valid respawn point.
* <br>
* Unlike online players, the location if found will not be loaded by default.
*
* @return respawn location if exists, otherwise {@code null}.
* @see #getRespawnLocation(boolean) for more fine-grained control over chunk loading and validation behaviour.
*/
default @Nullable Location getRespawnLocation() {
return this.getRespawnLocation(false); // keep old behavior for offline players
}
/**
* Gets the Location where the player will spawn at, {@code null} if they
* don't have a valid respawn point.
*
* @return respawn location if exists, otherwise null.
* @param loadLocationAndValidate load the expected respawn location to retrieve the exact position of the spawn
* block and check if this position is still valid or not. Loading the location
* will induce a sync chunk load and must hence be used with caution.
* @return respawn location if exists, otherwise {@code null}.
*/
@Nullable
public Location getRespawnLocation();
@Nullable Location getRespawnLocation(boolean loadLocationAndValidate);
/**
* Increments the given statistic for this player.

View File

@ -525,6 +525,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
*/
Stream<T> stream();
/**
* Returns a new stream, which contains all registry keys, which are registered to the registry.
*
* @return a stream of all registry keys
*/
Stream<NamespacedKey> keyStream();
/**
* Attempts to match the registered object with the given key.
* <p>
@ -591,6 +598,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return this.map.values().iterator();
}
@Override
public Stream<NamespacedKey> keyStream() {
return this.map.keySet().stream();
}
@ApiStatus.Internal
@Deprecated(since = "1.20.6", forRemoval = true)
public Class<T> getType() {
@ -606,6 +618,11 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
return StreamSupport.stream(this.spliterator(), false);
}
@Override
public Stream<NamespacedKey> keyStream() {
return stream().map(this::getKey);
}
@Override
public int size() {
return Iterables.size(this);

View File

@ -14,6 +14,7 @@ import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Logger;
import io.papermc.paper.configuration.ServerConfiguration;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
@ -830,9 +831,8 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @param id the id of the map to get
* @return a map view if it exists, or null otherwise
*/
// @Deprecated(since = "1.6.2") // Paper - Not a magic value
@Nullable
public MapView getMap(int id);
MapView getMap(int id);
/**
* Create a new map with an automatically assigned ID.
@ -1268,6 +1268,13 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
*/
public boolean getOnlineMode();
/**
* Retrieves the server configuration.
*
* @return the instance of ServerConfiguration containing the server's configuration details
*/
@NotNull ServerConfiguration getServerConfig();
/**
* Gets whether this server allows flying or not.
*
@ -2320,6 +2327,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @see #getServerConfig()
* @return The server's spigot config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@ -2332,6 +2340,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @see #getServerConfig()
* @return The server's bukkit config.
*/
// Paper start
@ -2346,6 +2355,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @see #getServerConfig()
* @return The server's spigot config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)
@ -2359,6 +2369,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
* @deprecated Server config options may be renamed or removed without notice. Prefer using existing API
* wherever possible, rather than directly reading from a server config.
*
* @see #getServerConfig()
* @return The server's paper config.
*/
@Deprecated(since = "1.21.4", forRemoval = true)

View File

@ -817,4 +817,11 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr
return this.getBlockData().getDestroySpeed(itemStack, considerEnchants);
}
// Paper end - destroy speed API
/**
* Checks if the block can suffocate.
*
* @return {@code true} if the block can suffocate
*/
boolean isSuffocating();
}

View File

@ -5,12 +5,16 @@ import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.data.BlockData;
import org.bukkit.entity.Entity;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.MaterialData;
import org.bukkit.metadata.Metadatable;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import java.util.Collection;
/**
* Represents a captured state of a block, which will not change
@ -226,14 +230,14 @@ public interface BlockState extends Metadatable {
* @deprecated Magic value
*/
@Deprecated(since = "1.6.2", forRemoval = true)
public byte getRawData();
byte getRawData();
/**
* @param data The new data value for the block.
* @deprecated Magic value
*/
@Deprecated(since = "1.6.2", forRemoval = true)
public void setRawData(byte data);
void setRawData(byte data);
/**
* Returns whether this state is placed in the world.
@ -246,7 +250,6 @@ public interface BlockState extends Metadatable {
*/
boolean isPlaced();
// Paper start
/**
* Checks if this block state is collidable.
*
@ -261,7 +264,7 @@ public interface BlockState extends Metadatable {
* @throws IllegalStateException if this block state is not placed
*/
@NotNull
default java.util.@org.jetbrains.annotations.Unmodifiable Collection<org.bukkit.inventory.ItemStack> getDrops() {
default @Unmodifiable Collection<ItemStack> getDrops() {
return this.getDrops(null);
}
@ -274,7 +277,7 @@ public interface BlockState extends Metadatable {
* @throws IllegalStateException if this block state is not placed
*/
@NotNull
default java.util.@org.jetbrains.annotations.Unmodifiable Collection<org.bukkit.inventory.ItemStack> getDrops(@Nullable org.bukkit.inventory.ItemStack tool) {
default @Unmodifiable Collection<ItemStack> getDrops(@Nullable ItemStack tool) {
return this.getDrops(tool, null);
}
@ -288,6 +291,14 @@ public interface BlockState extends Metadatable {
* @throws IllegalStateException if this block state is not placed
*/
@NotNull
java.util.@org.jetbrains.annotations.Unmodifiable Collection<org.bukkit.inventory.ItemStack> getDrops(@Nullable org.bukkit.inventory.ItemStack tool, @Nullable org.bukkit.entity.Entity entity);
// Paper end
@Unmodifiable
Collection<ItemStack> getDrops(@Nullable ItemStack tool, @Nullable Entity entity);
/**
* Checks if the block state can suffocate.
*
* @return {@code true} if the block state can suffocate
* @throws IllegalStateException if this block state is not placed
*/
boolean isSuffocating();
}

View File

@ -121,7 +121,6 @@ import org.bukkit.block.data.type.WallHangingSign;
import org.bukkit.block.data.type.WallSign;
import org.bukkit.block.data.type.WallSkull;
import org.bukkit.inventory.ItemType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;

View File

@ -7,7 +7,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.GameRule;
import org.bukkit.Location;
import org.bukkit.Server;

View File

@ -4,6 +4,8 @@ import java.util.ArrayList;
import java.util.regex.Matcher; // Paper
import java.util.regex.Pattern; // Paper
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.NamedTextColor;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
@ -27,7 +29,7 @@ public class FormattedCommandAlias extends Command {
if (throwable instanceof IllegalArgumentException) {
sender.sendMessage(throwable.getMessage());
} else {
sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
sender.sendMessage(Component.text("An internal error occurred while attempting to perform this command", NamedTextColor.RED));
}
return false;
}

View File

@ -5,7 +5,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
@ -14,32 +13,26 @@ import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.command.defaults.BukkitCommand;
import org.bukkit.command.defaults.HelpCommand;
import org.bukkit.command.defaults.PluginsCommand;
import org.bukkit.command.defaults.ReloadCommand;
import org.bukkit.command.defaults.VersionCommand;
import org.bukkit.entity.Player;
import org.bukkit.util.StringUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class SimpleCommandMap implements CommandMap {
protected final Map<String, Command> knownCommands; // Paper
protected final Map<String, Command> knownCommands;
private final Server server;
// Paper start
@org.jetbrains.annotations.ApiStatus.Internal
public SimpleCommandMap(@NotNull final Server server, Map<String, Command> backing) {
this.knownCommands = backing;
// Paper end
this.server = server;
setDefaultCommands();
}
private void setDefaultCommands() {
register("bukkit", new VersionCommand("version"));
register("bukkit", new ReloadCommand("reload"));
//register("bukkit", new PluginsCommand("plugins")); // Paper
register("bukkit", new co.aikar.timings.TimingsCommand("timings")); // Paper
register("bukkit", new co.aikar.timings.TimingsCommand("timings"));
}
public void setFallbackCommands() {

View File

@ -10,8 +10,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.format.NamedTextColor;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.help.HelpMap;
@ -78,31 +81,29 @@ public class HelpCommand extends BukkitCommand {
}
if (topic == null || !topic.canSee(sender)) {
sender.sendMessage(ChatColor.RED + "No help for " + command);
sender.sendMessage(Component.text("No help for " + command, NamedTextColor.RED));
return true;
}
ChatPaginator.ChatPage page = ChatPaginator.paginate(topic.getFullText(sender), pageNumber, pageWidth, pageHeight);
StringBuilder header = new StringBuilder();
header.append(ChatColor.YELLOW);
header.append("--------- ");
header.append(ChatColor.WHITE);
header.append("Help: ");
header.append(topic.getName());
header.append(" ");
TextComponent.Builder header = Component.text()
.append(Component.text("--------- ", NamedTextColor.YELLOW))
.append(Component.text("Help: ", NamedTextColor.WHITE))
.append(Component.text(topic.getName()))
.append(Component.space());
if (page.getTotalPages() > 1) {
header.append("(");
header.append(page.getPageNumber());
header.append("/");
header.append(page.getTotalPages());
header.append(") ");
header.append(Component.text("("))
.append(Component.text(page.getPageNumber()))
.append(Component.text("/"))
.append(Component.text(page.getTotalPages()))
.append(Component.text(") "));
}
header.append(ChatColor.YELLOW);
for (int i = header.length(); i < ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH; i++) {
header.append("-");
}
sender.sendMessage(header.toString());
final TextComponent headerComponent = header.build();
final int headerSize = PlainTextComponentSerializer.plainText().serialize(headerComponent).length();
final int headerEndingCount = Math.max(0, ChatPaginator.GUARANTEED_NO_WRAP_CHAT_PAGE_WIDTH - headerSize);
sender.sendMessage(headerComponent.append(Component.text("-".repeat(headerEndingCount), NamedTextColor.YELLOW)));
sender.sendMessage(page.getLines());

View File

@ -32,6 +32,7 @@ import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.format.TextDecoration;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
@Deprecated(forRemoval = true)
public class VersionCommand extends BukkitCommand {
private VersionFetcher versionFetcher; // Paper - version command 2.0
private VersionFetcher getVersionFetcher() { // lazy load because unsafe isn't available at command registration

View File

@ -1,8 +1,38 @@
package org.bukkit.entity;
import org.jspecify.annotations.NullMarked;
/**
* Represents an Armadillo.
*/
@NullMarked
public interface Armadillo extends Animals {
/**
* Get the current state of the armadillo.
*
* @return the state of the armadillo
*/
State getState();
/**
* Attempt to roll up if the armadillo is {@link State#IDLE}
*/
void rollUp();
/**
* Attempt to roll out if the armadillo is not {@link State#IDLE}
*/
void rollOut();
/**
* Represents the current state of the armadillo.
*/
enum State {
IDLE,
ROLLING,
SCARED,
UNROLLING;
}
}

View File

@ -5,6 +5,7 @@ import java.util.Set;
import java.util.UUID;
import io.papermc.paper.datacomponent.DataComponentView;
import io.papermc.paper.entity.LookAnchor;
import net.kyori.adventure.util.TriState;
import org.bukkit.Chunk; // Paper
import org.bukkit.EntityEffect;
import org.bukkit.Location;
@ -19,6 +20,7 @@ import org.bukkit.command.CommandSender;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.inventory.ItemStack;
import org.bukkit.material.Directional;
import org.bukkit.metadata.Metadatable;
import org.bukkit.persistence.PersistentDataHolder;
@ -296,17 +298,43 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
/**
* Sets if the entity has visual fire (it will always appear to be on fire).
*
* @deprecated This method doesn't allow visually extinguishing a burning entity,
* use {@link #setVisualFire(TriState)} instead
* @param fire whether visual fire is enabled
*/
@Deprecated
void setVisualFire(boolean fire);
/**
* Sets if the entity has visual fire (it will always appear to be on fire).
* <ul>
* <li>{@link TriState#NOT_SET} will revert the entity's visual fire to default</li>
* <li>{@link TriState#TRUE} will make the entity appear to be on fire</li>
* <li>{@link TriState#FALSE} will make the entity appear to be not on fire</li>
* </ul>
*
* @param fire a TriState value representing the state of the visual fire.
*/
void setVisualFire(@NotNull TriState fire);
/**
* Gets if the entity has visual fire (it will always appear to be on fire).
*
* @deprecated This method can't properly reflect the three possible states of visual fire,
* use {@link #getVisualFire()} instead
* @return whether visual fire is enabled
*/
@Deprecated
boolean isVisualFire();
/**
* Retrieves the visual fire state of the object.
*
* @return A TriState indicating the current visual fire state.
*/
@NotNull
TriState getVisualFire();
/**
* Returns the entity's current freeze ticks (amount of ticks the entity has
* been in powdered snow).
@ -511,6 +539,15 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
*/
public boolean eject();
/**
* Gets the {@link ItemStack} that a player would select / create (in creative mode)
* when using the pick block action on this entity.
*
* @return item stack result or an empty item stack
*/
@NotNull
ItemStack getPickItemStack();
/**
* Returns the distance this entity has fallen
*

View File

@ -1,5 +1,7 @@
package org.bukkit.entity;
import org.bukkit.inventory.EquipmentSlot;
import io.papermc.paper.event.entity.FishHookStateChangeEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -305,6 +307,7 @@ public interface FishHook extends Projectile {
/**
* Represents a state in which a fishing hook may be.
* State transitions can be listened for using {@link FishHookStateChangeEvent}
*/
public enum HookState {
@ -323,7 +326,6 @@ public interface FishHook extends Projectile {
BOBBING;
}
// Paper start - More FishHook API
/**
* Get the number of ticks the hook needs to wait for a fish to bite.
*
@ -367,5 +369,18 @@ public interface FishHook extends Projectile {
* enchantment.
*/
void resetFishingState();
// Paper end
/**
* Retrieve this fishhook back to the casting player.
* <p>
* This method will trigger and respect API events, which may be subject to cancellation.
* Plugins listening to {@link org.bukkit.event.player.PlayerFishEvent} might for example cancel this action.
*
* @param slot Slot holding the fishing rod (must be HAND/OFF_HAND)
* @return The amount of damage which would be applied to the itemstack
* @throws IllegalStateException if the fish hook does not have a player casting it.
* @throws IllegalStateException if the player casting it is not holding a
* {@link org.bukkit.inventory.ItemType#FISHING_ROD} in the specified equipment slot.
*/
int retrieve(@NotNull EquipmentSlot slot);
}

View File

@ -485,9 +485,11 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
* to validate if the current respawn location is still valid.
*
* @return respawn location if exists, otherwise null.
* @deprecated this method doesn't take the respawn angle into account, use
* {@link Player#getRespawnLocation(boolean)} with loadLocationAndValidate = false instead
*/
@Nullable
Location getPotentialRespawnLocation();
@Deprecated(since = "1.21.5")
@Nullable Location getPotentialRespawnLocation();
/**
* @return the player's fishing hook if they are fishing

View File

@ -4,6 +4,8 @@ import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import io.papermc.paper.world.damagesource.CombatTracker;
import io.papermc.paper.world.damagesource.FallLocationType;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
import org.bukkit.Material;
@ -21,6 +23,7 @@ import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.scoreboard.Team;
import org.bukkit.util.RayTraceResult;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -1452,4 +1455,12 @@ public interface LivingEntity extends Attributable, Damageable, ProjectileSource
*/
boolean canUseEquipmentSlot(org.bukkit.inventory.@NotNull EquipmentSlot slot);
// Paper end - Expose canUseSlot
/**
* Gets the entity's combat tracker
*
* @return the entity's combat tracker
*/
@ApiStatus.Experimental
@NotNull CombatTracker getCombatTracker();
}

View File

@ -12,6 +12,7 @@ import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import io.papermc.paper.entity.LookAnchor;
import io.papermc.paper.entity.PlayerGiveResult;
import io.papermc.paper.math.Position;
import org.bukkit.BanEntry;
import org.bukkit.DyeColor;
import org.bukkit.Effect;
@ -52,7 +53,6 @@ import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.messaging.PluginMessageRecipient;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.profile.PlayerProfile;
import org.bukkit.scoreboard.Scoreboard;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
@ -293,7 +293,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* set in the client, the {@link CompletableFuture} will complete with a
* null value.
*/
CompletableFuture<byte[]> retrieveCookie(NamespacedKey key);
CompletableFuture<byte @Nullable []> retrieveCookie(NamespacedKey key);
/**
* Stores a cookie in this player's client.
@ -545,6 +545,20 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public boolean isSleepingIgnored();
/**
* Gets the Location where the player will spawn at, {@code null} if they
* don't have a valid respawn point.
* <br>
* Unlike offline players, the location if found will be loaded to validate by default.
*
* @return respawn location if exists, otherwise {@code null}.
* @see #getRespawnLocation(boolean) for more fine-grained control over chunk loading and validation behaviour.
*/
@Override
default @Nullable Location getRespawnLocation() {
return this.getRespawnLocation(true);
}
/**
* Sets the Location where the player will spawn at their bed.
*
@ -1164,7 +1178,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* (constructed e.g. via {@link Material#createBlockData()})
*/
@Deprecated // Paper
public void sendSignChange(Location loc, @Nullable String[] lines) throws IllegalArgumentException;
public void sendSignChange(Location loc, @Nullable String @Nullable [] lines) throws IllegalArgumentException;
/**
* Send a sign change. This fakes a sign change packet for a user at
@ -1190,7 +1204,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* (constructed e.g. via {@link Material#createBlockData()})
*/
@Deprecated // Paper
public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor) throws IllegalArgumentException;
public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor) throws IllegalArgumentException;
/**
* Send a sign change. This fakes a sign change packet for a user at
@ -1217,7 +1231,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* (constructed e.g. via {@link Material#createBlockData()})
*/
@Deprecated // Paper
public void sendSignChange(Location loc, @Nullable String[] lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException;
public void sendSignChange(Location loc, @Nullable String @Nullable [] lines, DyeColor dyeColor, boolean hasGlowingText) throws IllegalArgumentException;
/**
* Send a TileState change. This fakes a TileState change for a user at
@ -2109,6 +2123,8 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*
* @param other The other {@link Player} to list.
* @return True if the {@code other} player was not listed.
* @throws IllegalStateException if this player can't see the other player
* @see #canSee(Player)
*/
boolean listPlayer(Player other);
// Paper end
@ -2820,7 +2836,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
* @throws IllegalArgumentException Thrown if the hash is not 20 bytes
* long.
*/
public void addResourcePack(UUID id, String url, @Nullable byte[] hash, @Nullable String prompt, boolean force);
public void addResourcePack(UUID id, String url, byte @Nullable [] hash, @Nullable String prompt, boolean force);
/**
* Request that the player's client remove a resource pack sent by the
@ -3433,6 +3449,21 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
*/
public void openSign(Sign sign, Side side);
/**
* Open a sign for editing by the player.
* <p>
* The sign must only be placed locally for the player, which can be done with {@link #sendBlockChange(Location, BlockData)} and {@link #sendBlockUpdate(Location, TileState)}.
* A side-effect of this is that normal events, like {@link org.bukkit.event.block.SignChangeEvent} will not be called (unless there is an actual sign in the world).
* Additionally, the client may enforce distance limits to the opened position.
* </p>
*
* @param block The block where the client has a sign placed
* @param side The side to edit
* @see io.papermc.paper.event.packet.UncheckedSignChangeEvent
*/
@ApiStatus.Experimental
void openVirtualSign(Position block, Side side);
/**
* Shows the demo screen to the player, this screen is normally only seen in
* the demo version of the game.

View File

@ -5,7 +5,6 @@ import io.papermc.paper.registry.RegistryKey;
import org.bukkit.DyeColor;
import org.bukkit.Keyed;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.jetbrains.annotations.NotNull;
/**

View File

@ -71,7 +71,7 @@ public interface Zombie extends Monster, Ageable {
/**
* Gets the amount of ticks until this entity will be converted to a Drowned
* as a result of being underwater.
*
* <br>
* When this reaches 0, the entity will be converted.
*
* @return conversion time
@ -82,7 +82,7 @@ public interface Zombie extends Monster, Ageable {
/**
* Sets the amount of ticks until this entity will be converted to a Drowned
* as a result of being underwater.
*
* <br>
* When this reaches 0, the entity will be converted. A value of less than 0
* will stop the current conversion process without converting the current
* entity.
@ -121,7 +121,6 @@ public interface Zombie extends Monster, Ageable {
* Make zombie start drowning
*
* @param drownedConversionTime Amount of time until zombie converts from drowning
*
* @deprecated See {@link #setConversionTime(int)}
*/
@Deprecated
@ -136,7 +135,7 @@ public interface Zombie extends Monster, Ageable {
* Set if zombie has its arms raised
*
* @param raised True to raise arms
* @deprecated use {{@link #setAggressive(boolean)}}
* @deprecated use {@link #setAggressive(boolean)}
*/
@Deprecated
void setArmsRaised(boolean raised);

View File

@ -6,11 +6,12 @@ import org.bukkit.entity.Entity;
import org.bukkit.event.Cancellable;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jspecify.annotations.NullMarked;
/**
* Called when an entity is about to be replaced by another entity.
*/
@NullMarked
public class EntityTransformEvent extends EntityEvent implements Cancellable {
private static final HandlerList HANDLER_LIST = new HandlerList();
@ -22,10 +23,10 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable {
private boolean cancelled;
@ApiStatus.Internal
public EntityTransformEvent(@NotNull Entity original, @NotNull List<Entity> convertedList, @NotNull TransformReason transformReason) {
public EntityTransformEvent(Entity original, List<Entity> convertedList, TransformReason transformReason) {
super(original);
this.convertedList = Collections.unmodifiableList(convertedList);
this.converted = convertedList.get(0);
this.converted = convertedList.getFirst();
this.transformReason = transformReason;
}
@ -34,7 +35,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable {
*
* @return The transformed entities.
*/
@NotNull
public List<Entity> getTransformedEntities() {
return this.convertedList;
}
@ -47,7 +47,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable {
* @return The transformed entity.
* @see #getTransformedEntities()
*/
@NotNull
public Entity getTransformedEntity() {
return this.converted;
}
@ -57,7 +56,6 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable {
*
* @return The reason for conversion that has occurred.
*/
@NotNull
public TransformReason getTransformReason() {
return this.transformReason;
}
@ -72,13 +70,11 @@ public class EntityTransformEvent extends EntityEvent implements Cancellable {
this.cancelled = cancel;
}
@NotNull
@Override
public HandlerList getHandlers() {
return HANDLER_LIST;
}
@NotNull
public static HandlerList getHandlerList() {
return HANDLER_LIST;
}

View File

@ -18,27 +18,27 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca
private static final HandlerList HANDLER_LIST = new HandlerList();
private final AreaEffectCloud entity;
private final AreaEffectCloud effectCloud;
private boolean allowEmptyAreaEffectCreation;
private boolean cancelled;
@ApiStatus.Internal
@Deprecated(since = "1.20.2", forRemoval = true)
public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud entity) {
this(potion, null, null, null, entity);
public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @NotNull final AreaEffectCloud effectCloud) {
this(potion, null, null, null, effectCloud);
}
@ApiStatus.Internal
public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud entity) {
public LingeringPotionSplashEvent(@NotNull final ThrownPotion potion, @Nullable Entity hitEntity, @Nullable Block hitBlock, @Nullable BlockFace hitFace, @NotNull final AreaEffectCloud effectCloud) {
super(potion, hitEntity, hitBlock, hitFace);
this.entity = entity;
this.effectCloud = effectCloud;
}
@NotNull
@Override
public ThrownPotion getEntity() {
return (ThrownPotion) super.getEntity();
return (ThrownPotion) this.entity;
}
/**
@ -48,10 +48,9 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca
*/
@NotNull
public AreaEffectCloud getAreaEffectCloud() {
return entity;
return effectCloud;
}
// Paper start
/**
* Sets if an Empty AreaEffectCloud may be created
*
@ -69,7 +68,6 @@ public class LingeringPotionSplashEvent extends ProjectileHitEvent implements Ca
public boolean allowsEmptyCreation() {
return allowEmptyAreaEffectCreation;
}
// Paper end
@Override
public boolean isCancelled() {

View File

@ -19,7 +19,9 @@ public class PlayerDeathEvent extends EntityDeathEvent {
private int newExp = 0;
private int newLevel = 0;
private int newTotalExp = 0;
private boolean showDeathMessages;
private Component deathMessage;
private Component deathScreenMessageOverride = null;
private boolean doExpDrop;
private boolean keepLevel = false;
private boolean keepInventory = false;
@ -27,27 +29,28 @@ public class PlayerDeathEvent extends EntityDeathEvent {
private final List<ItemStack> itemsToKeep = new ArrayList<>();
@ApiStatus.Internal
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable Component deathMessage) {
this(player, damageSource, drops, droppedExp, 0, deathMessage);
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final @Nullable Component deathMessage, final boolean showDeathMessages) {
this(player, damageSource, drops, droppedExp, 0, deathMessage, showDeathMessages);
}
@ApiStatus.Internal
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final @Nullable Component deathMessage) {
this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage);
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final @Nullable Component deathMessage, final boolean showDeathMessages) {
this(player, damageSource, drops, droppedExp, newExp, 0, 0, deathMessage, showDeathMessages);
}
@ApiStatus.Internal
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage) {
this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, true);
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean showDeathMessages) {
this(player, damageSource, drops, droppedExp, newExp, newTotalExp, newLevel, deathMessage, showDeathMessages, true);
}
@ApiStatus.Internal
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean doExpDrop) {
public PlayerDeathEvent(final @NotNull Player player, final @NotNull DamageSource damageSource, final @NotNull List<ItemStack> drops, final int droppedExp, final int newExp, final int newTotalExp, final int newLevel, final @Nullable Component deathMessage, final boolean showDeathMessages, final boolean doExpDrop) {
super(player, damageSource, drops, droppedExp);
this.newExp = newExp;
this.newTotalExp = newTotalExp;
this.newLevel = newLevel;
this.deathMessage = deathMessage;
this.showDeathMessages = showDeathMessages;
this.doExpDrop = doExpDrop;
}
@ -76,6 +79,7 @@ public class PlayerDeathEvent extends EntityDeathEvent {
this.newExp = newExp;
this.newTotalExp = newTotalExp;
this.newLevel = newLevel;
this.showDeathMessages = true;
this.deathMessage = LegacyComponentSerializer.legacySection().deserializeOrNull(deathMessage);
this.doExpDrop = doExpDrop;
}
@ -86,6 +90,30 @@ public class PlayerDeathEvent extends EntityDeathEvent {
return (Player) this.entity;
}
/**
* Get whether the death message should be shown.
* By default, this is determined by {@link org.bukkit.GameRule#SHOW_DEATH_MESSAGES}.
*
* @return whether the death message should be shown
* @see #deathMessage()
* @see #deathScreenMessageOverride()
*/
public boolean getShowDeathMessages() {
return showDeathMessages;
}
/**
* Set whether the death message should be shown.
* By default, this is determined by {@link org.bukkit.GameRule#SHOW_DEATH_MESSAGES}.
*
* @param displayDeathMessage whether the death message should be shown
* @see #deathMessage()
* @see #deathScreenMessageOverride()
*/
public void setShowDeathMessages(boolean displayDeathMessage) {
this.showDeathMessages = displayDeathMessage;
}
/**
* Clarity method for getting the player. Not really needed except
* for reasons of clarity.
@ -177,7 +205,7 @@ public class PlayerDeathEvent extends EntityDeathEvent {
/**
* Set the death message that will appear to everyone on the server.
*
* @param deathMessage Message to appear to other players on the server.
* @param deathMessage message to appear to other players on the server.
* @deprecated in favour of {@link #deathMessage(Component)}
*/
@Deprecated
@ -197,6 +225,32 @@ public class PlayerDeathEvent extends EntityDeathEvent {
return LegacyComponentSerializer.legacySection().serializeOrNull(this.deathMessage);
}
/**
* Overrides the death message that will appear on the death screen of the dying player.
* By default, this is null.
* <p>
* If set to null, death screen message will be same as {@code deathMessage()}.
* <p>
* If the message exceeds 256 characters it will be truncated.
*
* @param deathScreenMessageOverride Message to appear on the death screen to the dying player.
*/
public void deathScreenMessageOverride(@Nullable Component deathScreenMessageOverride) {
this.deathScreenMessageOverride = deathScreenMessageOverride;
}
/**
* Get the death message override that will appear on the death screen of the dying player.
* By default, this is null.
* <p>
* If set to null, death screen message will be same as {@code deathMessage()}.
* <p>
* @return Message to appear on the death screen to the dying player.
*/
public @Nullable Component deathScreenMessageOverride() {
return this.deathScreenMessageOverride;
}
/**
* @return should experience be dropped from this death
*/

View File

@ -203,10 +203,10 @@ public class InventoryClickEvent extends InventoryInteractEvent {
/**
* If the ClickType is NUMBER_KEY, this method will return the index of
* the pressed key (0-8).
* the pressed key (0-8) and -1 if player swapped with off-hand (or the action is not NUMBER_KEY).
*
* @return the number on the key minus 1 (range 0-8); or -1 if not
* a NUMBER_KEY action
* @return the number on the key minus 1 (range 0-8);
* or -1 if ClickType is NUMBER_KEY and player did an off-hand swap. Is also -1 if ClickType is not NUMBER_KEY
*/
public int getHotbarButton() {
return this.hotbarKey;

View File

@ -1,5 +1,6 @@
package org.bukkit.event.player;
import io.papermc.paper.event.entity.FishHookStateChangeEvent;
import org.bukkit.entity.Entity;
import org.bukkit.entity.FishHook;
import org.bukkit.entity.Player;
@ -12,6 +13,8 @@ import org.jetbrains.annotations.Nullable;
/**
* Thrown when a player is fishing
*
* <p>If you want to monitor a fishhooks state transition, you can use {@link FishHookStateChangeEvent}.</p>
*/
public class PlayerFishEvent extends PlayerEvent implements Cancellable {

View File

@ -1,6 +1,7 @@
package org.bukkit.event.player;
import com.google.common.base.Preconditions;
import io.papermc.paper.event.player.AbstractRespawnEvent;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.HandlerList;
@ -15,17 +16,10 @@ import java.util.Set;
* If changing player state, see {@link com.destroystokyo.paper.event.player.PlayerPostRespawnEvent}
* because the player is "reset" between this event and that event and some changes won't persist.
*/
public class PlayerRespawnEvent extends PlayerEvent {
public class PlayerRespawnEvent extends AbstractRespawnEvent {
private static final HandlerList HANDLER_LIST = new HandlerList();
private final boolean isBedSpawn;
private final boolean isAnchorSpawn;
private final boolean missingRespawnBlock;
private final RespawnReason respawnReason;
private final Set<RespawnFlag> respawnFlags;
private Location respawnLocation;
@ApiStatus.Internal
@Deprecated(since = "1.16.1", forRemoval = true)
public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn) {
@ -35,40 +29,16 @@ public class PlayerRespawnEvent extends PlayerEvent {
@ApiStatus.Internal
@Deprecated(since = "1.19.4", forRemoval = true)
public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn) {
this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, RespawnReason.PLUGIN);
this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, false, RespawnReason.PLUGIN);
}
@ApiStatus.Internal
@Deprecated(forRemoval = true)
public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, @NotNull final RespawnReason respawnReason) {
this(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, false, respawnReason, com.google.common.collect.ImmutableSet.builder());
}
@ApiStatus.Internal
public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, final boolean missingRespawnBlock, @NotNull final RespawnReason respawnReason, @NotNull final com.google.common.collect.ImmutableSet.Builder<org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag> respawnFlags) {
super(respawnPlayer);
this.respawnLocation = respawnLocation;
this.isBedSpawn = isBedSpawn;
this.isAnchorSpawn = isAnchorSpawn;
this.respawnReason = respawnReason;
this.missingRespawnBlock = missingRespawnBlock;
if (this.isBedSpawn) { respawnFlags.add(RespawnFlag.BED_SPAWN); }
if (this.isAnchorSpawn) { respawnFlags.add(RespawnFlag.ANCHOR_SPAWN); }
this.respawnFlags = respawnFlags.build();
public PlayerRespawnEvent(@NotNull final Player respawnPlayer, @NotNull final Location respawnLocation, final boolean isBedSpawn, final boolean isAnchorSpawn, final boolean missingRespawnBlock, @NotNull final RespawnReason respawnReason) {
super(respawnPlayer, respawnLocation, isBedSpawn, isAnchorSpawn, missingRespawnBlock, respawnReason);
}
/**
* Gets the current respawn location
*
* @return Location current respawn location
*/
@NotNull
public Location getRespawnLocation() {
return this.respawnLocation;
}
/**
* Sets the new respawn location
* Sets the new respawn location.
*
* @param respawnLocation new location for the respawn
*/
@ -79,57 +49,6 @@ public class PlayerRespawnEvent extends PlayerEvent {
this.respawnLocation = respawnLocation.clone();
}
/**
* Gets whether the respawn location is the player's bed.
*
* @return {@code true} if the respawn location is the player's bed.
*/
public boolean isBedSpawn() {
return this.isBedSpawn;
}
/**
* Gets whether the respawn location is the player's respawn anchor.
*
* @return {@code true} if the respawn location is the player's respawn anchor.
*/
public boolean isAnchorSpawn() {
return this.isAnchorSpawn;
}
/**
* Gets whether the player is missing a valid respawn block.
* <p>
* This will occur if the players respawn block is obstructed,
* or it is the first death after it was either destroyed or
* in case of a respawn anchor, ran out of charges.
*
* @return whether the player is missing a valid respawn block
*/
public boolean isMissingRespawnBlock() {
return this.missingRespawnBlock;
}
/**
* Gets the reason this respawn event was called.
*
* @return the reason the event was called.
*/
@NotNull
public RespawnReason getRespawnReason() {
return this.respawnReason;
}
/**
* Get the set of flags that apply to this respawn.
*
* @return an immutable set of the flags that apply to this respawn
*/
@NotNull
public @Unmodifiable Set<RespawnFlag> getRespawnFlags() {
return this.respawnFlags;
}
@NotNull
@Override
public HandlerList getHandlers() {

View File

@ -1,5 +1,6 @@
package org.bukkit.event.player;
import io.papermc.paper.datacomponent.item.consumable.ConsumeEffect;
import io.papermc.paper.entity.TeleportFlag;
import org.bukkit.Location;
import org.bukkit.entity.Player;
@ -121,10 +122,9 @@ public class PlayerTeleportEvent extends PlayerMoveEvent {
*/
END_GATEWAY,
/**
* Indicates the teleportation was caused by a player consuming chorus
* fruit
* Indicates the teleportation was caused by a player consuming an item with a {@link ConsumeEffect.TeleportRandomly} effect
*/
CHORUS_FRUIT,
CONSUMABLE_EFFECT,
/**
* Indicates the teleportation was caused by a player exiting a vehicle
*/
@ -137,6 +137,14 @@ public class PlayerTeleportEvent extends PlayerMoveEvent {
* Indicates the teleportation was caused by an event not covered by
* this enum
*/
UNKNOWN
UNKNOWN;
/**
* Indicates the teleportation was caused by a player consuming chorus
* fruit
* @deprecated in favor of {@link #CONSUMABLE_EFFECT}
*/
@Deprecated(since = "1.21.5", forRemoval = true)
public static final TeleportCause CHORUS_FRUIT = CONSUMABLE_EFFECT;
}
}

View File

@ -87,7 +87,7 @@ public class TabCompleteEvent extends Event implements Cancellable {
/**
* Set the completions offered, overriding any already set.
* <br>
* The passed collection will be cloned to a new List. You must call {{@link #getCompletions()}} to mutate from here
* The passed collection will be cloned to a new List. You must call {@link #getCompletions()} to mutate from here
*
* @param completions the new completions
*/

View File

@ -2,6 +2,7 @@ package org.bukkit.inventory;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryType;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -321,4 +322,16 @@ public interface InventoryView {
*/
@Deprecated(since = "1.21.1") // Paper
public void setTitle(@NotNull String title);
/**
* Gets the menu type of the inventory view if applicable.
* <p>
* Some inventory types do not support a menu type. In such cases, this method
* returns null. This typically applies to inventories belonging to entities
* like players or animals (e.g., a horse).
*
* @return the menu type of the inventory view or null if not applicable
*/
@ApiStatus.Experimental
@Nullable MenuType getMenuType();
}

View File

@ -210,12 +210,12 @@ public interface ItemFactory {
@Deprecated(since = "1.19.3") // Paper
ItemStack enchantItem(@NotNull final ItemStack item, final int level, final boolean allowTreasures);
// Paper start - Adventure
/**
* Creates a hover event for the given item.
*
* @param item The item
* @return A hover event
* @throws IllegalArgumentException if the {@link ItemStack#getAmount()} is not between 1 and 99
*/
@NotNull
net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowItem> asHoverEvent(final @NotNull ItemStack item, final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowItem> op);
@ -223,12 +223,13 @@ public interface ItemFactory {
/**
* Get the formatted display name of the {@link ItemStack}.
*
* @apiNote this component include a {@link net.kyori.adventure.text.event.HoverEvent item hover event}.
* When used in chat, make sure to follow the ItemStack rules regarding amount, type, and other properties.
* @param itemStack the {@link ItemStack}
* @return display name of the {@link ItemStack}
*/
@NotNull
net.kyori.adventure.text.Component displayName(@NotNull ItemStack itemStack);
// Paper end - Adventure
// Paper start - add getI18NDisplayName
/**

View File

@ -9,6 +9,7 @@ import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Predicate;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.HoverEvent;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
@ -706,6 +707,13 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
return Bukkit.getItemFactory().enchantWithLevels(this, levels, keySet, random);
}
/**
* {@inheritDoc}
*
* @param op transformation on value
* @return a hover event
* @throws IllegalArgumentException if the {@link ItemStack#getAmount()} is not between 1 and 99
*/
@NotNull
@Override
public net.kyori.adventure.text.event.HoverEvent<net.kyori.adventure.text.event.HoverEvent.ShowItem> asHoverEvent(final @NotNull java.util.function.UnaryOperator<net.kyori.adventure.text.event.HoverEvent.ShowItem> op) {
@ -715,6 +723,8 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
/**
* Get the formatted display name of the {@link ItemStack}.
*
* @apiNote this component include a {@link net.kyori.adventure.text.event.HoverEvent item hover event}.
* When used in chat, make sure to follow the ItemStack rules regarding amount, type, and other properties.
* @return display name of the {@link ItemStack}
*/
public net.kyori.adventure.text.@NotNull Component displayName() {

View File

@ -5,6 +5,9 @@ import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.datacomponent.item.ItemAdventurePredicate;
import net.kyori.adventure.text.Component;
import org.bukkit.NamespacedKey;
import org.bukkit.Tag;
@ -1086,12 +1089,12 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
@NotNull
ItemMeta clone();
// Paper start - Add an API for can-place-on/can-break adventure mode predicates
/**
* Gets set of materials what given item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
*
* @return Set of materials
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_BREAK} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.14")
Set<org.bukkit.Material> getCanDestroy();
@ -1100,7 +1103,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Sets set of materials what given item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
*
* @param canDestroy Set of materials
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_BREAK} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.14")
void setCanDestroy(Set<org.bukkit.Material> canDestroy);
@ -1109,7 +1113,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Gets set of materials where given item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
*
* @return Set of materials
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.14")
Set<org.bukkit.Material> getCanPlaceOn();
@ -1118,7 +1123,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Sets set of materials where given item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
*
* @param canPlaceOn Set of materials
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.14")
void setCanPlaceOn(Set<org.bukkit.Material> canPlaceOn);
@ -1127,7 +1133,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Gets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
*
* @return Set of {@link com.destroystokyo.paper.Namespaced}
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_BREAK} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.20.6")
@NotNull
@ -1137,7 +1144,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Sets the collection of namespaced keys that the item can destroy in {@link org.bukkit.GameMode#ADVENTURE}
*
* @param canDestroy Collection of {@link com.destroystokyo.paper.Namespaced}
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_BREAK} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.20.6")
void setDestroyableKeys(@NotNull Collection<com.destroystokyo.paper.Namespaced> canDestroy);
@ -1146,7 +1154,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Gets the collection of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
*
* @return Set of {@link com.destroystokyo.paper.Namespaced}
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#getData(DataComponentType.Valued)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this.
*/
@NotNull
@Deprecated(forRemoval = true, since = "1.20.6")
@ -1156,7 +1165,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Sets the set of namespaced keys that the item can be placed on in {@link org.bukkit.GameMode#ADVENTURE}
*
* @param canPlaceOn Collection of {@link com.destroystokyo.paper.Namespaced}
* @deprecated this API is unsupported and will be replaced, its usage may result in data loss related to place/destroy predicates.
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#setData(DataComponentType.Valued, Object)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.20.6")
void setPlaceableKeys(@NotNull Collection<com.destroystokyo.paper.Namespaced> canPlaceOn);
@ -1165,7 +1175,8 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Checks for the existence of any keys that the item can be placed on
*
* @return true if this item has placeable keys
* @deprecated this API is unsupported and will be replaced
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#hasData(DataComponentType)} with {@link DataComponentTypes#CAN_PLACE_ON} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.20.6")
boolean hasPlaceableKeys();
@ -1174,9 +1185,9 @@ public interface ItemMeta extends Cloneable, ConfigurationSerializable, Persiste
* Checks for the existence of any keys that the item can destroy
*
* @return true if this item has destroyable keys
* @deprecated this API is unsupported and will be replaced
* @deprecated this API part has been replaced by the {@link ItemAdventurePredicate} API.
* Please use {@link ItemStack#hasData(DataComponentType)} with {@link DataComponentTypes#CAN_BREAK} instead of this.
*/
@Deprecated(forRemoval = true, since = "1.20.6")
boolean hasDestroyableKeys();
// Paper end - Add an API for can-place-on/can-break adventure mode predicates
}

View File

@ -8,6 +8,7 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
/**
* Represents a potion or item that can have custom effects.
@ -74,6 +75,16 @@ public interface PotionMeta extends ItemMeta {
@NotNull
List<PotionEffect> getCustomEffects();
/**
* All effects that this potion meta holds.
* <p>
* This is a combination of the base potion type and any custom effects.
*
* @return an unmodifiable list of all effects.
*/
@NotNull
@Unmodifiable List<PotionEffect> getAllEffects();
/**
* Adds a custom potion effect to this potion.
*
@ -146,6 +157,16 @@ public interface PotionMeta extends ItemMeta {
*/
void setColor(@Nullable Color color);
/**
* Computes the effective colour of this potion meta.
* <p>
* This blends all custom effects, or uses a default fallback color.
*
* @return the effective potion color
*/
@NotNull
Color computeEffectiveColor();
/**
* Checks for existence of a custom potion name translation suffix.
*

View File

@ -206,7 +206,16 @@ public final class PluginClassLoader extends URLClassLoader implements io.paperm
if (result == null) {
String path = name.replace('.', '/').concat(".class");
JarEntry entry = jar.getJarEntry(path);
// Add details to zip file errors - help debug classloading
JarEntry entry;
try {
entry = jar.getJarEntry(path);
} catch (IllegalStateException zipFileClosed) {
if (plugin == null) {
throw zipFileClosed;
}
throw new IllegalStateException("The plugin classloader for " + plugin.getName() + " has thrown a zip file error.", zipFileClosed);
}
if (entry != null) {
byte[] classBytes;

View File

@ -4,8 +4,12 @@ import io.papermc.generator.utils.ClassHelper;
import io.papermc.paper.datacomponent.DataComponentType;
import io.papermc.paper.datacomponent.DataComponentTypes;
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
import io.papermc.paper.registry.data.CatTypeRegistryEntry;
import io.papermc.paper.registry.data.ChickenVariantRegistryEntry;
import io.papermc.paper.registry.data.CowVariantRegistryEntry;
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.PaintingVariantRegistryEntry;
import java.lang.reflect.Field;
@ -20,6 +24,8 @@ 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;
@ -161,18 +167,18 @@ public final class RegistryEntries {
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).delayed(),
entry(Registries.WOLF_VARIANT, WolfVariants.class, Wolf.Variant.class).apiRegistryBuilder(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.INSTRUMENT, Instruments.class, MusicInstrument.class).allowDirect().delayed(),
entry(Registries.CAT_VARIANT, CatVariants.class, Cat.Type.class).delayed(),
entry(Registries.FROG_VARIANT, FrogVariants.class, Frog.Variant.class).delayed(),
entry(Registries.CHICKEN_VARIANT, ChickenVariants.class, Chicken.Variant.class),
entry(Registries.COW_VARIANT, CowVariants.class, Cow.Variant.class),
entry(Registries.PIG_VARIANT, PigVariants.class, Pig.Variant.class)
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")
);
public static final List<RegistryEntry<?>> API_ONLY = List.of(

View File

@ -15,7 +15,7 @@ plugins {
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
dependencies {
mache("io.papermc:mache:1.21.5+build.1")
mache("io.papermc:mache:1.21.5+build.2")
paperclip("io.papermc:paperclip:3.0.3")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
}
@ -135,7 +135,7 @@ dependencies {
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
implementation("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
implementation("net.minecrell:terminalconsoleappender:1.3.0")
implementation("io.papermc.adventure:adventure-text-serializer-ansi:4.21.0-mc1215-SNAPSHOT") // Keep in sync with adventureVersion from Paper-API build file // FIXME back to release
implementation("net.kyori:adventure-text-serializer-ansi:4.21.0") // Keep in sync with adventureVersion from Paper-API build file
runtimeConfiguration(sourceSets.main.map { it.runtimeClasspath })
/*

View File

@ -143,7 +143,7 @@ index 3a384175f8e7f204234bbaf3081bdc20c47a0d4b..5699bc15eba92e22433a20cb8326b59f
private ClientboundLevelChunkWithLightPacket(RegistryFriendlyByteBuf buffer) {
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index ef201f4add358fbf1818f3b2ec9e75fe2cce4c8b..fe9b4484d683fe48f435a053c9c90557fdf80e7b 100644
index 6b67cc939851745718f919488c997eb6719a16fc..085040aa98704f2874bcd95b751b0a81dcdb15ad 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -343,7 +343,7 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@ -186,7 +186,7 @@ index 342bc843c384761e883de861044f4f8930ae8763..14878690a88fd4de3e2c127086607e6c
if (io.papermc.paper.event.packet.PlayerChunkLoadEvent.getHandlerList().getRegisteredListeners().length > 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 a2a4dbcfb77d44657b3dfbe97cb629de215c29eb..73717609fccd9af12e2cc39824106f49426b581c 100644
index 9b2ee3e16e2c443e8ff03faec59dd55d729e9274..5ec9e3b37e575e9805bf9f0ce5cae5c1284461d8 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -407,7 +407,7 @@ public abstract class PlayerList {
@ -199,7 +199,7 @@ index a2a4dbcfb77d44657b3dfbe97cb629de215c29eb..73717609fccd9af12e2cc39824106f49
}
// Paper end - Send empty chunk
diff --git a/net/minecraft/world/level/Level.java b/net/minecraft/world/level/Level.java
index 1f26826b2161cfeb27e5b2060e178b493e9142d9..63f8b0c47e3321b74f4b6bcbc1e28cd751911198 100644
index 1bb40f18b671d63719d96a58ff283767c2cfe383..ba50f21707a69bbf720345996d7c83d2064e5246 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<Entity>, AutoCl
@ -209,10 +209,10 @@ index 1f26826b2161cfeb27e5b2060e178b493e9142d9..63f8b0c47e3321b74f4b6bcbc1e28cd7
+ public final io.papermc.paper.antixray.ChunkPacketBlockController chunkPacketBlockController; // Paper - Anti-Xray
private final CraftWorld world;
public boolean pvpMode;
public org.bukkit.generator.ChunkGenerator generator;
public @Nullable org.bukkit.generator.ChunkGenerator generator;
@@ -201,7 +202,8 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
org.bukkit.generator.BiomeProvider biomeProvider, // CraftBukkit
org.bukkit.World.Environment env, // CraftBukkit
@Nullable org.bukkit.generator.BiomeProvider biomeProvider, // Paper
org.bukkit.World.Environment environment, // Paper
java.util.function.Function<org.spigotmc.SpigotWorldConfig, // Spigot - create per world config
- io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator // Paper - create paper world config
+ io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, // Paper - create paper world config

View File

@ -3874,10 +3874,10 @@ index 0000000000000000000000000000000000000000..1c82dcd38f789707e15e8cbec72ef9cd
+}
diff --git a/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
new file mode 100644
index 0000000000000000000000000000000000000000..7554c109c35397bc1a43dd80e87764fd78645bbf
index 0000000000000000000000000000000000000000..2d24d03bbdb5ee0d862cbfff2219f58afffafe12
--- /dev/null
+++ b/ca/spottedleaf/moonrise/patches/chunk_system/level/entity/EntityLookup.java
@@ -0,0 +1,1002 @@
@@ -0,0 +1,1006 @@
+package ca.spottedleaf.moonrise.patches.chunk_system.level.entity;
+
+import ca.spottedleaf.concurrentutil.map.ConcurrentLong2ReferenceChainedHashTable;
@ -4059,6 +4059,10 @@ index 0000000000000000000000000000000000000000..7554c109c35397bc1a43dd80e87764fd
+ }
+ }
+
+ public Iterable<Entity> getAllMapped() {
+ return this.entityByUUID.values();
+ }
+
+ public int getEntityCount() {
+ synchronized (this.accessibleEntities) {
+ return this.accessibleEntities.size();
@ -26798,7 +26802,7 @@ index c50a1a01d167696134bd65b2d28db323d81d6ebd..5d63bf024cbcbd2f627c64fee77553c9
}
}
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
index 3f83a589442a80e9c16b5e9cd0f50792defd12bc..0005a1784ccaa00e5d6d67e7be98445150487982 100644
index 69fbcd734c269bbc9858b0ad0b3b268ddb81fcc6..a1ae77b70f69852d9e4332bf1cb3409c33b21de0 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -104,6 +104,11 @@ public class ServerEntity {
@ -26814,7 +26818,7 @@ index 3f83a589442a80e9c16b5e9cd0f50792defd12bc..0005a1784ccaa00e5d6d67e7be984451
if (!passengers.equals(this.lastPassengers)) {
List<UUID> 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 fe9b4484d683fe48f435a053c9c90557fdf80e7b..8afe96bfdc37e57129f1bb4af5b6d5cc22c11aee 100644
index 085040aa98704f2874bcd95b751b0a81dcdb15ad..cd72273468f596b640bd2d10d846fbe8813846a6 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;
@ -27565,10 +27569,10 @@ index fe9b4484d683fe48f435a053c9c90557fdf80e7b..8afe96bfdc37e57129f1bb4af5b6d5cc
}
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index a8c73bdf8fb130eed8922cb537a35cda07e66da5..3e73c69c9db8cbded28a001b20d9989acb11c638 100644
index 57af8cd7629fa14176c6e7a29956617ec9506999..63fecebe6048b0d3372ea84ac74dc74744de3273 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -187,7 +187,7 @@ import net.minecraft.world.scores.Team;
@@ -186,7 +186,7 @@ import net.minecraft.world.scores.Team;
import net.minecraft.world.scores.criteria.ObjectiveCriteria;
import org.slf4j.Logger;
@ -27577,7 +27581,7 @@ index a8c73bdf8fb130eed8922cb537a35cda07e66da5..3e73c69c9db8cbded28a001b20d9989a
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;
@@ -423,6 +423,36 @@ public class ServerPlayer extends Player {
@@ -415,6 +415,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
@ -28202,10 +28206,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 73717609fccd9af12e2cc39824106f49426b581c..72524ff3399a4477dfa3db2f4e79bb14f6519a8b 100644
index eda176c96bcf3d67650722ffce33863edfbdea9e..a7a07ebe6ceed99fa768b6834e350fe2f51a6950 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -1321,7 +1321,7 @@ public abstract class PlayerList {
@@ -1332,7 +1332,7 @@ public abstract class PlayerList {
public void setViewDistance(int viewDistance) {
this.viewDistance = viewDistance;
@ -28214,7 +28218,7 @@ index 73717609fccd9af12e2cc39824106f49426b581c..72524ff3399a4477dfa3db2f4e79bb14
for (ServerLevel serverLevel : this.server.getAllLevels()) {
if (serverLevel != null) {
@@ -1332,7 +1332,7 @@ public abstract class PlayerList {
@@ -1343,7 +1343,7 @@ public abstract class PlayerList {
public void setSimulationDistance(int simulationDistance) {
this.simulationDistance = simulationDistance;
@ -28597,7 +28601,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
+ // Paper end - block counting
}
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e36b7294f 100644
index 663fb13233afb51f935c30ac2acae808809754c6..81a18b8e605bd4c28b48a32c80be231609182970 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;
@ -28950,7 +28954,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
}
private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
@@ -2599,21 +2747,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -2616,21 +2764,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public boolean isInWall() {
@ -29072,7 +29076,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
}
public InteractionResult interact(Player player, InteractionHand hand) {
@@ -4061,15 +4298,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4078,15 +4315,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public Iterable<Entity> getIndirectPassengers() {
@ -29098,7 +29102,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
}
public int countPlayerPassengers() {
@@ -4212,77 +4451,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4229,77 +4468,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
return Mth.lerp(partialTick, this.yRotO, this.yRot);
}
@ -29289,7 +29293,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
public boolean touchingUnloadedChunk() {
AABB aabb = this.getBoundingBox().inflate(1.0);
@@ -4437,6 +4735,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4454,6 +4752,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
}
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
@ -29305,7 +29309,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
if (!checkPosition(this, x, y, z)) {
return;
}
@@ -4570,6 +4877,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4587,6 +4894,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
@ -29318,7 +29322,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause); // CraftBukkit
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
if (this.removalReason == null) {
@@ -4580,7 +4893,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4597,7 +4910,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
this.stopRiding();
}
@ -29327,7 +29331,7 @@ index 24f3fa347c889b4e2b7b2ce69cda0f68e9bbc346..48477efbd01bb1f8987d9a3ae195710e
this.levelCallback.onRemove(removalReason);
this.onRemoval(removalReason);
// Paper start - Folia schedulers
@@ -4614,7 +4927,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
@@ -4631,7 +4944,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
public boolean shouldBeSaved() {
return (this.removalReason == null || this.removalReason.shouldSave())
&& !this.isPassenger()
@ -29576,7 +29580,7 @@ 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 75bf15ccd8a12153951f886ed87be9f3bece3133..6f601a0a300bbf01f77d835576d15e25c8ba10b8 100644
index f5ce8151bb1bae9be638ced7f74899d452d517e1..5248f3c22abb608d7d7b338f169f13bfbf4cd2d6 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 {
@ -29725,7 +29729,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 63f8b0c47e3321b74f4b6bcbc1e28cd751911198..eb4d03cfdb34243901cfba832d35559d5be9e876 100644
index ba50f21707a69bbf720345996d7c83d2064e5246..e9751a95ffd88f365185d53f8764291d9d2473e2 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;
@ -30399,7 +30403,7 @@ index 63f8b0c47e3321b74f4b6bcbc1e28cd751911198..eb4d03cfdb34243901cfba832d35559d
+ // Paper end - getblock optimisations - cache world height/sections
this.spigotConfig = new org.spigotmc.SpigotWorldConfig(((net.minecraft.world.level.storage.PrimaryLevelData) levelData).getLevelName()); // Spigot
this.paperConfig = paperWorldConfigCreator.apply(this.spigotConfig); // Paper - create paper world config
this.generator = gen;
this.generator = generator;
@@ -281,6 +914,7 @@ public abstract class Level implements LevelAccessor, UUIDLookup<Entity>, AutoCl
});
// CraftBukkit end

View File

@ -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 0005a1784ccaa00e5d6d67e7be98445150487982..257ecbcf7d463eefb951867a5426eaf24e356305 100644
index a1ae77b70f69852d9e4332bf1cb3409c33b21de0..b118e91f1e0b5a8b8c0b2a4a32faabc5a34a5954 100644
--- a/net/minecraft/server/level/ServerEntity.java
+++ b/net/minecraft/server/level/ServerEntity.java
@@ -103,6 +103,13 @@ public class ServerEntity {
@ -77,7 +77,7 @@ index 0005a1784ccaa00e5d6d67e7be98445150487982..257ecbcf7d463eefb951867a5426eaf2
public void sendChanges() {
// Paper start - optimise collisions
if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) {
@@ -136,7 +143,7 @@ public class ServerEntity {
@@ -141,7 +148,7 @@ public class ServerEntity {
this.sendDirtyEntityData();
}
@ -86,7 +86,7 @@ index 0005a1784ccaa00e5d6d67e7be98445150487982..257ecbcf7d463eefb951867a5426eaf2
byte b = Mth.packDegrees(this.entity.getYRot());
byte b1 = Mth.packDegrees(this.entity.getXRot());
boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
@@ -171,7 +178,7 @@ public class ServerEntity {
@@ -176,7 +183,7 @@ public class ServerEntity {
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;
@ -95,7 +95,7 @@ index 0005a1784ccaa00e5d6d67e7be98445150487982..257ecbcf7d463eefb951867a5426eaf2
this.wasOnGround = this.entity.onGround();
this.teleportDelay = 0;
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
@@ -236,6 +243,7 @@ public class ServerEntity {
@@ -241,6 +248,7 @@ public class ServerEntity {
}
this.entity.hasImpulse = false;

View File

@ -5,7 +5,7 @@ Subject: [PATCH] Incremental chunk and player saving
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index 00f7f4356d6bffdd31f58b9d798c755edd9cd3ff..ea85cac4a41075efe8525c40755e7ebac6ca9dea 100644
index 094ef7f54ad71795a2d8c2a8d03a32bef6ff2164..79bc1b7d9f640d2322814177eb3e921da8671e87 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -952,7 +952,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -50,7 +50,7 @@ index 00f7f4356d6bffdd31f58b9d798c755edd9cd3ff..ea85cac4a41075efe8525c40755e7eba
ProfilerFiller profilerFiller = Profiler.get();
this.runAllTasks(); // Paper - move runAllTasks() into full server tick (previously for timings)
diff --git a/net/minecraft/server/level/ServerLevel.java b/net/minecraft/server/level/ServerLevel.java
index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378896c6fcb 100644
index 32c8d4675de341d5edad7dbd9c0bf4bce5037733..bfbfbaa9660d21071c420b60b10be0a02a1bc87e 100644
--- a/net/minecraft/server/level/ServerLevel.java
+++ b/net/minecraft/server/level/ServerLevel.java
@@ -1317,6 +1317,28 @@ public class ServerLevel extends Level implements ServerEntityGetter, WorldGenLe
@ -64,7 +64,7 @@ index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378
+ }
+
+ if (doFull) {
+ this.saveLevelData(true);
+ this.saveLevelData(false);
+ }
+ // chunk autosave is already called by the ChunkSystem during unload processing (ChunkMap#processUnloads)
+ // Copied from save()
@ -83,10 +83,10 @@ index debc511cf18d0be813803c200bd1cf0b07ba7974..2a4a40976215ea858c562c3f530db378
// Paper start - add close param
this.save(progress, flush, skipSave, false);
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
index bc901bc689c2690ac19e590bff1ae612b7071ee9..8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0 100644
index 5a60f2598560571e156612bf256c1c340d92a922..57e7d0a8b5f2a5bc65b0f290fb655625b1481f31 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -189,6 +189,7 @@ import org.slf4j.Logger;
@@ -188,6 +188,7 @@ import org.slf4j.Logger;
public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patches.chunk_system.player.ChunkSystemServerPlayer { // Paper - rewrite chunk system
private static final Logger LOGGER = LogUtils.getLogger();
@ -95,7 +95,7 @@ index bc901bc689c2690ac19e590bff1ae612b7071ee9..8e7ee4dc951eb53ccf65ab71214a0b89
private static final int NEUTRAL_MOB_DEATH_NOTIFICATION_RADII_Y = 10;
private static final int FLY_STAT_RECORDING_SPEED = 25;
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index 72524ff3399a4477dfa3db2f4e79bb14f6519a8b..6e22aedd36add8e39a82248193f324b36dfa27b5 100644
index a7a07ebe6ceed99fa768b6834e350fe2f51a6950..9ca3c55a3b5b1a532b86b08eb92460df4cb54f2a 100644
--- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java
@@ -486,6 +486,7 @@ public abstract class PlayerList {
@ -106,7 +106,7 @@ index 72524ff3399a4477dfa3db2f4e79bb14f6519a8b..6e22aedd36add8e39a82248193f324b3
this.playerIo.save(player);
ServerStatsCounter serverStatsCounter = player.getStats(); // CraftBukkit
if (serverStatsCounter != null) {
@@ -1068,9 +1069,23 @@ public abstract class PlayerList {
@@ -1079,9 +1080,23 @@ public abstract class PlayerList {
}
public void saveAll() {

View File

@ -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 8e7ee4dc951eb53ccf65ab71214a0b89bd932ba0..73a450e045eba5dbfc7a4e861e4c614c8f60d6b4 100644
index 4b2801749328f250ce5735fbe7f6941a6bede01a..af04fcdba1e57b4eac678235b56ad3e1c70169b7 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -403,6 +403,10 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -395,6 +395,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

View File

@ -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 73a450e045eba5dbfc7a4e861e4c614c8f60d6b4..105d6b3a40067f9e8ae5bbd9f2872171f73b3d07 100644
index af04fcdba1e57b4eac678235b56ad3e1c70169b7..3781d9cc174b7aecacb9b9855d52c7b1ff05835c 100644
--- a/net/minecraft/server/level/ServerPlayer.java
+++ b/net/minecraft/server/level/ServerPlayer.java
@@ -407,6 +407,7 @@ public class ServerPlayer extends Player implements ca.spottedleaf.moonrise.patc
@@ -399,6 +399,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
@ -72,7 +72,7 @@ index 73a450e045eba5dbfc7a4e861e4c614c8f60d6b4..105d6b3a40067f9e8ae5bbd9f2872171
public org.bukkit.craftbukkit.entity.CraftPlayer.TransferCookieConnection transferCookieConnection;
public String displayName;
diff --git a/net/minecraft/world/level/NaturalSpawner.java b/net/minecraft/world/level/NaturalSpawner.java
index 17b13baa3465530b11ff918c806c772eb5c39a2c..afd6da5c361e1dcf311a9afe8a7efe2faef2556a 100644
index c710e08ab48075ce7854e56826adb8f0364b025b..14a2514a408a66a83f7b5fb43b4c4dc8f23fd5f4 100644
--- a/net/minecraft/world/level/NaturalSpawner.java
+++ b/net/minecraft/world/level/NaturalSpawner.java
@@ -279,6 +279,11 @@ public final class NaturalSpawner {

View File

@ -48,7 +48,7 @@ index 0000000000000000000000000000000000000000..24a2090e068ad3c0d08705050944abdf
+ }
+}
diff --git a/net/minecraft/server/MinecraftServer.java b/net/minecraft/server/MinecraftServer.java
index ea85cac4a41075efe8525c40755e7ebac6ca9dea..7af29d3dc7b337d74cee5df7cbca35c420643370 100644
index 79bc1b7d9f640d2322814177eb3e921da8671e87..f1373fd5fdebb9f4600ba7f32a5df6188de3a0e9 100644
--- a/net/minecraft/server/MinecraftServer.java
+++ b/net/minecraft/server/MinecraftServer.java
@@ -1706,6 +1706,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
@ -60,10 +60,10 @@ index ea85cac4a41075efe8525c40755e7ebac6ca9dea..7af29d3dc7b337d74cee5df7cbca35c4
/* 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 5329dc9259f30011d277336bfc76da18c15d5d81..8391f51b7dd584dd346bda5dccbee900d4fa9c2d 100644
index 72cd623a1a3ce4b7a570a853456b067cd93736b1..ad7852a19ff73368ec9e7e63dcb7a064f78eefa0 100644
--- a/net/minecraft/world/item/ItemStack.java
+++ b/net/minecraft/world/item/ItemStack.java
@@ -832,10 +832,16 @@ public final class ItemStack implements DataComponentHolder {
@@ -831,10 +831,16 @@ public final class ItemStack implements DataComponentHolder {
}
public ItemStack copy() {

View File

@ -6,7 +6,7 @@ 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 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062b48d43fa 100644
index 0be741820fc7da2aac4f4aad85c4238ef49a0f57..337976c5c1ead87c36daa4e741b06e5a195b8302 100644
--- a/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -555,7 +555,7 @@ public class ServerGamePacketListenerImpl
@ -88,7 +88,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062
}
@Override
@@ -1430,7 +1462,7 @@ public class ServerGamePacketListenerImpl
@@ -1432,7 +1464,7 @@ public class ServerGamePacketListenerImpl
}
}
@ -97,7 +97,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062
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
@@ -1469,6 +1501,7 @@ public class ServerGamePacketListenerImpl
@@ -1471,6 +1503,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,7 +105,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062
// Paper start - prevent position desync
if (this.awaitingPositionFromClient != null) {
return; // ... thanks Mojang for letting move calls teleport across dimensions.
@@ -1501,7 +1534,17 @@ public class ServerGamePacketListenerImpl
@@ -1503,7 +1536,17 @@ public class ServerGamePacketListenerImpl
}
// Paper start - Add fail move event
@ -124,7 +124,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062
if (teleportBack) {
io.papermc.paper.event.player.PlayerFailMoveEvent event = fireFailMove(io.papermc.paper.event.player.PlayerFailMoveEvent.FailReason.CLIPPED_INTO_BLOCK,
toX, toY, toZ, toYaw, toPitch, false);
@@ -1638,7 +1681,7 @@ public class ServerGamePacketListenerImpl
@@ -1640,7 +1683,7 @@ public class ServerGamePacketListenerImpl
private boolean updateAwaitingTeleport() {
if (this.awaitingPositionFromClient != null) {
@ -133,7 +133,7 @@ index 5e921c490814be31fc2843327c0e2cc76bda6620..f49a2c18ec20a7181951389066b7d062
this.awaitingTeleportTime = this.tickCount;
this.teleport(
this.awaitingPositionFromClient.x,
@@ -1657,6 +1700,33 @@ public class ServerGamePacketListenerImpl
@@ -1659,6 +1702,33 @@ public class ServerGamePacketListenerImpl
}
}

View File

@ -1,126 +1,13 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Chaoscaot <chaos@chaoscaot.de>
Date: Sun, 30 Mar 2025 12:00:51 +0200
Date: Sun, 30 Mar 2025 12:00:50 +0200
Subject: [PATCH] SW Disable Commands
diff --git a/net/minecraft/commands/Commands.java b/net/minecraft/commands/Commands.java
index 9dd86cf63dd93620adb539a7a80a8d01c7ac08a2..3289d9f441aa219f019b63531b0ab431fcfe9115 100644
index 9dd86cf63dd93620adb539a7a80a8d01c7ac08a2..ca59e02fa0b2bbf2fdf53f088b0a6a876330fd73 100644
--- a/net/minecraft/commands/Commands.java
+++ b/net/minecraft/commands/Commands.java
@@ -155,67 +155,67 @@ public class Commands {
}
public Commands(Commands.CommandSelection selection, CommandBuildContext context, final boolean modern) {
// Paper end - Brigadier API - modern minecraft overloads that do not use redirects but are copies instead
- AdvancementCommands.register(this.dispatcher);
- AttributeCommand.register(this.dispatcher, context);
- ExecuteCommand.register(this.dispatcher, context);
- BossBarCommands.register(this.dispatcher, context);
+ //AdvancementCommands.register(this.dispatcher);
+ //AttributeCommand.register(this.dispatcher, context);
+ //ExecuteCommand.register(this.dispatcher, context);
+ //BossBarCommands.register(this.dispatcher, context);
ClearInventoryCommands.register(this.dispatcher, context);
- CloneCommands.register(this.dispatcher, context);
- DamageCommand.register(this.dispatcher, context);
- DataCommands.register(this.dispatcher);
- DataPackCommand.register(this.dispatcher);
- DebugCommand.register(this.dispatcher);
- DefaultGameModeCommands.register(this.dispatcher);
- DifficultyCommand.register(this.dispatcher);
+ //CloneCommands.register(this.dispatcher, context);
+ //DamageCommand.register(this.dispatcher, context);
+ //DataCommands.register(this.dispatcher);
+ //DataPackCommand.register(this.dispatcher);
+ //DebugCommand.register(this.dispatcher);
+ //DefaultGameModeCommands.register(this.dispatcher);
+ //DifficultyCommand.register(this.dispatcher);
EffectCommands.register(this.dispatcher, context);
- EmoteCommands.register(this.dispatcher);
+ //EmoteCommands.register(this.dispatcher);
EnchantCommand.register(this.dispatcher, context);
- ExperienceCommand.register(this.dispatcher);
- FillCommand.register(this.dispatcher, context);
+ //ExperienceCommand.register(this.dispatcher);
+ //FillCommand.register(this.dispatcher, context);
FillBiomeCommand.register(this.dispatcher, context);
- ForceLoadCommand.register(this.dispatcher);
- FunctionCommand.register(this.dispatcher);
+ //ForceLoadCommand.register(this.dispatcher);
+ //FunctionCommand.register(this.dispatcher);
GameModeCommand.register(this.dispatcher);
GameRuleCommand.register(this.dispatcher, context);
GiveCommand.register(this.dispatcher, context);
- HelpCommand.register(this.dispatcher);
- ItemCommands.register(this.dispatcher, context);
+ //HelpCommand.register(this.dispatcher);
+ //ItemCommands.register(this.dispatcher, context);
KickCommand.register(this.dispatcher);
KillCommand.register(this.dispatcher);
- ListPlayersCommand.register(this.dispatcher);
- LocateCommand.register(this.dispatcher, context);
- LootCommand.register(this.dispatcher, context);
- MsgCommand.register(this.dispatcher);
- ParticleCommand.register(this.dispatcher, context);
- PlaceCommand.register(this.dispatcher);
- PlaySoundCommand.register(this.dispatcher);
- RandomCommand.register(this.dispatcher);
- ReloadCommand.register(this.dispatcher);
- RecipeCommand.register(this.dispatcher);
- ReturnCommand.register(this.dispatcher);
- RideCommand.register(this.dispatcher);
+ //ListPlayersCommand.register(this.dispatcher);
+ //LocateCommand.register(this.dispatcher, context);
+ //LootCommand.register(this.dispatcher, context);
+ //MsgCommand.register(this.dispatcher);
+ //ParticleCommand.register(this.dispatcher, context);
+ //PlaceCommand.register(this.dispatcher);
+ //PlaySoundCommand.register(this.dispatcher);
+ //RandomCommand.register(this.dispatcher);
+ //ReloadCommand.register(this.dispatcher);
+ //RecipeCommand.register(this.dispatcher);
+ //ReturnCommand.register(this.dispatcher);
+ //RideCommand.register(this.dispatcher);
RotateCommand.register(this.dispatcher);
- SayCommand.register(this.dispatcher);
- ScheduleCommand.register(this.dispatcher);
- ScoreboardCommand.register(this.dispatcher, context);
- SeedCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
- SetBlockCommand.register(this.dispatcher, context);
- SetSpawnCommand.register(this.dispatcher);
+ //SayCommand.register(this.dispatcher);
+ //ScheduleCommand.register(this.dispatcher);
+ //ScoreboardCommand.register(this.dispatcher, context);
+ //SeedCommand.register(this.dispatcher, selection != Commands.CommandSelection.INTEGRATED);
+ //SetBlockCommand.register(this.dispatcher, context);
+ //SetSpawnCommand.register(this.dispatcher);
SetWorldSpawnCommand.register(this.dispatcher);
SpectateCommand.register(this.dispatcher);
- SpreadPlayersCommand.register(this.dispatcher);
- StopSoundCommand.register(this.dispatcher);
+ //SpreadPlayersCommand.register(this.dispatcher);
+ //StopSoundCommand.register(this.dispatcher);
SummonCommand.register(this.dispatcher, context);
- TagCommand.register(this.dispatcher);
- TeamCommand.register(this.dispatcher, context);
- TeamMsgCommand.register(this.dispatcher);
+ //TagCommand.register(this.dispatcher);
+ //TeamCommand.register(this.dispatcher, context);
+ //TeamMsgCommand.register(this.dispatcher);
TeleportCommand.register(this.dispatcher);
- TellRawCommand.register(this.dispatcher, context);
- TestCommand.register(this.dispatcher, context);
+ //TellRawCommand.register(this.dispatcher, context);
+ //TestCommand.register(this.dispatcher, context);
TickCommand.register(this.dispatcher);
TimeCommand.register(this.dispatcher);
- TitleCommand.register(this.dispatcher, context);
- TriggerCommand.register(this.dispatcher);
+ //TitleCommand.register(this.dispatcher, context);
+ //TriggerCommand.register(this.dispatcher);
WeatherCommand.register(this.dispatcher);
WorldBorderCommand.register(this.dispatcher);
if (JvmProfiler.INSTANCE.isAvailable()) {
@@ -235,20 +235,20 @@ public class Commands {
}

View File

@ -13,7 +13,7 @@
+ public CommandNode<net.minecraft.commands.CommandSourceStack> clientNode; // Paper - Brigadier API
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> unwrappedCached = null; // Paper - Brigadier Command API
+ public CommandNode<io.papermc.paper.command.brigadier.CommandSourceStack> wrappedCached = null; // Paper - Brigadier Command API
+ public io.papermc.paper.command.brigadier.PluginCommandMeta pluginCommandMeta; // Paper - Brigadier Command API
+ public io.papermc.paper.command.brigadier.APICommandMeta apiCommandMeta; // Paper - Brigadier Command API
+ // CraftBukkit start
+ public void removeCommand(String name) {
+ this.children.remove(name);

View File

@ -172,7 +172,7 @@
}
return null;
@@ -359,26 +_,120 @@
@@ -359,26 +_,121 @@
}
public void sendCommands(ServerPlayer player) {
@ -252,6 +252,7 @@
+ }
+ // 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<SharedSuggestionProvider, ?> argumentBuilder = (ArgumentBuilder) commandNode.createBuilder();
+ // Paper start

View File

@ -0,0 +1,10 @@
--- a/net/minecraft/core/ClientAsset.java
+++ b/net/minecraft/core/ClientAsset.java
@@ -12,6 +_,6 @@
public static final StreamCodec<ByteBuf, ClientAsset> STREAM_CODEC = StreamCodec.composite(ResourceLocation.STREAM_CODEC, ClientAsset::id, ClientAsset::new);
public ClientAsset(ResourceLocation id) {
- this(id, id.withPath(string -> "textures/" + string + ".png"));
+ this(id, id.withPath(string -> "textures/" + string + ".png")); // Paper - diff on change - io.papermc.paper.registry.data.client.ClientAssetImpl#pathFromIdentifier
}
}

View File

@ -1,33 +0,0 @@
--- a/net/minecraft/network/HashedStack.java
+++ b/net/minecraft/network/HashedStack.java
@@ -17,7 +_,7 @@
}
@Override
- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic
return stack.isEmpty();
}
};
@@ -27,7 +_,7 @@
hashedStack -> hashedStack instanceof HashedStack.ActualItem actualItem ? Optional.of(actualItem) : Optional.empty()
);
- boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator);
+ boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching); // Paper - add flag to simplify remote matching logic
static HashedStack create(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
return (HashedStack)(stack.isEmpty()
@@ -47,10 +_,10 @@
);
@Override
- public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator) {
+ public boolean matches(ItemStack stack, HashedPatchMap.HashGenerator hashGenerator, final boolean simplifyMatching) { // Paper - add flag to simplify remote matching logic
return this.count == stack.getCount()
&& this.item.equals(stack.getItemHolder())
- && this.components.matches(stack.getComponentsPatch(), hashGenerator);
+ && (simplifyMatching || this.components.matches(stack.getComponentsPatch(), hashGenerator)); // Paper - add flag to simplify remote matching logic
}
}
}

View File

@ -0,0 +1,31 @@
--- a/net/minecraft/network/syncher/EntityDataSerializers.java
+++ b/net/minecraft/network/syncher/EntityDataSerializers.java
@@ -51,10 +_,27 @@
public static final EntityDataSerializer<Optional<Component>> OPTIONAL_COMPONENT = EntityDataSerializer.forValueType(
ComponentSerialization.TRUSTED_OPTIONAL_STREAM_CODEC
);
+ // Paper start - do not obfuscate items sent as entity data
+ public static final StreamCodec<RegistryFriendlyByteBuf, ItemStack> OVERSIZED_ITEM_CODEC = new net.minecraft.network.codec.StreamCodec<>() {
+ @Override
+ public net.minecraft.world.item.ItemStack decode(final net.minecraft.network.RegistryFriendlyByteBuf buffer) {
+ return ItemStack.OPTIONAL_STREAM_CODEC.decode(buffer);
+ }
+
+ @Override
+ public void encode(final net.minecraft.network.RegistryFriendlyByteBuf buffer, final net.minecraft.world.item.ItemStack value) {
+ // If the codec is called during an obfuscation session, downgrade the context's obf level to OVERSIZED if it isn't already.
+ // Entity data cannot be fully obfuscated as entities might render out specific values (e.g. count or custom name).
+ try (final io.papermc.paper.util.SafeAutoClosable ignored = io.papermc.paper.util.sanitizer.ItemObfuscationSession.withContext(c -> c.level(io.papermc.paper.util.sanitizer.ItemObfuscationSession.ObfuscationLevel.OVERSIZED))) {
+ ItemStack.OPTIONAL_STREAM_CODEC.encode(buffer, value);
+ }
+ }
+ };
+ // Paper end - do not obfuscate items sent as entity data
public static final EntityDataSerializer<ItemStack> ITEM_STACK = new EntityDataSerializer<ItemStack>() {
@Override
public StreamCodec<? super RegistryFriendlyByteBuf, ItemStack> codec() {
- return ItemStack.OPTIONAL_STREAM_CODEC;
+ return OVERSIZED_ITEM_CODEC; // Paper - do not obfuscate items sent as entity data
}
@Override

View File

@ -1,12 +1,13 @@
--- a/net/minecraft/server/ReloadableServerResources.java
+++ b/net/minecraft/server/ReloadableServerResources.java
@@ -38,7 +_,8 @@
@@ -38,7 +_,9 @@
this.fullRegistryHolder = new ReloadableServerRegistries.Holder(registryAccess.compositeAccess());
this.postponedTags = postponedTags;
this.recipes = new RecipeManager(registries);
- this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures));
+ this.commands = new Commands(commandSelection, CommandBuildContext.simple(registries, enabledFeatures), true); // Paper - Brigadier Command API - use modern alias registration
+ io.papermc.paper.command.brigadier.PaperCommands.INSTANCE.setDispatcher(this.commands, CommandBuildContext.simple(registries, enabledFeatures)); // Paper - Brigadier Command API
+ io.papermc.paper.command.PaperCommands.registerCommands(); // Paper
this.advancements = new ServerAdvancementManager(registries);
this.functionLibrary = new ServerFunctionLibrary(functionCompilationLevel, this.commands.getDispatcher());
}

View File

@ -28,7 +28,15 @@
this.level = level;
this.broadcast = broadcast;
this.entity = entity;
@@ -106,13 +_,14 @@
@@ -103,16 +_,22 @@
if (!passengers.equals(this.lastPassengers)) {
List<UUID> list = this.mountedOrDismounted(passengers).map(Entity::getUUID).toList();
this.broadcastWithIgnore.accept(new ClientboundSetPassengersPacket(this.entity), list);
+ // Paper start - Allow riding players
+ if (this.entity instanceof ServerPlayer player) {
+ player.connection.send(new ClientboundSetPassengersPacket(this.entity));
+ }
+ // Paper end - Allow riding players
this.lastPassengers = passengers;
}

View File

@ -1,5 +1,13 @@
--- 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 @@
private int levitationStartTime;
private boolean disconnected;
@ -10,7 +18,7 @@
@Nullable
private Vec3 startingToFallPosition;
@Nullable
@@ -281,6 +_,20 @@
@@ -281,6 +_,13 @@
}
}
@ -20,26 +28,10 @@
+ ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(ServerPlayer.this.inventoryMenu.containerId, ServerPlayer.this.inventoryMenu.incrementStateId(), net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT, ServerPlayer.this.inventoryMenu.getSlot(net.minecraft.world.inventory.InventoryMenu.SHIELD_SLOT).getItem().copy()));
+ }
+ // Paper end - Sync offhand slot in menus
+
+ // Paper start - add flag to simplify remote matching logic
+ @Override
+ public ServerPlayer player() {
+ return ServerPlayer.this;
+ }
+ // Paper end - add flag to simplify remote matching logic
+
@Override
public void sendSlotChange(AbstractContainerMenu container, int slot, ItemStack itemStack) {
ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slot, itemStack));
@@ -302,7 +_,7 @@
@Override
public RemoteSlot createSlot() {
- return new RemoteSlot.Synchronized(this.cache::getUnchecked);
+ return new RemoteSlot.Synchronized(this.cache::getUnchecked, ServerPlayer.this.getBukkitEntity().simplifyContainerDesyncCheck()); // Paper - add flag to simplify remote matching logic
}
};
private final ContainerListener containerListener = new ContainerListener() {
@@ -316,6 +_,32 @@
}
}
@ -316,12 +308,19 @@
}
float saturationLevel = this.foodData.getSaturationLevel();
@@ -793,15 +_,84 @@
@@ -793,15 +_,36 @@
}
private void updateScoreForCriteria(ObjectiveCriteria criteria, int points) {
- this.getScoreboard().forAllObjectives(criteria, this, score -> score.set(points));
- }
-
- @Override
- public void die(DamageSource cause) {
- this.gameEvent(GameEvent.ENTITY_DIE);
- boolean _boolean = this.serverLevel().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
+ }
+
@ -348,13 +347,24 @@
+ return false;
+ }
+ // Paper end - PlayerDeathEvent#getItemsToKeep
@Override
public void die(DamageSource cause) {
- this.gameEvent(GameEvent.ENTITY_DIE);
- boolean _boolean = this.serverLevel().getGameRules().getBoolean(GameRules.RULE_SHOWDEATHMESSAGES);
- if (_boolean) {
- Component deathMessage = this.getCombatTracker().getDeathMessage();
+ // Paper start - Expand PlayerDeathEvent API
+ private void sendClientboundPlayerCombatKillPacket(boolean displayMessage, Component deathMessage) {
+ if (displayMessage && deathMessage != CommonComponents.EMPTY) {
+ // Paper - moved from below die(DamageSource) method
this.connection
.send(
new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage),
@@ -818,6 +_,65 @@
}
)
);
+ } else {
+ this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY));
+ }
+ }
+ // Paper end - Expand PlayerDeathEvent API
+ @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
+ // CraftBukkit start - fire PlayerDeathEvent
@ -382,7 +392,7 @@
+
+ String deathmessage = defaultMessage.getString();
+ this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
+ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerDeathEvent(this, cause, loot, io.papermc.paper.adventure.PaperAdventure.asAdventure(defaultMessage), keepInventory); // Paper - Adventure
+ org.bukkit.event.entity.PlayerDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerDeathEvent(this, cause, loot, io.papermc.paper.adventure.PaperAdventure.asAdventure(defaultMessage), showDeathMessage, keepInventory); // Paper - Adventure; Expand PlayerDeathEvent API
+ // Paper start - cancellable death event
+ if (event.isCancelled()) {
+ // make compatible with plugins that might have already set the health in an event listener
@ -400,13 +410,25 @@
+ }
+
+ net.kyori.adventure.text.Component apiDeathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
+ Component deathScreenMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(event.deathScreenMessageOverride() != null ? event.deathScreenMessageOverride() : apiDeathMessage); // Paper - Expand PlayerDeathEvent API
+
+ if (apiDeathMessage != null && apiDeathMessage != net.kyori.adventure.text.Component.empty() && showDeathMessage) { // Paper - Adventure // TODO: allow plugins to override?
+ if (apiDeathMessage != null && apiDeathMessage != net.kyori.adventure.text.Component.empty() && event.getShowDeathMessages()) { // Paper - Adventure; Expand PlayerDeathEvent API
+ Component deathMessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(apiDeathMessage); // Paper - Adventure
+
this.connection
.send(
new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage),
+ // Paper - moved up to sendClientboundPlayerCombatKillPacket()
+ sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent
Team team = this.getTeam();
if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) {
this.server.getPlayerList().broadcastSystemMessage(deathMessage, false);
@@ -827,7 +_,7 @@
this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, deathMessage);
}
} else {
- this.connection.send(new ClientboundPlayerCombatKillPacket(this.getId(), CommonComponents.EMPTY));
+ sendClientboundPlayerCombatKillPacket(event.getShowDeathMessages(), deathScreenMessage); // Paper - Expand PlayerDeathEvent
}
this.removeEntitiesOnShoulder();
@@ -835,11 +_,35 @@
this.tellNeutralMobsThatIDied();
}
@ -491,7 +513,7 @@
}
}
@@ -914,23 +_,82 @@
@@ -914,23 +_,77 @@
}
private boolean isPvpAllowed() {
@ -541,18 +563,13 @@
+ );
+
+ // Paper start - respawn flags
+ com.google.common.collect.ImmutableSet.Builder<org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag> builder = com.google.common.collect.ImmutableSet.builder();
+ if (respawnReason == org.bukkit.event.player.PlayerRespawnEvent.RespawnReason.END_PORTAL) {
+ builder.add(org.bukkit.event.player.PlayerRespawnEvent.RespawnFlag.END_PORTAL);
+ }
+ org.bukkit.event.player.PlayerRespawnEvent respawnEvent = new org.bukkit.event.player.PlayerRespawnEvent(
+ respawnPlayer,
+ location,
+ isBedSpawn,
+ isAnchorSpawn,
+ teleportTransition.missingRespawnBlock(),
+ respawnReason,
+ builder
+ respawnReason
+ );
+ // Paper end - respawn flags
+ this.level().getCraftServer().getPluginManager().callEvent(respawnEvent);

View File

@ -523,7 +523,7 @@
this.player.sendSystemMessage(Component.translatable("advMode.notAllowed"));
} else {
BaseCommandBlock commandBlock = packet.getCommandBlock(this.player.level());
@@ -661,7 +_,7 @@
@@ -661,11 +_,11 @@
boolean flag = this.player.hasInfiniteMaterials() && packet.includeData();
ItemStack cloneItemStack = blockState.getCloneItemStack(serverLevel, blockPos, flag);
if (!cloneItemStack.isEmpty()) {
@ -532,7 +532,23 @@
addBlockDataToItem(blockState, serverLevel, blockPos, cloneItemStack);
}
@@ -698,18 +_,29 @@
- this.tryPickItem(cloneItemStack);
+ this.tryPickItem(cloneItemStack, blockPos, null, packet.includeData()); // Paper - Extend PlayerPickItemEvent API
}
}
}
@@ -689,27 +_,40 @@
if (entityOrPart != null && this.player.canInteractWithEntity(entityOrPart, 3.0)) {
ItemStack pickResult = entityOrPart.getPickResult();
if (pickResult != null && !pickResult.isEmpty()) {
- this.tryPickItem(pickResult);
+ this.tryPickItem(pickResult, null, entityOrPart, packet.includeData()); // Paper - Extend PlayerPickItemEvent API
}
}
}
- private void tryPickItem(ItemStack stack) {
+ private void tryPickItem(ItemStack stack, @Nullable BlockPos blockPos, @Nullable Entity entity, boolean includeData) { // Paper - Extend PlayerPickItemEvent API
if (stack.isItemEnabled(this.player.level().enabledFeatures())) {
Inventory inventory = this.player.getInventory();
int i = inventory.findSlotMatchingItem(stack);
@ -540,7 +556,9 @@
+ final int sourceSlot = i;
+ final int targetSlot = Inventory.isHotbarSlot(sourceSlot) ? sourceSlot : inventory.getSuitableHotbarSlot();
+ final org.bukkit.entity.Player bukkitPlayer = this.player.getBukkitEntity();
+ final io.papermc.paper.event.player.PlayerPickItemEvent event = new io.papermc.paper.event.player.PlayerPickItemEvent(bukkitPlayer, targetSlot, sourceSlot);
+ final io.papermc.paper.event.player.PlayerPickItemEvent event = entity != null
+ ? new io.papermc.paper.event.player.PlayerPickEntityEvent(bukkitPlayer, entity.getBukkitEntity(), includeData, targetSlot, sourceSlot)
+ : new io.papermc.paper.event.player.PlayerPickBlockEvent(bukkitPlayer, org.bukkit.craftbukkit.block.CraftBlock.at(this.player.level(), blockPos), includeData, targetSlot, sourceSlot);
+ if (!event.callEvent()) {
+ return;
+ }
@ -1237,14 +1255,21 @@
} else {
Component component1 = Component.translatable("build.tooHigh", maxY).withStyle(ChatFormatting.RED);
this.player.sendSystemMessage(component1, true);
@@ -1268,6 +_,7 @@
@@ -1268,13 +_,7 @@
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos));
this.player.connection.send(new ClientboundBlockUpdatePacket(serverLevel, blockPos.relative(direction)));
- } else {
- LOGGER.warn(
- "Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.",
- this.player.getGameProfile().getName(),
- location,
- blockPos
- );
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().unsupportedSettings.updateEquipmentOnPlayerActions) this.player.detectEquipmentUpdates(); // Paper - Force update attributes.
} else {
LOGGER.warn(
"Rejecting UseItemOnPacket from {}: Location {} too far away from hit block {}.",
}
}
}
@@ -1284,6 +_,8 @@
@Override
public void handleUseItem(ServerboundUseItemPacket packet) {
@ -2461,7 +2486,7 @@
} else if (flag && flag2) {
if (this.dropSpamThrottler.isUnderThreshold()) {
this.dropSpamThrottler.increment();
@@ -1895,11 +_,24 @@
@@ -1895,15 +_,38 @@
@Override
public void handleSignUpdate(ServerboundSignUpdatePacket packet) {
@ -2487,6 +2512,20 @@
this.player.resetLastActionTime();
ServerLevel serverLevel = this.player.serverLevel();
BlockPos pos = packet.getPos();
if (serverLevel.hasChunkAt(pos)) {
+ // Paper start - Add API for client-side signs
+ if (!new io.papermc.paper.event.packet.UncheckedSignChangeEvent(
+ this.player.getBukkitEntity(),
+ io.papermc.paper.util.MCUtil.toPosition(pos),
+ packet.isFrontText() ? org.bukkit.block.sign.Side.FRONT : org.bukkit.block.sign.Side.BACK,
+ filteredText.stream().<net.kyori.adventure.text.Component>map(line -> net.kyori.adventure.text.Component.text(line.raw())).toList())
+ .callEvent()) {
+ return;
+ }
+ // Paper end - Add API for client-side signs
if (!(serverLevel.getBlockEntity(pos) instanceof SignBlockEntity signBlockEntity)) {
return;
}
@@ -1915,14 +_,32 @@
@Override
public void handlePlayerAbilities(ServerboundPlayerAbilitiesPacket packet) {
@ -2559,7 +2598,7 @@
);
}
}
@@ -1997,6 +_,7 @@
@@ -1997,27 +_,32 @@
private void resetPlayerChatState(RemoteChatSession chatSession) {
this.chatSession = chatSession;
@ -2567,16 +2606,19 @@
this.signedMessageDecoder = chatSession.createMessageDecoder(this.player.getUUID());
this.chatMessageChain
.append(
@@ -2005,7 +_,7 @@
() -> {
+ server.executeBlocking(() -> { // Paper - Broadcast chat session update sync
this.player.setChatSession(chatSession);
this.server
.getPlayerList()
.broadcastAll(
- new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player))
+ new ClientboundPlayerInfoUpdatePacket(EnumSet.of(ClientboundPlayerInfoUpdatePacket.Action.INITIALIZE_CHAT), List.of(this.player)), this.player // Paper - Use single player info update packet on join
);
+ });
}
);
@@ -2013,11 +_,13 @@
}
@Override
public void handleCustomPayload(ServerboundCustomPayloadPacket packet) {

View File

@ -9,10 +9,10 @@
+ static final java.util.regex.Pattern HOST_PATTERN = java.util.regex.Pattern.compile("[0-9a-f\\.:]{0,45}");
+ static final java.util.regex.Pattern PROP_PATTERN = java.util.regex.Pattern.compile("\\w{0,16}");
+ // Spigot end
+ // CraftBukkit start - add fields
+ private static final java.util.HashMap<java.net.InetAddress, Long> throttleTracker = new java.util.HashMap<>();
+ // Paper start - Connection throttle
+ private static final java.util.Map<java.net.InetAddress, Long> throttleTracker = new java.util.HashMap<>();
+ private static int throttleCounter = 0;
+ // CraftBukkit end
+ // Paper end - Connection throttle
+ private static final boolean BYPASS_HOSTCHECK = Boolean.getBoolean("Paper.bypassHostCheck"); // Paper
private final MinecraftServer server;
private final Connection connection;
@ -29,7 +29,7 @@
switch (packet.intention()) {
case LOGIN:
this.beginLogin(packet, false);
@@ -50,22 +_,117 @@
@@ -50,22 +_,118 @@
default:
throw new UnsupportedOperationException("Invalid intention " + packet.intention());
}
@ -42,17 +42,18 @@
private void beginLogin(ClientIntentionPacket packet, boolean transferred) {
this.connection.setupOutboundProtocol(LoginProtocols.CLIENTBOUND);
+ // CraftBukkit start - Connection throttle
+ // Paper start - Connection throttle
+ try {
+ if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket
+ final long connectionThrottle = this.server.server.getConnectionThrottle();
+ final boolean isUnixDomainSocket = this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress; // Paper - Unix domain socket support; the connection throttle is useless when you have a Unix domain socket
+ if (connectionThrottle > 0 && !isUnixDomainSocket && this.connection.getRemoteAddress() instanceof java.net.InetSocketAddress socketAddress && !socketAddress.isUnresolved() && !socketAddress.getAddress().isLoopbackAddress()) {
+ long currentTime = System.currentTimeMillis();
+ long connectionThrottle = this.server.server.getConnectionThrottle();
+ java.net.InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
+ java.net.InetAddress address = socketAddress.getAddress();
+
+ synchronized (ServerHandshakePacketListenerImpl.throttleTracker) {
+ if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) {
+ if (ServerHandshakePacketListenerImpl.throttleTracker.containsKey(address) && currentTime - ServerHandshakePacketListenerImpl.throttleTracker.get(address) < connectionThrottle) {
+ ServerHandshakePacketListenerImpl.throttleTracker.put(address, currentTime);
+ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle); // Paper - Configurable connection throttle kick message
+ Component chatmessage = io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.connectionThrottle);
+ this.connection.send(new ClientboundLoginDisconnectPacket(chatmessage));
+ this.connection.disconnect(chatmessage);
+ return;
@ -67,11 +68,11 @@
+ ServerHandshakePacketListenerImpl.throttleTracker.values().removeIf(time -> time > connectionThrottle);
+ }
+ }
+ } // Paper - Unix domain socket support
+ }
+ } catch (Throwable t) {
+ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
+ }
+ // CraftBukkit end
+ // Paper end - Connection throttle
if (packet.protocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
- Component component;
- if (packet.protocolVersion() < 754) {

View File

@ -524,7 +524,7 @@
IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress);
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason());
if (ipBanListEntry.getExpires() != null) {
@@ -381,69 +_,130 @@
@@ -381,69 +_,131 @@
);
}
@ -649,6 +649,7 @@
+ // Paper start - Add PlayerPostRespawnEvent
+ boolean isBedSpawn = false;
+ boolean isRespawn = false;
+ boolean isAnchorSpawn = false;
+ // Paper end - Add PlayerPostRespawnEvent
+
+ // CraftBukkit start - fire PlayerRespawnEvent
@ -714,13 +715,17 @@
serverPlayer.setHealth(serverPlayer.getHealth());
ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig();
if (!keepInventory && respawnConfig != null) {
@@ -477,8 +_,41 @@
@@ -477,8 +_,52 @@
)
);
}
+ // Paper start - Add PlayerPostRespawnEvent
+ if (blockState.is(net.minecraft.tags.BlockTags.BEDS) && !teleportTransition.missingRespawnBlock()) {
+ isBedSpawn = true;
+ if (!teleportTransition.missingRespawnBlock()) {
+ if (blockState.is(net.minecraft.tags.BlockTags.BEDS)) {
+ isBedSpawn = true;
+ } else if (blockState.is(Blocks.RESPAWN_ANCHOR)) {
+ isAnchorSpawn = true;
+ }
+ }
+ // Paper end - Add PlayerPostRespawnEvent
}
@ -748,7 +753,14 @@
+
+ // Paper start - Add PlayerPostRespawnEvent
+ if (isRespawn) {
+ cserver.getPluginManager().callEvent(new com.destroystokyo.paper.event.player.PlayerPostRespawnEvent(player.getBukkitEntity(), location, isBedSpawn));
+ new com.destroystokyo.paper.event.player.PlayerPostRespawnEvent(
+ player.getBukkitEntity(),
+ location,
+ isBedSpawn,
+ isAnchorSpawn,
+ teleportTransition.missingRespawnBlock(),
+ eventReason
+ ).callEvent();
+ }
+ // Paper end - Add PlayerPostRespawnEvent
+
@ -756,7 +768,7 @@
return serverPlayer;
}
@@ -488,24 +_,60 @@
@@ -488,24 +_,59 @@
}
public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) {
@ -800,12 +812,11 @@
+ // CraftBukkit start - add a world/entity limited version
+ public void broadcastAll(Packet packet, net.minecraft.world.entity.player.Player entityhuman) {
+ for (int i = 0; i < this.players.size(); ++i) {
+ ServerPlayer entityplayer = this.players.get(i);
+ for (ServerPlayer entityplayer : this.players) { // Paper - replace for i with for each for thread safety
+ if (entityhuman != null && !entityplayer.getBukkitEntity().canSee(entityhuman.getBukkitEntity())) {
+ continue;
+ }
+ ((ServerPlayer) this.players.get(i)).connection.send(packet);
+ ((ServerPlayer) entityplayer).connection.send(packet); // Paper - replace for i with for each for thread safety
+ }
+ }
+

Some files were not shown because too many files have changed in this diff Show More