Compare commits

...
Author SHA1 Message Date
Jake Potrebic 64107df246 temporarily disable final local var check 2025-01-11 22:07:07 -08:00
Jake Potrebic 5e2d34c096 ok, fine. just use a proper gradle plugin 2025-01-11 18:57:23 -08:00
Jake Potrebic a0bec2312c move logic out of paper-api build.gradle.kts 2025-01-11 10:21:36 -08:00
Jake Potrebic 849d6107a9 remove unused runForAll 2025-01-07 00:14:27 -08:00
Jake Potrebic 1c35f64788 use checkstyle to create a much nicer nullability annotation test 2025-01-05 01:52:31 -08:00
Jake Potrebic cb005e4559 disable more warnings if root class is deprecated for removal 2025-01-04 23:22:51 -08:00
Jake Potrebic 08370f6416 enforce javadoc param description alignment 2025-01-04 22:13:28 -08:00
Jake Potrebic 6d981e0f10 simplify to just skip all packages until manually removed 2025-01-04 14:56:58 -08:00
Jake Potrebic ed5d703779 move to convention plugin 2025-01-04 13:40:29 -08:00
Jake Potrebic 7920bd0568 actually use file contents provider 2025-01-04 13:40:28 -08:00
Jake Potrebic 7a85e6cdfc fix for multiple source sets 2025-01-04 13:40:28 -08:00
Jake Potrebic d86abcf028 refactor a bunch to use task caching 2025-01-04 13:40:28 -08:00
Jake Potrebic d6c754a520 silence fetch 2025-01-04 13:40:28 -08:00
Jake Potrebic af3882662f setup github workflow 2025-01-04 13:40:28 -08:00
Jake Potrebic 8078445228 Naming and Whitespace
also only gets diff for commits that are on HEAD but not remote main
2025-01-04 13:40:28 -08:00
Jake Potrebic 3af3c9b773 only run on changed files for specific users 2025-01-04 13:40:28 -08:00
Jake Potrebic a95608398b Javadoc Comments, Misc and Modifiers 2025-01-04 13:40:28 -08:00
Jake Potrebic d7799ff7e8 Coding and Imports 2025-01-04 13:40:28 -08:00
Jake Potrebic 6c6e412974 remove redundant bit from include filter 2025-01-04 13:40:28 -08:00
Jake Potrebic b27cc5ddd4 beginning of checkstyle configuration for API 2025-01-04 13:40:28 -08:00
Tamion 9f90b4c324 Fix ItemDamageEvents called for 0 damage (#11900) 2025-01-04 21:54:40 +01:00
Pedro f367f107cf Add rotation helpers to Location (#11908) 2025-01-04 21:54:27 +01:00
Pedro 33a590bca6 Fix TargetHitEvent#getSignalStrength() post-hard-fork (#11897) 2025-01-04 21:30:41 +01:00
ChromMob 6ab13521b7 Improve performance of PoiCompetitorScan by unrolling stream (#11871) 2025-01-04 21:23:21 +01:00
Shane Bee 4106da712c Fix retain passengers teleport flag (#11858) 2025-01-04 21:19:07 +01:00
Pedro edde7264c6 [ci skip] Add missing Nullable annotations for NMS DamageSource (#11875) 2025-01-03 11:22:20 -08:00
Hannes Greule daddcf6742 Fix JOML javadoc URL (#11883) 2025-01-02 08:15:47 +00:00
Noah van der Aa 83995d7e80 Fix settings changes not being saved (#11881)
Closes #11878
2025-01-01 21:56:23 +01:00
Nassim Jahnke 1dd52bed49 Use playerlist whitelist status instead of properties
The actual property value is final, only the serialized output is changed. This uses the correct value from PlayerList instead
Fixes #11878
2025-01-01 18:53:23 +01:00
powercas_gamer bdfad1c838 Add sendRich/PlainMessage methods to Server (#11872) 2024-12-31 19:47:57 -05:00
Jason Penilla 9298f593b7 Update paperweight to 2.0.0-beta.10 2024-12-30 12:35:18 -08:00
33 changed files with 981 additions and 438 deletions

No files matched your search

+16 -1
View File
@@ -8,6 +8,7 @@ ij_any_block_comment_add_space = false
ij_any_block_comment_at_first_column = false
ij_any_line_comment_at_first_column = false
ij_any_line_comment_add_space = true
trim_trailing_whitespace = true
[*.tiny]
indent_style=tab
@@ -18,7 +19,7 @@ end_of_line=crlf
[*.yml]
indent_size=2
[*.patch]
[{*.patch,*.md}]
trim_trailing_whitespace=false
[*.java]
@@ -27,12 +28,26 @@ ij_java_class_count_to_use_import_on_demand = 999999
ij_java_insert_inner_class_imports = false
ij_java_names_count_to_use_import_on_demand = 999999
ij_java_imports_layout = *,|,$*
ij_java_layout_static_imports_separately = true
ij_java_generate_final_locals = true
ij_java_generate_final_parameters = true
ij_java_method_parameters_new_line_after_left_paren = true
ij_java_method_parameters_right_paren_on_new_line = true
ij_java_use_fq_class_names = false
ij_java_class_names_in_javadoc = 1
# javadoc
ij_java_doc_add_blank_line_after_description = true
ij_java_doc_add_blank_line_after_param_comments = false
ij_java_doc_add_blank_line_after_return = false
ij_java_doc_add_p_tag_on_empty_lines = true
ij_java_doc_align_exception_comments = true
ij_java_doc_align_param_comments = true
ij_java_doc_do_not_wrap_if_one_line = false
ij_java_doc_enable_formatting = true
ij_java_doc_enable_leading_asterisks = true
ij_java_doc_indent_on_continuation = true
ij_java_doc_param_description_on_new_line = false
ij_java_doc_use_throws_not_exception_tag = true
[paper-server/src/minecraft/java/**/*.java]
ij_java_use_fq_class_names = true
+1 -1
View File
@@ -1,4 +1,4 @@
tiny 2 0 spigot mojang+yarn
tiny 2 0 spigot mojang
# Originally DistanceManager, which also implements DistanceManager, so clashes since the implemented class
# is imported and not fully qualified. Easiest fix is to just change the name
+1
View File
@@ -196,6 +196,7 @@ public net.minecraft.world.entity.Entity random
public net.minecraft.world.entity.Entity setLevel(Lnet/minecraft/world/level/Level;)V
public net.minecraft.world.entity.Entity setRot(FF)V
public net.minecraft.world.entity.Entity setSharedFlag(IZ)V
public net.minecraft.world.entity.Entity teleportPassengers()V
public net.minecraft.world.entity.Entity unsetRemoved()V
public net.minecraft.world.entity.Entity wasTouchingWater
public net.minecraft.world.entity.ExperienceOrb count
+1 -1
View File
@@ -10,7 +10,7 @@
# a significant amount of time for us to track down every possible issue, so this file will likely be around and in
# use - at least in some capacity - for a long time.
tiny 2 0 mojang+yarn spigot
tiny 2 0 mojang spigot
# CraftBukkit changes type
c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer
+1 -1
View File
@@ -12,7 +12,7 @@ import java.nio.file.Path
import kotlin.random.Random
plugins {
id("io.papermc.paperweight.core") version "2.0.0-beta.8" apply false
id("io.papermc.paperweight.core") version "2.0.0-SNAPSHOT" apply false
}
subprojects {
+214
View File
@@ -0,0 +1,214 @@
<!DOCTYPE module PUBLIC
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<module name="SuppressionFilter">
<property name="file" value="${config_loc}/suppressions.xml"/>
<property name="optional" value="false"/>
</module>
<!--Single Suppression Filters-->
<module name="SuppressionSingleFilter">
<!--Suppresses warnings except for common TYPE_USE that should be on same line-->
<property name="checks" value="AnnotationOnSameLine"/>
<property name="message" value="^Annotation '(?!(${type_use_annotations}))"/>
</module>
<module name="SuppressionSingleFilter">
<property name="checks" value="Javadoc(Method|Type)"/>
<!--[A-Z].* check is for java annotations inside code blocks inside javadocs-->
<property name="message" value="^Unknown tag '(${custom_javadoc_tags}|[A-Z].*)'.$"/>
</module>
<!--Javadoc Comments-->
<module name="JavadocPackage"/>
<!--Misc-->
<module name="NewlineAtEndOfFile"/>
<module name="OrderedProperties"/>
<!--Whitespace-->
<module name="FileTabCharacter"/>
<module name="TreeWalker">
<module name="SuppressionXpathFilter">
<property name="file" value="${config_loc}/xpath-suppressions.xml"/>
<property name="optional" value="false"/>
</module>
<!--Annotations-->
<module name="AnnotationOnSameLine">
<!--matches all annotations, but most are suppressed in above-->
<property name="tokens" value="METHOD_DEF"/>
</module>
<module name="AnnotationUseStyle"/>
<module name="MissingDeprecated"/>
<!--Block Checks-->
<module name="AvoidNestedBlocks"/>
<module name="EmptyBlock"/>
<module name="LeftCurly"/>
<module name="RightCurly"/>
<module name="OneTopLevelClass"/>
<module name="SealedShouldHavePermitsList"/>
<!--Class Design-->
<module name="FinalClass"/>
<module name="HideUtilityClassConstructor"/>
<module name="InterfaceIsType"/>
<!--Coding-->
<module name="ArrayTrailingComma"/>
<module name="AvoidDoubleBraceInitialization"/>
<module name="AvoidNoArgumentSuperConstructorCall"/>
<module name="ConstructorsDeclarationGrouping"/>
<module name="CovariantEquals"/>
<module name="DeclarationOrder"/>
<module name="DefaultComesLast"/>
<module name="EmptyStatement"/>
<module name="EqualsAvoidNull"/>
<module name="EqualsHashCode"/>
<module name="FallThrough"/>
<!--<module name="FinalLocalVariable">
<property name="validateEnhancedForLoopVariable" value="true"/>
<property name="validateUnnamedVariables" value="true"/>
&lt;!&ndash;TODO atm, PARAMETER_DEF doesn't seem to function inside interfaces&ndash;&gt;
&lt;!&ndash;https://github.com/checkstyle/checkstyle/issues/16081&ndash;&gt;
<property name="tokens" value="PARAMETER_DEF,VARIABLE_DEF"/>
</module>-->
<module name="IllegalToken"/> <!--just labels by default-->
<module name="IllegalType"/>
<module name="RequireThis">
<property name="validateOnlyOverlapping" value="false"/>
</module>
<module name="SimplifyBooleanExpression"/>
<module name="SimplifyBooleanReturn"/>
<module name="StringLiteralEquality"/>
<module name="UnnecessarySemicolonAfterOuterTypeDeclaration"/>
<module name="UnnecessarySemicolonAfterTypeMemberDeclaration"/>
<module name="UnnecessarySemicolonInEnumeration"/>
<module name="UnnecessarySemicolonInTryWithResources"/>
<module name="UnusedCatchParameterShouldBeUnnamed"/>
<module name="UnusedLambdaParameterShouldBeUnnamed"/>
<module name="UnusedLocalVariable"/>
<module name="WhenShouldBeUsed"/>
<!--Headers--> <!--N/A-->
<!--Imports-->
<module name="AvoidStarImport"/>
<module name="CustomImportOrder">
<property name="customImportOrderRules" value="THIRD_PARTY_PACKAGE,STATIC"/>
<property name="standardPackageRegExp" value="^$"/>
<property name="sortImportsInGroupAlphabetically" value="true"/>
</module>
<module name="IllegalImport">
<property name="regexp" value="true"/>
<!--checker-qual nullability-->
<property name="illegalClasses" value="org\.checkerframework\.checker\.nullness\.qual\.(Nullable|NonNull|DefaultQualifier)"/>
<!--jetbrains nullability-->
<property name="illegalClasses" value="org\.jetbrains\.annotations\.(NotNull|Nullable|NotNullByDefault)"/>
<!--javax nullability-->
</module>
<module name="IllegalImport">
<property name="regexp" value="true"/>
<!--attempts to guard against nested imports (by looking for capital letters in imports)-->
<property name="illegalClasses" value="^[^\.A-Z]+(\.[^\.A-Z]+)+?(\.[A-Z][^\.]*)(\.[A-Z][^\.]*)+$"/>
<message key="import.illegal" value="Illegal nested import - {0}"/>
</module>
<module name="RedundantImport"/>
<module name="UnusedImports"/>
<!--Javadoc Comments-->
<module name="AtclauseOrder">
<property name="tagOrder" value="@param, @return, @throws, @see, @deprecated, @hidden"/>
</module>
<module name="InvalidJavadocPosition"/>
<module name="JavadocBlockTagLocation"/>
<module name="JavadocContentLocation"/>
<module name="JavadocLeadingAsteriskAlign"/>
<module name="JavadocMethod">
<!--checks all, but doesn't require. If we have a doc, it should be valid-->
<property name="validateThrows" value="true"/>
</module>
<module name="JavadocMissingLeadingAsterisk"/>
<module name="JavadocMissingWhitespaceAfterAsterisk"/>
<module name="JavadocStyle"/> <!--checks all, but doesn't require. If we have a doc, it should be valid-->
<module name="JavadocTagContinuationIndentation"/>
<module name="JavadocType"/> <!--checks all, but doesn't require. If we have a doc, it should be valid-->
<module name="MissingJavadocMethod">
<property name="allowedAnnotations" value="Override, ApiStatus.Internal"/>
<property name="ignoreMethodNamesRegex" value="^getHandlerList$"/>
</module>
<module name="MissingJavadocPackage"/>
<module name="MissingJavadocType">
<property name="skipAnnotations" value="Generated, ApiStatus.Internal" />
</module>
<module name="NonEmptyAtclauseDescription"/>
<module name="RequireEmptyLineBeforeBlockTagGroup"/>
<!--Metrics--> <!--N/A-->
<!--Miscellaneous-->
<module name="ArrayTypeStyle"/>
<module name="AvoidEscapedUnicodeCharacters"/>
<module name="CommentsIndentation"/>
<module name="FinalParameters"/>
<module name="NoCodeInFile"/>
<module name="OuterTypeFilename"/>
<module name="UpperEll"/>
<!--Modifiers-->
<module name="ModifierOrder"/>
<module name="RedundantModifier"/>
<!--Naming Conventions-->
<module name="AbbreviationAsWordInName">
<property name="allowedAbbreviations" value="JSON,UUID"/>
<property name="ignoreFinal" value="false"/>
</module>
<module name="ClassTypeParameterName"/>
<module name="ConstantName"/>
<module name="IllegalIdentifierName"/>
<module name="InterfaceTypeParameterName"/>
<module name="LambdaParameterName"/>
<module name="LocalFinalVariableName"/>
<module name="LocalVariableName"/>
<module name="MemberName"/>
<module name="MethodName"/>
<module name="MethodTypeParameterName"/>
<module name="PackageName">
<property name="format" value="^[a-z]+(\.[a-z][a-z0-9]*)*$"/>
</module>
<module name="ParameterName"/>
<module name="PatternVariableName"/>
<module name="RecordComponentName"/>
<module name="RecordTypeParameterName"/>
<module name="StaticVariableName"/>
<module name="TypeName"/>
<!--Regexp--> <!--N/A-->
<!--Size Violations--> <!--N/A-->
<!--Whitespace-->
<module name="EmptyForInitializerPad"/>
<module name="EmptyForIteratorPad"/>
<module name="EmptyLineSeparator">
<property name="allowNoEmptyLineBetweenFields" value="true"/>
<property name="tokens" value="IMPORT,STATIC_IMPORT,CLASS_DEF,INTERFACE_DEF,ENUM_DEF,STATIC_INIT,INSTANCE_INIT,METHOD_DEF,CTOR_DEF,VARIABLE_DEF,RECORD_DEF,COMPACT_CTOR_DEF"/>
</module>
<module name="GenericWhitespace"/>
<module name="MethodParamPad"/>
<module name="NoLineWrap"/> <!--just imports and packages-->
<module name="NoWhitespaceAfter"/>
<module name="NoWhitespaceBefore"/>
<module name="NoWhitespaceBeforeCaseDefaultColon"/>
<module name="ParenPad"/>
<module name="SingleSpaceSeparator"/>
<module name="TypecastParenPad"/>
<module name="WhitespaceAfter"/>
<module name="WhitespaceAround"/>
<!--Custom-->
<module name="JavadocAlignParameterDescription"/>
<module name="NullabilityAnnotations"/>
</module>
</module>
+182
View File
@@ -0,0 +1,182 @@
paper-api-generator/generated/com/destroystokyo/paper/entity/ai/
paper-api-generator/generated/io/papermc/paper/registry/keys/
paper-api-generator/generated/io/papermc/paper/registry/keys/tags/
paper-api/src/main/java/co/aikar/timings/
paper-api/src/main/java/co/aikar/util/
paper-api/src/main/java/com/destroystokyo/paper/
paper-api/src/main/java/com/destroystokyo/paper/block/
paper-api/src/main/java/com/destroystokyo/paper/brigadier/
paper-api/src/main/java/com/destroystokyo/paper/entity/
paper-api/src/main/java/com/destroystokyo/paper/entity/ai/
paper-api/src/main/java/com/destroystokyo/paper/entity/villager/
paper-api/src/main/java/com/destroystokyo/paper/event/block/
paper-api/src/main/java/com/destroystokyo/paper/event/brigadier/
paper-api/src/main/java/com/destroystokyo/paper/event/entity/
paper-api/src/main/java/com/destroystokyo/paper/event/inventory/
paper-api/src/main/java/com/destroystokyo/paper/event/player/
paper-api/src/main/java/com/destroystokyo/paper/event/profile/
paper-api/src/main/java/com/destroystokyo/paper/event/server/
paper-api/src/main/java/com/destroystokyo/paper/exception/
paper-api/src/main/java/com/destroystokyo/paper/inventory/meta/
paper-api/src/main/java/com/destroystokyo/paper/loottable/
paper-api/src/main/java/com/destroystokyo/paper/network/
paper-api/src/main/java/com/destroystokyo/paper/profile/
paper-api/src/main/java/com/destroystokyo/paper/util/
paper-api/src/main/java/com/destroystokyo/paper/utils/
paper-api/src/main/java/io/papermc/paper/advancement/
paper-api/src/main/java/io/papermc/paper/annotation/
paper-api/src/main/java/io/papermc/paper/ban/
paper-api/src/main/java/io/papermc/paper/block/
paper-api/src/main/java/io/papermc/paper/block/fluid/
paper-api/src/main/java/io/papermc/paper/block/fluid/type/
paper-api/src/main/java/io/papermc/paper/brigadier/
paper-api/src/main/java/io/papermc/paper/chat/
paper-api/src/main/java/io/papermc/paper/command/
paper-api/src/main/java/io/papermc/paper/command/brigadier/
paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/
paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/predicate/
paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/range/
paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/
paper-api/src/main/java/io/papermc/paper/command/brigadier/argument/resolvers/selector/
paper-api/src/main/java/io/papermc/paper/datacomponent/
paper-api/src/main/java/io/papermc/paper/datacomponent/item/
paper-api/src/main/java/io/papermc/paper/datacomponent/item/consumable/
paper-api/src/main/java/io/papermc/paper/datapack/
paper-api/src/main/java/io/papermc/paper/enchantments/
paper-api/src/main/java/io/papermc/paper/entity/
paper-api/src/main/java/io/papermc/paper/event/block/
paper-api/src/main/java/io/papermc/paper/event/entity/
paper-api/src/main/java/io/papermc/paper/event/executor/
paper-api/src/main/java/io/papermc/paper/event/packet/
paper-api/src/main/java/io/papermc/paper/event/player/
paper-api/src/main/java/io/papermc/paper/event/server/
paper-api/src/main/java/io/papermc/paper/event/world/
paper-api/src/main/java/io/papermc/paper/event/world/border/
paper-api/src/main/java/io/papermc/paper/generated/
paper-api/src/main/java/io/papermc/paper/inventory/
paper-api/src/main/java/io/papermc/paper/inventory/tooltip/
paper-api/src/main/java/io/papermc/paper/item/
paper-api/src/main/java/io/papermc/paper/math/
paper-api/src/main/java/io/papermc/paper/persistence/
paper-api/src/main/java/io/papermc/paper/plugin/
paper-api/src/main/java/io/papermc/paper/plugin/bootstrap/
paper-api/src/main/java/io/papermc/paper/plugin/configuration/
paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/
paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/
paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/handler/configuration/
paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/registrar/
paper-api/src/main/java/io/papermc/paper/plugin/lifecycle/event/types/
paper-api/src/main/java/io/papermc/paper/plugin/loader/
paper-api/src/main/java/io/papermc/paper/plugin/loader/library/
paper-api/src/main/java/io/papermc/paper/plugin/loader/library/impl/
paper-api/src/main/java/io/papermc/paper/plugin/provider/classloader/
paper-api/src/main/java/io/papermc/paper/plugin/provider/entrypoint/
paper-api/src/main/java/io/papermc/paper/plugin/provider/util/
paper-api/src/main/java/io/papermc/paper/potion/
paper-api/src/main/java/io/papermc/paper/registry/
paper-api/src/main/java/io/papermc/paper/registry/data/
paper-api/src/main/java/io/papermc/paper/registry/event/
paper-api/src/main/java/io/papermc/paper/registry/event/type/
paper-api/src/main/java/io/papermc/paper/registry/set/
paper-api/src/main/java/io/papermc/paper/registry/tag/
paper-api/src/main/java/io/papermc/paper/scoreboard/numbers/
paper-api/src/main/java/io/papermc/paper/tag/
paper-api/src/main/java/io/papermc/paper/text/
paper-api/src/main/java/io/papermc/paper/threadedregions/scheduler/
paper-api/src/main/java/io/papermc/paper/util/
paper-api/src/main/java/io/papermc/paper/world/
paper-api/src/main/java/io/papermc/paper/world/flag/
paper-api/src/main/java/org/bukkit/
paper-api/src/main/java/org/bukkit/advancement/
paper-api/src/main/java/org/bukkit/attribute/
paper-api/src/main/java/org/bukkit/ban/
paper-api/src/main/java/org/bukkit/block/
paper-api/src/main/java/org/bukkit/block/banner/
paper-api/src/main/java/org/bukkit/block/data/
paper-api/src/main/java/org/bukkit/block/data/type/
paper-api/src/main/java/org/bukkit/block/sign/
paper-api/src/main/java/org/bukkit/block/spawner/
paper-api/src/main/java/org/bukkit/block/structure/
paper-api/src/main/java/org/bukkit/boss/
paper-api/src/main/java/org/bukkit/command/
paper-api/src/main/java/org/bukkit/command/defaults/
paper-api/src/main/java/org/bukkit/configuration/
paper-api/src/main/java/org/bukkit/configuration/file/
paper-api/src/main/java/org/bukkit/configuration/serialization/
paper-api/src/main/java/org/bukkit/conversations/
paper-api/src/main/java/org/bukkit/damage/
paper-api/src/main/java/org/bukkit/enchantments/
paper-api/src/main/java/org/bukkit/entity/
paper-api/src/main/java/org/bukkit/entity/boat/
paper-api/src/main/java/org/bukkit/entity/memory/
paper-api/src/main/java/org/bukkit/entity/minecart/
paper-api/src/main/java/org/bukkit/event/
paper-api/src/main/java/org/bukkit/event/block/
paper-api/src/main/java/org/bukkit/event/command/
paper-api/src/main/java/org/bukkit/event/enchantment/
paper-api/src/main/java/org/bukkit/event/entity/
paper-api/src/main/java/org/bukkit/event/hanging/
paper-api/src/main/java/org/bukkit/event/inventory/
paper-api/src/main/java/org/bukkit/event/player/
paper-api/src/main/java/org/bukkit/event/raid/
paper-api/src/main/java/org/bukkit/event/server/
paper-api/src/main/java/org/bukkit/event/vehicle/
paper-api/src/main/java/org/bukkit/event/weather/
paper-api/src/main/java/org/bukkit/event/world/
paper-api/src/main/java/org/bukkit/generator/
paper-api/src/main/java/org/bukkit/generator/structure/
paper-api/src/main/java/org/bukkit/help/
paper-api/src/main/java/org/bukkit/inventory/
paper-api/src/main/java/org/bukkit/inventory/meta/
paper-api/src/main/java/org/bukkit/inventory/meta/components/
paper-api/src/main/java/org/bukkit/inventory/meta/tags/
paper-api/src/main/java/org/bukkit/inventory/meta/trim/
paper-api/src/main/java/org/bukkit/inventory/recipe/
paper-api/src/main/java/org/bukkit/inventory/view/
paper-api/src/main/java/org/bukkit/loot/
paper-api/src/main/java/org/bukkit/map/
paper-api/src/main/java/org/bukkit/material/
paper-api/src/main/java/org/bukkit/material/types/
paper-api/src/main/java/org/bukkit/metadata/
paper-api/src/main/java/org/bukkit/packs/
paper-api/src/main/java/org/bukkit/permissions/
paper-api/src/main/java/org/bukkit/persistence/
paper-api/src/main/java/org/bukkit/plugin/
paper-api/src/main/java/org/bukkit/plugin/java/
paper-api/src/main/java/org/bukkit/plugin/messaging/
paper-api/src/main/java/org/bukkit/potion/
paper-api/src/main/java/org/bukkit/profile/
paper-api/src/main/java/org/bukkit/projectiles/
paper-api/src/main/java/org/bukkit/scheduler/
paper-api/src/main/java/org/bukkit/scoreboard/
paper-api/src/main/java/org/bukkit/spawner/
paper-api/src/main/java/org/bukkit/structure/
paper-api/src/main/java/org/bukkit/tag/
paper-api/src/main/java/org/bukkit/util/
paper-api/src/main/java/org/bukkit/util/io/
paper-api/src/main/java/org/bukkit/util/noise/
paper-api/src/main/java/org/bukkit/util/permissions/
paper-api/src/main/java/org/spigotmc/
paper-api/src/main/java/org/spigotmc/event/player/
paper-api/src/test/java/com/destroystokyo/paper/
paper-api/src/test/java/io/papermc/paper/
paper-api/src/test/java/io/papermc/paper/adventure/
paper-api/src/test/java/io/papermc/paper/registry/
paper-api/src/test/java/io/papermc/paper/testing/
paper-api/src/test/java/io/papermc/paper/util/
paper-api/src/test/java/org/bukkit/
paper-api/src/test/java/org/bukkit/configuration/
paper-api/src/test/java/org/bukkit/configuration/file/
paper-api/src/test/java/org/bukkit/conversations/
paper-api/src/test/java/org/bukkit/entity/memory/
paper-api/src/test/java/org/bukkit/event/
paper-api/src/test/java/org/bukkit/materials/
paper-api/src/test/java/org/bukkit/metadata/
paper-api/src/test/java/org/bukkit/plugin/
paper-api/src/test/java/org/bukkit/plugin/messaging/
paper-api/src/test/java/org/bukkit/scoreboard/
paper-api/src/test/java/org/bukkit/support/
paper-api/src/test/java/org/bukkit/support/provider/
paper-api/src/test/java/org/bukkit/support/test/
paper-api/src/test/java/org/bukkit/util/
paper-api/src/test/java/org/bukkit/util/io/
+6
View File
@@ -0,0 +1,6 @@
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<suppress checks="MissingJavadoc.*" files="src[\\/]test[\\/]java[^\\/]*[\\/].*"/>
</suppressions>
@@ -0,0 +1,9 @@
NonNull
NotNull
Nullable
UnknownNullability
Unmodifiable
UnmodifiableView
Range
Positive
NonNegative
@@ -0,0 +1,17 @@
<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionXpathFilter Experimental Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2_xpath_experimental.dtd">
<suppressions>
<!--ignores all checks for @Deprecated(forRemoval=*) children-->
<suppress-xpath checks=".*" query="//*[MODIFIERS/ANNOTATION[(@text = 'Deprecated' or *[@text = 'Deprecated'] and ANNOTATION_MEMBER_VALUE_PAIR/IDENT[@text='forRemoval'])]]/descendant-or-self::node()"/>
<!--special case to ignore extra checks outside the root CLASS_DEF if the root CLASS_DEF is marked as deprecated for removal-->
<suppress-xpath checks=".*" query="/COMPILATION_UNIT[CLASS_DEF/MODIFIERS/ANNOTATION[IDENT[@text = 'Deprecated'] and ANNOTATION_MEMBER_VALUE_PAIR/IDENT[@text='forRemoval']]]/descendant-or-self::node()"/>
<!--ignores MissingJavadoc for ApiStatus.Internal children-->
<suppress-xpath checks="MissingJavadoc(Method|Type)" query="//*[MODIFIERS/ANNOTATION/DOT[@text = 'Internal' or *[@text = 'Internal']]]/descendant-or-self::node()"/>
<!--skip for private classes-->
<suppress-xpath checks="FinalClass" query="//CLASS_DEF[MODIFIERS/LITERAL_PRIVATE]"/>
<!--skip for classes inside of methods-->
<suppress-xpath checks="HideUtilityClassConstructor|MissingJavadoc(Method|Type)" query="//CLASS_DEF[ancestor::METHOD_DEF]"/>
</suppressions>
+24 -2
View File
@@ -1,7 +1,12 @@
import io.papermc.paperweight.checkstyle.JavadocTag
import io.papermc.paperweight.checkstyle.PaperCheckstyleTask
import io.papermc.paperweight.checkstyle.setCustomJavadocTags
plugins {
`java-library`
`maven-publish`
idea
id("io.papermc.paperweight.paper-checkstyle")
}
java {
@@ -9,6 +14,22 @@ java {
withJavadocJar()
}
val customJavadocTags = setOf(
JavadocTag("apiNote", "a", "API Note:"),
)
paperCheckstyle {
val packagesToSkipSource = providers.fileContents(projectLocalCheckstyleConfig.file("packages.txt")).asText.map { it.trim().split("\n").toSet() }
val typeUseAnnotationsProvider = providers.fileContents(projectLocalCheckstyleConfig.file("type-use-annotations.txt")).asText.map { it.trim().split("\n").toSet() }
directoriesToSkip.set(packagesToSkipSource)
typeUseAnnotations.set(typeUseAnnotationsProvider)
}
tasks.withType<PaperCheckstyleTask> {
setCustomJavadocTags(customJavadocTags)
}
val annotationsVersion = "26.0.1"
val bungeeCordChatVersion = "1.20-R0.2"
val adventureVersion = "4.18.0"
@@ -39,6 +60,7 @@ abstract class MockitoAgentProvider : CommandLineArgumentProvider {
}
dependencies {
checkstyle(project(":paper-api:custom-checkstyle"))
// api dependencies are listed transitively to API consumers
api("com.google.guava:guava:33.3.1-jre")
@@ -176,7 +198,7 @@ tasks.withType<Javadoc> {
"https://guava.dev/releases/33.3.1-jre/api/docs/",
"https://javadoc.io/doc/org.yaml/snakeyaml/2.2/",
"https://javadoc.io/doc/org.jetbrains/annotations/$annotationsVersion/",
"https://javadoc.io/doc/org.joml/joml/1.10.8/index.html",
"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/$adventureVersion/",
@@ -190,7 +212,7 @@ tasks.withType<Javadoc> {
"https://javadoc.io/doc/org.apache.logging.log4j/log4j-api/$log4jVersion/",
"https://javadoc.io/doc/org.apache.maven.resolver/maven-resolver-api/1.7.3",
)
options.tags("apiNote:a:API Note:")
options.tags(customJavadocTags.map { it.toOptionString() })
inputs.files(apiAndDocs).ignoreEmptyDirectories().withPropertyName(apiAndDocs.name + "-configuration")
val apiAndDocsElements = apiAndDocs.elements
@@ -0,0 +1,8 @@
plugins {
java
}
dependencies {
implementation("com.puppycrawl.tools:checkstyle:10.21.1")
implementation("org.jspecify:jspecify:1.0.0")
}
@@ -0,0 +1,90 @@
package io.papermc.checkstyle;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
import com.puppycrawl.tools.checkstyle.utils.TokenUtil;
import java.util.Iterator;
import java.util.NoSuchElementException;
import org.jspecify.annotations.Nullable;
/**
* Utility class containing utility methods for custom checkstyle checks.
*/
public final class Util {
private Util() {
}
/**
* Gets the previous sibling of the given node with the given type.
*
* @param node the node
* @param type the type
* @return the previous sibling with the given type, or {@code null} if not found
*/
public static @Nullable DetailNode getPreviousSibling(final DetailNode node, final int type) {
DetailNode sibling = JavadocUtil.getPreviousSibling(node);
while (sibling != null && sibling.getType() != type) {
sibling = JavadocUtil.getPreviousSibling(sibling);
}
return sibling;
}
/**
* Gets the next sibling of the given node with the given type.
*
* @param node the node
* @param type the type
* @return the next sibling with the given type, or {@code null} if not found
*/
public static @Nullable DetailAST getNextSibling(final DetailAST node, final int type) {
DetailAST sibling = node.getNextSibling();
while (sibling != null && sibling.getType() != type) {
sibling = sibling.getNextSibling();
}
return sibling;
}
/**
* Gets the enclosing type declaration of the given node.
*
* @param node the node
* @return the enclosing type declaration, or {@code null} if not found
*/
public static @Nullable DetailAST getEnclosingTypeDeclaration(final DetailAST node) {
DetailAST parent = node.getParent();
while (parent != null && !TokenUtil.isTypeDeclaration(parent.getType())) {
parent = parent.getParent();
}
return parent;
}
/**
* Gets an iterator over the children of the given node with the given type.
*
* @param ast the node
* @param type the type
* @return the iterator
*/
public static Iterable<DetailAST> childrenIterator(final DetailAST ast, final int type) {
return () -> new Iterator<>() {
private @Nullable DetailAST current = TokenUtil.findFirstTokenByPredicate(ast, child -> child.getType() == type).orElse(null);
@Override
public boolean hasNext() {
return this.current != null;
}
@Override
public DetailAST next() {
if (this.current == null) {
throw new NoSuchElementException();
}
final DetailAST result = this.current;
this.current = getNextSibling(this.current, type);
return result;
}
};
}
}
@@ -0,0 +1,49 @@
package io.papermc.checkstyle.checks;
import com.puppycrawl.tools.checkstyle.api.DetailNode;
import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
import com.puppycrawl.tools.checkstyle.checks.javadoc.AbstractJavadocCheck;
import com.puppycrawl.tools.checkstyle.utils.JavadocUtil;
import io.papermc.checkstyle.Util;
import java.util.ArrayList;
import java.util.List;
/**
* Checks that parameter descriptions in Javadoc are aligned.
*/
public final class JavadocAlignParameterDescriptionCheck extends AbstractJavadocCheck {
@Override
public int[] getDefaultJavadocTokens() {
return new int[]{JavadocTokenTypes.JAVADOC};
}
@Override
public void visitJavadocToken(final DetailNode detailNode) {
final List<DetailNode> params = new ArrayList<>();
int maxColumn = -1;
for (final DetailNode child : detailNode.getChildren()) {
final DetailNode paramLiteralNode = JavadocUtil.findFirstToken(child, JavadocTokenTypes.PARAM_LITERAL);
if (child.getType() != JavadocTokenTypes.JAVADOC_TAG || paramLiteralNode == null) {
continue;
}
final DetailNode paramDescription = JavadocUtil.getNextSibling(paramLiteralNode, JavadocTokenTypes.DESCRIPTION);
maxColumn = Math.max(maxColumn, paramDescription.getColumnNumber());
params.add(paramDescription);
}
for (final DetailNode param : params) {
if (param.getColumnNumber() != maxColumn) {
final DetailNode paramNameNode = Util.getPreviousSibling(param, JavadocTokenTypes.PARAMETER_NAME);
if (paramNameNode == null) {
continue;
}
this.log(
param.getLineNumber(),
param.getColumnNumber() - 1,
"Param description for %s should start at column %d".formatted(paramNameNode.getText(), maxColumn)
);
}
}
}
}
@@ -0,0 +1,154 @@
package io.papermc.checkstyle.checks;
import com.puppycrawl.tools.checkstyle.JavaParser;
import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
import com.puppycrawl.tools.checkstyle.api.CheckstyleException;
import com.puppycrawl.tools.checkstyle.api.DetailAST;
import com.puppycrawl.tools.checkstyle.api.TokenTypes;
import io.papermc.checkstyle.Util;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Objects;
import java.util.Set;
import org.jspecify.annotations.Nullable;
/**
* Checks that nullability annotations are present where required.
*/
public final class NullabilityAnnotationsCheck extends AbstractCheck {
@Override
public int[] getDefaultTokens() {
return this.getRequiredTokens();
}
@Override
public int[] getAcceptableTokens() {
return this.getRequiredTokens();
}
@Override
public int[] getRequiredTokens() {
return new int[]{
TokenTypes.METHOD_DEF,
TokenTypes.PARAMETER_DEF,
TokenTypes.ANNOTATION_FIELD_DEF,
TokenTypes.RECORD_COMPONENT_DEF, // annotations are in ANNOTATIONS token block
};
}
private static final Set<String> NULLABILITY_ANNOTATIONS = Set.of("Nullable", "NonNull");
// for checking for annotations on nested types like "OuterType.@Nullable InnerType"
private static boolean typeHasNullabilityAnnotation(final @Nullable DetailAST type) {
final DetailAST dot;
if (type == null || (dot = type.findFirstToken(TokenTypes.DOT)) == null) {
return false;
}
return hasNullabilityAnnotationChild(dot.findFirstToken(TokenTypes.ANNOTATIONS));
}
private static boolean hasNullabilityAnnotationChild(final @Nullable DetailAST ast) {
if (ast == null) {
return false;
}
for (final DetailAST annotation : Util.childrenIterator(ast, TokenTypes.ANNOTATION)) {
if (annotation.getChildCount(TokenTypes.IDENT) != 1) {
// skip `.` annotations like ApiStatus.Internal as these aren't nullability annotations
continue;
}
final String ident = annotation.findFirstToken(TokenTypes.IDENT).getText();
if (NULLABILITY_ANNOTATIONS.contains(ident)) {
return true;
}
}
return false;
}
private static boolean hasNullabilityAnnotation(final DetailAST inputAst) {
if (inputAst.getType() == TokenTypes.RECORD_COMPONENT_DEF && hasNullabilityAnnotationChild(inputAst.findFirstToken(TokenTypes.ANNOTATIONS))) {
return true;
} else if (inputAst.getType() != TokenTypes.RECORD_COMPONENT_DEF && hasNullabilityAnnotationChild(inputAst.findFirstToken(TokenTypes.MODIFIERS))) {
return true;
} else {
return typeHasNullabilityAnnotation(inputAst.findFirstToken(TokenTypes.TYPE));
}
}
private static boolean isNullMarkedAnnotation(final DetailAST annotation) {
if (annotation.getChildCount(TokenTypes.IDENT) != 1) {
return false;
}
final String ident = annotation.findFirstToken(TokenTypes.IDENT).getText();
return "NullMarked".equals(ident);
}
private static boolean isTypeDeclarationNullMarked(final DetailAST typeDeclaration) {
final DetailAST modifiers = typeDeclaration.findFirstToken(TokenTypes.MODIFIERS);
if (modifiers == null) {
return false;
}
for (final DetailAST annotation : Util.childrenIterator(modifiers, TokenTypes.ANNOTATION)) {
if (isNullMarkedAnnotation(annotation)) {
return true;
}
}
return false;
}
private boolean isPackageInfoNullMarked() {
final Path currentPath = Path.of(this.getFilePath());
final Path packageInfo = currentPath.getParent().resolve("package-info.java");
if (Files.notExists(packageInfo)) {
return false;
}
final DetailAST packageInfoAst;
try {
packageInfoAst = JavaParser.parseFile(packageInfo.toFile(), JavaParser.Options.WITHOUT_COMMENTS);
} catch (final IOException | CheckstyleException e) {
throw new RuntimeException(e);
}
final DetailAST firstToken = packageInfoAst.findFirstToken(TokenTypes.PACKAGE_DEF);
if (firstToken == null) {
return false;
}
final DetailAST annotations = firstToken.findFirstToken(TokenTypes.ANNOTATIONS);
for (final DetailAST annotation : Util.childrenIterator(annotations, TokenTypes.ANNOTATION)) {
if (isNullMarkedAnnotation(annotation)) {
return true;
}
}
return false;
}
@Override
public void visitToken(final DetailAST ast) {
if (hasNullabilityAnnotation(ast)) {
return;
}
for (DetailAST parentDef = Util.getEnclosingTypeDeclaration(ast); parentDef != null; parentDef = Util.getEnclosingTypeDeclaration(parentDef)) {
if (isTypeDeclarationNullMarked(parentDef)) {
return;
}
}
if (this.isPackageInfoNullMarked()) {
return;
}
this.recordViolation(ast);
}
private static DetailAST getTypeAstForViolation(final DetailAST inputAst) {
final DetailAST typeToken = inputAst.findFirstToken(TokenTypes.TYPE);
final DetailAST dot;
if (typeToken != null && (dot = typeToken.findFirstToken(TokenTypes.DOT)) != null) {
return Objects.requireNonNullElse(dot.getLastChild(), inputAst);
}
return Objects.requireNonNullElse(typeToken, inputAst);
}
private void recordViolation(final DetailAST ast) {
final DetailAST typeAst = getTypeAstForViolation(ast);
this.log(typeAst.getLineNo(), typeAst.getColumnNo() - 1, "Missing nullability annotation");
}
}
@@ -0,0 +1,8 @@
/**
* Custom checkstyle checks for PaperMC projects.
*/
@NullMarked
@SuppressWarnings("unused")
package io.papermc.checkstyle.checks;
import org.jspecify.annotations.NullMarked;
@@ -0,0 +1,7 @@
/**
* This package contains custom checkstyle rules for PaperMC projects.
*/
@NullMarked
package io.papermc.checkstyle;
import org.jspecify.annotations.NullMarked;
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE checkstyle-packages PUBLIC
"-//Checkstyle//DTD Package Names Configuration 1.0//EN"
"https://checkstyle.org/dtds/packages_1_0.dtd">
<checkstyle-packages>
<package name="io.papermc.checkstyle.checks"/>
</checkstyle-packages>
@@ -3,7 +3,6 @@ package io.papermc.paper;
import net.kyori.adventure.util.Services;
import org.bukkit.damage.DamageEffect;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Static bridge to the server internals.
@@ -12,7 +11,6 @@ import org.jspecify.annotations.NullMarked;
* cause issues when called under unexpected circumstances.
*/
@ApiStatus.Internal
@NullMarked
public interface InternalAPIBridge {
/**
@@ -36,4 +34,3 @@ public interface InternalAPIBridge {
*/
DamageEffect getDamageEffect(String key);
}
@@ -6,12 +6,10 @@ import java.util.OptionalInt;
import net.kyori.adventure.key.Key;
import net.kyori.adventure.util.Services;
import org.jetbrains.annotations.ApiStatus;
import org.jspecify.annotations.NullMarked;
/**
* Information about the current server build.
*/
@NullMarked
@ApiStatus.NonExtendable
public interface ServerBuildInfo {
/**
@@ -30,6 +28,7 @@ public interface ServerBuildInfo {
static final Optional<ServerBuildInfo> INSTANCE = Services.service(ServerBuildInfo.class);
}
//</editor-fold>
return Holder.INSTANCE.orElseThrow();
}
@@ -47,7 +46,7 @@ public interface ServerBuildInfo {
* @return {@code true} if the server supports the specified brand
*/
@ApiStatus.Experimental
boolean isBrandCompatible(final Key brandId);
boolean isBrandCompatible(Key brandId);
/**
* Gets the brand name of the server.
@@ -104,7 +103,7 @@ public interface ServerBuildInfo {
* @param representation the type of representation
* @return a string
*/
String asString(final StringRepresentation representation);
String asString(StringRepresentation representation);
/**
* String representation types.
@@ -0,0 +1,7 @@
/**
* Root package for the Paper API.
*/
@NullMarked
package io.papermc.paper;
import org.jspecify.annotations.NullMarked;
@@ -3,24 +3,21 @@ package org.bukkit;
import com.google.common.base.Preconditions;
import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import com.google.common.base.Preconditions; // Paper
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Predicate;
import io.papermc.paper.math.FinePosition;
import org.bukkit.block.Block;
import org.bukkit.configuration.serialization.ConfigurationSerializable;
import org.bukkit.entity.Entity; // Paper
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
// Paper start
import java.util.Collection;
import java.util.function.Predicate;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
// Paper end
import org.bukkit.util.NumberConversions;
import org.bukkit.util.Vector;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* Represents a 3-dimensional position in a world.
@@ -30,7 +27,7 @@ import org.bukkit.entity.Player;
* magnitude than 360 are valid, but may be normalized to any other equivalent
* representation by the implementation.
*/
public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition { // Paper
public class Location implements Cloneable, ConfigurationSerializable, io.papermc.paper.math.FinePosition {
private Reference<World> world;
private double x;
private double y;
@@ -46,7 +43,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
* @param y The y-coordinate of this new location
* @param z The z-coordinate of this new location
*/
public Location(@UndefinedNullability final World world, final double x, final double y, final double z) { // Paper
public Location(@UndefinedNullability final World world, final double x, final double y, final double z) {
this(world, x, y, z, 0, 0);
}
@@ -60,7 +57,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
* @param yaw The absolute rotation on the x-plane, in degrees
* @param pitch The absolute rotation on the y-plane, in degrees
*/
public Location(@UndefinedNullability final World world, final double x, final double y, final double z, final float yaw, final float pitch) { // Paper
public Location(@UndefinedNullability final World world, final double x, final double y, final double z, final float yaw, final float pitch) {
if (world != null) {
this.world = new WeakReference<>(world);
}
@@ -102,7 +99,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
* @throws IllegalArgumentException when world is unloaded
* @see #isWorldLoaded()
*/
@UndefinedNullability // Paper
@UndefinedNullability
public World getWorld() {
if (this.world == null) {
return null;
@@ -398,6 +395,22 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return this;
}
/**
* Adds rotation in the form of yaw and patch to this location. Not world-aware.
*
* @param yaw yaw, measured in degrees.
* @param pitch pitch, measured in degrees.
* @return the same location
* @see Vector
*/
@NotNull
@Contract(value = "_,_ -> this", mutates = "this")
public Location addRotation(final float yaw, final float pitch) {
this.yaw += yaw;
this.pitch += pitch;
return this;
}
/**
* Subtracts the location by another.
*
@@ -451,6 +464,22 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return this;
}
/**
* Subtracts rotation in the form of yaw and patch from this location.
*
* @param yaw yaw, measured in degrees.
* @param pitch pitch, measured in degrees.
* @return the same location
* @see Vector
*/
@NotNull
@Contract(value = "_,_ -> this", mutates = "this")
public Location subtractRotation(final float yaw, final float pitch) {
this.yaw -= yaw;
this.pitch -= pitch;
return this;
}
/**
* Gets the magnitude of the location, defined as sqrt(x^2+y^2+z^2). The
* value of this method is not cached and uses a costly square-root
@@ -543,9 +572,10 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return this;
}
public boolean isChunkLoaded() { return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4); } // Paper
public boolean isChunkLoaded() {
return this.getWorld().isChunkLoaded(locToBlock(x) >> 4, locToBlock(z) >> 4);
}
// Paper start - isGenerated API
/**
* Checks if a {@link Chunk} has been generated at this location.
*
@@ -556,9 +586,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
Preconditions.checkNotNull(world, "Location has no world!");
return world.isChunkGenerated(locToBlock(x) >> 4, locToBlock(z) >> 4);
}
// Paper end - isGenerated API
// Paper start - expand location manipulation API
/**
* Sets the position of this Location and returns itself
@@ -578,6 +605,23 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return this;
}
/**
* Sets the rotation of this location and returns itself.
* <p>
* This mutates this object, clone first.
*
* @param yaw yaw, measured in degrees.
* @param pitch pitch, measured in degrees.
* @return self (not cloned)
*/
@NotNull
@Contract(value = "_,_ -> this", mutates = "this")
public Location setRotation(final float yaw, final float pitch) {
this.yaw = yaw;
this.pitch = pitch;
return this;
}
/**
* Takes the x/y/z from base and adds the specified x/y/z to it and returns self
* <p>
@@ -609,9 +653,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
public Location subtract(@NotNull Location base, double x, double y, double z) {
return this.set(base.x - x, base.y - y, base.z - z);
}
// Paper end - expand location manipulation API
// Paper start - expand Location API
/**
* @return A new location where X/Y/Z are on the Block location (integer value of X/Y/Z)
*/
@@ -624,7 +666,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return blockLoc;
}
// Paper start
/**
* @return The block key for this location's block location.
* @see Block#getBlockKey(int, int, int)
@@ -634,7 +675,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
public long toBlockKey() {
return Block.getBlockKey(getBlockX(), getBlockY(), getBlockZ());
}
// Paper end
/**
* @return A new location where X/Y/Z are the center of the block
@@ -647,9 +687,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
centerLoc.setZ(getBlockZ() + 0.5);
return centerLoc;
}
// Paper end - expand Location API
// Paper start - Add heightmap api
/**
* 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())
@@ -671,9 +709,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
ret.setY(this.getWorld().getHighestBlockYAt(this, heightMap));
return ret;
}
// Paper end - Add heightmap api
// Paper start - Expand Explosions API
/**
* Creates explosion at this location with given power
* <p>
@@ -754,9 +790,7 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
public boolean createExplosion(@Nullable Entity source, float power, boolean setFire, boolean breakBlocks) {
return this.getWorld().createExplosion(source, this, power, setFire, breakBlocks);
}
// Paper end - Expand Explosions API
// Paper start - additional getNearbyEntities API
/**
* Returns a list of entities within a bounding box centered around a Location.
* <p>
@@ -979,7 +1013,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
}
return world.getNearbyEntitiesByType(clazz, this, xRadius, yRadius, zRadius, predicate);
}
// Paper end - additional getNearbyEntities API
@Override
public boolean equals(Object obj) {
@@ -1155,7 +1188,6 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
return pitch;
}
// Paper - add Position
@Override
public double x() {
return this.getX();
@@ -1173,12 +1205,11 @@ public class Location implements Cloneable, ConfigurationSerializable, io.paperm
@Override
public boolean isFinite() {
return io.papermc.paper.math.FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch());
return FinePosition.super.isFinite() && Float.isFinite(this.getYaw()) && Float.isFinite(this.getPitch());
}
@Override
public @NotNull Location toLocation(@NotNull World world) {
return new Location(world, this.x(), this.y(), this.z(), this.getYaw(), this.getPitch());
}
// Paper end
}
@@ -14,6 +14,9 @@ import java.util.Set;
import java.util.UUID;
import java.util.function.Consumer;
import java.util.logging.Logger;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Warning.WarningState;
import org.bukkit.advancement.Advancement;
import org.bukkit.block.data.BlockData;
@@ -409,6 +412,40 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
}
// Paper end
/**
* Sends a message with the MiniMessage format to the server.
* <p>
* See <a href="https://docs.advntr.dev/minimessage/">MiniMessage docs</a>
* for more information on the format.
*
* @param message MiniMessage content
*/
default void sendRichMessage(final @NotNull String message) {
this.sendMessage(MiniMessage.miniMessage().deserialize(message));
}
/**
* Sends a message with the MiniMessage format to the server.
* <p>
* See <a href="https://docs.advntr.dev/minimessage/">MiniMessage docs</a> and <a href="https://docs.advntr.dev/minimessage/dynamic-replacements">MiniMessage Placeholders docs</a>
* for more information on the format.
*
* @param message MiniMessage content
* @param resolvers resolvers to use
*/
default void sendRichMessage(final @NotNull String message, final @NotNull TagResolver... resolvers) {
this.sendMessage(MiniMessage.miniMessage().deserialize(message, resolvers));
}
/**
* Sends a plain message to the server.
*
* @param message plain message
*/
default void sendPlainMessage(final @NotNull String message) {
this.sendMessage(Component.text(message));
}
/**
* Gets the name of the update folder. The update folder is used to safely
* update plugins at the right moment on a plugin load.
@@ -1,370 +0,0 @@
package org.bukkit;
import static org.junit.jupiter.api.Assertions.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.junit.jupiter.api.Test;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.AnnotationNode;
import org.objectweb.asm.tree.ClassNode;
import org.objectweb.asm.tree.MethodNode;
import org.objectweb.asm.tree.ParameterNode;
public class AnnotationTest {
private static final String[] ACCEPTED_ANNOTATIONS = {
"Lorg/jetbrains/annotations/Nullable;",
"Lorg/jetbrains/annotations/NotNull;",
"Lorg/jetbrains/annotations/Contract;",
"Lorg/bukkit/UndefinedNullability;",
// Paper start
"Lorg/checkerframework/checker/nullness/qual/MonotonicNonNull;",
"Lorg/checkerframework/checker/nullness/qual/NonNull;",
"Lorg/checkerframework/checker/nullness/qual/Nullable;",
"Lorg/checkerframework/checker/nullness/qual/PolyNull;",
// Paper end
};
private static final String[] EXCLUDED_CLASSES = {
// Internal technical classes
"org/bukkit/plugin/java/JavaPluginLoader",
"org/bukkit/util/io/BukkitObjectInputStream",
"org/bukkit/util/io/BukkitObjectOutputStream",
"org/bukkit/util/io/Wrapper",
"org/bukkit/plugin/java/PluginClassLoader",
// Generic functional interface
"org/bukkit/util/Consumer",
// Paper start
"io/papermc/paper/util/TransformingRandomAccessList",
"io/papermc/paper/util/TransformingRandomAccessList$TransformedListIterator",
// Timings history is broken in terms of nullability due to guavas Function defining that the param is NonNull
"co/aikar/timings/TimingHistory$2",
"co/aikar/timings/TimingHistory$2$1",
"co/aikar/timings/TimingHistory$2$1$1",
"co/aikar/timings/TimingHistory$2$1$2",
"co/aikar/timings/TimingHistory$3",
"co/aikar/timings/TimingHistory$4",
"co/aikar/timings/TimingHistoryEntry$1"
// Paper end
};
@Test
public void testAll() throws IOException, URISyntaxException {
URL loc = Bukkit.class.getProtectionDomain().getCodeSource().getLocation();
File file = new File(loc.toURI());
// Running from jar is not supported yet
assertTrue(file.isDirectory(), "code must be in a directory");
final HashMap<String, ClassNode> foundClasses = new HashMap<>();
collectClasses(file, foundClasses);
final ArrayList<String> errors = new ArrayList<>();
for (ClassNode clazz : foundClasses.values()) {
if (!isClassIncluded(clazz, foundClasses)) {
continue;
}
// Paper start - skip class if it's @NullMarked
if (isClassNullMarked(clazz, foundClasses)) {
continue;
}
// Paper end - skip class if it's @NullMarked
for (MethodNode method : clazz.methods) {
if (!isMethodIncluded(clazz, method, foundClasses)) {
continue;
}
if (mustBeAnnotated(Type.getReturnType(method.desc)) && !isWellAnnotated(method.invisibleAnnotations)) {
// Paper start - Allow use of TYPE_USE annotations
boolean warn = true;
if (isWellAnnotated(method.visibleTypeAnnotations)) {
warn = false;
} else if (method.invisibleTypeAnnotations != null) {
dance: for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_RETURN && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
warn = false;
break dance; // cha cha real smooth
}
}
}
if (warn)
// Paper end
warn(errors, clazz, method, "return value");
}
Type[] paramTypes = Type.getArgumentTypes(method.desc);
List<ParameterNode> parameters = method.parameters;
dancing: // Paper
for (int i = 0; i < paramTypes.length; i++) {
if (mustBeAnnotated(paramTypes[i]) ^ isWellAnnotated(method.invisibleParameterAnnotations == null ? null : method.invisibleParameterAnnotations[i])) {
// Paper start
if (method.invisibleTypeAnnotations != null) {
for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.invisibleTypeAnnotations) {
final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
continue dancing;
}
}
}
if (method.visibleTypeAnnotations != null) {
for (final org.objectweb.asm.tree.TypeAnnotationNode invisibleTypeAnnotation : method.visibleTypeAnnotations) {
final org.objectweb.asm.TypeReference ref = new org.objectweb.asm.TypeReference(invisibleTypeAnnotation.typeRef);
if (ref.getSort() == org.objectweb.asm.TypeReference.METHOD_FORMAL_PARAMETER && ref.getTypeParameterIndex() == i && java.util.Arrays.asList(ACCEPTED_ANNOTATIONS).contains(invisibleTypeAnnotation.desc)) {
continue dancing;
}
}
}
// Paper end - Allow use of TYPE_USE annotations
ParameterNode paramNode = parameters == null ? null : parameters.get(i);
String paramName = paramNode == null ? null : paramNode.name;
warn(errors, clazz, method, "parameter " + i + (paramName == null ? "" : ": " + paramName));
}
}
}
}
if (errors.isEmpty()) {
// Success
return;
}
Collections.sort(errors);
StringBuilder builder = new StringBuilder()
.append("There ")
.append(errors.size() != 1 ? "are " : "is ")
.append(errors.size())
.append(" missing annotation")
.append(errors.size() != 1 ? "s:\n" : ":\n");
for (String message : errors) {
builder.append("\t").append(message).append("\n");
}
fail(builder.toString());
}
private static void collectClasses(@NotNull File from, @NotNull Map<String, ClassNode> to) throws IOException {
if (from.isDirectory()) {
// Paper start - skip packages with @NullMarked
final File packageInfo = new File(from, "package-info.class");
if (packageInfo.exists()) {
try (final FileInputStream in = new FileInputStream(packageInfo)) {
final ClassReader cr = new ClassReader(in);
final ClassNode node = new ClassNode();
cr.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
if (isClassNullMarked0(node)) {
return; // skip packages with @NullMarked
}
}
}
// Paper end - skip packages with @NullMarked
final File[] files = from.listFiles();
assert files != null;
for (File file : files) {
collectClasses(file, to);
}
return;
}
if (!from.getName().endsWith(".class")) {
return;
}
try (FileInputStream in = new FileInputStream(from)) {
final ClassReader cr = new ClassReader(in);
final ClassNode node = new ClassNode();
cr.accept(node, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
to.put(node.name, node);
}
}
// Paper start - skip class if it's @NullMarked
private static boolean isClassNullMarked(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) {
if (isClassNullMarked0(clazz)) {
return true;
}
if (clazz.nestHostClass != null) {
final ClassNode nestHostNode = allClasses.get(clazz.nestHostClass);
if (nestHostNode != null) {
return isClassNullMarked(nestHostNode, allClasses);
}
}
return false;
}
private static boolean isClassNullMarked0(@NotNull ClassNode clazz) {
return clazz.visibleAnnotations != null && clazz.visibleAnnotations.stream().anyMatch(node -> "Lorg/jspecify/annotations/NullMarked;".equals(node.desc));
}
// Paper end - skip class if it's @NullMarked
private static boolean isClassIncluded(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) {
// Exclude private, synthetic or deprecated classes and annotations, since their members can't be null
if ((clazz.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED | Opcodes.ACC_ANNOTATION)) != 0) {
return false;
}
if (isSubclassOf(clazz, "org/bukkit/material/MaterialData", allClasses)) {
throw new AssertionError("Subclass of MaterialData must be deprecated: " + clazz.name);
}
if (isSubclassOf(clazz, "java/lang/Exception", allClasses)
|| isSubclassOf(clazz, "java/lang/RuntimeException", allClasses)) {
// Exceptions are excluded
return false;
}
// Paper start
if (isInternal(clazz.invisibleAnnotations)) {
return false;
}
// Paper end
for (String excludedClass : EXCLUDED_CLASSES) {
if (excludedClass.equals(clazz.name)) {
return false;
}
}
return true;
}
private static boolean isMethodIncluded(@NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull Map<String, ClassNode> allClasses) {
// Exclude private, synthetic and deprecated methods
if ((method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC | Opcodes.ACC_DEPRECATED)) != 0 || (method.access & (Opcodes.ACC_PRIVATE | Opcodes.ACC_PROTECTED | Opcodes.ACC_PUBLIC)) == 0) { // Paper - ignore package-private
return false;
}
// Exclude Java methods
if (is(method, "toString", 0) || is(method, "clone", 0) || is(method, "equals", 1)) {
return false;
}
// Exclude generated Enum methods
if (isSubclassOf(clazz, "java/lang/Enum", allClasses) && (is(method, "values", 0) || is(method, "valueOf", 1))) {
return false;
}
// Anonymous classes have generated constructors, which can't be annotated nor invoked
if ("<init>".equals(method.name) && isAnonymous(clazz)) {
return false;
}
// Paper start
if (isInternal(method.invisibleAnnotations)) {
return false;
}
// Paper end
return true;
}
// Paper start
private static boolean isInternal(List<? extends AnnotationNode> annotations) {
if (annotations == null) {
return false;
}
for (AnnotationNode node : annotations) {
if (node.desc.equals("Lorg/jetbrains/annotations/ApiStatus$Internal;")) {
return true;
}
}
return false;
}
// Paper end
private static boolean isWellAnnotated(@Nullable List<? extends AnnotationNode> annotations) { // Paper
if (annotations == null) {
return false;
}
for (AnnotationNode node : annotations) {
for (String acceptedAnnotation : ACCEPTED_ANNOTATIONS) {
if (acceptedAnnotation.equals(node.desc)) {
return true;
}
}
}
return false;
}
private static boolean mustBeAnnotated(@NotNull Type type) {
return type.getSort() == Type.ARRAY || type.getSort() == Type.OBJECT;
}
private static boolean is(@NotNull MethodNode method, @NotNull String name, int parameters) {
final List<ParameterNode> params = method.parameters;
return method.name.equals(name) && (params == null || params.size() == parameters);
}
/**
* Checks if the class is anonymous.
*
* @param clazz the class to check
* @return true if given class is anonymous
*/
private static boolean isAnonymous(@NotNull ClassNode clazz) {
final String name = clazz.name;
if (name == null) {
return false;
}
final int nestedSeparator = name.lastIndexOf('$');
if (nestedSeparator == -1 || nestedSeparator + 1 == name.length()) {
return false;
}
// Nested classes have purely numeric names. Java classes can't begin with a number,
// so if first character is a number, the class must be anonymous
final char c = name.charAt(nestedSeparator + 1);
return c >= '0' && c <= '9';
}
private static boolean isSubclassOf(@NotNull ClassNode what, @NotNull String ofWhat, @NotNull Map<String, ClassNode> allClasses) {
if (ofWhat.equals(what.name)
// Not only optimization: Super class may not be present in allClasses, so it is checked here
|| ofWhat.equals(what.superName)) {
return true;
}
final ClassNode parent = allClasses.get(what.superName);
if (parent != null && isSubclassOf(parent, ofWhat, allClasses)) {
return true;
}
for (String superInterface : what.interfaces) {
final ClassNode interfaceParent = allClasses.get(superInterface);
if (interfaceParent != null && isSubclassOf(interfaceParent, ofWhat, allClasses)) {
return true;
}
}
return false;
}
private static void warn(@NotNull Collection<String> out, @NotNull ClassNode clazz, @NotNull MethodNode method, @NotNull String description) {
out.add(clazz.name + " \t" + method.name + " \t" + description);
}
}
@@ -1262,11 +1262,12 @@
}
}
@@ -1652,10 +_,11 @@
@@ -1651,11 +_,12 @@
public void kickUnlistedPlayers(CommandSourceStack commandSource) {
if (this.isEnforceWhitelist()) {
PlayerList playerList = commandSource.getServer().getPlayerList();
+ if (!playerList.isUsingWhitelist()) return; // Paper - whitelist not enabled
UserWhiteList whiteList = playerList.getWhiteList();
+ if (!((net.minecraft.server.dedicated.DedicatedServer) this).getProperties().whiteList.get()) return; // Paper - whitelist not enabled
for (ServerPlayer serverPlayer : Lists.newArrayList(playerList.getPlayers())) {
- if (!whiteList.isWhiteListed(serverPlayer.getGameProfile())) {
@@ -122,7 +122,7 @@
Properties map = Settings.this.cloneProperties();
map.put(this.key, this.serializer.apply(newValue));
- return Settings.this.reload(registryAccess, map);
+ return Settings.this.reload(registryAccess, properties, Settings.this.options); // CraftBukkit
+ return Settings.this.reload(registryAccess, map, Settings.this.options); // CraftBukkit
}
}
}
@@ -1,6 +1,6 @@
--- a/net/minecraft/world/damagesource/DamageSource.java
+++ b/net/minecraft/world/damagesource/DamageSource.java
@@ -20,6 +_,105 @@
@@ -20,6 +_,107 @@
private final Entity directEntity;
@Nullable
private final Vec3 damageSourcePosition;
@@ -58,18 +58,19 @@
+ return damageSource;
+ }
+
+ @Nullable
+ public org.bukkit.block.Block getDirectBlock() {
+ return this.directBlock;
+ }
+
+ public DamageSource directBlock(net.minecraft.world.level.Level world, net.minecraft.core.BlockPos blockPosition) {
+ public DamageSource directBlock(@Nullable net.minecraft.world.level.Level world, @Nullable net.minecraft.core.BlockPos blockPosition) {
+ if (blockPosition == null || world == null) {
+ return this;
+ }
+ return this.directBlock(org.bukkit.craftbukkit.block.CraftBlock.at(world, blockPosition));
+ }
+
+ public DamageSource directBlock(org.bukkit.block.Block block) {
+ public DamageSource directBlock(@Nullable org.bukkit.block.Block block) {
+ if (block == null) {
+ return this;
+ }
@@ -79,11 +80,12 @@
+ return damageSource;
+ }
+
+ @Nullable
+ public org.bukkit.block.BlockState getDirectBlockState() {
+ return this.directBlockState;
+ }
+
+ public DamageSource directBlockState(org.bukkit.block.BlockState blockState) {
+ public DamageSource directBlockState(@Nullable org.bukkit.block.BlockState blockState) {
+ if (blockState == null) {
+ return this;
+ }
@@ -0,0 +1,42 @@
--- a/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java
+++ b/net/minecraft/world/entity/ai/behavior/PoiCompetitorScan.java
@@ -22,13 +_,32 @@
level.getPoiManager()
.getType(globalPos.pos())
.ifPresent(
- poi -> instance.<List<LivingEntity>>get(nearestLivingEntities)
- .stream()
- .filter(entity -> entity instanceof Villager && entity != villager)
- .map(entity -> (Villager)entity)
- .filter(LivingEntity::isAlive)
- .filter(v -> competesForSameJobsite(globalPos, poi, v))
- .reduce(villager, PoiCompetitorScan::selectWinner)
+ // Paper start - Improve performance of PoiCompetitorScan by unrolling stream
+ // The previous logic used Stream#reduce to simulate a form of single-iteration bubble sort
+ // in which the "winning" villager would maintain MemoryModuleType.JOB_SITE while all others
+ // would lose said memory module type by passing each "current winner" and incoming next
+ // villager to #selectWinner.
+ poi -> {
+ final List<LivingEntity> livingEntities = instance.get(nearestLivingEntities);
+
+ Villager winner = villager;
+ for (final LivingEntity other : livingEntities) {
+ if (other == villager) {
+ continue;
+ }
+ if (!(other instanceof final net.minecraft.world.entity.npc.Villager otherVillager)) {
+ continue;
+ }
+ if (!other.isAlive()) {
+ continue;
+ }
+ if (!competesForSameJobsite(globalPos, poi, otherVillager)) {
+ continue;
+ }
+ winner = selectWinner(winner, otherVillager);
+ }
+ }
+ // Paper end - Improve performance of PoiCompetitorScan by unrolling stream
);
return true;
}
@@ -218,6 +218,7 @@
- public void hurtAndBreak(int damage, ServerLevel level, @Nullable ServerPlayer player, Consumer<Item> onBreak) {
- int i = this.processDurabilityChange(damage, level, player);
- if (i != 0) {
+ public void hurtAndBreak(int damage, ServerLevel level, @Nullable LivingEntity player, Consumer<Item> onBreak) { // Paper - Add EntityDamageItemEvent
+ // Paper start - add force boolean overload
+ this.hurtAndBreak(damage, level, player, onBreak, false);
@@ -227,7 +228,7 @@
+ final int originalDamage = damage; // Paper - Expand PlayerItemDamageEvent
+ int i = this.processDurabilityChange(damage, level, player, force); // Paper
+ // CraftBukkit start
+ if (player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent
+ if (i > 0 && player instanceof final ServerPlayer serverPlayer) { // Paper - Add EntityDamageItemEvent - limit to positive damage and run for player
+ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i, originalDamage); // Paper - Add EntityDamageItemEvent
+ event.getPlayer().getServer().getPluginManager().callEvent(event);
+
@@ -240,7 +241,7 @@
+
+ i = event.getDamage();
+ // Paper start - Add EntityDamageItemEvent
+ } else if (player != null) {
+ } else if (i > 0 && player != null) {
+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this), i);
+ if (!event.callEvent()) {
+ return;
@@ -249,7 +250,7 @@
+ // Paper end - Add EntityDamageItemEvent
+ }
+ // CraftBukkit end
if (i != 0) {
+ if (i != 0) { // Paper - Add EntityDamageItemEvent - diff on change for above event ifs.
this.applyDamage(this.getDamageValue() + i, player, onBreak);
}
}
@@ -20,12 +20,12 @@
+ if (projectile instanceof Projectile) {
+ final org.bukkit.craftbukkit.block.CraftBlock craftBlock = org.bukkit.craftbukkit.block.CraftBlock.at(level, hit.getBlockPos());
+ final org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(hit.getDirection());
+ final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, i);
+ final io.papermc.paper.event.block.TargetHitEvent targetHitEvent = new io.papermc.paper.event.block.TargetHitEvent((org.bukkit.entity.Projectile) projectile.getBukkitEntity(), craftBlock, blockFace, redstoneStrength);
+ if (targetHitEvent.callEvent()) {
+ i = targetHitEvent.getSignalStrength();
+ redstoneStrength = targetHitEvent.getSignalStrength();
+ shouldAward = true;
+ } else {
+ return i;
+ return redstoneStrength;
+ }
+ }
+ // Paper end - Add TargetHitEvent
@@ -35,7 +35,7 @@
+
+ // Paper start - Award Hit Criteria after Block Update
+ if (shouldAward) {
+ awardTargetHitCriteria((Projectile) projectile, hit, i);
+ awardTargetHitCriteria((Projectile) projectile, hit, redstoneStrength);
+ }
+ // Paper end - Award Hit Criteria after Block Update
@@ -883,7 +883,7 @@ public final class CraftServer implements Server {
@Override
public boolean hasWhitelist() {
return this.getProperties().whiteList.get();
return this.playerList.isUsingWhitelist();
}
// NOTE: Temporary calls through to server.properies until its replaced
@@ -245,7 +245,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
// Paper start - Teleport passenger API
Set<io.papermc.paper.entity.TeleportFlag> flagSet = Set.of(flags);
boolean dismount = !flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_VEHICLE);
boolean ignorePassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
boolean retainPassengers = flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS);
// Don't allow teleporting between worlds while keeping passengers
if (flagSet.contains(io.papermc.paper.entity.TeleportFlag.EntityState.RETAIN_PASSENGERS) && this.entity.isVehicle() && location.getWorld() != this.getWorld()) {
return false;
@@ -257,7 +257,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
}
// Paper end
if ((!ignorePassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API
if ((!retainPassengers && this.entity.isVehicle()) || this.entity.isRemoved()) { // Paper - Teleport passenger API
return false;
}
@@ -288,6 +288,9 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
// SPIGOT-619: Force sync head rotation also
this.entity.setYHeadRot(location.getYaw());
// Ensure passengers of entity are teleported
if (retainPassengers && this.entity.isVehicle()) this.entity.teleportPassengers();
return true;
}
+6 -4
View File
@@ -2,6 +2,7 @@ import java.util.Locale
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
maven("https://repo.papermc.io/repository/maven-public/")
}
@@ -13,17 +14,17 @@ plugins {
if (!file(".git").exists()) {
val errorText = """
=====================[ ERROR ]=====================
The Paper project directory is not a properly cloned Git repository.
In order to build Paper from source you must clone
the Paper repository using Git, not download a code
zip from GitHub.
Built Paper jars are available for download at
https://papermc.io/downloads/paper
See https://github.com/PaperMC/Paper/blob/main/CONTRIBUTING.md
for further information on building and modifying Paper.
===================================================
@@ -42,6 +43,7 @@ for (name in listOf("paper-api", "paper-server")) {
optionalInclude("test-plugin")
optionalInclude("paper-api-generator")
include("paper-api:custom-checkstyle")
fun optionalInclude(name: String, op: (ProjectDescriptor.() -> Unit)? = null) {
val settingsFile = file("$name.settings.gradle.kts")