Merge pull request 'Merge Latest Changes' (#2) from update into main
Some checks failed
Build Paper / build (21) (push) Has been cancelled
Build Paper / Event File (push) Has been cancelled
Some checks failed
Build Paper / build (21) (push) Has been cancelled
Build Paper / Event File (push) Has been cancelled
Reviewed-on: https://steamwar.de/devlabs/SteamWar/Paper/pulls/2
This commit is contained in:
@ -31,6 +31,11 @@ ij_java_generate_final_locals = true
|
|||||||
ij_java_generate_final_parameters = true
|
ij_java_generate_final_parameters = true
|
||||||
ij_java_method_parameters_new_line_after_left_paren = true
|
ij_java_method_parameters_new_line_after_left_paren = true
|
||||||
ij_java_method_parameters_right_paren_on_new_line = 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
|
||||||
|
|
||||||
|
[paper-server/src/minecraft/java/**/*.java]
|
||||||
|
ij_java_use_fq_class_names = true
|
||||||
|
|
||||||
[paper-server/src/minecraft/resources/data/**/*.json]
|
[paper-server/src/minecraft/resources/data/**/*.json]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|||||||
13
.github/workflows/build.yml
vendored
13
.github/workflows/build.yml
vendored
@ -16,8 +16,17 @@ on:
|
|||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
# Run on all label events (won't be duplicated) or all push events or on PR syncs not from the same repo
|
# The goal of the build workflow is split into multiple requirements.
|
||||||
if: (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'build-pr-jar') || github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name
|
# 1. Run on pushes to same repo.
|
||||||
|
# 2. Run on PR open/reopen/syncs from repos that are not the same (PRs from the same repo are covered by 1)
|
||||||
|
# 3. Run on labeled PRs that have the build-pr-jar flag.
|
||||||
|
if: >
|
||||||
|
(
|
||||||
|
(github.event_name == 'push')
|
||||||
|
|| (github.event_name == 'pull_request' && github.repository != github.event.pull_request.head.repo.full_name && contains(fromJSON('["opened", "reopened", "synchronize"]'), github.event.action))
|
||||||
|
|| (github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'build-pr-jar')
|
||||||
|
)
|
||||||
|
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
|
|||||||
@ -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
|
# 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
|
# is imported and not fully qualified. Easiest fix is to just change the name
|
||||||
|
|||||||
@ -110,6 +110,8 @@ 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.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.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
|
public net.minecraft.server.packs.repository.Pack resources
|
||||||
public net.minecraft.server.players.PlayerList playerIo
|
public net.minecraft.server.players.PlayerList playerIo
|
||||||
public net.minecraft.server.players.PlayerList players
|
public net.minecraft.server.players.PlayerList players
|
||||||
|
|||||||
@ -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
|
# 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.
|
# use - at least in some capacity - for a long time.
|
||||||
|
|
||||||
tiny 2 0 mojang+yarn spigot
|
tiny 2 0 mojang spigot
|
||||||
|
|
||||||
# CraftBukkit changes type
|
# CraftBukkit changes type
|
||||||
c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer
|
c net/minecraft/server/level/ServerLevel net/minecraft/server/level/WorldServer
|
||||||
|
|||||||
@ -12,7 +12,7 @@ import java.nio.file.Path
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("io.papermc.paperweight.core") version "2.0.0-beta.8" apply false
|
id("io.papermc.paperweight.core") version "2.0.0-beta.10" apply false
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
|
|||||||
@ -16,7 +16,7 @@ dependencies {
|
|||||||
implementation("com.squareup:javapoet:1.13.0")
|
implementation("com.squareup:javapoet:1.13.0")
|
||||||
implementation(project(":paper-api"))
|
implementation(project(":paper-api"))
|
||||||
implementation("io.github.classgraph:classgraph:4.8.47")
|
implementation("io.github.classgraph:classgraph:4.8.47")
|
||||||
implementation("org.jetbrains:annotations:24.1.0")
|
implementation("org.jetbrains:annotations:26.0.1")
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.10.2")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,288 @@
|
|||||||
|
package io.papermc.paper.registry.keys.tags;
|
||||||
|
|
||||||
|
import static net.kyori.adventure.key.Key.key;
|
||||||
|
|
||||||
|
import io.papermc.paper.generated.GeneratedFrom;
|
||||||
|
import io.papermc.paper.registry.RegistryKey;
|
||||||
|
import io.papermc.paper.registry.tag.TagKey;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vanilla keys for {@link RegistryKey#ENTITY_TYPE}.
|
||||||
|
*
|
||||||
|
* @apiNote The fields provided here are a direct representation of
|
||||||
|
* what is available from the vanilla game source. They may be
|
||||||
|
* changed (including removals) on any Minecraft version
|
||||||
|
* bump, so cross-version compatibility is not provided on the
|
||||||
|
* same level as it is on most of the other API.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings({
|
||||||
|
"unused",
|
||||||
|
"SpellCheckingInspection"
|
||||||
|
})
|
||||||
|
@GeneratedFrom("1.21.4")
|
||||||
|
@NullMarked
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public final class EntityTypeTagKeys {
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:aquatic}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> AQUATIC = create(key("aquatic"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:arrows}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> ARROWS = create(key("arrows"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:arthropod}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> ARTHROPOD = create(key("arthropod"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:axolotl_always_hostiles}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> AXOLOTL_ALWAYS_HOSTILES = create(key("axolotl_always_hostiles"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:axolotl_hunt_targets}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> AXOLOTL_HUNT_TARGETS = create(key("axolotl_hunt_targets"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:beehive_inhabitors}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> BEEHIVE_INHABITORS = create(key("beehive_inhabitors"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:boat}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> BOAT = create(key("boat"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:can_breathe_under_water}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> CAN_BREATHE_UNDER_WATER = create(key("can_breathe_under_water"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:can_turn_in_boats}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> CAN_TURN_IN_BOATS = create(key("can_turn_in_boats"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:deflects_projectiles}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> DEFLECTS_PROJECTILES = create(key("deflects_projectiles"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:dismounts_underwater}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> DISMOUNTS_UNDERWATER = create(key("dismounts_underwater"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:fall_damage_immune}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> FALL_DAMAGE_IMMUNE = create(key("fall_damage_immune"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:freeze_hurts_extra_types}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> FREEZE_HURTS_EXTRA_TYPES = create(key("freeze_hurts_extra_types"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:freeze_immune_entity_types}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> FREEZE_IMMUNE_ENTITY_TYPES = create(key("freeze_immune_entity_types"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:frog_food}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> FROG_FOOD = create(key("frog_food"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:ignores_poison_and_regen}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> IGNORES_POISON_AND_REGEN = create(key("ignores_poison_and_regen"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:illager}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> ILLAGER = create(key("illager"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:illager_friends}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> ILLAGER_FRIENDS = create(key("illager_friends"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:immune_to_infested}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> IMMUNE_TO_INFESTED = create(key("immune_to_infested"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:immune_to_oozing}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> IMMUNE_TO_OOZING = create(key("immune_to_oozing"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:impact_projectiles}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> IMPACT_PROJECTILES = create(key("impact_projectiles"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:inverted_healing_and_harm}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> INVERTED_HEALING_AND_HARM = create(key("inverted_healing_and_harm"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:no_anger_from_wind_charge}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> NO_ANGER_FROM_WIND_CHARGE = create(key("no_anger_from_wind_charge"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:non_controlling_rider}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> NON_CONTROLLING_RIDER = create(key("non_controlling_rider"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:not_scary_for_pufferfish}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> NOT_SCARY_FOR_PUFFERFISH = create(key("not_scary_for_pufferfish"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:powder_snow_walkable_mobs}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> POWDER_SNOW_WALKABLE_MOBS = create(key("powder_snow_walkable_mobs"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:raiders}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> RAIDERS = create(key("raiders"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:redirectable_projectile}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> REDIRECTABLE_PROJECTILE = create(key("redirectable_projectile"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:sensitive_to_bane_of_arthropods}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> SENSITIVE_TO_BANE_OF_ARTHROPODS = create(key("sensitive_to_bane_of_arthropods"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:sensitive_to_impaling}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> SENSITIVE_TO_IMPALING = create(key("sensitive_to_impaling"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:sensitive_to_smite}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> SENSITIVE_TO_SMITE = create(key("sensitive_to_smite"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:skeletons}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> SKELETONS = create(key("skeletons"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:undead}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> UNDEAD = create(key("undead"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:wither_friends}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> WITHER_FRIENDS = create(key("wither_friends"));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@code #minecraft:zombies}
|
||||||
|
*
|
||||||
|
* @apiNote This field is version-dependant and may be removed in future Minecraft versions
|
||||||
|
*/
|
||||||
|
public static final TagKey<EntityType> ZOMBIES = create(key("zombies"));
|
||||||
|
|
||||||
|
private EntityTypeTagKeys() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a tag key for {@link EntityType} in the registry {@code minecraft:entity_type}.
|
||||||
|
*
|
||||||
|
* @param key the tag key's key
|
||||||
|
* @return a new tag key
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
public static TagKey<EntityType> create(final Key key) {
|
||||||
|
return TagKey.create(RegistryKey.ENTITY_TYPE, key);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -21,6 +21,7 @@ import org.bukkit.block.banner.PatternType;
|
|||||||
import org.bukkit.damage.DamageType;
|
import org.bukkit.damage.DamageType;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.bukkit.entity.Cat;
|
import org.bukkit.entity.Cat;
|
||||||
|
import org.bukkit.entity.EntityType;
|
||||||
import org.bukkit.entity.Frog;
|
import org.bukkit.entity.Frog;
|
||||||
import org.bukkit.entity.Villager;
|
import org.bukkit.entity.Villager;
|
||||||
import org.bukkit.entity.Wolf;
|
import org.bukkit.entity.Wolf;
|
||||||
@ -79,6 +80,9 @@ public interface Generators {
|
|||||||
simpleTagKey("BannerPatternTagKeys", PatternType.class, Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN),
|
simpleTagKey("BannerPatternTagKeys", PatternType.class, Registries.BANNER_PATTERN, RegistryKey.BANNER_PATTERN),
|
||||||
simpleTagKey("PaintingVariantTagKeys", Art.class, Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT),
|
simpleTagKey("PaintingVariantTagKeys", Art.class, Registries.PAINTING_VARIANT, RegistryKey.PAINTING_VARIANT),
|
||||||
simpleTagKey("InstrumentTagKeys", MusicInstrument.class, Registries.INSTRUMENT, RegistryKey.INSTRUMENT),
|
simpleTagKey("InstrumentTagKeys", MusicInstrument.class, Registries.INSTRUMENT, RegistryKey.INSTRUMENT),
|
||||||
|
|
||||||
|
// api only
|
||||||
|
simpleTagKey("EntityTypeTagKeys", EntityType.class, Registries.ENTITY_TYPE, RegistryKey.ENTITY_TYPE),
|
||||||
new MobGoalGenerator("VanillaGoal", "com.destroystokyo.paper.entity.ai")
|
new MobGoalGenerator("VanillaGoal", "com.destroystokyo.paper.entity.ai")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -9,9 +9,9 @@ java {
|
|||||||
withJavadocJar()
|
withJavadocJar()
|
||||||
}
|
}
|
||||||
|
|
||||||
val annotationsVersion = "24.1.0"
|
val annotationsVersion = "26.0.1"
|
||||||
val bungeeCordChatVersion = "1.20-R0.2"
|
val bungeeCordChatVersion = "1.20-R0.2"
|
||||||
val adventureVersion = "4.17.0"
|
val adventureVersion = "4.18.0"
|
||||||
val slf4jVersion = "2.0.9"
|
val slf4jVersion = "2.0.9"
|
||||||
val log4jVersion = "2.17.1"
|
val log4jVersion = "2.17.1"
|
||||||
|
|
||||||
@ -68,9 +68,6 @@ dependencies {
|
|||||||
apiAndDocs("net.kyori:adventure-text-serializer-plain")
|
apiAndDocs("net.kyori:adventure-text-serializer-plain")
|
||||||
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
|
apiAndDocs("net.kyori:adventure-text-logger-slf4j")
|
||||||
|
|
||||||
implementation("org.ow2.asm:asm:9.7.1")
|
|
||||||
implementation("org.ow2.asm:asm-commons:9.7.1")
|
|
||||||
|
|
||||||
api("org.apache.maven:maven-resolver-provider:3.9.6") // make API dependency for Paper Plugins
|
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")
|
compileOnly("org.apache.maven.resolver:maven-resolver-connector-basic:1.9.18")
|
||||||
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
|
compileOnly("org.apache.maven.resolver:maven-resolver-transport-http:1.9.18")
|
||||||
|
|||||||
@ -1,54 +0,0 @@
|
|||||||
package com.destroystokyo.paper.event.executor;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.util.SneakyThrow;
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.EventException;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.plugin.EventExecutor;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
|
||||||
import org.jspecify.annotations.Nullable;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@NullMarked
|
|
||||||
public class MethodHandleEventExecutor implements EventExecutor {
|
|
||||||
|
|
||||||
private final Class<? extends Event> eventClass;
|
|
||||||
private final MethodHandle handle;
|
|
||||||
private final @Nullable Method method;
|
|
||||||
|
|
||||||
public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final MethodHandle handle) {
|
|
||||||
this.eventClass = eventClass;
|
|
||||||
this.handle = handle;
|
|
||||||
this.method = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public MethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
|
|
||||||
this.eventClass = eventClass;
|
|
||||||
try {
|
|
||||||
m.setAccessible(true);
|
|
||||||
this.handle = MethodHandles.lookup().unreflect(m);
|
|
||||||
} catch (final IllegalAccessException e) {
|
|
||||||
throw new AssertionError("Unable to set accessible", e);
|
|
||||||
}
|
|
||||||
this.method = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final Listener listener, final Event event) throws EventException {
|
|
||||||
if (!this.eventClass.isInstance(event)) return;
|
|
||||||
try {
|
|
||||||
this.handle.invoke(listener, event);
|
|
||||||
} catch (final Throwable t) {
|
|
||||||
SneakyThrow.sneaky(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "MethodHandleEventExecutor['" + this.method + "']";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,51 +0,0 @@
|
|||||||
package com.destroystokyo.paper.event.executor;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.util.SneakyThrow;
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.EventException;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.plugin.EventExecutor;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@NullMarked
|
|
||||||
public class StaticMethodHandleEventExecutor implements EventExecutor {
|
|
||||||
|
|
||||||
private final Class<? extends Event> eventClass;
|
|
||||||
private final MethodHandle handle;
|
|
||||||
private final Method method;
|
|
||||||
|
|
||||||
public StaticMethodHandleEventExecutor(final Class<? extends Event> eventClass, final Method m) {
|
|
||||||
Preconditions.checkArgument(Modifier.isStatic(m.getModifiers()), "Not a static method: %s", m);
|
|
||||||
Preconditions.checkArgument(eventClass != null, "eventClass is null");
|
|
||||||
this.eventClass = eventClass;
|
|
||||||
try {
|
|
||||||
m.setAccessible(true);
|
|
||||||
this.handle = MethodHandles.lookup().unreflect(m);
|
|
||||||
} catch (final IllegalAccessException e) {
|
|
||||||
throw new AssertionError("Unable to set accessible", e);
|
|
||||||
}
|
|
||||||
this.method = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void execute(final Listener listener, final Event event) throws EventException {
|
|
||||||
if (!this.eventClass.isInstance(event)) return;
|
|
||||||
try {
|
|
||||||
this.handle.invoke(event);
|
|
||||||
} catch (final Throwable throwable) {
|
|
||||||
SneakyThrow.sneaky(throwable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return "StaticMethodHandleEventExecutor['" + this.method + "']";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,59 +0,0 @@
|
|||||||
package com.destroystokyo.paper.event.executor.asm;
|
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.concurrent.atomic.AtomicInteger;
|
|
||||||
import org.bukkit.plugin.EventExecutor;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
|
||||||
import org.objectweb.asm.ClassWriter;
|
|
||||||
import org.objectweb.asm.Type;
|
|
||||||
import org.objectweb.asm.commons.GeneratorAdapter;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
|
||||||
import static org.objectweb.asm.Opcodes.INVOKEINTERFACE;
|
|
||||||
import static org.objectweb.asm.Opcodes.INVOKESPECIAL;
|
|
||||||
import static org.objectweb.asm.Opcodes.INVOKEVIRTUAL;
|
|
||||||
import static org.objectweb.asm.Opcodes.V1_8;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@NullMarked
|
|
||||||
public final class ASMEventExecutorGenerator {
|
|
||||||
|
|
||||||
private static final String EXECUTE_DESCRIPTOR = "(Lorg/bukkit/event/Listener;Lorg/bukkit/event/Event;)V";
|
|
||||||
|
|
||||||
public static byte[] generateEventExecutor(final Method m, final String name) {
|
|
||||||
final ClassWriter writer = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
|
|
||||||
writer.visit(V1_8, ACC_PUBLIC, name.replace('.', '/'), null, Type.getInternalName(Object.class), new String[]{Type.getInternalName(EventExecutor.class)});
|
|
||||||
// Generate constructor
|
|
||||||
GeneratorAdapter methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null), ACC_PUBLIC, "<init>", "()V");
|
|
||||||
methodGenerator.loadThis();
|
|
||||||
methodGenerator.visitMethodInsn(INVOKESPECIAL, Type.getInternalName(Object.class), "<init>", "()V", false); // Invoke the super class (Object) constructor
|
|
||||||
methodGenerator.returnValue();
|
|
||||||
methodGenerator.endMethod();
|
|
||||||
// Generate the execute method
|
|
||||||
methodGenerator = new GeneratorAdapter(writer.visitMethod(ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR, null, null), ACC_PUBLIC, "execute", EXECUTE_DESCRIPTOR);
|
|
||||||
methodGenerator.loadArg(0);
|
|
||||||
methodGenerator.checkCast(Type.getType(m.getDeclaringClass()));
|
|
||||||
methodGenerator.loadArg(1);
|
|
||||||
methodGenerator.checkCast(Type.getType(m.getParameterTypes()[0]));
|
|
||||||
methodGenerator.visitMethodInsn(m.getDeclaringClass().isInterface() ? INVOKEINTERFACE : INVOKEVIRTUAL, Type.getInternalName(m.getDeclaringClass()), m.getName(), Type.getMethodDescriptor(m), m.getDeclaringClass().isInterface());
|
|
||||||
// The only purpose of this switch statement is to generate the correct pop instruction, should the event handler method return something other than void.
|
|
||||||
// Non-void event handlers will be unsupported in a future release.
|
|
||||||
switch (Type.getType(m.getReturnType()).getSize()) {
|
|
||||||
// case 0 is omitted because the only type that has size 0 is void - no pop instruction needed.
|
|
||||||
case 1 -> methodGenerator.pop(); // handles reference types and most primitives
|
|
||||||
case 2 -> methodGenerator.pop2(); // handles long and double
|
|
||||||
}
|
|
||||||
methodGenerator.returnValue();
|
|
||||||
methodGenerator.endMethod();
|
|
||||||
writer.visitEnd();
|
|
||||||
return writer.toByteArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static AtomicInteger NEXT_ID = new AtomicInteger(1);
|
|
||||||
|
|
||||||
public static String generateName() {
|
|
||||||
final int id = NEXT_ID.getAndIncrement();
|
|
||||||
return "com.destroystokyo.paper.event.executor.asm.generated.GeneratedEventExecutor" + id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,35 +0,0 @@
|
|||||||
package com.destroystokyo.paper.event.executor.asm;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@NullMarked
|
|
||||||
public interface ClassDefiner {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns if the defined classes can bypass access checks
|
|
||||||
*
|
|
||||||
* @return if classes bypass access checks
|
|
||||||
*/
|
|
||||||
default boolean isBypassAccessChecks() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a class
|
|
||||||
*
|
|
||||||
* @param parentLoader the parent classloader
|
|
||||||
* @param name the name of the class
|
|
||||||
* @param data the class data to load
|
|
||||||
* @return the defined class
|
|
||||||
* @throws ClassFormatError if the class data is invalid
|
|
||||||
* @throws NullPointerException if any of the arguments are null
|
|
||||||
*/
|
|
||||||
Class<?> defineClass(ClassLoader parentLoader, String name, byte[] data);
|
|
||||||
|
|
||||||
static ClassDefiner getInstance() {
|
|
||||||
return SafeClassDefiner.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,66 +0,0 @@
|
|||||||
package com.destroystokyo.paper.event.executor.asm;
|
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
import com.google.common.collect.MapMaker;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@NullMarked
|
|
||||||
public class SafeClassDefiner implements ClassDefiner {
|
|
||||||
|
|
||||||
/* default */ static final SafeClassDefiner INSTANCE = new SafeClassDefiner();
|
|
||||||
|
|
||||||
private SafeClassDefiner() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private final ConcurrentMap<ClassLoader, GeneratedClassLoader> loaders = new MapMaker().weakKeys().makeMap();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Class<?> defineClass(final ClassLoader parentLoader, final String name, final byte[] data) {
|
|
||||||
final GeneratedClassLoader loader = this.loaders.computeIfAbsent(parentLoader, GeneratedClassLoader::new);
|
|
||||||
synchronized (loader.getClassLoadingLock(name)) {
|
|
||||||
Preconditions.checkState(!loader.hasClass(name), "%s already defined", name);
|
|
||||||
final Class<?> c = loader.define(name, data);
|
|
||||||
assert c.getName().equals(name);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class GeneratedClassLoader extends ClassLoader {
|
|
||||||
|
|
||||||
static {
|
|
||||||
ClassLoader.registerAsParallelCapable();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected GeneratedClassLoader(final ClassLoader parent) {
|
|
||||||
super(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Class<?> define(final String name, final byte[] data) {
|
|
||||||
synchronized (this.getClassLoadingLock(name)) {
|
|
||||||
assert !this.hasClass(name);
|
|
||||||
final Class<?> c = this.defineClass(name, data, 0, data.length);
|
|
||||||
this.resolveClass(c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getClassLoadingLock(final String name) {
|
|
||||||
return super.getClassLoadingLock(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean hasClass(final String name) {
|
|
||||||
synchronized (this.getClassLoadingLock(name)) {
|
|
||||||
try {
|
|
||||||
Class.forName(name);
|
|
||||||
return true;
|
|
||||||
} catch (final ClassNotFoundException e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -304,8 +304,7 @@ public class PaperServerListPingEvent extends ServerListPingEvent implements Can
|
|||||||
return new PlayerIterator();
|
return new PlayerIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
protected @NotNull Object @NotNull [] getOnlinePlayers() {
|
||||||
protected Object[] getOnlinePlayers() {
|
|
||||||
return Bukkit.getOnlinePlayers().toArray();
|
return Bukkit.getOnlinePlayers().toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
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.
|
||||||
|
* <p>
|
||||||
|
* Any and all methods in here are *not* to be called by plugin developers, may change at any time and may generally
|
||||||
|
* cause issues when called under unexpected circumstances.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Internal
|
||||||
|
@NullMarked
|
||||||
|
public interface InternalAPIBridge {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Yields the instance of this API bridge by lazily requesting it from the java service loader API.
|
||||||
|
*
|
||||||
|
* @return the instance.
|
||||||
|
*/
|
||||||
|
static InternalAPIBridge get() {
|
||||||
|
class Holder {
|
||||||
|
public static final InternalAPIBridge INSTANCE = Services.service(InternalAPIBridge.class).orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Holder.INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a damage effect instance for the passed key.
|
||||||
|
*
|
||||||
|
* @param key the string key.
|
||||||
|
* @return the damage effect.
|
||||||
|
*/
|
||||||
|
DamageEffect getDamageEffect(String key);
|
||||||
|
}
|
||||||
|
|
||||||
@ -1,10 +1,8 @@
|
|||||||
package io.papermc.paper.datapack;
|
package io.papermc.paper.datapack;
|
||||||
|
|
||||||
import java.util.Set;
|
|
||||||
import net.kyori.adventure.text.Component;
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.FeatureFlag;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.Contract;
|
import org.jetbrains.annotations.Contract;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -12,50 +10,8 @@ import org.jspecify.annotations.NullMarked;
|
|||||||
* won't be updated as datapacks are updated.
|
* won't be updated as datapacks are updated.
|
||||||
*/
|
*/
|
||||||
@NullMarked
|
@NullMarked
|
||||||
public interface Datapack {
|
@ApiStatus.NonExtendable
|
||||||
|
public interface Datapack extends DiscoveredDatapack {
|
||||||
/**
|
|
||||||
* Gets the name/id of this datapack.
|
|
||||||
*
|
|
||||||
* @return the name of the pack
|
|
||||||
*/
|
|
||||||
@Contract(pure = true)
|
|
||||||
String getName();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the title component of this datapack.
|
|
||||||
*
|
|
||||||
* @return the title
|
|
||||||
*/
|
|
||||||
Component getTitle();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the description component of this datapack.
|
|
||||||
*
|
|
||||||
* @return the description
|
|
||||||
*/
|
|
||||||
Component getDescription();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets if this datapack is required to be enabled.
|
|
||||||
*
|
|
||||||
* @return true if the pack is required
|
|
||||||
*/
|
|
||||||
boolean isRequired();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the compatibility status of this pack.
|
|
||||||
*
|
|
||||||
* @return the compatibility of the pack
|
|
||||||
*/
|
|
||||||
Compatibility getCompatibility();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the set of required features for this datapack.
|
|
||||||
*
|
|
||||||
* @return the set of required features
|
|
||||||
*/
|
|
||||||
@Unmodifiable Set<FeatureFlag> getRequiredFeatures();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the enabled state of this pack.
|
* Gets the enabled state of this pack.
|
||||||
@ -74,13 +30,6 @@ public interface Datapack {
|
|||||||
*/
|
*/
|
||||||
void setEnabled(boolean enabled);
|
void setEnabled(boolean enabled);
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the source for this datapack.
|
|
||||||
*
|
|
||||||
* @return the pack source
|
|
||||||
*/
|
|
||||||
DatapackSource getSource();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes the component vanilla Minecraft uses
|
* Computes the component vanilla Minecraft uses
|
||||||
* to display this datapack. Includes the {@link #getSource()},
|
* to display this datapack. Includes the {@link #getSource()},
|
||||||
@ -96,4 +45,11 @@ public interface Datapack {
|
|||||||
TOO_NEW,
|
TOO_NEW,
|
||||||
COMPATIBLE,
|
COMPATIBLE,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Position of the pack in the load order.
|
||||||
|
*/
|
||||||
|
enum Position {
|
||||||
|
TOP, BOTTOM
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,202 @@
|
|||||||
|
package io.papermc.paper.datapack;
|
||||||
|
|
||||||
|
import io.papermc.paper.plugin.configuration.PluginMeta;
|
||||||
|
import io.papermc.paper.plugin.lifecycle.event.registrar.Registrar;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The registrar for datapacks. The event for this registrar
|
||||||
|
* is called anytime the game tries to discover datapacks at any of the
|
||||||
|
* configured locations. This means that if a datapack should stay available to the server,
|
||||||
|
* it must always be discovered whenever this event fires.
|
||||||
|
* <p>An example of a plugin loading a datapack from within it's own jar is below</p>
|
||||||
|
* <pre>{@code
|
||||||
|
* public class YourPluginBootstrap implements PluginBootstrap {
|
||||||
|
* @Override
|
||||||
|
* public void bootstrap(BoostrapContext context) {
|
||||||
|
* final LifecycleEventManager<BootstrapContext> manager = context.getLifecycleManager();
|
||||||
|
* manager.registerEventHandler(LifecycleEvents.DATAPACK_DISCOVERY, event -> {
|
||||||
|
* DatapackRegistrar registrar = event.registrar();
|
||||||
|
* try {
|
||||||
|
* final URI uri = Objects.requireNonNull(
|
||||||
|
* YourPluginBootstrap.class.getResource("/pack")
|
||||||
|
* ).toURI();
|
||||||
|
* registrar.discoverPack(uri, "packId");
|
||||||
|
* } catch (final URISyntaxException | IOException e) {
|
||||||
|
* throw new RuntimeException(e);
|
||||||
|
* }
|
||||||
|
* });
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }</pre>
|
||||||
|
* @see io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents#DATAPACK_DISCOVERY
|
||||||
|
*/
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@NullMarked
|
||||||
|
public interface DatapackRegistrar extends Registrar {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a datapack with the specified name has been discovered.
|
||||||
|
*
|
||||||
|
* @param name the name of the pack
|
||||||
|
* @return true if the pack has been discovered
|
||||||
|
* @see Datapack#getName()
|
||||||
|
*/
|
||||||
|
@Contract(pure = true)
|
||||||
|
boolean hasPackDiscovered(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a discovered datapack by its name.
|
||||||
|
*
|
||||||
|
* @param name the name of the pack
|
||||||
|
* @return the datapack
|
||||||
|
* @throws java.util.NoSuchElementException if the pack is not discovered
|
||||||
|
* @see Datapack#getName()
|
||||||
|
*/
|
||||||
|
@Contract(pure = true)
|
||||||
|
DiscoveredDatapack getDiscoveredPack(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes a discovered datapack by its name.
|
||||||
|
*
|
||||||
|
* @param name the name of the pack
|
||||||
|
* @return true if the pack was removed
|
||||||
|
* @see Datapack#getName()
|
||||||
|
*/
|
||||||
|
@Contract(mutates = "this")
|
||||||
|
boolean removeDiscoveredPack(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all discovered datapacks.
|
||||||
|
*
|
||||||
|
* @return an unmodifiable map of discovered packs
|
||||||
|
*/
|
||||||
|
@Contract(pure = true)
|
||||||
|
@Unmodifiable Map<String, DiscoveredDatapack> getDiscoveredPacks();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link URI} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param uri the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
default @Nullable DiscoveredDatapack discoverPack(final URI uri, final String id) throws IOException {
|
||||||
|
return this.discoverPack(uri, id, c -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link URI} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param uri the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @param configurer a configurer for extra options
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
@Nullable DiscoveredDatapack discoverPack(URI uri, String id, Consumer<Configurer> configurer) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link Path} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param path the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
default @Nullable DiscoveredDatapack discoverPack(final Path path, final String id) throws IOException {
|
||||||
|
return this.discoverPack(path, id, c -> {});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link Path} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param path the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @param configurer a configurer for extra options
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
@Nullable DiscoveredDatapack discoverPack(Path path, String id, Consumer<Configurer> configurer) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link URI} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param pluginMeta the plugin which will be the "owner" of this datapack
|
||||||
|
* @param uri the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @param configurer a configurer for extra options
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
@Nullable DiscoveredDatapack discoverPack(PluginMeta pluginMeta, URI uri, String id, Consumer<Configurer> configurer) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Discovers a datapack at the specified {@link Path} with the id.
|
||||||
|
* <p>Symlinks obey the {@code allowed_symlinks.txt} in the server root directory.</p>
|
||||||
|
*
|
||||||
|
* @param pluginMeta the plugin which will be the "owner" of this datapack
|
||||||
|
* @param path the location of the pack
|
||||||
|
* @param id a unique id (will be combined with plugin for the datapacks name)
|
||||||
|
* @param configurer a configurer for extra options
|
||||||
|
* @return the discovered datapack (or null if it failed)
|
||||||
|
* @throws IOException if any IO error occurs
|
||||||
|
*/
|
||||||
|
@Nullable DiscoveredDatapack discoverPack(PluginMeta pluginMeta, Path path, String id, Consumer<Configurer> configurer) throws IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures additional, optional, details about a datapack.
|
||||||
|
*/
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
interface Configurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the title of the datapack from the default which
|
||||||
|
* is just the "id" in the {@code registerPack} methods.
|
||||||
|
*
|
||||||
|
* @param title the new title
|
||||||
|
* @return the configurer for chaining
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Configurer title(Component title);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether this pack is going to be automatically enabled on server starts even if previously disabled.
|
||||||
|
* Defaults to false.
|
||||||
|
*
|
||||||
|
* @param autoEnableOnServerStart true to ensure the pack is enabled on server starts.
|
||||||
|
* @return the configurer for chaining
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Configurer autoEnableOnServerStart(boolean autoEnableOnServerStart);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the position in the
|
||||||
|
* load order of this datapack.
|
||||||
|
*
|
||||||
|
* @param fixed won't move around in the load order as packs are added/removed
|
||||||
|
* @param position try to insert at the top of the order or bottom
|
||||||
|
* @return the configurer for chaining
|
||||||
|
*/
|
||||||
|
@Contract(value = "_, _ -> this", mutates = "this")
|
||||||
|
Configurer position(boolean fixed, Datapack.Position position);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ public sealed interface DatapackSource permits DatapackSourceImpl {
|
|||||||
DatapackSource FEATURE = create("feature");
|
DatapackSource FEATURE = create("feature");
|
||||||
DatapackSource WORLD = create("world");
|
DatapackSource WORLD = create("world");
|
||||||
DatapackSource SERVER = create("server");
|
DatapackSource SERVER = create("server");
|
||||||
|
DatapackSource PLUGIN = create("plugin");
|
||||||
|
|
||||||
private static DatapackSource create(final String name) {
|
private static DatapackSource create(final String name) {
|
||||||
return new DatapackSourceImpl(name);
|
return new DatapackSourceImpl(name);
|
||||||
|
|||||||
@ -0,0 +1,74 @@
|
|||||||
|
package io.papermc.paper.datapack;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
|
import org.bukkit.FeatureFlag;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a snapshot of a datapack that the server has found by
|
||||||
|
* searching available sources. It may or may not be enabled and isn't
|
||||||
|
* guaranteed to be available. This object won't be
|
||||||
|
* updated as datapacks are updated.
|
||||||
|
* @see DatapackRegistrar
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface DiscoveredDatapack {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the name/id of this datapack.
|
||||||
|
*
|
||||||
|
* @return the name of the pack
|
||||||
|
*/
|
||||||
|
@Contract(pure = true)
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the title component of this datapack.
|
||||||
|
*
|
||||||
|
* @return the title
|
||||||
|
*/
|
||||||
|
Component getTitle();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the description component of this datapack.
|
||||||
|
*
|
||||||
|
* @return the description
|
||||||
|
*/
|
||||||
|
Component getDescription();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets if this datapack is required.
|
||||||
|
* <p>
|
||||||
|
* A "required" datapack will always be enabled on server startup, even if previously disabled.
|
||||||
|
*
|
||||||
|
* @return true if the pack is required
|
||||||
|
*/
|
||||||
|
boolean isRequired();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the compatibility status of this pack.
|
||||||
|
*
|
||||||
|
* @return the compatibility of the pack
|
||||||
|
*/
|
||||||
|
Datapack.Compatibility getCompatibility();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the set of required features for this datapack.
|
||||||
|
*
|
||||||
|
* @return the set of required features
|
||||||
|
*/
|
||||||
|
@Unmodifiable
|
||||||
|
Set<FeatureFlag> getRequiredFeatures();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the source for this datapack.
|
||||||
|
*
|
||||||
|
* @return the pack source
|
||||||
|
*/
|
||||||
|
DatapackSource getSource();
|
||||||
|
}
|
||||||
@ -0,0 +1,38 @@
|
|||||||
|
package io.papermc.paper.entity;
|
||||||
|
|
||||||
|
import org.bukkit.UnsafeValues;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents flags for entity serialization.
|
||||||
|
*
|
||||||
|
* @see UnsafeValues#serializeEntity(Entity, EntitySerializationFlag... serializationFlags)
|
||||||
|
* @since 1.21.4
|
||||||
|
*/
|
||||||
|
public enum EntitySerializationFlag {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Serialize entities that wouldn't be serialized normally
|
||||||
|
* (e.g. dead, despawned, non-persistent, etc.).
|
||||||
|
*
|
||||||
|
* @see Entity#isValid()
|
||||||
|
* @see Entity#isPersistent()
|
||||||
|
*/
|
||||||
|
FORCE,
|
||||||
|
/**
|
||||||
|
* Serialize misc non-saveable entities like lighting bolts, fishing bobbers, etc.
|
||||||
|
* <br>Note: players require a separate flag: {@link #PLAYER}.
|
||||||
|
*/
|
||||||
|
MISC,
|
||||||
|
/**
|
||||||
|
* Include passengers in the serialized data.
|
||||||
|
*/
|
||||||
|
PASSENGERS,
|
||||||
|
/**
|
||||||
|
* Allow serializing {@link Player}s.
|
||||||
|
* <p>Note: deserializing player data will always fail.
|
||||||
|
*/
|
||||||
|
PLAYER
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,74 @@
|
|||||||
|
package io.papermc.paper.event.executor;
|
||||||
|
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.EventExecutor;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.lang.constant.ConstantDescs;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
@NullMarked
|
||||||
|
public final class EventExecutorFactory {
|
||||||
|
private static final byte[] TEMPLATE_CLASS_BYTES;
|
||||||
|
|
||||||
|
static {
|
||||||
|
try (final InputStream is = EventExecutorFactory.class.getResourceAsStream("MethodHandleEventExecutorTemplate.class")) {
|
||||||
|
TEMPLATE_CLASS_BYTES = Objects.requireNonNull(is, "template class is missing").readAllBytes();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private EventExecutorFactory() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return an {@link EventExecutor} implemented by a hidden class calling a method handle}
|
||||||
|
*
|
||||||
|
* @param method the method to be invoked by the created event executor
|
||||||
|
* @param eventClass the class of the event to handle
|
||||||
|
*/
|
||||||
|
public static EventExecutor create(final Method method, final Class<? extends Event> eventClass) {
|
||||||
|
final List<?> classData = List.of(method, eventClass);
|
||||||
|
try {
|
||||||
|
final MethodHandles.Lookup newClass = MethodHandles.lookup().defineHiddenClassWithClassData(TEMPLATE_CLASS_BYTES, classData, true);
|
||||||
|
return newClass.lookupClass().asSubclass(EventExecutor.class).getDeclaredConstructor().newInstance();
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
record ClassData(Method method, MethodHandle methodHandle, Class<? extends Event> eventClass) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts the class data and creates an adjusted MethodHandle directly usable by the lookup class.
|
||||||
|
* The logic is kept here to minimize memory usage per created class.
|
||||||
|
*/
|
||||||
|
static ClassData classData(final MethodHandles.Lookup lookup) {
|
||||||
|
try {
|
||||||
|
final Method method = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Method.class, 0);
|
||||||
|
MethodHandle mh = lookup.unreflect(method);
|
||||||
|
if (Modifier.isStatic(method.getModifiers())) {
|
||||||
|
mh = MethodHandles.dropArguments(mh, 0, Listener.class);
|
||||||
|
}
|
||||||
|
mh = mh.asType(MethodType.methodType(void.class, Listener.class, Event.class));
|
||||||
|
final Class<?> eventClass = MethodHandles.classDataAt(lookup, ConstantDescs.DEFAULT_NAME, Class.class, 1);
|
||||||
|
return new ClassData(method, mh, eventClass.asSubclass(Event.class));
|
||||||
|
} catch (ReflectiveOperationException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,56 @@
|
|||||||
|
package io.papermc.paper.event.executor;
|
||||||
|
|
||||||
|
import com.destroystokyo.paper.util.SneakyThrow;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
import org.bukkit.event.EventException;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.EventExecutor;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is designed to be used as hidden class template.
|
||||||
|
* Initializing the class directly will fail due to missing {@code classData}.
|
||||||
|
* Instead, {@link java.lang.invoke.MethodHandles.Lookup#defineHiddenClassWithClassData(byte[], Object, boolean, MethodHandles.Lookup.ClassOption...)}
|
||||||
|
* must be used, with the {@code classData} object being a list consisting of two elements:
|
||||||
|
* <ol>
|
||||||
|
* <li>A {@link Method} representing the event handler method</li>
|
||||||
|
* <li>A {@link Class} representing the event type</li>
|
||||||
|
* </ol>
|
||||||
|
* The method must take {@link Event} or a subtype of it as its single parameter.
|
||||||
|
* If the method is non-static, it also needs to reside in a class implementing {@link Listener}.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
@ApiStatus.Internal
|
||||||
|
@NullMarked
|
||||||
|
class MethodHandleEventExecutorTemplate implements EventExecutor {
|
||||||
|
private static final Method METHOD;
|
||||||
|
private static final MethodHandle HANDLE;
|
||||||
|
private static final Class<? extends Event> EVENT_CLASS;
|
||||||
|
|
||||||
|
static {
|
||||||
|
final MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||||
|
final EventExecutorFactory.ClassData classData = EventExecutorFactory.classData(lookup);
|
||||||
|
METHOD = classData.method();
|
||||||
|
HANDLE = classData.methodHandle();
|
||||||
|
EVENT_CLASS = classData.eventClass();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(final Listener listener, final Event event) throws EventException {
|
||||||
|
if (!EVENT_CLASS.isInstance(event)) return;
|
||||||
|
try {
|
||||||
|
HANDLE.invokeExact(listener, event);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
SneakyThrow.sneaky(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "MethodHandleEventExecutorTemplate['" + METHOD + "']";
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,12 @@
|
|||||||
package io.papermc.paper.plugin.lifecycle.event.types;
|
package io.papermc.paper.plugin.lifecycle.event.types;
|
||||||
|
|
||||||
import io.papermc.paper.command.brigadier.Commands;
|
import io.papermc.paper.command.brigadier.Commands;
|
||||||
|
import io.papermc.paper.datapack.DatapackRegistrar;
|
||||||
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
import io.papermc.paper.plugin.bootstrap.BootstrapContext;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
import io.papermc.paper.plugin.lifecycle.event.LifecycleEvent;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventManager;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
import io.papermc.paper.plugin.lifecycle.event.LifecycleEventOwner;
|
||||||
|
import io.papermc.paper.plugin.lifecycle.event.registrar.RegistrarEvent;
|
||||||
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
import io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
@ -32,6 +34,14 @@ public final class LifecycleEvents {
|
|||||||
*/
|
*/
|
||||||
public static final TagEventTypeProvider TAGS = LifecycleEventTypeProvider.provider().tagProvider();
|
public static final TagEventTypeProvider TAGS = LifecycleEventTypeProvider.provider().tagProvider();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This event is for informing the server about any available datapacks from other sources such as inside a plugin's jar. You
|
||||||
|
* can register a handler for this event only in {@link io.papermc.paper.plugin.bootstrap.PluginBootstrap#bootstrap(BootstrapContext)}.
|
||||||
|
* @see DatapackRegistrar an example of a datapack being discovered
|
||||||
|
*/
|
||||||
|
public static final LifecycleEventType.Prioritizable<BootstrapContext, RegistrarEvent<DatapackRegistrar>> DATAPACK_DISCOVERY = bootstrapPrioritized("datapack_discovery");
|
||||||
|
|
||||||
//<editor-fold desc="helper methods" defaultstate="collapsed">
|
//<editor-fold desc="helper methods" defaultstate="collapsed">
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) {
|
static <E extends LifecycleEvent> LifecycleEventType.Monitorable<Plugin, E> plugin(final String name) {
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
package io.papermc.paper.registry;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
import org.jspecify.annotations.NullMarked;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A factory to create a {@link RegistryBuilder} for a given {@link TypedKey}. For
|
||||||
|
* each instance of this class, once either {@link #empty()} or {@link #copyFrom(TypedKey)}
|
||||||
|
* is called once, any future calls to either method will throw an {@link IllegalStateException}.
|
||||||
|
*
|
||||||
|
* @param <T> The type of the registry
|
||||||
|
* @param <B> The type of the registry builder
|
||||||
|
*/
|
||||||
|
@NullMarked
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface RegistryBuilderFactory<T, B extends RegistryBuilder<T>> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new empty {@link RegistryBuilder}.
|
||||||
|
*
|
||||||
|
* @return A new empty {@link RegistryBuilder}
|
||||||
|
* @throws IllegalStateException if this method or {@link #copyFrom(TypedKey)}) has already been called once
|
||||||
|
*/
|
||||||
|
@Contract("-> new")
|
||||||
|
B empty();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new {@link RegistryBuilder} with the same properties as the given {@link TypedKey}.
|
||||||
|
*
|
||||||
|
* @param key The key to copy properties from
|
||||||
|
* @return A new {@link RegistryBuilder} with the same properties as the given key
|
||||||
|
* @throws IllegalStateException if this method or {@link #empty()} has already been called once
|
||||||
|
* @throws IllegalArgumentException if key doesn't exist
|
||||||
|
*/
|
||||||
|
@Contract("_ -> new")
|
||||||
|
B copyFrom(TypedKey<T> key);
|
||||||
|
}
|
||||||
@ -1,6 +1,8 @@
|
|||||||
package io.papermc.paper.registry;
|
package io.papermc.paper.registry;
|
||||||
|
|
||||||
import io.papermc.paper.datacomponent.DataComponentType;
|
import io.papermc.paper.datacomponent.DataComponentType;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.kyori.adventure.key.KeyPattern;
|
||||||
import net.kyori.adventure.key.Keyed;
|
import net.kyori.adventure.key.Keyed;
|
||||||
import org.bukkit.Art;
|
import org.bukkit.Art;
|
||||||
import org.bukkit.Fluid;
|
import org.bukkit.Fluid;
|
||||||
@ -200,4 +202,26 @@ public sealed interface RegistryKey<T> extends Keyed permits RegistryKeyImpl {
|
|||||||
RegistryKey<Particle> PARTICLE_TYPE = create("particle_type");
|
RegistryKey<Particle> PARTICLE_TYPE = create("particle_type");
|
||||||
RegistryKey<PotionType> POTION = create("potion");
|
RegistryKey<PotionType> POTION = create("potion");
|
||||||
RegistryKey<MemoryKey<?>> MEMORY_MODULE_TYPE = create("memory_module_type");
|
RegistryKey<MemoryKey<?>> MEMORY_MODULE_TYPE = create("memory_module_type");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link TypedKey} for this registry given the typed key's key.
|
||||||
|
*
|
||||||
|
* @param key the key of the typed key.
|
||||||
|
* @return the constructed typed key.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
default TypedKey<T> typedKey(final Key key) {
|
||||||
|
return TypedKey.create(this, key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new {@link TypedKey} for this registry given the typed key's key.
|
||||||
|
*
|
||||||
|
* @param key the string representation of the key that will be passed to {@link Key#key(String)}.
|
||||||
|
* @return the constructed typed key.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
default TypedKey<T> typedKey(final @KeyPattern String key) {
|
||||||
|
return TypedKey.create(this, key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package io.papermc.paper.registry;
|
package io.papermc.paper.registry;
|
||||||
|
|
||||||
import net.kyori.adventure.key.Key;
|
import net.kyori.adventure.key.Key;
|
||||||
|
import net.kyori.adventure.key.KeyPattern;
|
||||||
import net.kyori.adventure.key.Keyed;
|
import net.kyori.adventure.key.Keyed;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
@ -42,4 +43,18 @@ public sealed interface TypedKey<T> extends Key permits TypedKeyImpl {
|
|||||||
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final Key key) {
|
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final Key key) {
|
||||||
return new TypedKeyImpl<>(key, registryKey);
|
return new TypedKeyImpl<>(key, registryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a typed key from a string and a registry key.
|
||||||
|
*
|
||||||
|
* @param registryKey the registry this key is for
|
||||||
|
* @param key the string version of a {@link Key} that will be passed to {@link Key#key(String)} for parsing.
|
||||||
|
* @param <T> value type
|
||||||
|
* @return a new key for the value key and registry key
|
||||||
|
* @see Key#key(String)
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
static <T> TypedKey<T> create(final RegistryKey<T> registryKey, final @KeyPattern String key) {
|
||||||
|
return create(registryKey, Key.key(key));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,65 @@
|
|||||||
|
package io.papermc.paper.registry.data;
|
||||||
|
|
||||||
|
import io.papermc.paper.registry.RegistryBuilder;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
|
import org.bukkit.block.banner.PatternType;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data-centric version-specific registry entry for the {@link PatternType} type.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface BannerPatternRegistryEntry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the asset id of the pattern type, which is the location of the sprite to use.
|
||||||
|
*
|
||||||
|
* @return the asset id.
|
||||||
|
*/
|
||||||
|
Key assetId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the translation key for displaying the pattern inside the banner's tooltip.
|
||||||
|
*
|
||||||
|
* @return the translation key.
|
||||||
|
*/
|
||||||
|
String translationKey();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mutable builder for the {@link BannerPatternRegistryEntry} plugins may change in applicable registry events.
|
||||||
|
* <p>
|
||||||
|
* The following values are required for each builder:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #assetId(Key)}</li>
|
||||||
|
* <li>{@link #translationKey(String)}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
interface Builder extends BannerPatternRegistryEntry, RegistryBuilder<PatternType> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the asset id of the pattern type, which is the location of the sprite to use.
|
||||||
|
*
|
||||||
|
* @param assetId the asset id.
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see BannerPatternRegistryEntry#assetId()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder assetId(Key assetId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the translation key for displaying the pattern inside the banner's tooltip.
|
||||||
|
*
|
||||||
|
* @param translationKey the translation key.
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see BannerPatternRegistryEntry#translationKey()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder translationKey(String translationKey);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,120 @@
|
|||||||
|
package io.papermc.paper.registry.data;
|
||||||
|
|
||||||
|
import io.papermc.paper.registry.RegistryBuilder;
|
||||||
|
import org.bukkit.damage.DamageEffect;
|
||||||
|
import org.bukkit.damage.DamageScaling;
|
||||||
|
import org.bukkit.damage.DamageType;
|
||||||
|
import org.bukkit.damage.DeathMessageType;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
import org.jetbrains.annotations.Contract;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A data-centric version-specific registry entry for the {@link DamageType} type.
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface DamageTypeRegistryEntry {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides part of the death message translation key. (death.attack.<message_id>)
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong> The translation key is only used if
|
||||||
|
* {@link #deathMessageType()} is {@link DeathMessageType#DEFAULT}
|
||||||
|
*
|
||||||
|
* @return part of the translation key
|
||||||
|
*/
|
||||||
|
String messageId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the amount of hunger exhaustion caused by this damage type.
|
||||||
|
*
|
||||||
|
* @return the exhaustion
|
||||||
|
*/
|
||||||
|
float exhaustion();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@link DamageScaling} for this damage type.
|
||||||
|
*
|
||||||
|
* @return the damage scaling
|
||||||
|
*/
|
||||||
|
DamageScaling damageScaling();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@link DamageEffect} for this damage type.
|
||||||
|
*
|
||||||
|
* @return the damage effect
|
||||||
|
*/
|
||||||
|
DamageEffect damageEffect();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the {@link DeathMessageType} for this damage type.
|
||||||
|
*
|
||||||
|
* @return the death message type
|
||||||
|
*/
|
||||||
|
DeathMessageType deathMessageType();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mutable builder for the {@link DamageTypeRegistryEntry} plugins may change in applicable registry events.
|
||||||
|
* <p>
|
||||||
|
* The following values are required for each builder:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link #messageId(String)}</li>
|
||||||
|
* <li>{@link #exhaustion(float)}</li>
|
||||||
|
* <li>{@link #damageScaling(DamageScaling)}</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
interface Builder extends DamageTypeRegistryEntry, RegistryBuilder<DamageType> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets part of the death message translation key.
|
||||||
|
*
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see DamageTypeRegistryEntry#messageId()
|
||||||
|
* @see DamageType#getTranslationKey()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder messageId(String messageId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the amount of hunger exhaustion caused by this damage type.
|
||||||
|
*
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see DamageTypeRegistryEntry#exhaustion()
|
||||||
|
* @see DamageType#getExhaustion()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder exhaustion(float exhaustion);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DamageScaling} for this damage type.
|
||||||
|
*
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see DamageTypeRegistryEntry#damageScaling()
|
||||||
|
* @see DamageType#getDamageScaling()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder damageScaling(DamageScaling scaling);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DamageEffect} for this damage type.
|
||||||
|
*
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see DamageTypeRegistryEntry#damageEffect()
|
||||||
|
* @see DamageType#getDamageEffect()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder damageEffect(DamageEffect effect);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the {@link DeathMessageType} for this damage type.
|
||||||
|
*
|
||||||
|
* @return this builder instance.
|
||||||
|
* @see DamageTypeRegistryEntry#deathMessageType()
|
||||||
|
* @see DamageType#getDeathMessageType()
|
||||||
|
*/
|
||||||
|
@Contract(value = "_ -> this", mutates = "this")
|
||||||
|
Builder deathMessageType(DeathMessageType deathMessageType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,22 @@
|
|||||||
|
package io.papermc.paper.registry.data;
|
||||||
|
|
||||||
|
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.ServiceLoader;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import org.bukkit.Art;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
@ApiStatus.NonExtendable
|
||||||
|
public interface InlinedRegistryBuilderProvider {
|
||||||
|
|
||||||
|
static InlinedRegistryBuilderProvider instance() {
|
||||||
|
class Holder {
|
||||||
|
static final Optional<InlinedRegistryBuilderProvider> INSTANCE = ServiceLoader.load(InlinedRegistryBuilderProvider.class).findFirst();
|
||||||
|
}
|
||||||
|
return Holder.INSTANCE.orElseThrow();
|
||||||
|
}
|
||||||
|
|
||||||
|
Art createPaintingVariant(Consumer<RegistryBuilderFactory<Art, ? extends PaintingVariantRegistryEntry.Builder>> value);
|
||||||
|
}
|
||||||
@ -1,11 +1,15 @@
|
|||||||
package io.papermc.paper.registry.event;
|
package io.papermc.paper.registry.event;
|
||||||
|
|
||||||
import io.papermc.paper.registry.RegistryKey;
|
import io.papermc.paper.registry.RegistryKey;
|
||||||
|
import io.papermc.paper.registry.data.BannerPatternRegistryEntry;
|
||||||
|
import io.papermc.paper.registry.data.DamageTypeRegistryEntry;
|
||||||
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
|
import io.papermc.paper.registry.data.EnchantmentRegistryEntry;
|
||||||
import io.papermc.paper.registry.data.GameEventRegistryEntry;
|
import io.papermc.paper.registry.data.GameEventRegistryEntry;
|
||||||
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
|
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
|
||||||
import org.bukkit.Art;
|
import org.bukkit.Art;
|
||||||
import org.bukkit.GameEvent;
|
import org.bukkit.GameEvent;
|
||||||
|
import org.bukkit.block.banner.PatternType;
|
||||||
|
import org.bukkit.damage.DamageType;
|
||||||
import org.bukkit.enchantments.Enchantment;
|
import org.bukkit.enchantments.Enchantment;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jspecify.annotations.NullMarked;
|
import org.jspecify.annotations.NullMarked;
|
||||||
@ -23,6 +27,8 @@ public final class RegistryEvents {
|
|||||||
public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT);
|
public static final RegistryEventProvider<GameEvent, GameEventRegistryEntry.Builder> GAME_EVENT = create(RegistryKey.GAME_EVENT);
|
||||||
public static final RegistryEventProvider<Enchantment, EnchantmentRegistryEntry.Builder> ENCHANTMENT = create(RegistryKey.ENCHANTMENT);
|
public static final RegistryEventProvider<Enchantment, EnchantmentRegistryEntry.Builder> ENCHANTMENT = create(RegistryKey.ENCHANTMENT);
|
||||||
public static final RegistryEventProvider<Art, PaintingVariantRegistryEntry.Builder> PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT);
|
public static final RegistryEventProvider<Art, PaintingVariantRegistryEntry.Builder> PAINTING_VARIANT = create(RegistryKey.PAINTING_VARIANT);
|
||||||
|
public static final RegistryEventProvider<PatternType, BannerPatternRegistryEntry.Builder> BANNER_PATTERN = create(RegistryKey.BANNER_PATTERN);
|
||||||
|
public static final RegistryEventProvider<DamageType, DamageTypeRegistryEntry.Builder> DAMAGE_TYPE = create(RegistryKey.DAMAGE_TYPE);
|
||||||
|
|
||||||
private RegistryEvents() {
|
private RegistryEvents() {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package io.papermc.paper.registry.event;
|
package io.papermc.paper.registry.event;
|
||||||
|
|
||||||
import io.papermc.paper.registry.RegistryBuilder;
|
import io.papermc.paper.registry.RegistryBuilder;
|
||||||
|
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||||
import io.papermc.paper.registry.TypedKey;
|
import io.papermc.paper.registry.TypedKey;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
@ -24,5 +25,18 @@ public interface WritableRegistry<T, B extends RegistryBuilder<T>> {
|
|||||||
* @param key the entry's key (must be unique from others)
|
* @param key the entry's key (must be unique from others)
|
||||||
* @param value a consumer for the entry's builder
|
* @param value a consumer for the entry's builder
|
||||||
*/
|
*/
|
||||||
void register(TypedKey<T> key, Consumer<? super B> value);
|
default void register(final TypedKey<T> key, final Consumer<? super B> value) {
|
||||||
|
this.registerWith(key, factory -> value.accept(factory.empty()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a new value with the specified key. This will
|
||||||
|
* fire a {@link RegistryEntryAddEvent} for the new entry. The
|
||||||
|
* {@link RegistryBuilderFactory} lets you pre-fill a builder with
|
||||||
|
* an already-existing entry's properties.
|
||||||
|
*
|
||||||
|
* @param key the entry's key (must be unique from others)
|
||||||
|
* @param value a consumer of a builder factory
|
||||||
|
*/
|
||||||
|
void registerWith(TypedKey<T> key, Consumer<RegistryBuilderFactory<T, B>> value);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,9 +2,14 @@ package org.bukkit;
|
|||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import io.papermc.paper.registry.RegistryBuilderFactory;
|
||||||
|
import io.papermc.paper.registry.data.InlinedRegistryBuilderProvider;
|
||||||
|
import io.papermc.paper.registry.data.PaintingVariantRegistryEntry;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import org.bukkit.packs.DataPack;
|
import org.bukkit.packs.DataPack;
|
||||||
import org.bukkit.util.OldEnum;
|
import org.bukkit.util.OldEnum;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -18,6 +23,17 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
*/
|
*/
|
||||||
public interface Art extends OldEnum<Art>, Keyed {
|
public interface Art extends OldEnum<Art>, Keyed {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create an inlined painting variant.
|
||||||
|
*
|
||||||
|
* @param value a consumer for the builder factory
|
||||||
|
* @return the created painting variant
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
static @NotNull Art create(final @NotNull Consumer<RegistryBuilderFactory<Art, ? extends PaintingVariantRegistryEntry.Builder>> value) {
|
||||||
|
return InlinedRegistryBuilderProvider.instance().createPaintingVariant(value);
|
||||||
|
}
|
||||||
|
|
||||||
Art KEBAB = getArt("kebab");
|
Art KEBAB = getArt("kebab");
|
||||||
Art AZTEC = getArt("aztec");
|
Art AZTEC = getArt("aztec");
|
||||||
Art ALBAN = getArt("alban");
|
Art ALBAN = getArt("alban");
|
||||||
|
|||||||
@ -1184,7 +1184,7 @@ public final class Bukkit {
|
|||||||
* @return the {@link Recipe} resulting from the given crafting matrix.
|
* @return the {@link Recipe} resulting from the given crafting matrix.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Recipe getCraftingRecipe(@NotNull ItemStack[] craftingMatrix, @NotNull World world) {
|
public static Recipe getCraftingRecipe(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world) {
|
||||||
return server.getCraftingRecipe(craftingMatrix, world);
|
return server.getCraftingRecipe(craftingMatrix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1213,7 +1213,7 @@ public final class Bukkit {
|
|||||||
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player) {
|
public static ItemCraftResult craftItemResult(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world, @NotNull Player player) {
|
||||||
return server.craftItemResult(craftingMatrix, world, player);
|
return server.craftItemResult(craftingMatrix, world, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1235,7 +1235,7 @@ public final class Bukkit {
|
|||||||
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world) {
|
public static ItemCraftResult craftItemResult(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world) {
|
||||||
return server.craftItemResult(craftingMatrix, world);
|
return server.craftItemResult(craftingMatrix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1266,7 +1266,7 @@ public final class Bukkit {
|
|||||||
* an ItemStack of {@link Material#AIR} is returned.
|
* an ItemStack of {@link Material#AIR} is returned.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player) {
|
public static ItemStack craftItem(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world, @NotNull Player player) {
|
||||||
return server.craftItem(craftingMatrix, world, player);
|
return server.craftItem(craftingMatrix, world, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1289,7 +1289,7 @@ public final class Bukkit {
|
|||||||
* an ItemStack of {@link Material#AIR} is returned.
|
* an ItemStack of {@link Material#AIR} is returned.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public static ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world) {
|
public static ItemStack craftItem(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world) {
|
||||||
return server.craftItem(craftingMatrix, world);
|
return server.craftItem(craftingMatrix, world);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1756,8 +1756,7 @@ public final class Bukkit {
|
|||||||
*
|
*
|
||||||
* @return an array containing all previous players
|
* @return an array containing all previous players
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static @NotNull OfflinePlayer @NotNull [] getOfflinePlayers() {
|
||||||
public static OfflinePlayer[] getOfflinePlayers() {
|
|
||||||
return server.getOfflinePlayers();
|
return server.getOfflinePlayers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2404,8 +2403,7 @@ public final class Bukkit {
|
|||||||
* Gets the current server TPS
|
* Gets the current server TPS
|
||||||
* @return current server TPS (1m, 5m, 15m in Paper-Server)
|
* @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static double @NotNull [] getTPS() {
|
||||||
public static double[] getTPS() {
|
|
||||||
return server.getTPS();
|
return server.getTPS();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2414,8 +2412,7 @@ public final class Bukkit {
|
|||||||
*
|
*
|
||||||
* @return A sample of the servers last tick times (in nanos)
|
* @return A sample of the servers last tick times (in nanos)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static long @NotNull [] getTickTimes() {
|
||||||
public static long[] getTickTimes() {
|
|
||||||
return server.getTickTimes();
|
return server.getTickTimes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -133,8 +133,7 @@ public interface Chunk extends PersistentDataHolder {
|
|||||||
*
|
*
|
||||||
* @return The entities.
|
* @return The entities.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull Entity @NotNull [] getEntities();
|
||||||
Entity[] getEntities();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of all tile entities in the chunk.
|
* Get a list of all tile entities in the chunk.
|
||||||
@ -143,7 +142,7 @@ public interface Chunk extends PersistentDataHolder {
|
|||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
// Paper start
|
// Paper start
|
||||||
default BlockState[] getTileEntities() {
|
default BlockState @NotNull [] getTileEntities() {
|
||||||
return getTileEntities(true);
|
return getTileEntities(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +153,7 @@ public interface Chunk extends PersistentDataHolder {
|
|||||||
* @return The tile entities.
|
* @return The tile entities.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
BlockState[] getTileEntities(boolean useSnapshot);
|
BlockState @NotNull [] getTileEntities(boolean useSnapshot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a list of all tile entities that match a given predicate in the chunk.
|
* Get a list of all tile entities that match a given predicate in the chunk.
|
||||||
|
|||||||
@ -3,13 +3,22 @@ package org.bukkit;
|
|||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import io.papermc.paper.datacomponent.DataComponentType;
|
||||||
|
import io.papermc.paper.registry.RegistryAccess;
|
||||||
|
import io.papermc.paper.registry.RegistryKey;
|
||||||
|
import io.papermc.paper.registry.TypedKey;
|
||||||
|
import io.papermc.paper.registry.tag.Tag;
|
||||||
|
import io.papermc.paper.registry.tag.TagKey;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import java.util.stream.StreamSupport;
|
import java.util.stream.StreamSupport;
|
||||||
|
import net.kyori.adventure.key.Key;
|
||||||
import org.bukkit.advancement.Advancement;
|
import org.bukkit.advancement.Advancement;
|
||||||
import org.bukkit.attribute.Attribute;
|
import org.bukkit.attribute.Attribute;
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
@ -35,8 +44,8 @@ import org.bukkit.map.MapCursor;
|
|||||||
import org.bukkit.potion.PotionEffectType;
|
import org.bukkit.potion.PotionEffectType;
|
||||||
import org.bukkit.potion.PotionType;
|
import org.bukkit.potion.PotionType;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jspecify.annotations.NullMarked;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a registry of Bukkit objects that may be retrieved by
|
* Represents a registry of Bukkit objects that may be retrieved by
|
||||||
@ -44,39 +53,34 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
*
|
*
|
||||||
* @param <T> type of item in the registry
|
* @param <T> type of item in the registry
|
||||||
*/
|
*/
|
||||||
|
@NullMarked
|
||||||
public interface Registry<T extends Keyed> extends Iterable<T> {
|
public interface Registry<T extends Keyed> extends Iterable<T> {
|
||||||
|
|
||||||
|
private static <A extends Keyed> Registry<A> registryFor(final RegistryKey<A> registryKey) {
|
||||||
|
return RegistryAccess.registryAccess().getRegistry(registryKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("removal")
|
||||||
|
@Deprecated(forRemoval = true, since = "1.21.4")
|
||||||
|
private static <A extends Keyed> Registry<A> legacyRegistryFor(final Class<A> clazz) {
|
||||||
|
return Objects.requireNonNull(RegistryAccess.registryAccess().getRegistry(clazz), "No registry present for " + clazz.getSimpleName() + ". This is a bug.");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Server advancements.
|
* Server advancements.
|
||||||
*
|
*
|
||||||
* @see Bukkit#getAdvancement(org.bukkit.NamespacedKey)
|
* @see Bukkit#getAdvancement(NamespacedKey)
|
||||||
* @see Bukkit#advancementIterator()
|
* @see Bukkit#advancementIterator()
|
||||||
|
* @deprecated use {@link Bukkit#getAdvancement(NamespacedKey)} and {@link Bukkit#advancementIterator()}
|
||||||
*/
|
*/
|
||||||
Registry<Advancement> ADVANCEMENT = new Registry<Advancement>() {
|
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||||
|
Registry<Advancement> ADVANCEMENT = new NotARegistry<>() {
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public Advancement get(@NotNull NamespacedKey key) {
|
public @Nullable Advancement get(final NamespacedKey key) {
|
||||||
return Bukkit.getAdvancement(key);
|
return Bukkit.getAdvancement(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Advancement getOrThrow(@NotNull NamespacedKey key) {
|
|
||||||
Advancement advancement = get(key);
|
|
||||||
|
|
||||||
Preconditions.checkArgument(advancement != null, "No Advancement registry entry found for key %s.", key);
|
|
||||||
|
|
||||||
return advancement;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Stream<Advancement> stream() {
|
|
||||||
return StreamSupport.stream(spliterator(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<Advancement> iterator() {
|
public Iterator<Advancement> iterator() {
|
||||||
return Bukkit.advancementIterator();
|
return Bukkit.advancementIterator();
|
||||||
@ -86,71 +90,54 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* Server art.
|
* Server art.
|
||||||
*
|
*
|
||||||
* @see Art
|
* @see Art
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#PAINTING_VARIANT}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#PAINTING_VARIANT}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.21.3") // Paper
|
@Deprecated(since = "1.21.3") // Paper
|
||||||
Registry<Art> ART = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Art.class), "No registry present for Art. This is a bug.");
|
Registry<Art> ART = legacyRegistryFor(Art.class);
|
||||||
/**
|
/**
|
||||||
* Attribute.
|
* Attribute.
|
||||||
*
|
*
|
||||||
* @see Attribute
|
* @see Attribute
|
||||||
*/
|
*/
|
||||||
Registry<Attribute> ATTRIBUTE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ATTRIBUTE); // Paper
|
Registry<Attribute> ATTRIBUTE = registryFor(RegistryKey.ATTRIBUTE);
|
||||||
/**
|
/**
|
||||||
* Server banner patterns.
|
* Server banner patterns.
|
||||||
*
|
*
|
||||||
* @see PatternType
|
* @see PatternType
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BANNER_PATTERN}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BANNER_PATTERN}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.21") // Paper
|
@Deprecated(since = "1.21") // Paper
|
||||||
Registry<PatternType> BANNER_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(PatternType.class), "No registry present for PatternType. This is a bug."); // Paper
|
Registry<PatternType> BANNER_PATTERN = legacyRegistryFor(PatternType.class);
|
||||||
/**
|
/**
|
||||||
* Server biomes.
|
* Server biomes.
|
||||||
*
|
*
|
||||||
* @see Biome
|
* @see Biome
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#BIOME}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#BIOME}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.21.3") // Paper
|
@Deprecated(since = "1.21.3") // Paper
|
||||||
Registry<Biome> BIOME = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Biome.class), "No registry present for Biome. This is a bug.");
|
Registry<Biome> BIOME = legacyRegistryFor(Biome.class);
|
||||||
/**
|
/**
|
||||||
* Server block types.
|
* Server block types.
|
||||||
*
|
*
|
||||||
* @see BlockType
|
* @see BlockType
|
||||||
* @apiNote BlockType is not ready for public usage yet
|
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Experimental
|
||||||
Registry<BlockType> BLOCK = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.BLOCK); // Paper
|
Registry<BlockType> BLOCK = registryFor(RegistryKey.BLOCK);
|
||||||
/**
|
/**
|
||||||
* Custom boss bars.
|
* Custom boss bars.
|
||||||
*
|
*
|
||||||
* @see Bukkit#getBossBar(org.bukkit.NamespacedKey)
|
* @see Bukkit#getBossBar(org.bukkit.NamespacedKey)
|
||||||
* @see Bukkit#getBossBars()
|
* @see Bukkit#getBossBars()
|
||||||
|
* @deprecated use {@link Bukkit#getBossBar(NamespacedKey)} and {@link Bukkit#getBossBars()}
|
||||||
*/
|
*/
|
||||||
Registry<KeyedBossBar> BOSS_BARS = new Registry<KeyedBossBar>() {
|
@Deprecated(since = "1.21.4", forRemoval = true)
|
||||||
|
Registry<KeyedBossBar> BOSS_BARS = new NotARegistry<>() {
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public KeyedBossBar get(@NotNull NamespacedKey key) {
|
public @Nullable KeyedBossBar get(final NamespacedKey key) {
|
||||||
return Bukkit.getBossBar(key);
|
return Bukkit.getBossBar(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public KeyedBossBar getOrThrow(@NotNull NamespacedKey key) {
|
|
||||||
KeyedBossBar keyedBossBar = get(key);
|
|
||||||
|
|
||||||
Preconditions.checkArgument(keyedBossBar != null, "No KeyedBossBar registry entry found for key %s.", key);
|
|
||||||
|
|
||||||
return keyedBossBar;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Stream<KeyedBossBar> stream() {
|
|
||||||
return StreamSupport.stream(spliterator(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<KeyedBossBar> iterator() {
|
public Iterator<KeyedBossBar> iterator() {
|
||||||
return Bukkit.getBossBars();
|
return Bukkit.getBossBars();
|
||||||
@ -161,37 +148,36 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
*
|
*
|
||||||
* @see Cat.Type
|
* @see Cat.Type
|
||||||
*/
|
*/
|
||||||
Registry<Cat.Type> CAT_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.CAT_VARIANT); // Paper
|
Registry<Cat.Type> CAT_VARIANT = registryFor(RegistryKey.CAT_VARIANT);
|
||||||
/**
|
/**
|
||||||
* Server enchantments.
|
* Server enchantments.
|
||||||
*
|
*
|
||||||
* @see Enchantment
|
* @see Enchantment
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#ENCHANTMENT}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#ENCHANTMENT}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.21")
|
@Deprecated(since = "1.21")
|
||||||
Registry<Enchantment> ENCHANTMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Enchantment.class), "No registry present for Enchantment. This is a bug."); // Paper
|
Registry<Enchantment> ENCHANTMENT = legacyRegistryFor(Enchantment.class);
|
||||||
/**
|
/**
|
||||||
* Server entity types.
|
* Server entity types.
|
||||||
*
|
*
|
||||||
* @see EntityType
|
* @see EntityType
|
||||||
*/
|
*/
|
||||||
Registry<EntityType> ENTITY_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ENTITY_TYPE); // Paper
|
Registry<EntityType> ENTITY_TYPE = registryFor(RegistryKey.ENTITY_TYPE);
|
||||||
/**
|
/**
|
||||||
* Server instruments.
|
* Server instruments.
|
||||||
*
|
*
|
||||||
* @see MusicInstrument
|
* @see MusicInstrument
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#INSTRUMENT}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#INSTRUMENT}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.21.2")
|
@Deprecated(since = "1.21.2")
|
||||||
Registry<MusicInstrument> INSTRUMENT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(MusicInstrument.class), "No registry present for Instruments. This is a bug."); // Paper
|
Registry<MusicInstrument> INSTRUMENT = legacyRegistryFor(MusicInstrument.class);
|
||||||
/**
|
/**
|
||||||
* Server item types.
|
* Server item types.
|
||||||
*
|
*
|
||||||
* @see ItemType
|
* @see ItemType
|
||||||
* @apiNote ItemType is not ready for public usage yet
|
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Experimental
|
||||||
Registry<ItemType> ITEM = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.ITEM); // Paper
|
Registry<ItemType> ITEM = registryFor(RegistryKey.ITEM);
|
||||||
/**
|
/**
|
||||||
* Default server loot tables.
|
* Default server loot tables.
|
||||||
*
|
*
|
||||||
@ -210,25 +196,25 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* @see MenuType
|
* @see MenuType
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
Registry<MenuType> MENU = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MENU); // Paper
|
Registry<MenuType> MENU = registryFor(RegistryKey.MENU);
|
||||||
/**
|
/**
|
||||||
* Server mob effects.
|
* Server mob effects.
|
||||||
*
|
*
|
||||||
* @see PotionEffectType
|
* @see PotionEffectType
|
||||||
*/
|
*/
|
||||||
Registry<PotionEffectType> EFFECT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MOB_EFFECT); // Paper
|
Registry<PotionEffectType> MOB_EFFECT = registryFor(RegistryKey.MOB_EFFECT);
|
||||||
/**
|
/**
|
||||||
* Server particles.
|
* Server particles.
|
||||||
*
|
*
|
||||||
* @see Particle
|
* @see Particle
|
||||||
*/
|
*/
|
||||||
Registry<Particle> PARTICLE_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.PARTICLE_TYPE); // Paper
|
Registry<Particle> PARTICLE_TYPE = registryFor(RegistryKey.PARTICLE_TYPE); // Paper
|
||||||
/**
|
/**
|
||||||
* Server potions.
|
* Server potions.
|
||||||
*
|
*
|
||||||
* @see PotionType
|
* @see PotionType
|
||||||
*/
|
*/
|
||||||
Registry<PotionType> POTION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.POTION); // Paper
|
Registry<PotionType> POTION = registryFor(RegistryKey.POTION); // Paper
|
||||||
/**
|
/**
|
||||||
* Server statistics.
|
* Server statistics.
|
||||||
*
|
*
|
||||||
@ -239,160 +225,161 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* Server structures.
|
* Server structures.
|
||||||
*
|
*
|
||||||
* @see Structure
|
* @see Structure
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#STRUCTURE}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#STRUCTURE}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.20.6") // Paper
|
@Deprecated(since = "1.20.6") // Paper
|
||||||
Registry<Structure> STRUCTURE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Structure.class), "No registry present for Structure. This is a bug."); // Paper
|
Registry<Structure> STRUCTURE = legacyRegistryFor(Structure.class);
|
||||||
/**
|
/**
|
||||||
* Server structure types.
|
* Server structure types.
|
||||||
*
|
*
|
||||||
* @see StructureType
|
* @see StructureType
|
||||||
*/
|
*/
|
||||||
Registry<StructureType> STRUCTURE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.STRUCTURE_TYPE), "No registry present for StructureType. This is a bug."); // Paper
|
Registry<StructureType> STRUCTURE_TYPE = registryFor(RegistryKey.STRUCTURE_TYPE);
|
||||||
/**
|
/**
|
||||||
* Sound keys.
|
* Sound events.
|
||||||
*
|
*
|
||||||
* @see Sound
|
* @see Sound
|
||||||
*/
|
*/
|
||||||
Registry<Sound> SOUNDS = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.SOUND_EVENT); // Paper
|
Registry<Sound> SOUND_EVENT = registryFor(RegistryKey.SOUND_EVENT);
|
||||||
/**
|
/**
|
||||||
* Trim materials.
|
* Trim materials.
|
||||||
*
|
*
|
||||||
* @see TrimMaterial
|
* @see TrimMaterial
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_MATERIAL}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_MATERIAL}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.20.6") // Paper
|
@Deprecated(since = "1.20.6") // Paper
|
||||||
Registry<TrimMaterial> TRIM_MATERIAL = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimMaterial.class), "No registry present for TrimMaterial. This is a bug."); // Paper
|
Registry<TrimMaterial> TRIM_MATERIAL = legacyRegistryFor(TrimMaterial.class);
|
||||||
/**
|
/**
|
||||||
* Trim patterns.
|
* Trim patterns.
|
||||||
*
|
*
|
||||||
* @see TrimPattern
|
* @see TrimPattern
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#TRIM_PATTERN}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#TRIM_PATTERN}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.20.6")
|
@Deprecated(since = "1.20.6")
|
||||||
Registry<TrimPattern> TRIM_PATTERN = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(TrimPattern.class), "No registry present for TrimPattern. This is a bug."); // Paper
|
Registry<TrimPattern> TRIM_PATTERN = legacyRegistryFor(TrimPattern.class);
|
||||||
/**
|
/**
|
||||||
* Damage types.
|
* Damage types.
|
||||||
*
|
*
|
||||||
* @see DamageType
|
* @see DamageType
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#DAMAGE_TYPE}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#DAMAGE_TYPE}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.20.6")
|
@Deprecated(since = "1.20.6")
|
||||||
Registry<DamageType> DAMAGE_TYPE = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(DamageType.class), "No registry present for DamageType. This is a bug."); // Paper
|
Registry<DamageType> DAMAGE_TYPE = legacyRegistryFor(DamageType.class);
|
||||||
/**
|
/**
|
||||||
* Jukebox songs.
|
* Jukebox songs.
|
||||||
*
|
*
|
||||||
* @see JukeboxSong
|
* @see JukeboxSong
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#JUKEBOX_SONG}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#JUKEBOX_SONG}
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
@Deprecated(since = "1.21")
|
@Deprecated(since = "1.21")
|
||||||
Registry<JukeboxSong> JUKEBOX_SONG = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(JukeboxSong.class), "No registry present for JukeboxSong. This is a bug."); // Paper
|
Registry<JukeboxSong> JUKEBOX_SONG = legacyRegistryFor(JukeboxSong.class);
|
||||||
/**
|
/**
|
||||||
* Villager profession.
|
* Villager profession.
|
||||||
*
|
*
|
||||||
* @see Villager.Profession
|
* @see Villager.Profession
|
||||||
*/
|
*/
|
||||||
Registry<Villager.Profession> VILLAGER_PROFESSION = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_PROFESSION); // Paper
|
Registry<Villager.Profession> VILLAGER_PROFESSION = registryFor(RegistryKey.VILLAGER_PROFESSION);
|
||||||
/**
|
/**
|
||||||
* Villager type.
|
* Villager type.
|
||||||
*
|
*
|
||||||
* @see Villager.Type
|
* @see Villager.Type
|
||||||
*/
|
*/
|
||||||
Registry<Villager.Type> VILLAGER_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.VILLAGER_TYPE); // Paper
|
Registry<Villager.Type> VILLAGER_TYPE = registryFor(RegistryKey.VILLAGER_TYPE);
|
||||||
/**
|
/**
|
||||||
* Memory Keys.
|
* Memory Keys.
|
||||||
*
|
*
|
||||||
* @see MemoryKey
|
* @see MemoryKey
|
||||||
*/
|
*/
|
||||||
Registry<MemoryKey> MEMORY_MODULE_TYPE = new Registry<MemoryKey>() {
|
Registry<MemoryKey> MEMORY_MODULE_TYPE = new NotARegistry<>() {
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator iterator() {
|
public Iterator iterator() {
|
||||||
return MemoryKey.values().iterator();
|
return MemoryKey.values().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public MemoryKey get(@NotNull NamespacedKey key) {
|
public @Nullable MemoryKey get(final NamespacedKey key) {
|
||||||
return MemoryKey.getByKey(key);
|
return MemoryKey.getByKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public MemoryKey getOrThrow(@NotNull NamespacedKey key) {
|
|
||||||
MemoryKey memoryKey = get(key);
|
|
||||||
|
|
||||||
Preconditions.checkArgument(memoryKey != null, "No MemoryKey registry entry found for key %s.", key);
|
|
||||||
|
|
||||||
return memoryKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Stream<MemoryKey> stream() {
|
|
||||||
return StreamSupport.stream(spliterator(), false);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Server fluids.
|
* Server fluids.
|
||||||
*
|
*
|
||||||
* @see Fluid
|
* @see Fluid
|
||||||
*/
|
*/
|
||||||
Registry<Fluid> FLUID = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FLUID); // Paper
|
Registry<Fluid> FLUID = registryFor(RegistryKey.FLUID);
|
||||||
/**
|
/**
|
||||||
* Frog variants.
|
* Frog variants.
|
||||||
*
|
*
|
||||||
* @see Frog.Variant
|
* @see Frog.Variant
|
||||||
*/
|
*/
|
||||||
Registry<Frog.Variant> FROG_VARIANT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.FROG_VARIANT); // Paper
|
Registry<Frog.Variant> FROG_VARIANT = registryFor(RegistryKey.FROG_VARIANT);
|
||||||
/**
|
/**
|
||||||
* Wolf variants.
|
* Wolf variants.
|
||||||
*
|
*
|
||||||
* @see Wolf.Variant
|
* @see Wolf.Variant
|
||||||
* @deprecated use {@link io.papermc.paper.registry.RegistryAccess#getRegistry(io.papermc.paper.registry.RegistryKey)} with {@link io.papermc.paper.registry.RegistryKey#WOLF_VARIANT}
|
* @deprecated use {@link RegistryAccess#getRegistry(RegistryKey)} with {@link RegistryKey#WOLF_VARIANT}
|
||||||
*/
|
*/
|
||||||
@Deprecated(since = "1.20.6")
|
@Deprecated(since = "1.20.6")
|
||||||
Registry<Wolf.Variant> WOLF_VARIANT = Objects.requireNonNull(io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(Wolf.Variant.class), "No registry present for Wolf$Variant. This is a bug."); // Paper
|
Registry<Wolf.Variant> WOLF_VARIANT = legacyRegistryFor(Wolf.Variant.class);
|
||||||
/**
|
/**
|
||||||
* Map cursor types.
|
* Map cursor types.
|
||||||
*
|
*
|
||||||
* @see MapCursor.Type
|
* @see MapCursor.Type
|
||||||
*/
|
*/
|
||||||
Registry<MapCursor.Type> MAP_DECORATION_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.MAP_DECORATION_TYPE); // Paper
|
Registry<MapCursor.Type> MAP_DECORATION_TYPE = registryFor(RegistryKey.MAP_DECORATION_TYPE);
|
||||||
/**
|
/**
|
||||||
* Game events.
|
* Game events.
|
||||||
*
|
*
|
||||||
* @see GameEvent
|
* @see GameEvent
|
||||||
|
* @see io.papermc.paper.registry.event.RegistryEvents#GAME_EVENT
|
||||||
*/
|
*/
|
||||||
Registry<GameEvent> GAME_EVENT = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.GAME_EVENT); // Paper
|
Registry<GameEvent> GAME_EVENT = registryFor(RegistryKey.GAME_EVENT);
|
||||||
|
/**
|
||||||
|
* Data component types.
|
||||||
|
*
|
||||||
|
* @see DataComponentType
|
||||||
|
*/
|
||||||
|
Registry<DataComponentType> DATA_COMPONENT_TYPE = registryFor(RegistryKey.DATA_COMPONENT_TYPE); // Paper
|
||||||
|
|
||||||
// Paper start - potion effect type registry
|
//<editor-fold desc="renames" defaultstate="collapsed">
|
||||||
/**
|
/**
|
||||||
* Potion effect types.
|
* @apiNote use {@link #MOB_EFFECT} instead
|
||||||
*
|
* @hidden
|
||||||
* @see org.bukkit.potion.PotionEffectType
|
|
||||||
*/
|
*/
|
||||||
|
@ApiStatus.Obsolete(since = "1.21.4")
|
||||||
|
Registry<PotionEffectType> EFFECT = MOB_EFFECT;
|
||||||
|
/**
|
||||||
|
* @apiNote use {@link #MOB_EFFECT} instead
|
||||||
|
* @hidden
|
||||||
|
*/
|
||||||
|
@ApiStatus.Obsolete(since = "1.21.4")
|
||||||
Registry<org.bukkit.potion.PotionEffectType> POTION_EFFECT_TYPE = EFFECT;
|
Registry<org.bukkit.potion.PotionEffectType> POTION_EFFECT_TYPE = EFFECT;
|
||||||
// Paper end - potion effect type registry
|
|
||||||
Registry<io.papermc.paper.datacomponent.DataComponentType> DATA_COMPONENT_TYPE = io.papermc.paper.registry.RegistryAccess.registryAccess().getRegistry(io.papermc.paper.registry.RegistryKey.DATA_COMPONENT_TYPE); // Paper
|
|
||||||
/**
|
/**
|
||||||
* Get the object by its key.
|
* @apiNote use {@link #SOUND_EVENT}
|
||||||
*
|
* @hidden
|
||||||
* @param key non-null key
|
|
||||||
* @return item or null if does not exist
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@ApiStatus.Obsolete(since = "1.21.4")
|
||||||
T get(@NotNull NamespacedKey key);
|
Registry<Sound> SOUNDS = registryFor(RegistryKey.SOUND_EVENT);
|
||||||
// Paper start
|
//</editor-fold>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the object by its key.
|
* Get the object by its key.
|
||||||
*
|
*
|
||||||
* @param key non-null key
|
* @param key non-null key
|
||||||
* @return item or null if it does not exist
|
* @return item or null if it does not exist
|
||||||
*/
|
*/
|
||||||
default @Nullable T get(final net.kyori.adventure.key.@NotNull Key key) {
|
@Nullable T get(NamespacedKey key);
|
||||||
|
// Paper start
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the object by its key.
|
||||||
|
*
|
||||||
|
* @param key non-null key
|
||||||
|
* @return item or null if it does not exist
|
||||||
|
*/
|
||||||
|
default @Nullable T get(final Key key) {
|
||||||
return key instanceof final NamespacedKey nsKey ? this.get(nsKey) : this.get(new NamespacedKey(key.namespace(), key.value()));
|
return key instanceof final NamespacedKey nsKey ? this.get(nsKey) : this.get(new NamespacedKey(key.namespace(), key.value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -402,23 +389,26 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* @param typedKey non-null typed key
|
* @param typedKey non-null typed key
|
||||||
* @return item or null if it does not exist
|
* @return item or null if it does not exist
|
||||||
*/
|
*/
|
||||||
default @Nullable T get(final io.papermc.paper.registry.@NotNull TypedKey<T> typedKey) {
|
default @Nullable T get(final TypedKey<T> typedKey) {
|
||||||
|
Preconditions.checkArgument(typedKey != null, "typedKey cannot be null");
|
||||||
return this.get(typedKey.key());
|
return this.get(typedKey.key());
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
|
|
||||||
// Paper start - improve Registry
|
// Paper start - improve Registry
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the object by its key or throws if it doesn't exist.
|
* Gets the object by its key or throws if it doesn't exist.
|
||||||
*
|
*
|
||||||
* @param key the key to get the object of in this registry
|
* @param key the key to get the object of in this registry
|
||||||
* @return the object for the key
|
* @return the object for the key
|
||||||
* @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry
|
* @throws NoSuchElementException if the key doesn't point to an object in the registry
|
||||||
*/
|
*/
|
||||||
default @NotNull T getOrThrow(final net.kyori.adventure.key.@NotNull Key key) {
|
default T getOrThrow(final net.kyori.adventure.key.Key key) {
|
||||||
|
Preconditions.checkArgument(key != null, "key cannot be null");
|
||||||
final T value = this.get(key);
|
final T value = this.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new java.util.NoSuchElementException("No value for " + key + " in " + this);
|
throw new NoSuchElementException("No value for " + key + " in " + this);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -428,12 +418,12 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
*
|
*
|
||||||
* @param key the key to get the object of in this registry
|
* @param key the key to get the object of in this registry
|
||||||
* @return the object for the key
|
* @return the object for the key
|
||||||
* @throws java.util.NoSuchElementException if the key doesn't point to an object in the registry
|
* @throws NoSuchElementException if the key doesn't point to an object in the registry
|
||||||
*/
|
*/
|
||||||
default @NotNull T getOrThrow(final io.papermc.paper.registry.@NotNull TypedKey<T> key) {
|
default T getOrThrow(final TypedKey<T> key) {
|
||||||
final T value = this.get(key);
|
final T value = this.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new java.util.NoSuchElementException("No value for " + key + " in " + this);
|
throw new NoSuchElementException("No value for " + key + " in " + this);
|
||||||
}
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -447,14 +437,13 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
*
|
*
|
||||||
* @param value the value to get the key of in this registry
|
* @param value the value to get the key of in this registry
|
||||||
* @return the key for the value
|
* @return the key for the value
|
||||||
* @throws java.util.NoSuchElementException if the value doesn't exist in this registry
|
* @throws NoSuchElementException if the value doesn't exist in this registry
|
||||||
* @see #getKey(Keyed)
|
* @see #getKey(Keyed)
|
||||||
*/
|
*/
|
||||||
default @NotNull NamespacedKey getKeyOrThrow(final @NotNull T value) {
|
default NamespacedKey getKeyOrThrow(final T value) {
|
||||||
Preconditions.checkArgument(value != null, "value cannot be null");
|
|
||||||
final NamespacedKey key = this.getKey(value);
|
final NamespacedKey key = this.getKey(value);
|
||||||
if (key == null) {
|
if (key == null) {
|
||||||
throw new java.util.NoSuchElementException(value + " has no key in " + this);
|
throw new NoSuchElementException(value + " has no key in " + this);
|
||||||
}
|
}
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@ -470,14 +459,7 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* @return the key for the value or null if not in the registry
|
* @return the key for the value or null if not in the registry
|
||||||
* @see #getKeyOrThrow(Keyed)
|
* @see #getKeyOrThrow(Keyed)
|
||||||
*/
|
*/
|
||||||
default @Nullable NamespacedKey getKey(final @NotNull T value) {
|
@Nullable NamespacedKey getKey(T value);
|
||||||
Preconditions.checkArgument(value != null, "value cannot be null");
|
|
||||||
//noinspection ConstantValue (it might not be in the future...)
|
|
||||||
if (value instanceof Keyed) {
|
|
||||||
return value.getKey();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Paper end - improve Registry
|
// Paper end - improve Registry
|
||||||
|
|
||||||
// Paper start - RegistrySet API
|
// Paper start - RegistrySet API
|
||||||
@ -486,46 +468,52 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
*
|
*
|
||||||
* @param key the key to check for
|
* @param key the key to check for
|
||||||
* @return true if this registry has a tag with the given key, false otherwise
|
* @return true if this registry has a tag with the given key, false otherwise
|
||||||
* @see #getTag(io.papermc.paper.registry.tag.TagKey)
|
* @throws UnsupportedOperationException if this registry doesn't have or support tags
|
||||||
|
* @see #getTag(TagKey)
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
default boolean hasTag(final io.papermc.paper.registry.tag.@NotNull TagKey<T> key) {
|
boolean hasTag(TagKey<T> key);
|
||||||
throw new UnsupportedOperationException(this + " doesn't have tags");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the named registry set (tag) for the given key.
|
* Gets the named registry set (tag) for the given key.
|
||||||
*
|
*
|
||||||
* @param key the key to get the tag for
|
* @param key the key to get the tag for
|
||||||
* @return the tag for the key
|
* @return the tag for the key
|
||||||
* @throws java.util.NoSuchElementException if no tag with the given key is found
|
* @throws NoSuchElementException if no tag with the given key is found
|
||||||
* @throws UnsupportedOperationException if this registry doesn't have or support tags
|
* @throws UnsupportedOperationException if this registry doesn't have or support tags
|
||||||
* @see #hasTag(io.papermc.paper.registry.tag.TagKey)
|
* @see #hasTag(TagKey)
|
||||||
*/
|
*/
|
||||||
@ApiStatus.Experimental
|
@ApiStatus.Experimental
|
||||||
default @NotNull io.papermc.paper.registry.tag.Tag<T> getTag(final io.papermc.paper.registry.tag.@NotNull TagKey<T> key) {
|
Tag<T> getTag(TagKey<T> key);
|
||||||
throw new UnsupportedOperationException(this + " doesn't have tags");
|
|
||||||
}
|
/**
|
||||||
|
* Gets all the tags in this registry.
|
||||||
|
*
|
||||||
|
* @return a stream of all tags in this registry
|
||||||
|
* @throws UnsupportedOperationException if this registry doesn't have or support tags
|
||||||
|
*/
|
||||||
|
@ApiStatus.Experimental
|
||||||
|
Collection<Tag<T>> getTags();
|
||||||
// Paper end - RegistrySet API
|
// Paper end - RegistrySet API
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the object by its key.
|
* Get the object by its key.
|
||||||
*
|
* <p>
|
||||||
* If there is no object with the given key, an exception will be thrown.
|
* If there is no object with the given key, an exception will be thrown.
|
||||||
*
|
*
|
||||||
* @param key to get the object from
|
* @param key to get the object from
|
||||||
* @return object with the given key
|
* @return object with the given key
|
||||||
* @throws IllegalArgumentException if there is no object with the given key
|
* @throws NoSuchElementException if there is no object with the given key
|
||||||
*/
|
*/
|
||||||
@NotNull
|
default T getOrThrow(final NamespacedKey key) {
|
||||||
T getOrThrow(@NotNull NamespacedKey key);
|
return this.getOrThrow((Key) key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a new stream, which contains all registry items, which are registered to the registry.
|
* Returns a new stream, which contains all registry items, which are registered to the registry.
|
||||||
*
|
*
|
||||||
* @return a stream of all registry items
|
* @return a stream of all registry items
|
||||||
*/
|
*/
|
||||||
@NotNull
|
|
||||||
Stream<T> stream();
|
Stream<T> stream();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -539,64 +527,47 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
* @deprecated this method's behavior is broken and not useful. If you want to get an object
|
* @deprecated this method's behavior is broken and not useful. If you want to get an object
|
||||||
* based on its vanilla name, or a key, wrap it in a {@link NamespacedKey} object and use {@link #get(NamespacedKey)}
|
* based on its vanilla name, or a key, wrap it in a {@link NamespacedKey} object and use {@link #get(NamespacedKey)}
|
||||||
*/
|
*/
|
||||||
@Nullable
|
// Paper
|
||||||
@Deprecated(forRemoval = true) // Paper
|
@Deprecated(forRemoval = true)
|
||||||
default T match(@NotNull String input) {
|
default @Nullable T match(final String input) {
|
||||||
Preconditions.checkArgument(input != null, "input must not be null");
|
Preconditions.checkArgument(input != null, "input must not be null");
|
||||||
|
|
||||||
String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_");
|
final String filtered = input.toLowerCase(Locale.ROOT).replaceAll("\\s+", "_");
|
||||||
NamespacedKey namespacedKey = NamespacedKey.fromString(filtered);
|
final NamespacedKey namespacedKey = NamespacedKey.fromString(filtered);
|
||||||
return (namespacedKey != null) ? get(namespacedKey) : null;
|
return (namespacedKey != null) ? this.get(namespacedKey) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
class SimpleRegistry<T extends Enum<T> & Keyed> implements Registry<T> { // Paper - remove final
|
@ApiStatus.Internal
|
||||||
|
class SimpleRegistry<T extends Enum<T> & Keyed> extends NotARegistry<T> { // Paper - remove final
|
||||||
|
|
||||||
private final Class<T> type;
|
private final Class<T> type;
|
||||||
private final Map<NamespacedKey, T> map;
|
private final Map<NamespacedKey, T> map;
|
||||||
|
|
||||||
protected SimpleRegistry(@NotNull Class<T> type) {
|
protected SimpleRegistry(final Class<T> type) {
|
||||||
this(type, Predicates.<T>alwaysTrue());
|
this(type, Predicates.alwaysTrue());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SimpleRegistry(@NotNull Class<T> type, @NotNull Predicate<T> predicate) {
|
protected SimpleRegistry(final Class<T> type, final Predicate<T> predicate) {
|
||||||
ImmutableMap.Builder<NamespacedKey, T> builder = ImmutableMap.builder();
|
final ImmutableMap.Builder<NamespacedKey, T> builder = ImmutableMap.builder();
|
||||||
|
|
||||||
for (T entry : type.getEnumConstants()) {
|
for (final T entry : type.getEnumConstants()) {
|
||||||
if (predicate.test(entry)) {
|
if (predicate.test(entry)) {
|
||||||
builder.put(entry.getKey(), entry);
|
builder.put(entry.getKey(), entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map = builder.build();
|
this.map = builder.build();
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
@Override
|
||||||
public T get(@NotNull NamespacedKey key) {
|
public @Nullable T get(final NamespacedKey key) {
|
||||||
return map.get(key);
|
return this.map.get(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public T getOrThrow(@NotNull NamespacedKey key) {
|
|
||||||
T object = get(key);
|
|
||||||
|
|
||||||
Preconditions.checkArgument(object != null, "No %s registry entry found for key %s.", type, key);
|
|
||||||
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
|
||||||
public Stream<T> stream() {
|
|
||||||
return StreamSupport.stream(spliterator(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return map.values().iterator();
|
return this.map.values().iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiStatus.Internal
|
@ApiStatus.Internal
|
||||||
@ -604,12 +575,34 @@ public interface Registry<T extends Keyed> extends Iterable<T> {
|
|||||||
public Class<T> getType() {
|
public Class<T> getType() {
|
||||||
return this.type;
|
return this.type;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
abstract class NotARegistry<A extends Keyed> implements Registry<A> {
|
||||||
|
|
||||||
// Paper start - improve Registry
|
|
||||||
@Override
|
@Override
|
||||||
public @NotNull NamespacedKey getKey(final @NotNull T value) {
|
public Stream<A> stream() {
|
||||||
|
return StreamSupport.stream(this.spliterator(), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NamespacedKey getKey(final A value) {
|
||||||
return value.getKey();
|
return value.getKey();
|
||||||
}
|
}
|
||||||
// Paper end - improve Registry
|
|
||||||
|
@Override
|
||||||
|
public boolean hasTag(final TagKey<A> key) {
|
||||||
|
throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Tag<A> getTag(final TagKey<A> key) {
|
||||||
|
throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Tag<A>> getTags() {
|
||||||
|
throw new UnsupportedOperationException("This is not a real registry and therefore cannot support tags");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1018,7 +1018,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
* @return the {@link Recipe} resulting from the given crafting matrix.
|
* @return the {@link Recipe} resulting from the given crafting matrix.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public Recipe getCraftingRecipe(@NotNull ItemStack[] craftingMatrix, @NotNull World world);
|
public Recipe getCraftingRecipe(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the crafted item using the list of {@link ItemStack} provided.
|
* Get the crafted item using the list of {@link ItemStack} provided.
|
||||||
@ -1046,7 +1046,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
* an ItemStack of {@link Material#AIR} is returned.
|
* an ItemStack of {@link Material#AIR} is returned.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player);
|
public ItemStack craftItem(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world, @NotNull Player player);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the crafted item using the list of {@link ItemStack} provided.
|
* Get the crafted item using the list of {@link ItemStack} provided.
|
||||||
@ -1067,7 +1067,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
* an ItemStack of {@link Material#AIR} is returned.
|
* an ItemStack of {@link Material#AIR} is returned.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public ItemStack craftItem(@NotNull ItemStack[] craftingMatrix, @NotNull World world);
|
public ItemStack craftItem(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the crafted item using the list of {@link ItemStack} provided.
|
* Get the crafted item using the list of {@link ItemStack} provided.
|
||||||
@ -1094,7 +1094,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world, @NotNull Player player);
|
public ItemCraftResult craftItemResult(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world, @NotNull Player player);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the crafted item using the list of {@link ItemStack} provided.
|
* Get the crafted item using the list of {@link ItemStack} provided.
|
||||||
@ -1114,7 +1114,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
* @return resulting {@link ItemCraftResult} containing the resulting item, matrix and any overflow items.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public ItemCraftResult craftItemResult(@NotNull ItemStack[] craftingMatrix, @NotNull World world);
|
public ItemCraftResult craftItemResult(@NotNull ItemStack @NotNull [] craftingMatrix, @NotNull World world);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an iterator through the list of crafting recipes.
|
* Get an iterator through the list of crafting recipes.
|
||||||
@ -1503,8 +1503,7 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
*
|
*
|
||||||
* @return an array containing all previous players
|
* @return an array containing all previous players
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull OfflinePlayer @NotNull [] getOfflinePlayers();
|
||||||
public OfflinePlayer[] getOfflinePlayers();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link Messenger} responsible for this server.
|
* Gets the {@link Messenger} responsible for this server.
|
||||||
@ -2057,16 +2056,14 @@ public interface Server extends PluginMessageRecipient, net.kyori.adventure.audi
|
|||||||
*
|
*
|
||||||
* @return current server TPS (1m, 5m, 15m in Paper-Server)
|
* @return current server TPS (1m, 5m, 15m in Paper-Server)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public double @NotNull [] getTPS();
|
||||||
public double[] getTPS();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a sample of the servers last tick times (in nanos)
|
* Get a sample of the servers last tick times (in nanos)
|
||||||
*
|
*
|
||||||
* @return A sample of the servers last tick times (in nanos)
|
* @return A sample of the servers last tick times (in nanos)
|
||||||
*/
|
*/
|
||||||
@NotNull
|
long @NotNull [] getTickTimes();
|
||||||
long[] getTickTimes();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the average tick time (in millis)
|
* Get the average tick time (in millis)
|
||||||
|
|||||||
@ -1050,9 +1050,16 @@ public interface Tag<T extends Keyed> extends Keyed {
|
|||||||
*/
|
*/
|
||||||
Tag<Material> ITEMS_REPAIRS_WOLF_ARMOR = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("repairs_wolf_armor"), Material.class);
|
Tag<Material> ITEMS_REPAIRS_WOLF_ARMOR = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("repairs_wolf_armor"), Material.class);
|
||||||
/**
|
/**
|
||||||
* Vanilla item tag representing all furnace materials.
|
* Vanilla item tag representing all stone based materials for crafting.
|
||||||
*/
|
*/
|
||||||
Tag<Material> ITEMS_FURNACE_MATERIALS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("furnace_materials"), Material.class);
|
Tag<Material> ITEMS_STONE_CRAFTING_MATERIALS = Bukkit.getTag(REGISTRY_ITEMS, NamespacedKey.minecraft("stone_crafting_materials"), Material.class);
|
||||||
|
/**
|
||||||
|
* Vanilla item tag representing all furnace materials.
|
||||||
|
*
|
||||||
|
* @deprecated partially replaced by {@link #ITEMS_STONE_CRAFTING_MATERIALS}
|
||||||
|
*/
|
||||||
|
@Deprecated(since = "1.16.2", forRemoval = true)
|
||||||
|
Tag<Material> ITEMS_FURNACE_MATERIALS = ITEMS_STONE_CRAFTING_MATERIALS;
|
||||||
/**
|
/**
|
||||||
* Vanilla item tag representing all compasses.
|
* Vanilla item tag representing all compasses.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
package org.bukkit;
|
package org.bukkit;
|
||||||
|
|
||||||
import com.google.common.collect.Multimap;
|
import com.google.common.collect.Multimap;
|
||||||
|
import io.papermc.paper.entity.EntitySerializationFlag;
|
||||||
import org.bukkit.advancement.Advancement;
|
import org.bukkit.advancement.Advancement;
|
||||||
import org.bukkit.attribute.Attribute;
|
import org.bukkit.attribute.Attribute;
|
||||||
import org.bukkit.attribute.AttributeModifier;
|
import org.bukkit.attribute.AttributeModifier;
|
||||||
@ -9,7 +10,9 @@ import org.bukkit.block.data.BlockData;
|
|||||||
import org.bukkit.damage.DamageEffect;
|
import org.bukkit.damage.DamageEffect;
|
||||||
import org.bukkit.damage.DamageSource;
|
import org.bukkit.damage.DamageSource;
|
||||||
import org.bukkit.damage.DamageType;
|
import org.bukkit.damage.DamageType;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
import org.bukkit.entity.EntityType;
|
import org.bukkit.entity.EntityType;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.inventory.CreativeCategory;
|
import org.bukkit.inventory.CreativeCategory;
|
||||||
import org.bukkit.inventory.EquipmentSlot;
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.ItemStack;
|
import org.bukkit.inventory.ItemStack;
|
||||||
@ -123,10 +126,6 @@ public interface UnsafeValues {
|
|||||||
@Deprecated(since = "1.20.2", forRemoval = true)
|
@Deprecated(since = "1.20.2", forRemoval = true)
|
||||||
PotionType.InternalPotionData getInternalPotionData(NamespacedKey key);
|
PotionType.InternalPotionData getInternalPotionData(NamespacedKey key);
|
||||||
|
|
||||||
@ApiStatus.Internal
|
|
||||||
@Nullable
|
|
||||||
DamageEffect getDamageEffect(@NotNull String key);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link DamageSource.Builder}.
|
* Create a new {@link DamageSource.Builder}.
|
||||||
*
|
*
|
||||||
@ -198,13 +197,81 @@ public interface UnsafeValues {
|
|||||||
*/
|
*/
|
||||||
@NotNull ItemStack deserializeItemFromJson(@NotNull com.google.gson.JsonObject data) throws IllegalArgumentException;
|
@NotNull ItemStack deserializeItemFromJson(@NotNull com.google.gson.JsonObject data) throws IllegalArgumentException;
|
||||||
|
|
||||||
byte[] serializeEntity(org.bukkit.entity.Entity entity);
|
/**
|
||||||
|
* Serializes the provided entity.
|
||||||
|
*
|
||||||
|
* @param entity entity
|
||||||
|
* @return serialized entity data
|
||||||
|
* @see #serializeEntity(Entity, EntitySerializationFlag...)
|
||||||
|
* @see #deserializeEntity(byte[], World, boolean, boolean)
|
||||||
|
* @throws IllegalArgumentException if couldn't serialize the entity
|
||||||
|
* @since 1.17.1
|
||||||
|
*/
|
||||||
|
default byte @NotNull [] serializeEntity(@NotNull Entity entity) {
|
||||||
|
return serializeEntity(entity, new EntitySerializationFlag[0]);
|
||||||
|
}
|
||||||
|
|
||||||
default org.bukkit.entity.Entity deserializeEntity(byte[] data, World world) {
|
/**
|
||||||
|
* Serializes the provided entity.
|
||||||
|
*
|
||||||
|
* @param entity entity
|
||||||
|
* @param serializationFlags serialization flags
|
||||||
|
* @return serialized entity data
|
||||||
|
* @throws IllegalArgumentException if couldn't serialize the entity
|
||||||
|
* @see #deserializeEntity(byte[], World, boolean, boolean)
|
||||||
|
* @since 1.21.4
|
||||||
|
*/
|
||||||
|
byte @NotNull [] serializeEntity(@NotNull Entity entity, @NotNull EntitySerializationFlag... serializationFlags);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes the entity from data.
|
||||||
|
* <br>The entity's {@link java.util.UUID} as well as passengers will not be preserved.
|
||||||
|
*
|
||||||
|
* @param data serialized entity data
|
||||||
|
* @param world world
|
||||||
|
* @return deserialized entity
|
||||||
|
* @throws IllegalArgumentException if invalid serialized entity data provided
|
||||||
|
* @see #deserializeEntity(byte[], World, boolean, boolean)
|
||||||
|
* @see #serializeEntity(Entity, EntitySerializationFlag...)
|
||||||
|
* @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason)
|
||||||
|
* @since 1.17.1
|
||||||
|
*/
|
||||||
|
default @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world) {
|
||||||
return deserializeEntity(data, world, false);
|
return deserializeEntity(data, world, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
org.bukkit.entity.Entity deserializeEntity(byte[] data, World world, boolean preserveUUID);
|
/**
|
||||||
|
* Deserializes the entity from data.
|
||||||
|
* <br>The entity's passengers will not be preserved.
|
||||||
|
*
|
||||||
|
* @param data serialized entity data
|
||||||
|
* @param world world
|
||||||
|
* @param preserveUUID whether to preserve the entity's uuid
|
||||||
|
* @return deserialized entity
|
||||||
|
* @throws IllegalArgumentException if invalid serialized entity data provided
|
||||||
|
* @see #deserializeEntity(byte[], World, boolean, boolean)
|
||||||
|
* @see #serializeEntity(Entity, EntitySerializationFlag...)
|
||||||
|
* @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason)
|
||||||
|
* @since 1.17.1
|
||||||
|
*/
|
||||||
|
default @NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID) {
|
||||||
|
return deserializeEntity(data, world, preserveUUID, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deserializes the entity from data.
|
||||||
|
*
|
||||||
|
* @param data serialized entity data
|
||||||
|
* @param world world
|
||||||
|
* @param preserveUUID whether to preserve uuids of the entity and its passengers
|
||||||
|
* @param preservePassengers whether to preserve passengers
|
||||||
|
* @return deserialized entity
|
||||||
|
* @throws IllegalArgumentException if invalid serialized entity data provided
|
||||||
|
* @see #serializeEntity(Entity, EntitySerializationFlag...)
|
||||||
|
* @see Entity#spawnAt(Location, CreatureSpawnEvent.SpawnReason)
|
||||||
|
* @since 1.21.4
|
||||||
|
*/
|
||||||
|
@NotNull Entity deserializeEntity(byte @NotNull [] data, @NotNull World world, boolean preserveUUID, boolean preservePassengers);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates and returns the next EntityId available.
|
* Creates and returns the next EntityId available.
|
||||||
|
|||||||
@ -346,8 +346,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
|||||||
*
|
*
|
||||||
* @return Chunk[] containing all loaded chunks
|
* @return Chunk[] containing all loaded chunks
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull Chunk @NotNull [] getLoadedChunks();
|
||||||
public Chunk[] getLoadedChunks();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the specified {@link Chunk}.
|
* Loads the specified {@link Chunk}.
|
||||||
@ -3563,8 +3562,7 @@ public interface World extends RegionAccessor, WorldInfo, PluginMessageRecipient
|
|||||||
*
|
*
|
||||||
* @return An array of {@link GameRule} names.
|
* @return An array of {@link GameRule} names.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull String @NotNull [] getGameRules();
|
||||||
public String[] getGameRules();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current state of the specified rule
|
* Gets the current state of the specified rule
|
||||||
|
|||||||
@ -89,7 +89,7 @@ public interface Attribute extends OldEnum<Attribute>, Keyed, Translatable, net.
|
|||||||
*/
|
*/
|
||||||
Attribute JUMP_STRENGTH = getAttribute("jump_strength");
|
Attribute JUMP_STRENGTH = getAttribute("jump_strength");
|
||||||
/**
|
/**
|
||||||
* How long an entity remains burning after ingition.
|
* How long an entity remains burning after ignition.
|
||||||
*/
|
*/
|
||||||
Attribute BURNING_TIME = getAttribute("burning_time");
|
Attribute BURNING_TIME = getAttribute("burning_time");
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -66,7 +66,7 @@ public abstract class Command {
|
|||||||
* @param args All arguments passed to the command, split via ' '
|
* @param args All arguments passed to the command, split via ' '
|
||||||
* @return true if the command was successful, otherwise false
|
* @return true if the command was successful, otherwise false
|
||||||
*/
|
*/
|
||||||
public abstract boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String[] args);
|
public abstract boolean execute(@NotNull CommandSender sender, @NotNull String commandLabel, @NotNull String @NotNull [] args);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executed on tab completion for this command, returning a list of
|
* Executed on tab completion for this command, returning a list of
|
||||||
@ -80,7 +80,7 @@ public abstract class Command {
|
|||||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args) throws IllegalArgumentException {
|
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args) throws IllegalArgumentException {
|
||||||
return tabComplete0(sender, alias, args, null);
|
return tabComplete0(sender, alias, args, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,7 +97,7 @@ public abstract class Command {
|
|||||||
* @throws IllegalArgumentException if sender, alias, or args is null
|
* @throws IllegalArgumentException if sender, alias, or args is null
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String[] args, @Nullable Location location) throws IllegalArgumentException {
|
public List<String> tabComplete(@NotNull CommandSender sender, @NotNull String alias, @NotNull String @NotNull [] args, @Nullable Location location) throws IllegalArgumentException {
|
||||||
return tabComplete(sender, alias, args);
|
return tabComplete(sender, alias, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -19,5 +19,5 @@ public interface CommandExecutor {
|
|||||||
* @param args Passed command arguments
|
* @param args Passed command arguments
|
||||||
* @return true if a valid command, otherwise false
|
* @return true if a valid command, otherwise false
|
||||||
*/
|
*/
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args);
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -22,7 +22,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
public interface MessageCommandSender extends CommandSender {
|
public interface MessageCommandSender extends CommandSender {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void sendMessage(@NotNull String[] messages) {
|
default void sendMessage(@NotNull String @NotNull [] messages) {
|
||||||
for (String message : messages) {
|
for (String message : messages) {
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ public interface MessageCommandSender extends CommandSender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
default void sendMessage(@Nullable UUID sender, @NotNull String[] messages) {
|
default void sendMessage(@Nullable UUID sender, @NotNull String @NotNull [] messages) {
|
||||||
for (String message : messages) {
|
for (String message : messages) {
|
||||||
sendMessage(message);
|
sendMessage(message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,8 +18,7 @@ public class MultipleCommandAlias extends Command {
|
|||||||
*
|
*
|
||||||
* @return commands associated with alias
|
* @return commands associated with alias
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull Command @NotNull [] getCommands() {
|
||||||
public Command[] getCommands() {
|
|
||||||
return commands;
|
return commands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -23,5 +23,5 @@ public interface TabCompleter {
|
|||||||
* to default to the command executor
|
* to default to the command executor
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args);
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package org.bukkit.damage;
|
package org.bukkit.damage;
|
||||||
|
|
||||||
import com.google.common.base.Preconditions;
|
import com.google.common.base.Preconditions;
|
||||||
import org.bukkit.Bukkit;
|
import io.papermc.paper.InternalAPIBridge;
|
||||||
import org.bukkit.Sound;
|
import org.bukkit.Sound;
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@ -40,7 +40,7 @@ public interface DamageEffect {
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static DamageEffect getDamageEffect(@NotNull String key) {
|
private static DamageEffect getDamageEffect(@NotNull String key) {
|
||||||
return Preconditions.checkNotNull(Bukkit.getUnsafe().getDamageEffect(key), "No DamageEffect found for %s. This is a bug.", key);
|
return Preconditions.checkNotNull(InternalAPIBridge.get().getDamageEffect(key), "No DamageEffect found for %s. This is a bug.", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -14,6 +14,7 @@ import org.bukkit.World;
|
|||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.block.PistonMoveReaction;
|
import org.bukkit.block.PistonMoveReaction;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
|
import org.bukkit.event.entity.CreatureSpawnEvent;
|
||||||
import org.bukkit.event.entity.EntityDamageEvent;
|
import org.bukkit.event.entity.EntityDamageEvent;
|
||||||
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
import org.bukkit.material.Directional;
|
import org.bukkit.material.Directional;
|
||||||
@ -1072,11 +1073,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
|||||||
* <p>
|
* <p>
|
||||||
* Also, this method will fire the same events as a normal entity spawn.
|
* Also, this method will fire the same events as a normal entity spawn.
|
||||||
*
|
*
|
||||||
* @param location The location to spawn the entity at.
|
* @param location the location to spawn the entity at
|
||||||
* @return Whether the entity was successfully spawned.
|
* @return whether the entity was successfully spawned
|
||||||
|
* @since 1.17.1
|
||||||
*/
|
*/
|
||||||
public default boolean spawnAt(@NotNull Location location) {
|
default boolean spawnAt(@NotNull Location location) {
|
||||||
return spawnAt(location, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
return spawnAt(location, CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1086,11 +1088,12 @@ public interface Entity extends Metadatable, CommandSender, Nameable, Persistent
|
|||||||
* <p>
|
* <p>
|
||||||
* Also, this method will fire the same events as a normal entity spawn.
|
* Also, this method will fire the same events as a normal entity spawn.
|
||||||
*
|
*
|
||||||
* @param location The location to spawn the entity at.
|
* @param location the location to spawn the entity at
|
||||||
* @param reason The reason for the entity being spawned.
|
* @param reason the reason for the entity being spawned
|
||||||
* @return Whether the entity was successfully spawned.
|
* @return whether the entity was successfully spawned
|
||||||
|
* @since 1.17.1
|
||||||
*/
|
*/
|
||||||
public boolean spawnAt(@NotNull Location location, @NotNull org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason);
|
boolean spawnAt(@NotNull Location location, @NotNull CreatureSpawnEvent.SpawnReason reason);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if entity is inside powdered snow.
|
* Check if entity is inside powdered snow.
|
||||||
|
|||||||
@ -2,10 +2,12 @@ package org.bukkit.entity;
|
|||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.function.Consumer;
|
||||||
import org.bukkit.GameMode;
|
import org.bukkit.GameMode;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
|
import org.bukkit.inventory.EquipmentSlot;
|
||||||
import org.bukkit.inventory.Inventory;
|
import org.bukkit.inventory.Inventory;
|
||||||
import org.bukkit.inventory.InventoryHolder;
|
import org.bukkit.inventory.InventoryHolder;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
@ -14,6 +16,7 @@ import org.bukkit.inventory.MainHand;
|
|||||||
import org.bukkit.inventory.Merchant;
|
import org.bukkit.inventory.Merchant;
|
||||||
import org.bukkit.inventory.PlayerInventory;
|
import org.bukkit.inventory.PlayerInventory;
|
||||||
import org.bukkit.inventory.meta.FireworkMeta;
|
import org.bukkit.inventory.meta.FireworkMeta;
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
@ -703,8 +706,115 @@ public interface HumanEntity extends LivingEntity, AnimalTamer, InventoryHolder
|
|||||||
*
|
*
|
||||||
* @param dropAll True to drop entire stack, false to drop 1 of the stack
|
* @param dropAll True to drop entire stack, false to drop 1 of the stack
|
||||||
* @return True if item was dropped successfully
|
* @return True if item was dropped successfully
|
||||||
|
* @apiNote You should instead use {@link #dropItem(EquipmentSlot, int)} or {@link #dropItem(EquipmentSlot)} with a {@link EquipmentSlot#HAND} parameter.
|
||||||
*/
|
*/
|
||||||
public boolean dropItem(boolean dropAll);
|
@ApiStatus.Obsolete(since = "1.21.4")
|
||||||
|
boolean dropItem(boolean dropAll);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop all items from their inventory based on the inventory slot.
|
||||||
|
*
|
||||||
|
* @param slot the equipment slot to drop
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Item dropItem(final int slot) {
|
||||||
|
return this.dropItem(slot, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop an item from their inventory based on the inventory slot.
|
||||||
|
*
|
||||||
|
* @param slot the slot to drop
|
||||||
|
* @param amount the number of items to drop from this slot. Values below one always return null
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
* @throws IllegalArgumentException if the slot is negative or bigger than the player's inventory
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Item dropItem(final int slot, final int amount) {
|
||||||
|
return this.dropItem(slot, amount, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop an item from their inventory based on the inventory slot.
|
||||||
|
*
|
||||||
|
* @param slot the slot to drop
|
||||||
|
* @param amount the number of items to drop from this slot. Values below one always return null
|
||||||
|
* @param throwRandomly controls the randomness of the dropped items velocity, where {@code true} mimics dropped
|
||||||
|
* items during a player's death, while {@code false} acts like a normal item drop.
|
||||||
|
* @param entityOperation the function to be run before adding the entity into the world
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
* @throws IllegalArgumentException if the slot is negative or bigger than the player's inventory
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Item dropItem(int slot, int amount, boolean throwRandomly, @Nullable Consumer<Item> entityOperation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop all items from their inventory based on the equipment slot.
|
||||||
|
*
|
||||||
|
* @param slot the equipment slot to drop
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Item dropItem(final @NotNull EquipmentSlot slot) {
|
||||||
|
return this.dropItem(slot, Integer.MAX_VALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop an item from their inventory based on the equipment slot.
|
||||||
|
*
|
||||||
|
* @param slot the equipment slot to drop
|
||||||
|
* @param amount the amount of items to drop from this equipment slot. Values below one always return null
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Item dropItem(final @NotNull EquipmentSlot slot, final int amount) {
|
||||||
|
return this.dropItem(slot, amount, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop an item from their inventory based on the equipment slot.
|
||||||
|
*
|
||||||
|
* @param slot the equipment slot to drop
|
||||||
|
* @param amount The amount of items to drop from this equipment slot. Values below one always return null
|
||||||
|
* @param throwRandomly controls the randomness of the dropped items velocity, where {@code true} mimics dropped
|
||||||
|
* items during a player's death, while {@code false} acts like a normal item drop.
|
||||||
|
* @param entityOperation the function to be run before adding the entity into the world
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Item dropItem(@NotNull EquipmentSlot slot, int amount, boolean throwRandomly, @Nullable Consumer<Item> entityOperation);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
|
||||||
|
* has that item in their inventory.
|
||||||
|
* <p>
|
||||||
|
* This method modifies neither the item nor the player's inventory.
|
||||||
|
* Item removal has to be handled by the method caller.
|
||||||
|
*
|
||||||
|
* @param itemStack the itemstack to drop
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
default Item dropItem(final @NotNull ItemStack itemStack) {
|
||||||
|
return this.dropItem(itemStack, false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes the player drop any arbitrary {@link ItemStack}, independently of whether the player actually
|
||||||
|
* has that item in their inventory.
|
||||||
|
* <p>
|
||||||
|
* This method modifies neither the item nor the player's inventory.
|
||||||
|
* Item removal has to be handled by the method caller.
|
||||||
|
*
|
||||||
|
* @param itemStack the itemstack to drop
|
||||||
|
* @param throwRandomly controls the randomness of the dropped items velocity, where {@code true} mimics dropped
|
||||||
|
* items during a player's death, while {@code false} acts like a normal item drop.
|
||||||
|
* @param entityOperation the function to be run before adding the entity into the world
|
||||||
|
* @return the dropped item entity, or null if the action was unsuccessful
|
||||||
|
*/
|
||||||
|
@Nullable
|
||||||
|
Item dropItem(final @NotNull ItemStack itemStack, boolean throwRandomly, @Nullable Consumer<Item> entityOperation);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the players current exhaustion level.
|
* Gets the players current exhaustion level.
|
||||||
|
|||||||
@ -2308,7 +2308,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
|||||||
* long.
|
* long.
|
||||||
*/
|
*/
|
||||||
@Deprecated // Paper - adventure
|
@Deprecated // Paper - adventure
|
||||||
public void setResourcePack(@NotNull String url, @Nullable byte[] hash);
|
public void setResourcePack(@NotNull String url, byte @Nullable [] hash);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request that the player's client download and switch resource packs.
|
* Request that the player's client download and switch resource packs.
|
||||||
@ -2353,7 +2353,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
|||||||
* long.
|
* long.
|
||||||
*/
|
*/
|
||||||
@Deprecated // Paper - adventure
|
@Deprecated // Paper - adventure
|
||||||
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt);
|
public void setResourcePack(@NotNull String url, byte @Nullable [] hash, @Nullable String prompt);
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
/**
|
/**
|
||||||
@ -2447,7 +2447,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
|||||||
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
||||||
*/
|
*/
|
||||||
@Deprecated // Paper - adventure
|
@Deprecated // Paper - adventure
|
||||||
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, boolean force);
|
public void setResourcePack(@NotNull String url, byte @Nullable [] hash, boolean force);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Request that the player's client download and switch resource packs.
|
* Request that the player's client download and switch resource packs.
|
||||||
@ -2494,7 +2494,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
|||||||
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
||||||
*/
|
*/
|
||||||
@Deprecated // Paper
|
@Deprecated // Paper
|
||||||
public void setResourcePack(@NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force);
|
public void setResourcePack(@NotNull String url, byte @Nullable [] hash, @Nullable String prompt, boolean force);
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
/**
|
/**
|
||||||
@ -2592,7 +2592,7 @@ public interface Player extends HumanEntity, Conversable, OfflinePlayer, PluginM
|
|||||||
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
* @deprecated in favour of {@link #sendResourcePacks(net.kyori.adventure.resource.ResourcePackRequest)}
|
||||||
*/
|
*/
|
||||||
@Deprecated // Paper - adventure
|
@Deprecated // Paper - adventure
|
||||||
public void setResourcePack(@NotNull UUID id, @NotNull String url, @Nullable byte[] hash, @Nullable String prompt, boolean force);
|
public void setResourcePack(@NotNull UUID id, @NotNull String url, byte @Nullable [] hash, @Nullable String prompt, boolean force);
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -203,8 +203,7 @@ public class HandlerList {
|
|||||||
*
|
*
|
||||||
* @return the array of registered listeners
|
* @return the array of registered listeners
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull RegisteredListener @NotNull [] getRegisteredListeners() {
|
||||||
public RegisteredListener[] getRegisteredListeners() {
|
|
||||||
RegisteredListener[] handlers;
|
RegisteredListener[] handlers;
|
||||||
while ((handlers = this.handlers) == null) bake(); // This prevents fringe cases of returning null
|
while ((handlers = this.handlers) == null) bake(); // This prevents fringe cases of returning null
|
||||||
return handlers;
|
return handlers;
|
||||||
|
|||||||
@ -241,6 +241,9 @@ public class PlayerInteractEvent extends PlayerEvent implements Cancellable {
|
|||||||
@Nullable
|
@Nullable
|
||||||
@Deprecated // Paper
|
@Deprecated // Paper
|
||||||
public Vector getClickedPosition() {
|
public Vector getClickedPosition() {
|
||||||
|
if (this.clickedPosistion == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return clickedPosistion.clone();
|
return clickedPosistion.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -329,7 +329,7 @@ public interface EntityEquipment {
|
|||||||
*
|
*
|
||||||
* @param items The items to set the armor as. Individual items may be null.
|
* @param items The items to set the armor as. Individual items may be null.
|
||||||
*/
|
*/
|
||||||
void setArmorContents(@NotNull ItemStack[] items);
|
void setArmorContents(@NotNull ItemStack @NotNull [] items);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the entity of all armor and held items
|
* Clears the entity of all armor and held items
|
||||||
|
|||||||
@ -24,8 +24,7 @@ public interface ItemCraftResult {
|
|||||||
*
|
*
|
||||||
* @return resulting matrix
|
* @return resulting matrix
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull ItemStack @NotNull [] getResultingMatrix();
|
||||||
public ItemStack[] getResultingMatrix();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the overflowed items for items that don't fit back into the crafting
|
* Gets the overflowed items for items that don't fit back into the crafting
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import java.util.LinkedHashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import net.kyori.adventure.text.Component;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.NamespacedKey;
|
import org.bukkit.NamespacedKey;
|
||||||
@ -710,6 +711,17 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
|||||||
return Bukkit.getServer().getItemFactory().displayName(this);
|
return Bukkit.getServer().getItemFactory().displayName(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the effective name of this item stack shown to player in inventory.
|
||||||
|
* It takes into account the display name (with italics) from the item meta,
|
||||||
|
* the potion effect, translatable name, rarity etc.
|
||||||
|
*
|
||||||
|
* @return the effective name of this item stack
|
||||||
|
*/
|
||||||
|
public @NotNull Component effectiveName() {
|
||||||
|
return this.craftDelegate.effectiveName();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Minecraft updates are converting simple item stacks into more complex NBT oriented Item Stacks.
|
* Minecraft updates are converting simple item stacks into more complex NBT oriented Item Stacks.
|
||||||
*
|
*
|
||||||
@ -732,8 +744,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
|||||||
* @param bytes bytes representing an item in NBT
|
* @param bytes bytes representing an item in NBT
|
||||||
* @return ItemStack migrated to this version of Minecraft if needed.
|
* @return ItemStack migrated to this version of Minecraft if needed.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public static @NotNull ItemStack deserializeBytes(final byte @NotNull [] bytes) {
|
||||||
public static ItemStack deserializeBytes(@NotNull byte[] bytes) {
|
|
||||||
return org.bukkit.Bukkit.getUnsafe().deserializeItem(bytes);
|
return org.bukkit.Bukkit.getUnsafe().deserializeItem(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -742,8 +753,7 @@ public class ItemStack implements Cloneable, ConfigurationSerializable, Translat
|
|||||||
* use the built in data converter instead of bukkits dangerous serialization system.
|
* use the built in data converter instead of bukkits dangerous serialization system.
|
||||||
* @return bytes representing this item in NBT.
|
* @return bytes representing this item in NBT.
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public byte @NotNull [] serializeAsBytes() {
|
||||||
public byte[] serializeAsBytes() {
|
|
||||||
return org.bukkit.Bukkit.getUnsafe().serializeItem(this);
|
return org.bukkit.Bukkit.getUnsafe().serializeItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -118,7 +118,7 @@ public interface PlayerInventory extends Inventory {
|
|||||||
*
|
*
|
||||||
* @param items The ItemStacks to use as armour
|
* @param items The ItemStacks to use as armour
|
||||||
*/
|
*/
|
||||||
public void setArmorContents(@Nullable ItemStack[] items);
|
public void setArmorContents(@Nullable ItemStack @NotNull [] items);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put the given ItemStacks into the extra slots
|
* Put the given ItemStacks into the extra slots
|
||||||
@ -127,7 +127,7 @@ public interface PlayerInventory extends Inventory {
|
|||||||
*
|
*
|
||||||
* @param items The ItemStacks to use as extra
|
* @param items The ItemStacks to use as extra
|
||||||
*/
|
*/
|
||||||
public void setExtraContents(@Nullable ItemStack[] items);
|
public void setExtraContents(@Nullable ItemStack @NotNull [] items);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Put the given ItemStack into the helmet slot. This does not check if
|
* Put the given ItemStack into the helmet slot. This does not check if
|
||||||
|
|||||||
@ -234,8 +234,7 @@ public class ShapedRecipe extends CraftingRecipe {
|
|||||||
* @return The recipe's shape.
|
* @return The recipe's shape.
|
||||||
* @throws NullPointerException when not set yet
|
* @throws NullPointerException when not set yet
|
||||||
*/
|
*/
|
||||||
@NotNull
|
public @NotNull String @NotNull [] getShape() {
|
||||||
public String[] getShape() {
|
|
||||||
return rows.clone();
|
return rows.clone();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,7 @@ import org.bukkit.enchantments.EnchantmentOffer;
|
|||||||
import org.bukkit.inventory.EnchantingInventory;
|
import org.bukkit.inventory.EnchantingInventory;
|
||||||
import org.bukkit.inventory.InventoryView;
|
import org.bukkit.inventory.InventoryView;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jspecify.annotations.Nullable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An instance of {@link InventoryView} which provides extra methods related to
|
* An instance of {@link InventoryView} which provides extra methods related to
|
||||||
@ -36,8 +37,7 @@ public interface EnchantmentView extends InventoryView {
|
|||||||
*
|
*
|
||||||
* @return The enchantment offers that are provided
|
* @return The enchantment offers that are provided
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@Nullable EnchantmentOffer @NotNull [] getOffers();
|
||||||
EnchantmentOffer[] getOffers();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the offers to provide to the player.
|
* Sets the offers to provide to the player.
|
||||||
@ -45,5 +45,5 @@ public interface EnchantmentView extends InventoryView {
|
|||||||
* @param offers The offers to provide
|
* @param offers The offers to provide
|
||||||
* @throws IllegalArgumentException if the array length isn't 3
|
* @throws IllegalArgumentException if the array length isn't 3
|
||||||
*/
|
*/
|
||||||
void setOffers(@NotNull EnchantmentOffer[] offers) throws IllegalArgumentException;
|
void setOffers(@Nullable EnchantmentOffer @NotNull [] offers) throws IllegalArgumentException;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,7 +16,7 @@ public interface Lootable {
|
|||||||
/**
|
/**
|
||||||
* Set the loot table for a container or entity.
|
* Set the loot table for a container or entity.
|
||||||
* <br>
|
* <br>
|
||||||
* To remove a loot table use null.
|
* If the provided loot table is null, the loot table will be reset to its default behavior.
|
||||||
*
|
*
|
||||||
* @param table the Loot Table this {@link org.bukkit.block.Container} or
|
* @param table the Loot Table this {@link org.bukkit.block.Container} or
|
||||||
* {@link org.bukkit.entity.Mob} will have.
|
* {@link org.bukkit.entity.Mob} will have.
|
||||||
@ -38,6 +38,8 @@ public interface Lootable {
|
|||||||
// Paper start
|
// Paper start
|
||||||
/**
|
/**
|
||||||
* Set the loot table and seed for a container or entity at the same time.
|
* Set the loot table and seed for a container or entity at the same time.
|
||||||
|
* <br>
|
||||||
|
* If the provided loot table is null, the loot table will be reset to its default behavior.
|
||||||
*
|
*
|
||||||
* @param table the Loot Table this {@link org.bukkit.block.Container} or {@link org.bukkit.entity.Mob} will have.
|
* @param table the Loot Table this {@link org.bukkit.block.Container} or {@link org.bukkit.entity.Mob} will have.
|
||||||
* @param seed the seed to used to generate loot. Default is 0.
|
* @param seed the seed to used to generate loot. Default is 0.
|
||||||
@ -53,7 +55,8 @@ public interface Lootable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clears the associated Loot Table to this object
|
* Clears the associated Loot Table to this object, essentially resetting it to default
|
||||||
|
* @see #setLootTable(LootTable)
|
||||||
*/
|
*/
|
||||||
default void clearLootTable() {
|
default void clearLootTable() {
|
||||||
this.setLootTable(null);
|
this.setLootTable(null);
|
||||||
|
|||||||
@ -112,7 +112,7 @@ public class MapFont {
|
|||||||
private final int height;
|
private final int height;
|
||||||
private final boolean[] data;
|
private final boolean[] data;
|
||||||
|
|
||||||
public CharacterSprite(int width, int height, @NotNull boolean[] data) {
|
public CharacterSprite(int width, int height, boolean @NotNull [] data) {
|
||||||
this.width = width;
|
this.width = width;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|||||||
@ -1,24 +1,15 @@
|
|||||||
package org.bukkit.plugin;
|
package org.bukkit.plugin;
|
||||||
|
|
||||||
|
import com.google.common.base.Preconditions;
|
||||||
|
import io.papermc.paper.event.executor.EventExecutorFactory;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.EventException;
|
import org.bukkit.event.EventException;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
import org.bukkit.plugin.java.JavaPlugin;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
// Paper start
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.lang.reflect.Modifier;
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
|
||||||
import java.util.concurrent.ConcurrentMap;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import com.destroystokyo.paper.event.executor.MethodHandleEventExecutor;
|
|
||||||
import com.destroystokyo.paper.event.executor.StaticMethodHandleEventExecutor;
|
|
||||||
import com.destroystokyo.paper.event.executor.asm.ASMEventExecutorGenerator;
|
|
||||||
import com.destroystokyo.paper.event.executor.asm.ClassDefiner;
|
|
||||||
import com.google.common.base.Preconditions;
|
|
||||||
// Paper end
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface which defines the class for event call backs to plugins
|
* Interface which defines the class for event call backs to plugins
|
||||||
*/
|
*/
|
||||||
@ -26,69 +17,25 @@ public interface EventExecutor {
|
|||||||
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException;
|
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException;
|
||||||
|
|
||||||
// Paper start
|
// Paper start
|
||||||
ConcurrentMap<Method, Class<? extends EventExecutor>> eventExecutorMap = new ConcurrentHashMap<Method, Class<? extends EventExecutor>>() {
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
static EventExecutor create(@NotNull Method m, @NotNull Class<? extends Event> eventClass) {
|
||||||
public Class<? extends EventExecutor> computeIfAbsent(@NotNull Method key, @NotNull Function<? super Method, ? extends Class<? extends EventExecutor>> mappingFunction) {
|
|
||||||
Class<? extends EventExecutor> executorClass = get(key);
|
|
||||||
if (executorClass != null)
|
|
||||||
return executorClass;
|
|
||||||
|
|
||||||
//noinspection SynchronizationOnLocalVariableOrMethodParameter
|
|
||||||
synchronized (key) {
|
|
||||||
executorClass = get(key);
|
|
||||||
if (executorClass != null)
|
|
||||||
return executorClass;
|
|
||||||
|
|
||||||
return super.computeIfAbsent(key, mappingFunction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public static EventExecutor create(@NotNull Method m, @NotNull Class<? extends Event> eventClass) {
|
|
||||||
Preconditions.checkNotNull(m, "Null method");
|
Preconditions.checkNotNull(m, "Null method");
|
||||||
Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
|
Preconditions.checkArgument(m.getParameterCount() != 0, "Incorrect number of arguments %s", m.getParameterCount());
|
||||||
Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
|
Preconditions.checkArgument(m.getParameterTypes()[0] == eventClass, "First parameter %s doesn't match event class %s", m.getParameterTypes()[0], eventClass);
|
||||||
ClassDefiner definer = ClassDefiner.getInstance();
|
|
||||||
if (m.getReturnType() != Void.TYPE) {
|
if (m.getReturnType() != Void.TYPE) {
|
||||||
final org.bukkit.plugin.java.JavaPlugin plugin = org.bukkit.plugin.java.JavaPlugin.getProvidingPlugin(m.getDeclaringClass());
|
final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(m.getDeclaringClass());
|
||||||
org.bukkit.Bukkit.getLogger().warning("@EventHandler method " + m.getDeclaringClass().getName() + (Modifier.isStatic(m.getModifiers()) ? '.' : '#') + m.getName()
|
org.bukkit.Bukkit.getLogger().warning("@EventHandler method " + m.getDeclaringClass().getName() + (Modifier.isStatic(m.getModifiers()) ? '.' : '#') + m.getName()
|
||||||
+ " returns non-void type " + m.getReturnType().getName() + ". This is unsupported behavior and will no longer work in a future version of Paper."
|
+ " returns non-void type " + m.getReturnType().getName() + ". This is unsupported behavior and will no longer work in a future version of Paper."
|
||||||
+ " This should be reported to the developers of " + plugin.getPluginMeta().getDisplayName() + " (" + String.join(",", plugin.getPluginMeta().getAuthors()) + ')');
|
+ " This should be reported to the developers of " + plugin.getPluginMeta().getDisplayName() + " (" + String.join(",", plugin.getPluginMeta().getAuthors()) + ')');
|
||||||
}
|
}
|
||||||
if (Modifier.isStatic(m.getModifiers())) {
|
if (!m.trySetAccessible()) {
|
||||||
return new StaticMethodHandleEventExecutor(eventClass, m);
|
final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(m.getDeclaringClass());
|
||||||
} else if (definer.isBypassAccessChecks() || Modifier.isPublic(m.getDeclaringClass().getModifiers()) && Modifier.isPublic(m.getModifiers())) {
|
throw new AssertionError(
|
||||||
// get the existing generated EventExecutor class for the Method or generate one
|
"@EventHandler method " + m.getDeclaringClass().getName() + (Modifier.isStatic(m.getModifiers()) ? '.' : '#') + m.getName() + " is not accessible."
|
||||||
Class<? extends EventExecutor> executorClass = eventExecutorMap.computeIfAbsent(m, (__) -> {
|
+ " This should be reported to the developers of " + plugin.getDescription().getName() + " (" + String.join(",", plugin.getDescription().getAuthors()) + ')'
|
||||||
String name = ASMEventExecutorGenerator.generateName();
|
);
|
||||||
byte[] classData = ASMEventExecutorGenerator.generateEventExecutor(m, name);
|
|
||||||
return definer.defineClass(m.getDeclaringClass().getClassLoader(), name, classData).asSubclass(EventExecutor.class);
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
|
||||||
EventExecutor asmExecutor = executorClass.newInstance();
|
|
||||||
// Define a wrapper to conform to bukkit stupidity (passing in events that don't match and wrapper exception)
|
|
||||||
return new EventExecutor() {
|
|
||||||
@Override
|
|
||||||
public void execute(@NotNull Listener listener, @NotNull Event event) throws EventException {
|
|
||||||
if (!eventClass.isInstance(event)) return;
|
|
||||||
asmExecutor.execute(listener, event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@NotNull
|
|
||||||
public String toString() {
|
|
||||||
return "ASMEventExecutor['" + m + "']";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} catch (InstantiationException | IllegalAccessException e) {
|
|
||||||
throw new AssertionError("Unable to initialize generated event executor", e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return new MethodHandleEventExecutor(eventClass, m);
|
|
||||||
}
|
}
|
||||||
|
return EventExecutorFactory.create(m, eventClass);
|
||||||
}
|
}
|
||||||
// Paper end
|
// Paper end
|
||||||
}
|
}
|
||||||
|
|||||||
@ -319,7 +319,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String[] args) {
|
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command, @NotNull String label, @NotNull String @NotNull [] args) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -328,7 +328,7 @@ public abstract class JavaPlugin extends PluginBase {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Nullable
|
@Nullable
|
||||||
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String[] args) {
|
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command, @NotNull String alias, @NotNull String @NotNull [] args) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -229,5 +229,5 @@ public interface Messenger {
|
|||||||
* @param channel Channel that the message was sent by.
|
* @param channel Channel that the message was sent by.
|
||||||
* @param message Raw payload of the message.
|
* @param message Raw payload of the message.
|
||||||
*/
|
*/
|
||||||
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, @NotNull byte[] message);
|
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, byte @NotNull [] message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,5 +17,5 @@ public interface PluginMessageListener {
|
|||||||
* @param player Source of the message.
|
* @param player Source of the message.
|
||||||
* @param message The raw message that was sent.
|
* @param message The raw message that was sent.
|
||||||
*/
|
*/
|
||||||
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, @NotNull byte[] message);
|
public void onPluginMessageReceived(@NotNull String channel, @NotNull Player player, byte @NotNull [] message);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ public interface PluginMessageRecipient {
|
|||||||
* @throws ChannelNotRegisteredException Thrown if the channel is not
|
* @throws ChannelNotRegisteredException Thrown if the channel is not
|
||||||
* registered for this plugin.
|
* registered for this plugin.
|
||||||
*/
|
*/
|
||||||
public void sendPluginMessage(@NotNull Plugin source, @NotNull String channel, @NotNull byte[] message);
|
public void sendPluginMessage(@NotNull Plugin source, @NotNull String channel, byte @NotNull [] message);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets a set containing all the Plugin Channels that this client is
|
* Gets a set containing all the Plugin Channels that this client is
|
||||||
|
|||||||
@ -439,7 +439,7 @@ public class StandardMessenger implements Messenger {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, @NotNull byte[] message) {
|
public void dispatchIncomingMessage(@NotNull Player source, @NotNull String channel, byte @NotNull [] message) {
|
||||||
if (source == null) {
|
if (source == null) {
|
||||||
throw new IllegalArgumentException("Player source cannot be null");
|
throw new IllegalArgumentException("Player source cannot be null");
|
||||||
}
|
}
|
||||||
@ -534,7 +534,7 @@ public class StandardMessenger implements Messenger {
|
|||||||
* @throws ChannelNotRegisteredException Thrown if the channel is not
|
* @throws ChannelNotRegisteredException Thrown if the channel is not
|
||||||
* registered for this plugin.
|
* registered for this plugin.
|
||||||
*/
|
*/
|
||||||
public static void validatePluginMessage(@NotNull Messenger messenger, @NotNull Plugin source, @NotNull String channel, @NotNull byte[] message) {
|
public static void validatePluginMessage(@NotNull Messenger messenger, @NotNull Plugin source, @NotNull String channel, byte @NotNull [] message) {
|
||||||
if (messenger == null) {
|
if (messenger == null) {
|
||||||
throw new IllegalArgumentException("Messenger cannot be null");
|
throw new IllegalArgumentException("Messenger cannot be null");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -150,7 +150,7 @@ public class ChatPaginator {
|
|||||||
private int pageNumber;
|
private int pageNumber;
|
||||||
private int totalPages;
|
private int totalPages;
|
||||||
|
|
||||||
public ChatPage(@NotNull String[] lines, int pageNumber, int totalPages) {
|
public ChatPage(@NotNull String @NotNull [] lines, int pageNumber, int totalPages) {
|
||||||
this.lines = lines;
|
this.lines = lines;
|
||||||
this.pageNumber = pageNumber;
|
this.pageNumber = pageNumber;
|
||||||
this.totalPages = totalPages;
|
this.totalPages = totalPages;
|
||||||
@ -165,7 +165,7 @@ public class ChatPaginator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String[] getLines() {
|
public String @NotNull [] getLines() {
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,7 +12,7 @@ public abstract class OctaveGenerator {
|
|||||||
protected double yScale = 1;
|
protected double yScale = 1;
|
||||||
protected double zScale = 1;
|
protected double zScale = 1;
|
||||||
|
|
||||||
protected OctaveGenerator(@NotNull NoiseGenerator[] octaves) {
|
protected OctaveGenerator(@NotNull NoiseGenerator @NotNull [] octaves) {
|
||||||
this.octaves = octaves;
|
this.octaves = octaves;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ public abstract class OctaveGenerator {
|
|||||||
* @return Clone of the individual octaves
|
* @return Clone of the individual octaves
|
||||||
*/
|
*/
|
||||||
@NotNull
|
@NotNull
|
||||||
public NoiseGenerator[] getOctaves() {
|
public NoiseGenerator @NotNull [] getOctaves() {
|
||||||
return octaves.clone();
|
return octaves.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -78,15 +78,15 @@ public class SimplexNoiseGenerator extends PerlinNoiseGenerator {
|
|||||||
offsetW = rand.nextDouble() * 256;
|
offsetW = rand.nextDouble() * 256;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static double dot(@NotNull int[] g, double x, double y) {
|
protected static double dot(int @NotNull [] g, double x, double y) {
|
||||||
return g[0] * x + g[1] * y;
|
return g[0] * x + g[1] * y;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static double dot(@NotNull int[] g, double x, double y, double z) {
|
protected static double dot(int @NotNull [] g, double x, double y, double z) {
|
||||||
return g[0] * x + g[1] * y + g[2] * z;
|
return g[0] * x + g[1] * y + g[2] * z;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static double dot(@NotNull int[] g, double x, double y, double z, double w) {
|
protected static double dot(int @NotNull [] g, double x, double y, double z, double w) {
|
||||||
return g[0] * x + g[1] * y + g[2] * z + g[3] * w;
|
return g[0] * x + g[1] * y + g[2] * z + g[3] * w;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -205,14 +205,16 @@ public class AnnotationTest {
|
|||||||
|
|
||||||
// Paper start - skip class if it's @NullMarked
|
// Paper start - skip class if it's @NullMarked
|
||||||
private static boolean isClassNullMarked(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) {
|
private static boolean isClassNullMarked(@NotNull ClassNode clazz, @NotNull Map<String, ClassNode> allClasses) {
|
||||||
|
if (isClassNullMarked0(clazz)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
if (clazz.nestHostClass != null) {
|
if (clazz.nestHostClass != null) {
|
||||||
final ClassNode nestHostNode = allClasses.get(clazz.nestHostClass);
|
final ClassNode nestHostNode = allClasses.get(clazz.nestHostClass);
|
||||||
if (nestHostNode != null) {
|
if (nestHostNode != null) {
|
||||||
return isClassNullMarked0(nestHostNode);
|
return isClassNullMarked(nestHostNode, allClasses);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
return isClassNullMarked0(clazz);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isClassNullMarked0(@NotNull ClassNode clazz) {
|
private static boolean isClassNullMarked0(@NotNull ClassNode clazz) {
|
||||||
|
|||||||
@ -11,7 +11,7 @@ plugins {
|
|||||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
mache("io.papermc:mache:1.21.4+build.6")
|
mache("io.papermc:mache:1.21.4+build.7")
|
||||||
paperclip("io.papermc:paperclip:3.0.3")
|
paperclip("io.papermc:paperclip:3.0.3")
|
||||||
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ dependencies {
|
|||||||
implementation("org.jline:jline-terminal-ffm:3.27.1") // use ffm on java 22+
|
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("org.jline:jline-terminal-jni:3.27.1") // fall back to jni on java 21
|
||||||
implementation("net.minecrell:terminalconsoleappender:1.3.0")
|
implementation("net.minecrell:terminalconsoleappender:1.3.0")
|
||||||
implementation("net.kyori:adventure-text-serializer-ansi:4.17.0") // Keep in sync with adventureVersion from Paper-API build file
|
implementation("net.kyori:adventure-text-serializer-ansi:4.18.0") // Keep in sync with adventureVersion from Paper-API build file
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Required to add the missing Log4j2Plugins.dat file from log4j-core
|
Required to add the missing Log4j2Plugins.dat file from log4j-core
|
||||||
|
|||||||
@ -239,7 +239,7 @@ index 0f346faa82b988e86834c38837f6f11bea7f31c6..771d6ed6a7c889c09efd4ff6e20298c8
|
|||||||
if (blockState == null) {
|
if (blockState == null) {
|
||||||
// CraftBukkit start - remove blockstate if failed (or the same)
|
// CraftBukkit start - remove blockstate if failed (or the same)
|
||||||
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
index 809b3c37d3749c76c3c243cd91c593d03693e9b3..860d1c9729c4ee97ec6f40f7aa969829070b27c0 100644
|
index c82780db7fe5b1557a7802d3111f38099be55ac1..d63d745a0220963a297cfedf1e8983aeb471a045 100644
|
||||||
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
@@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
@@ -114,14 +114,14 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||||
@ -261,7 +261,7 @@ index 809b3c37d3749c76c3c243cd91c593d03693e9b3..860d1c9729c4ee97ec6f40f7aa969829
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
index 51a136cf015de730ca0d1b48cf618a2ed69ea89f..96b0342ab7b922aa16d07b6c00542e6cb66c974a 100644
|
index ce781ba2c8b3f9f051201d3809a9cb041036f93a..cad71ac79fc52225a192aa5c5d07b13c831fc2c1 100644
|
||||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
@@ -109,7 +109,7 @@ public class LevelChunk extends ChunkAccess {
|
@@ -109,7 +109,7 @@ public class LevelChunk extends ChunkAccess {
|
||||||
@ -270,11 +270,11 @@ index 51a136cf015de730ca0d1b48cf618a2ed69ea89f..96b0342ab7b922aa16d07b6c00542e6c
|
|||||||
) {
|
) {
|
||||||
- super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData);
|
- super(pos, data, level, level.registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData);
|
||||||
+ super(pos, data, level, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry
|
+ super(pos, data, level, net.minecraft.server.MinecraftServer.getServer().registryAccess().lookupOrThrow(Registries.BIOME), inhabitedTime, sections, blendingData); // Paper - Anti-Xray - The world isn't ready yet, use server singleton for registry
|
||||||
this.level = (net.minecraft.server.level.ServerLevel) level; // CraftBukkit - type
|
this.level = (ServerLevel) level; // CraftBukkit - type
|
||||||
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
|
this.gameEventListenerRegistrySections = new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
index baa9f3e2e6e45c250930658e82bad70a3a292b05..fc21c3268c4b4fda2933d71f0913db28e3796653 100644
|
index b3d600b0d6deaf44f232dfc86e1456c867e1c07f..a7fabde0f32f09d7f7bed65576ce469f069a21fa 100644
|
||||||
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
|
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
@@ -38,9 +38,15 @@ public class LevelChunkSection {
|
@@ -38,9 +38,15 @@ public class LevelChunkSection {
|
||||||
@ -550,7 +550,7 @@ index bfbb1a2bb4abbb369a24f2f01439e9ea3e16794b..8d6ed8be4d93f7d4e6ea80c351020d88
|
|||||||
int getSerializedSize();
|
int getSerializedSize();
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
index 37437a86d74291fab1de9495008aafb15dfadce0..cf6e2053d81f7b0f8c8e58b9c0fad3285ebc047d 100644
|
index c7c87bc8df86ceeef3e15a8f23fc252d4cee1984..3b55e7fb27d680204b8621666ae9200870def3eb 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
@@ -94,7 +94,7 @@ public record SerializableChunkData(
|
@@ -94,7 +94,7 @@ public record SerializableChunkData(
|
||||||
@ -607,9 +607,9 @@ index 37437a86d74291fab1de9495008aafb15dfadce0..cf6e2053d81f7b0f8c8e58b9c0fad328
|
|||||||
@@ -414,7 +418,7 @@ public record SerializableChunkData(
|
@@ -414,7 +418,7 @@ public record SerializableChunkData(
|
||||||
|
|
||||||
// CraftBukkit start - read/write
|
// CraftBukkit start - read/write
|
||||||
private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> iregistry) {
|
private static Codec<PalettedContainer<Holder<Biome>>> makeBiomeCodecRW(Registry<Biome> biomeRegistry) {
|
||||||
- return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS));
|
- return PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS));
|
||||||
+ return PalettedContainer.codecRW(iregistry.asHolderIdMap(), iregistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, iregistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes
|
+ return PalettedContainer.codecRW(biomeRegistry.asHolderIdMap(), biomeRegistry.holderByNameCodec(), PalettedContainer.Strategy.SECTION_BIOMES, biomeRegistry.getOrThrow(Biomes.PLAINS), null); // Paper - Anti-Xray - Add preset biomes
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
|
|||||||
@ -30633,10 +30633,10 @@ index 0d65bf24f515b80701150fdc430f324a533cb478..b92a3da5c325e69f5601416d4205fb33
|
|||||||
Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> atomicReference.get().runServer(), "Server thread");
|
Thread thread = new ca.spottedleaf.moonrise.common.util.TickThread(() -> atomicReference.get().runServer(), "Server thread");
|
||||||
thread.setUncaughtExceptionHandler((thread1, exception) -> LOGGER.error("Uncaught exception in server thread", exception));
|
thread.setUncaughtExceptionHandler((thread1, exception) -> LOGGER.error("Uncaught exception in server thread", exception));
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d5946cf2501 100644
|
index 1a0455936cbca2d3812866b332e00a3aaacae8bd..5ba7f724687401c9ea1756a6491498e03548a257 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
+++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
@@ -85,7 +85,7 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -54,7 +54,7 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
@ -30644,8 +30644,8 @@ index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d59
|
|||||||
+ if (false && version < 1466) { // Paper - no longer needed, data converter system / DFU handles it now
|
+ if (false && version < 1466) { // Paper - no longer needed, data converter system / DFU handles it now
|
||||||
CompoundTag level = chunkData.getCompound("Level");
|
CompoundTag level = chunkData.getCompound("Level");
|
||||||
if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) {
|
if (level.getBoolean("TerrainPopulated") && !level.getBoolean("LightPopulated")) {
|
||||||
net.minecraft.server.level.ServerChunkCache cps = (generatoraccess == null) ? null : ((net.minecraft.server.level.ServerLevel) generatoraccess).getChunkSource();
|
// Light is purged updating to 1.14+. We need to set light populated to true so the converter recognizes the chunk as being "full"
|
||||||
@@ -96,7 +96,7 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -63,7 +63,7 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
if (version < 1493) {
|
if (version < 1493) {
|
||||||
@ -30654,7 +30654,7 @@ index 1b931e68634e72c3465a99aa29aa53009163046b..80bc7ad9ad076968d06279dedd845d59
|
|||||||
if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
||||||
LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage);
|
LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage);
|
||||||
chunkData = legacyStructureHandler.updateFromLegacy(chunkData);
|
chunkData = legacyStructureHandler.updateFromLegacy(chunkData);
|
||||||
@@ -113,7 +113,7 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -80,7 +80,7 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
// Spigot end
|
// Spigot end
|
||||||
|
|
||||||
injectDatafixingContext(chunkData, levelKey, chunkGeneratorKey);
|
injectDatafixingContext(chunkData, levelKey, chunkGeneratorKey);
|
||||||
@ -30741,7 +30741,7 @@ index feb4cd21e26598509dc140028496a6f4254c0680..de43e54698125ce9f319d4889dd49f70
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
diff --git a/net/minecraft/world/level/storage/PlayerDataStorage.java b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||||
index 6c9640f5432e9110e7811b6db246d268c6243feb..45f2800c4862a726490048576fca8e1f24252676 100644
|
index d68c6c978ac0f154ffe541fd204bec03f033ae96..c44110b123ba5912af18faf0065e9ded780da9b7 100644
|
||||||
--- a/net/minecraft/world/level/storage/PlayerDataStorage.java
|
--- a/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||||
+++ b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
+++ b/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||||
@@ -115,7 +115,7 @@ public class PlayerDataStorage {
|
@@ -115,7 +115,7 @@ public class PlayerDataStorage {
|
||||||
|
|||||||
@ -23508,10 +23508,10 @@ index 3d3eec1db91cb47395f40c4f47aa77164ad42175..216f97207dac88cc1dc3df59c6ee8a62
|
|||||||
+ // Paper end - optimise collisions
|
+ // Paper end - optimise collisions
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java
|
diff --git a/net/minecraft/core/MappedRegistry.java b/net/minecraft/core/MappedRegistry.java
|
||||||
index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff642b19ed 100644
|
index 452c358c2cfa0c39e0b09853cd4a9a12c6ced65d..5f752603aa5611ce9d3dd44cc5b70c27ac46a86e 100644
|
||||||
--- a/net/minecraft/core/MappedRegistry.java
|
--- a/net/minecraft/core/MappedRegistry.java
|
||||||
+++ b/net/minecraft/core/MappedRegistry.java
|
+++ b/net/minecraft/core/MappedRegistry.java
|
||||||
@@ -50,6 +50,19 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
@@ -51,6 +51,19 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||||
return this.getTags();
|
return this.getTags();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23531,10 +23531,10 @@ index 47b1fafd91b39e73c4e9134b0b8048000fba108a..76994c1491221c06cca5405ba239e6ff
|
|||||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle registryLifecycle) {
|
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle registryLifecycle) {
|
||||||
this(key, registryLifecycle, false);
|
this(key, registryLifecycle, false);
|
||||||
}
|
}
|
||||||
@@ -114,6 +127,7 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
@@ -116,6 +129,7 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||||
this.toId.put(value, size);
|
|
||||||
this.registrationInfos.put(key, registrationInfo);
|
this.registrationInfos.put(key, registrationInfo);
|
||||||
this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
|
this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
|
||||||
|
this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API
|
||||||
+ this.injectFluidRegister(key, value); // Paper - fluid method optimisations
|
+ this.injectFluidRegister(key, value); // Paper - fluid method optimisations
|
||||||
return reference;
|
return reference;
|
||||||
}
|
}
|
||||||
@ -26719,7 +26719,7 @@ index 2f49dbc919f7f5eea9abce6106723c72f5ae45fb..87d4291a3944f706a694536da6de0f28
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||||
index 70f6d068b3f3665b282d9750310c883839120ab2..870b9efd445ddadb3725e88351555ad986ce7c72 100644
|
index da793ad12565c36fffb26eb771ff68c76632caf7..db06f966077928419bfe469260f04d7dfda69f28 100644
|
||||||
--- a/net/minecraft/server/level/ServerEntity.java
|
--- a/net/minecraft/server/level/ServerEntity.java
|
||||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||||
@@ -91,6 +91,11 @@ public class ServerEntity {
|
@@ -91,6 +91,11 @@ public class ServerEntity {
|
||||||
@ -27496,7 +27496,7 @@ index 192977dd661ee795ada13db895db770293e9b402..95a4e37a3c93f9b3c56c7a7376ed521c
|
|||||||
}
|
}
|
||||||
|
|
||||||
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
diff --git a/net/minecraft/server/level/ServerPlayer.java b/net/minecraft/server/level/ServerPlayer.java
|
||||||
index ff5889f8fed0707a6654d9d21862e32e2ebc866d..e61fe83479f095e8addbd3e8f1d5179c998ae1eb 100644
|
index 097ec55166b9e9269142be58992c29687122fe28..aeabb79512aabd7a9e8af1be72e1745f0e7eefe4 100644
|
||||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||||
@@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team;
|
@@ -178,7 +178,7 @@ import net.minecraft.world.scores.Team;
|
||||||
@ -28372,7 +28372,7 @@ index 8cc5c0716392ba06501542ff5cbe71ee43979e5d..09fd99c9cbd23b5f3c899bfb00c9b896
|
|||||||
+ // Paper end - block counting
|
+ // Paper end - block counting
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
diff --git a/net/minecraft/world/entity/Entity.java b/net/minecraft/world/entity/Entity.java
|
||||||
index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab6814aef9ee 100644
|
index 189385600b9094291152035b17df869eaccc0428..25a1089a7376f0cbd96bb43b5c203640c88fc282 100644
|
||||||
--- a/net/minecraft/world/entity/Entity.java
|
--- a/net/minecraft/world/entity/Entity.java
|
||||||
+++ b/net/minecraft/world/entity/Entity.java
|
+++ b/net/minecraft/world/entity/Entity.java
|
||||||
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
@@ -135,7 +135,7 @@ import net.minecraft.world.scores.ScoreHolder;
|
||||||
@ -28725,7 +28725,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
|
private static float[] collectCandidateStepUpHeights(AABB box, List<VoxelShape> colliders, float deltaY, float maxUpStep) {
|
||||||
@@ -2664,23 +2812,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -2662,23 +2810,110 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isInWall() {
|
public boolean isInWall() {
|
||||||
@ -28849,7 +28849,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
}
|
}
|
||||||
|
|
||||||
public InteractionResult interact(Player player, InteractionHand hand) {
|
public InteractionResult interact(Player player, InteractionHand hand) {
|
||||||
@@ -4104,15 +4339,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4102,15 +4337,17 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
}
|
}
|
||||||
|
|
||||||
public Iterable<Entity> getIndirectPassengers() {
|
public Iterable<Entity> getIndirectPassengers() {
|
||||||
@ -28875,7 +28875,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int countPlayerPassengers() {
|
public int countPlayerPassengers() {
|
||||||
@@ -4250,77 +4487,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4248,77 +4485,136 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
return Mth.lerp(partialTick, this.yRotO, this.yRot);
|
return Mth.lerp(partialTick, this.yRotO, this.yRot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29066,7 +29066,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
|
|
||||||
public boolean touchingUnloadedChunk() {
|
public boolean touchingUnloadedChunk() {
|
||||||
AABB aabb = this.getBoundingBox().inflate(1.0);
|
AABB aabb = this.getBoundingBox().inflate(1.0);
|
||||||
@@ -4473,6 +4769,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4471,6 +4767,15 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
this.setPosRaw(x, y, z, false);
|
this.setPosRaw(x, y, z, false);
|
||||||
}
|
}
|
||||||
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
|
public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) {
|
||||||
@ -29082,7 +29082,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
if (!checkPosition(this, x, y, z)) {
|
if (!checkPosition(this, x, y, z)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -4603,6 +4908,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4601,6 +4906,12 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
|
public final void setRemoved(Entity.RemovalReason removalReason, org.bukkit.event.entity.EntityRemoveEvent.Cause cause) {
|
||||||
@ -29095,7 +29095,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause);
|
org.bukkit.craftbukkit.event.CraftEventFactory.callEntityRemoveEvent(this, cause);
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
|
final boolean alreadyRemoved = this.removalReason != null; // Paper - Folia schedulers
|
||||||
@@ -4614,7 +4925,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4612,7 +4923,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
this.stopRiding();
|
this.stopRiding();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -29104,7 +29104,7 @@ index 45f69a914d5a0565196c4105d61541047301470f..f42bdae2f80805e5069212bd16e3ab68
|
|||||||
this.levelCallback.onRemove(removalReason);
|
this.levelCallback.onRemove(removalReason);
|
||||||
this.onRemoval(removalReason);
|
this.onRemoval(removalReason);
|
||||||
// Paper start - Folia schedulers
|
// Paper start - Folia schedulers
|
||||||
@@ -4648,7 +4959,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
@@ -4646,7 +4957,7 @@ public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess
|
||||||
public boolean shouldBeSaved() {
|
public boolean shouldBeSaved() {
|
||||||
return (this.removalReason == null || this.removalReason.shouldSave())
|
return (this.removalReason == null || this.removalReason.shouldSave())
|
||||||
&& !this.isPassenger()
|
&& !this.isPassenger()
|
||||||
@ -30907,7 +30907,7 @@ index 8d98cba3830dc5dfb5cae9a6f5fedfffee0d2cd8..73962e79a0f3d892e3155443a1b84508
|
|||||||
|
|
||||||
public interface NoiseBiomeSource {
|
public interface NoiseBiomeSource {
|
||||||
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
|
diff --git a/net/minecraft/world/level/block/Block.java b/net/minecraft/world/level/block/Block.java
|
||||||
index 91d7d250f7c3de8a71aef26e23c12764b06b322b..0d36b1ac7d54283af71f2494accded11c059dba5 100644
|
index a4eb9a10b6c1351c7341bc031bb9f819e17ff1e5..976de81d65b6494cdad20f4ec5125fceec86f951 100644
|
||||||
--- a/net/minecraft/world/level/block/Block.java
|
--- a/net/minecraft/world/level/block/Block.java
|
||||||
+++ b/net/minecraft/world/level/block/Block.java
|
+++ b/net/minecraft/world/level/block/Block.java
|
||||||
@@ -259,7 +259,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
@@ -259,7 +259,7 @@ public class Block extends BlockBehaviour implements ItemLike {
|
||||||
@ -30920,7 +30920,7 @@ index 91d7d250f7c3de8a71aef26e23c12764b06b322b..0d36b1ac7d54283af71f2494accded11
|
|||||||
|
|
||||||
public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
|
public void animateTick(BlockState state, Level level, BlockPos pos, RandomSource random) {
|
||||||
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
diff --git a/net/minecraft/world/level/block/state/BlockBehaviour.java b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||||
index 25e49a24cedfa8ad04245d59fcac3231bcd62103..061d94a35d957ca72a01bae959d38aab59b1a64d 100644
|
index fa816de449a6077c05fee76835a1625f5b2008ac..5473b4006f7e0266ea11a7b05cef78a113c30d97 100644
|
||||||
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
|
--- a/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||||
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
+++ b/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||||
@@ -416,7 +416,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
@@ -416,7 +416,7 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||||
@ -31399,7 +31399,7 @@ index 92350434746f06bbf4a161c6bc42602de7b45220..1c24f38d21da1be9740512981f219924
|
|||||||
|
|
||||||
public Property.Value<T> value(T value) {
|
public Property.Value<T> value(T value) {
|
||||||
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
diff --git a/net/minecraft/world/level/chunk/ChunkAccess.java b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf0a5998c6 100644
|
index d63d745a0220963a297cfedf1e8983aeb471a045..6d565b52552534ce9cacfc35ad1bf4adcb69eac3 100644
|
||||||
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
--- a/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
+++ b/net/minecraft/world/level/chunk/ChunkAccess.java
|
||||||
@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick;
|
@@ -57,7 +57,7 @@ import net.minecraft.world.ticks.SavedTick;
|
||||||
@ -31537,8 +31537,8 @@ index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf
|
|||||||
+ // Paper end - get block chunk optimisation
|
+ // Paper end - get block chunk optimisation
|
||||||
}
|
}
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
public void setBiome(int i, int j, int k, Holder<Biome> biome) {
|
public void setBiome(int x, int y, int z, Holder<Biome> biome) {
|
||||||
@@ -507,12 +572,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
@@ -503,12 +568,12 @@ public abstract class ChunkAccess implements BiomeManager.NoiseBiomeSource, Ligh
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initializeLightSources() {
|
public void initializeLightSources() {
|
||||||
@ -31554,7 +31554,7 @@ index 860d1c9729c4ee97ec6f40f7aa969829070b27c0..94de1217d18e1a7a0fb7b83f21436eaf
|
|||||||
|
|
||||||
public record PackedTicks(List<SavedTick<Block>> blocks, List<SavedTick<Fluid>> fluids) {
|
public record PackedTicks(List<SavedTick<Block>> blocks, List<SavedTick<Fluid>> fluids) {
|
||||||
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
diff --git a/net/minecraft/world/level/chunk/ChunkGenerator.java b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||||
index 65117a9cb9d1b8684cae8d36ea3b8e2050fb928c..a9d65e28b849c9660a14ef7c16ed17bd5182bd7e 100644
|
index b320519578f7e2c52b2116afb247e071b322696e..6ed51cf42b5864194d671b5b56f5b9bdf0291dc0 100644
|
||||||
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
|
--- a/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||||
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
+++ b/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||||
@@ -116,7 +116,7 @@ public abstract class ChunkGenerator {
|
@@ -116,7 +116,7 @@ public abstract class ChunkGenerator {
|
||||||
@ -31717,7 +31717,7 @@ index e7c0f4da8508fbca467326f475668d66454d7b77..41856c98d97e7eb0782f8e441b9a269a
|
|||||||
@Override
|
@Override
|
||||||
public BlockEntity getBlockEntity(BlockPos pos) {
|
public BlockEntity getBlockEntity(BlockPos pos) {
|
||||||
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
diff --git a/net/minecraft/world/level/chunk/LevelChunk.java b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
index 96b0342ab7b922aa16d07b6c00542e6cb66c974a..c1ae7755e8d6fa8501d2210dab7605d993c55722 100644
|
index cad71ac79fc52225a192aa5c5d07b13c831fc2c1..761fdcd4a4e18f45547afd8edff44f61c6eeacb4 100644
|
||||||
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
--- a/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
+++ b/net/minecraft/world/level/chunk/LevelChunk.java
|
||||||
@@ -52,7 +52,7 @@ import net.minecraft.world.ticks.LevelChunkTicks;
|
@@ -52,7 +52,7 @@ import net.minecraft.world.ticks.LevelChunkTicks;
|
||||||
@ -31896,7 +31896,7 @@ index 96b0342ab7b922aa16d07b6c00542e6cb66c974a..c1ae7755e8d6fa8501d2210dab7605d9
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
diff --git a/net/minecraft/world/level/chunk/LevelChunkSection.java b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
index fc21c3268c4b4fda2933d71f0913db28e3796653..2ff691bcd32f587e8add2d8eda7e7339ccbde6e8 100644
|
index a7fabde0f32f09d7f7bed65576ce469f069a21fa..412e7b1cf8c24f0ddf6d174967bedad576f10aba 100644
|
||||||
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
|
--- a/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
+++ b/net/minecraft/world/level/chunk/LevelChunkSection.java
|
||||||
@@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks;
|
@@ -13,7 +13,7 @@ import net.minecraft.world.level.block.Blocks;
|
||||||
@ -32627,7 +32627,7 @@ index 7a4d299d2ce36982204e30de9278ddfd5b37c3df..b8348976e80578d9eff64eea68c04c60
|
|||||||
private final ChunkStatus status;
|
private final ChunkStatus status;
|
||||||
@Nullable
|
@Nullable
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
diff --git a/net/minecraft/world/level/chunk/storage/ChunkStorage.java b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1c3b75ba6 100644
|
index 5ba7f724687401c9ea1756a6491498e03548a257..64343a3f6e6009eed5b392482ec053be8e00ee63 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
--- a/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
+++ b/net/minecraft/world/level/chunk/storage/ChunkStorage.java
|
||||||
@@ -22,20 +22,30 @@ import net.minecraft.world.level.chunk.ChunkGenerator;
|
@@ -22,20 +22,30 @@ import net.minecraft.world.level.chunk.ChunkGenerator;
|
||||||
@ -32665,7 +32665,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
@@ -99,7 +109,9 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -66,7 +76,9 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter
|
chunkData = ca.spottedleaf.dataconverter.minecraft.MCDataConverter.convertTag(ca.spottedleaf.dataconverter.minecraft.datatypes.MCTypeRegistry.CHUNK, chunkData, version, 1493); // Paper - replace chunk converter
|
||||||
if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
if (chunkData.getCompound("Level").getBoolean("hasLegacyStructureData")) {
|
||||||
LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage);
|
LegacyStructureDataHandler legacyStructureHandler = this.getLegacyStructureHandler(levelKey, storage);
|
||||||
@ -32675,7 +32675,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -163,7 +175,13 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -130,7 +142,13 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Optional<CompoundTag>> read(ChunkPos chunkPos) {
|
public CompletableFuture<Optional<CompoundTag>> read(ChunkPos chunkPos) {
|
||||||
@ -32690,7 +32690,7 @@ index 80bc7ad9ad076968d06279dedd845d5946cf2501..433feab7f7c1931f79836164a0b8c4a1
|
|||||||
}
|
}
|
||||||
|
|
||||||
public CompletableFuture<Void> write(ChunkPos pos, Supplier<CompoundTag> tagSupplier) {
|
public CompletableFuture<Void> write(ChunkPos pos, Supplier<CompoundTag> tagSupplier) {
|
||||||
@@ -179,29 +197,54 @@ public class ChunkStorage implements AutoCloseable {
|
@@ -146,29 +164,54 @@ public class ChunkStorage implements AutoCloseable {
|
||||||
};
|
};
|
||||||
// Paper end - guard against possible chunk pos desync
|
// Paper end - guard against possible chunk pos desync
|
||||||
this.handleLegacyStructureIndex(pos);
|
this.handleLegacyStructureIndex(pos);
|
||||||
@ -32784,7 +32784,7 @@ index 889e188e920edb284f04b264bcdd06146f54a4cb..2199a9e2a0141c646d108f2687a27f1d
|
|||||||
private final Long2ObjectLinkedOpenHashMap<CompletableFuture<BitSet>> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>();
|
private final Long2ObjectLinkedOpenHashMap<CompletableFuture<BitSet>> regionCacheForBlender = new Long2ObjectLinkedOpenHashMap<>();
|
||||||
private static final int REGION_CACHE_SIZE = 1024;
|
private static final int REGION_CACHE_SIZE = 1024;
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
diff --git a/net/minecraft/world/level/chunk/storage/RegionFile.java b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
index 783a2d80f6197dd0af0dc81909f0353a8ea2ecf4..7da388ffab162c282cad0f297bb7304f3c2abbaf 100644
|
index 4eb07097986aac67421dd8e6a17cc5436da91187..984db72272d552c7210bd6f437ea88694ddd2828 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
--- a/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
+++ b/net/minecraft/world/level/chunk/storage/RegionFile.java
|
||||||
@@ -22,7 +22,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler;
|
@@ -22,7 +22,7 @@ import net.minecraft.util.profiling.jfr.JvmProfiler;
|
||||||
@ -33324,7 +33324,7 @@ index 7dc1ffffd9d0fec54dbc254c154ee85ee750174d..778bd73a938c94ecb85ca0f8b686ff4e
|
|||||||
|
|
||||||
record PackedChunk<T>(Int2ObjectMap<T> sectionsByY, boolean versionChanged) {
|
record PackedChunk<T>(Int2ObjectMap<T> sectionsByY, boolean versionChanged) {
|
||||||
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
diff --git a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
index cf6e2053d81f7b0f8c8e58b9c0fad3285ebc047d..70a9972252576e039ac126f6057a6ed66b80cdfc 100644
|
index 3b55e7fb27d680204b8621666ae9200870def3eb..879d411775a2fece1d8a970300cb3a550baa6305 100644
|
||||||
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
--- a/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
+++ b/net/minecraft/world/level/chunk/storage/SerializableChunkData.java
|
||||||
@@ -148,7 +148,7 @@ public record SerializableChunkData(
|
@@ -148,7 +148,7 @@ public record SerializableChunkData(
|
||||||
@ -33700,10 +33700,10 @@ index 342c83309b19c64d86e0dd97c1756c96be52772b..423779a2b690f387a4f0bd07b97b50e0
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
diff --git a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||||
index 29d9f6e54421c539e9e55ab9f51b4c872da3fbb8..d77016287f5f9a0964d56f05d2d5256ef2e6e86c 100644
|
index 6d61739574155f89511b9adcaf1174841bdc7da7..65728ef17e63d71833677fdcbd5bb90794b4822b 100644
|
||||||
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
--- a/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||||
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
+++ b/net/minecraft/world/level/levelgen/NoiseBasedChunkGenerator.java
|
||||||
@@ -78,7 +78,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
@@ -77,7 +77,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||||
return CompletableFuture.supplyAsync(() -> {
|
return CompletableFuture.supplyAsync(() -> {
|
||||||
this.doCreateBiomes(blender, randomState, structureManager, chunk);
|
this.doCreateBiomes(blender, randomState, structureManager, chunk);
|
||||||
return chunk;
|
return chunk;
|
||||||
@ -33712,7 +33712,7 @@ index 29d9f6e54421c539e9e55ab9f51b4c872da3fbb8..d77016287f5f9a0964d56f05d2d5256e
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doCreateBiomes(Blender blender, RandomState random, StructureManager structureManager, ChunkAccess chunk) {
|
private void doCreateBiomes(Blender blender, RandomState random, StructureManager structureManager, ChunkAccess chunk) {
|
||||||
@@ -318,7 +318,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
@@ -317,7 +317,7 @@ public final class NoiseBasedChunkGenerator extends ChunkGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
return var20;
|
return var20;
|
||||||
@ -34002,7 +34002,7 @@ index ca23af013967b50420ebee178878ea79333de53b..d41b9266625ca6c5e32c5126f35a1f77
|
|||||||
|
|
||||||
public int getLightSectionCount() {
|
public int getLightSectionCount() {
|
||||||
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
|
diff --git a/net/minecraft/world/level/material/FlowingFluid.java b/net/minecraft/world/level/material/FlowingFluid.java
|
||||||
index 130ef38a50f1df1faa26b433b0c605a4507f71af..f6daca279788c3d983a9ee213df85d5d93fc6eed 100644
|
index 86fd2b831f42bdb5bd045e44b26489d5a8697dd9..e30499bdcd6600e5c9d4a755c1182fb6dff3735f 100644
|
||||||
--- a/net/minecraft/world/level/material/FlowingFluid.java
|
--- a/net/minecraft/world/level/material/FlowingFluid.java
|
||||||
+++ b/net/minecraft/world/level/material/FlowingFluid.java
|
+++ b/net/minecraft/world/level/material/FlowingFluid.java
|
||||||
@@ -45,6 +45,48 @@ public abstract class FlowingFluid extends Fluid {
|
@@ -45,6 +45,48 @@ public abstract class FlowingFluid extends Fluid {
|
||||||
|
|||||||
@ -60,7 +60,7 @@ index 3dff97f13586be3b52bbe786852c185f6753a019..ff6503bf8eb88d1264c3d848a89d0255
|
|||||||
} else if (this.seenBy.remove(player.connection)) {
|
} else if (this.seenBy.remove(player.connection)) {
|
||||||
this.serverEntity.removePairing(player);
|
this.serverEntity.removePairing(player);
|
||||||
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
diff --git a/net/minecraft/server/level/ServerEntity.java b/net/minecraft/server/level/ServerEntity.java
|
||||||
index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f7117281649b7a 100644
|
index db06f966077928419bfe469260f04d7dfda69f28..0fb253aa55a24b56b17f524b3261c5b75c7d7e59 100644
|
||||||
--- a/net/minecraft/server/level/ServerEntity.java
|
--- a/net/minecraft/server/level/ServerEntity.java
|
||||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||||
@@ -90,6 +90,13 @@ public class ServerEntity {
|
@@ -90,6 +90,13 @@ public class ServerEntity {
|
||||||
@ -77,7 +77,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172
|
|||||||
public void sendChanges() {
|
public void sendChanges() {
|
||||||
// Paper start - optimise collisions
|
// Paper start - optimise collisions
|
||||||
if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) {
|
if (((ca.spottedleaf.moonrise.patches.chunk_system.entity.ChunkSystemEntity)this.entity).moonrise$isHardColliding()) {
|
||||||
@@ -130,7 +137,7 @@ public class ServerEntity {
|
@@ -131,7 +138,7 @@ public class ServerEntity {
|
||||||
this.sendDirtyEntityData();
|
this.sendDirtyEntityData();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,7 +86,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172
|
|||||||
byte b = Mth.packDegrees(this.entity.getYRot());
|
byte b = Mth.packDegrees(this.entity.getYRot());
|
||||||
byte b1 = Mth.packDegrees(this.entity.getXRot());
|
byte b1 = Mth.packDegrees(this.entity.getXRot());
|
||||||
boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
|
boolean flag = Math.abs(b - this.lastSentYRot) >= 1 || Math.abs(b1 - this.lastSentXRot) >= 1;
|
||||||
@@ -165,7 +172,7 @@ public class ServerEntity {
|
@@ -166,7 +173,7 @@ public class ServerEntity {
|
||||||
long l1 = this.positionCodec.encodeY(vec3);
|
long l1 = this.positionCodec.encodeY(vec3);
|
||||||
long l2 = this.positionCodec.encodeZ(vec3);
|
long l2 = this.positionCodec.encodeZ(vec3);
|
||||||
boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L;
|
boolean flag5 = l < -32768L || l > 32767L || l1 < -32768L || l1 > 32767L || l2 < -32768L || l2 > 32767L;
|
||||||
@ -95,7 +95,7 @@ index 870b9efd445ddadb3725e88351555ad986ce7c72..a4da36060ca75968f5831adfc3f71172
|
|||||||
this.wasOnGround = this.entity.onGround();
|
this.wasOnGround = this.entity.onGround();
|
||||||
this.teleportDelay = 0;
|
this.teleportDelay = 0;
|
||||||
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
|
packet = ClientboundEntityPositionSyncPacket.of(this.entity);
|
||||||
@@ -230,6 +237,7 @@ public class ServerEntity {
|
@@ -231,6 +238,7 @@ public class ServerEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.entity.hasImpulse = false;
|
this.entity.hasImpulse = false;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
--- a/net/minecraft/core/MappedRegistry.java
|
--- a/net/minecraft/core/MappedRegistry.java
|
||||||
+++ b/net/minecraft/core/MappedRegistry.java
|
+++ b/net/minecraft/core/MappedRegistry.java
|
||||||
@@ -33,11 +_,11 @@
|
@@ -33,17 +_,18 @@
|
||||||
public class MappedRegistry<T> implements WritableRegistry<T> {
|
public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||||
private final ResourceKey<? extends Registry<T>> key;
|
private final ResourceKey<? extends Registry<T>> key;
|
||||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||||
@ -17,6 +17,29 @@
|
|||||||
private Lifecycle registryLifecycle;
|
private Lifecycle registryLifecycle;
|
||||||
private final Map<TagKey<T>, HolderSet.Named<T>> frozenTags = new IdentityHashMap<>();
|
private final Map<TagKey<T>, HolderSet.Named<T>> frozenTags = new IdentityHashMap<>();
|
||||||
MappedRegistry.TagSet<T> allTags = MappedRegistry.TagSet.unbound();
|
MappedRegistry.TagSet<T> allTags = MappedRegistry.TagSet.unbound();
|
||||||
|
private boolean frozen;
|
||||||
|
@Nullable
|
||||||
|
private Map<T, Holder.Reference<T>> unregisteredIntrusiveHolders;
|
||||||
|
+ public final Map<ResourceLocation, T> temporaryUnfrozenMap = new HashMap<>(); // Paper - support pre-filling in registry mod API
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Stream<HolderSet.Named<T>> listTags() {
|
||||||
|
@@ -114,6 +_,7 @@
|
||||||
|
this.toId.put(value, size);
|
||||||
|
this.registrationInfos.put(key, registrationInfo);
|
||||||
|
this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
|
||||||
|
+ this.temporaryUnfrozenMap.put(key.location(), value); // Paper - support pre-filling in registry mod API
|
||||||
|
return reference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -275,6 +_,7 @@
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
this.frozen = true;
|
||||||
|
+ this.temporaryUnfrozenMap.clear(); // Paper - support pre-filling in registry mod API
|
||||||
|
this.byValue.forEach((object, reference) -> reference.bindValue((T)object));
|
||||||
|
List<ResourceLocation> list = this.byKey
|
||||||
|
.entrySet()
|
||||||
@@ -509,4 +_,13 @@
|
@@ -509,4 +_,13 @@
|
||||||
|
|
||||||
Stream<HolderSet.Named<T>> getTags();
|
Stream<HolderSet.Named<T>> getTags();
|
||||||
|
|||||||
@ -26,7 +26,7 @@
|
|||||||
ResourceLocation resourceLocation = key.location();
|
ResourceLocation resourceLocation = key.location();
|
||||||
LOADERS.put(resourceLocation, () -> bootstrap.run(registry));
|
LOADERS.put(resourceLocation, () -> bootstrap.run(registry));
|
||||||
WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN);
|
WRITABLE_REGISTRY.register((ResourceKey)key, registry, RegistrationInfo.BUILT_IN);
|
||||||
@@ -328,7 +_,14 @@
|
@@ -328,16 +_,34 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void bootStrap() {
|
public static void bootStrap() {
|
||||||
@ -41,6 +41,26 @@
|
|||||||
freeze();
|
freeze();
|
||||||
validate(REGISTRY);
|
validate(REGISTRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void createContents() {
|
||||||
|
+ // Paper start - class-load org.bukkit.Registry
|
||||||
|
+ // we have to class-load Registry here to create all the CraftRegistry instances
|
||||||
|
+ // that will be created when Registry is class-loaded before RegistryAccess#getRegistry
|
||||||
|
+ // would try to create them in lockReferenceHolder
|
||||||
|
+ try {
|
||||||
|
+ Class.forName(org.bukkit.Registry.class.getName());
|
||||||
|
+ } catch (final ClassNotFoundException ex) {
|
||||||
|
+ throw new RuntimeException(ex);
|
||||||
|
+ }
|
||||||
|
+ // Paper end - class-load org.bukkit.Registry
|
||||||
|
LOADERS.forEach((resourceLocation, supplier) -> {
|
||||||
|
if (supplier.get() == null) {
|
||||||
|
LOGGER.error("Unable to bootstrap registry '{}'", resourceLocation);
|
||||||
|
}
|
||||||
|
+ io.papermc.paper.registry.PaperRegistryAccess.instance().lockReferenceHolders(ResourceKey.createRegistryKey(resourceLocation)); // Paper - lock reference holder creation
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@@ -346,6 +_,7 @@
|
@@ -346,6 +_,7 @@
|
||||||
|
|
||||||
for (Registry<?> registry : REGISTRY) {
|
for (Registry<?> registry : REGISTRY) {
|
||||||
|
|||||||
@ -34,11 +34,12 @@
|
|||||||
} catch (Exception var14) {
|
} catch (Exception var14) {
|
||||||
loadingErrors.put(
|
loadingErrors.put(
|
||||||
resourceKey,
|
resourceKey,
|
||||||
@@ -283,7 +_,8 @@
|
@@ -283,7 +_,9 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- TagLoader.loadTagsForRegistry(resourceManager, registry);
|
- TagLoader.loadTagsForRegistry(resourceManager, registry);
|
||||||
|
+ io.papermc.paper.registry.PaperRegistryAccess.instance().lockReferenceHolders(registry.key()); // Paper - lock reference holders
|
||||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners
|
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), conversions); // Paper - run pre-freeze listeners
|
||||||
+ TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause
|
+ TagLoader.loadTagsForRegistry(resourceManager, registry, io.papermc.paper.plugin.lifecycle.event.registrar.ReloadableRegistrarEvent.Cause.INITIAL); // Paper - tag lifecycle - add cause
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1193,15 +1193,18 @@
|
|||||||
return ReloadableServerResources.loadResources(
|
return ReloadableServerResources.loadResources(
|
||||||
closeableResourceManager,
|
closeableResourceManager,
|
||||||
this.registries,
|
this.registries,
|
||||||
@@ -1520,6 +_,7 @@
|
@@ -1520,20 +_,39 @@
|
||||||
)
|
)
|
||||||
.thenAcceptAsync(
|
.thenAcceptAsync(
|
||||||
reloadableResources -> {
|
reloadableResources -> {
|
||||||
+ io.papermc.paper.command.brigadier.PaperBrigadier.moveBukkitCommands(this.resources.managers().getCommands(), reloadableResources.managers().commands); // Paper
|
+ io.papermc.paper.command.brigadier.PaperBrigadier.moveBukkitCommands(this.resources.managers().getCommands(), reloadableResources.managers().commands); // Paper
|
||||||
this.resources.close();
|
this.resources.close();
|
||||||
this.resources = reloadableResources;
|
this.resources = reloadableResources;
|
||||||
this.packRepository.setSelected(selectedIds);
|
- this.packRepository.setSelected(selectedIds);
|
||||||
@@ -1529,11 +_,29 @@
|
+ this.packRepository.setSelected(selectedIds, false); // Paper - add pendingReload flag to determine required pack loading - false as this is *after* a reload (see above)
|
||||||
|
WorldDataConfiguration worldDataConfiguration = new WorldDataConfiguration(
|
||||||
|
getSelectedPacks(this.packRepository, true), this.worldData.enabledFeatures()
|
||||||
|
);
|
||||||
this.worldData.setDataConfiguration(worldDataConfiguration);
|
this.worldData.setDataConfiguration(worldDataConfiguration);
|
||||||
this.resources.managers.updateStaticRegistryTags();
|
this.resources.managers.updateStaticRegistryTags();
|
||||||
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
|
this.resources.managers.getRecipeManager().finalizeRecipeLoading(this.worldData.enabledFeatures());
|
||||||
@ -1232,6 +1235,33 @@
|
|||||||
},
|
},
|
||||||
this
|
this
|
||||||
);
|
);
|
||||||
|
@@ -1550,7 +_,7 @@
|
||||||
|
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
|
||||||
|
FeatureFlagSet featureFlagSet = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
|
||||||
|
FeatureFlagSet featureFlagSet1 = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
|
||||||
|
- packRepository.reload();
|
||||||
|
+ packRepository.reload(true); // Paper - will load resource packs
|
||||||
|
if (safeMode) {
|
||||||
|
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), featureFlagSet, false);
|
||||||
|
} else {
|
||||||
|
@@ -1605,7 +_,7 @@
|
||||||
|
private static WorldDataConfiguration configureRepositoryWithSelection(
|
||||||
|
PackRepository packRepository, Collection<String> selectedPacks, FeatureFlagSet enabledFeatures, boolean safeMode
|
||||||
|
) {
|
||||||
|
- packRepository.setSelected(selectedPacks);
|
||||||
|
+ packRepository.setSelected(selectedPacks, true); // Paper - add pendingReload flag to determine required pack loading - before the initial server load
|
||||||
|
enableForcedFeaturePacks(packRepository, enabledFeatures);
|
||||||
|
DataPackConfig selectedPacks1 = getSelectedPacks(packRepository, safeMode);
|
||||||
|
FeatureFlagSet featureFlagSet = packRepository.getRequestedFeatureFlags().join(enabledFeatures);
|
||||||
|
@@ -1637,7 +_,7 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- packRepository.setSelected(set);
|
||||||
|
+ packRepository.setSelected(set, true); // Paper - add pendingReload flag to determine required pack loading - before the initial server start
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1652,10 +_,11 @@
|
@@ -1652,10 +_,11 @@
|
||||||
if (this.isEnforceWhitelist()) {
|
if (this.isEnforceWhitelist()) {
|
||||||
PlayerList playerList = commandSource.getServer().getPlayerList();
|
PlayerList playerList = commandSource.getServer().getPlayerList();
|
||||||
|
|||||||
@ -9,6 +9,15 @@
|
|||||||
LOGGER.warn("Failed to execute reload", throwable);
|
LOGGER.warn("Failed to execute reload", throwable);
|
||||||
source.sendFailure(Component.translatable("commands.reload.failure"));
|
source.sendFailure(Component.translatable("commands.reload.failure"));
|
||||||
return null;
|
return null;
|
||||||
|
@@ -24,7 +_,7 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Collection<String> discoverNewPacks(PackRepository packRepository, WorldData worldData, Collection<String> selectedIds) {
|
||||||
|
- packRepository.reload();
|
||||||
|
+ packRepository.reload(true); // Paper - will perform a full reload
|
||||||
|
Collection<String> list = Lists.newArrayList(selectedIds);
|
||||||
|
Collection<String> disabled = worldData.getDataConfiguration().dataPacks().getDisabled();
|
||||||
|
|
||||||
@@ -36,6 +_,16 @@
|
@@ -36,6 +_,16 @@
|
||||||
|
|
||||||
return list;
|
return list;
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
removedPassengers(passengers, this.lastPassengers)
|
removedPassengers(passengers, this.lastPassengers)
|
||||||
.forEach(
|
.forEach(
|
||||||
removedPassenger -> {
|
removedPassenger -> {
|
||||||
@@ -102,10 +_,10 @@
|
@@ -102,13 +_,14 @@
|
||||||
this.lastPassengers = passengers;
|
this.lastPassengers = passengers;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,7 +42,12 @@
|
|||||||
+ MapId mapId = itemFrame.cachedMapId; // Paper - Perf: Cache map ids on item frames
|
+ MapId mapId = itemFrame.cachedMapId; // Paper - Perf: Cache map ids on item frames
|
||||||
MapItemSavedData savedData = MapItem.getSavedData(mapId, this.level);
|
MapItemSavedData savedData = MapItem.getSavedData(mapId, this.level);
|
||||||
if (savedData != null) {
|
if (savedData != null) {
|
||||||
for (ServerPlayer serverPlayer : this.level.players()) {
|
- for (ServerPlayer serverPlayer : this.level.players()) {
|
||||||
|
+ for (final net.minecraft.server.network.ServerPlayerConnection connection : this.trackedPlayers) { // Paper
|
||||||
|
+ final ServerPlayer serverPlayer = connection.getPlayer(); // Paper
|
||||||
|
savedData.tickCarriedBy(serverPlayer, item);
|
||||||
|
Packet<?> updatePacket = savedData.getUpdatePacket(mapId, serverPlayer);
|
||||||
|
if (updatePacket != null) {
|
||||||
@@ -141,7 +_,13 @@
|
@@ -141,7 +_,13 @@
|
||||||
} else {
|
} else {
|
||||||
this.teleportDelay++;
|
this.teleportDelay++;
|
||||||
|
|||||||
@ -1342,17 +1342,18 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public SectionPos getLastSectionPos() {
|
public SectionPos getLastSectionPos() {
|
||||||
@@ -1930,21 +_,54 @@
|
@@ -1930,21 +_,55 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
- public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem) {
|
- public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem) {
|
||||||
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem, boolean callEvent) { // CraftBukkit - SPIGOT-2942: Add boolean to call event
|
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean traceItem, boolean callEvent, @Nullable java.util.function.Consumer<org.bukkit.entity.Item> entityOperation) { // Paper start - Extend HumanEntity#dropItem API
|
||||||
ItemEntity itemEntity = this.createItemStackToDrop(droppedItem, dropAround, traceItem);
|
ItemEntity itemEntity = this.createItemStackToDrop(droppedItem, dropAround, traceItem);
|
||||||
if (itemEntity == null) {
|
if (itemEntity == null) {
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
+ // CraftBukkit start - fire PlayerDropItemEvent
|
+ // CraftBukkit start - fire PlayerDropItemEvent
|
||||||
|
+ if (entityOperation != null) entityOperation.accept((org.bukkit.entity.Item) itemEntity.getBukkitEntity());
|
||||||
+ if (callEvent) {
|
+ if (callEvent) {
|
||||||
+ org.bukkit.entity.Player player = this.getBukkitEntity();
|
+ org.bukkit.entity.Player player = this.getBukkitEntity();
|
||||||
+ org.bukkit.entity.Item drop = (org.bukkit.entity.Item) itemEntity.getBukkitEntity();
|
+ org.bukkit.entity.Item drop = (org.bukkit.entity.Item) itemEntity.getBukkitEntity();
|
||||||
|
|||||||
@ -95,7 +95,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,30 +_,117 @@
|
@@ -88,30 +_,119 @@
|
||||||
public void handlePong(ServerboundPongPacket packet) {
|
public void handlePong(ServerboundPongPacket packet) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,15 +208,16 @@
|
|||||||
Profiler.get().push("keepAlive");
|
Profiler.get().push("keepAlive");
|
||||||
long millis = Util.getMillis();
|
long millis = Util.getMillis();
|
||||||
- if (!this.isSingleplayerOwner() && millis - this.keepAliveTime >= 15000L) {
|
- if (!this.isSingleplayerOwner() && millis - this.keepAliveTime >= 15000L) {
|
||||||
- if (this.keepAlivePending) {
|
|
||||||
- this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE);
|
|
||||||
+ // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
+ // Paper start - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||||
+ // This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
+ // This should effectively place the keepalive handling back to "as it was" before 1.12.2
|
||||||
+ final long elapsedTime = millis - this.keepAliveTime;
|
+ final long elapsedTime = millis - this.keepAliveTime;
|
||||||
+ if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets
|
+ if (!this.isSingleplayerOwner() && elapsedTime >= 15000L) { // use vanilla's 15000L between keep alive packets
|
||||||
+ if (this.keepAlivePending && !this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
if (this.keepAlivePending) {
|
||||||
+ // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
- this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE);
|
||||||
|
+ if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
|
||||||
+ this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
|
+ this.disconnect(TIMEOUT_DISCONNECTION_MESSAGE, org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
|
||||||
|
+ }
|
||||||
|
+ // Paper end - give clients a longer time to respond to pings as per pre 1.12.2 timings
|
||||||
} else if (this.checkIfClosed(millis)) {
|
} else if (this.checkIfClosed(millis)) {
|
||||||
this.keepAlivePending = true;
|
this.keepAlivePending = true;
|
||||||
this.keepAliveTime = millis;
|
this.keepAliveTime = millis;
|
||||||
|
|||||||
@ -0,0 +1,76 @@
|
|||||||
|
--- a/net/minecraft/server/packs/repository/PackRepository.java
|
||||||
|
+++ b/net/minecraft/server/packs/repository/PackRepository.java
|
||||||
|
@@ -21,9 +_,13 @@
|
||||||
|
private final Set<RepositorySource> sources;
|
||||||
|
private Map<String, Pack> available = ImmutableMap.of();
|
||||||
|
private List<Pack> selected = ImmutableList.of();
|
||||||
|
+ private final net.minecraft.world.level.validation.DirectoryValidator validator; // Paper - add validator
|
||||||
|
|
||||||
|
- public PackRepository(RepositorySource... sources) {
|
||||||
|
- this.sources = ImmutableSet.copyOf(sources);
|
||||||
|
+ // Paper start - add validator
|
||||||
|
+ public PackRepository(net.minecraft.world.level.validation.DirectoryValidator validator, RepositorySource... providers) {
|
||||||
|
+ this.validator = validator;
|
||||||
|
+ // Paper end - add validator
|
||||||
|
+ this.sources = ImmutableSet.copyOf(providers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String displayPackList(Collection<Pack> packs) {
|
||||||
|
@@ -31,9 +_,14 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
+ // Paper start - add pendingReload flag to determine required pack loading
|
||||||
|
+ this.reload(false);
|
||||||
|
+ }
|
||||||
|
+ public void reload(final boolean pendingReload) {
|
||||||
|
+ // Paper end - add pendingReload flag to determine required pack loading
|
||||||
|
List<String> list = this.selected.stream().map(Pack::getId).collect(ImmutableList.toImmutableList());
|
||||||
|
this.available = this.discoverAvailable();
|
||||||
|
- this.selected = this.rebuildSelected(list);
|
||||||
|
+ this.selected = this.rebuildSelected(list, pendingReload); // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Pack> discoverAvailable() {
|
||||||
|
@@ -43,16 +_,23 @@
|
||||||
|
repositorySource.loadPacks(pack -> map.put(pack.getId(), pack));
|
||||||
|
}
|
||||||
|
|
||||||
|
- return ImmutableMap.copyOf(map);
|
||||||
|
+ // Paper start - custom plugin-loaded datapacks
|
||||||
|
+ final io.papermc.paper.datapack.PaperDatapackRegistrar registrar = new io.papermc.paper.datapack.PaperDatapackRegistrar(this.validator, map);
|
||||||
|
+ io.papermc.paper.plugin.lifecycle.event.LifecycleEventRunner.INSTANCE.callStaticRegistrarEvent(io.papermc.paper.plugin.lifecycle.event.types.LifecycleEvents.DATAPACK_DISCOVERY,
|
||||||
|
+ registrar,
|
||||||
|
+ io.papermc.paper.plugin.bootstrap.BootstrapContext.class
|
||||||
|
+ );
|
||||||
|
+ return ImmutableMap.copyOf(registrar.discoveredPacks);
|
||||||
|
+ // Paper end - custom plugin-loaded datapacks
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isAbleToClearAnyPack() {
|
||||||
|
- List<Pack> list = this.rebuildSelected(List.of());
|
||||||
|
+ List<Pack> list = this.rebuildSelected(List.of(), false); // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
return !this.selected.equals(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
- public void setSelected(Collection<String> ids) {
|
||||||
|
- this.selected = this.rebuildSelected(ids);
|
||||||
|
+ public void setSelected(Collection<String> ids, final boolean pendingReload) { // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
+ this.selected = this.rebuildSelected(ids, pendingReload); // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean addPack(String id) {
|
||||||
|
@@ -79,11 +_,11 @@
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- private List<Pack> rebuildSelected(Collection<String> ids) {
|
||||||
|
+ private List<Pack> rebuildSelected(Collection<String> ids, boolean pendingReload) { // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
List<Pack> list = this.getAvailablePacks(ids).collect(Util.toMutableList());
|
||||||
|
|
||||||
|
for (Pack pack : this.available.values()) {
|
||||||
|
- if (pack.isRequired() && !list.contains(pack)) {
|
||||||
|
+ if (pack.isRequired() && !list.contains(pack) && pendingReload) { // Paper - add pendingReload flag to determine required pack loading
|
||||||
|
pack.getDefaultPosition().insert(list, pack, Pack::selectionConfig, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,7 +9,7 @@
|
|||||||
.applyDevelopmentConfig()
|
.applyDevelopmentConfig()
|
||||||
.pushJarResources()
|
.pushJarResources()
|
||||||
.build(VANILLA_PACK_INFO);
|
.build(VANILLA_PACK_INFO);
|
||||||
@@ -68,7 +_,18 @@
|
@@ -68,15 +_,26 @@
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
protected Pack createBuiltinPack(String id, Pack.ResourcesSupplier resources, Component title) {
|
protected Pack createBuiltinPack(String id, Pack.ResourcesSupplier resources, Component title) {
|
||||||
@ -29,3 +29,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static PackRepository createPackRepository(Path folder, DirectoryValidator validator) {
|
public static PackRepository createPackRepository(Path folder, DirectoryValidator validator) {
|
||||||
|
- return new PackRepository(new ServerPacksSource(validator), new FolderRepositorySource(folder, PackType.SERVER_DATA, PackSource.WORLD, validator));
|
||||||
|
+ return new PackRepository(validator, new ServerPacksSource(validator), new FolderRepositorySource(folder, PackType.SERVER_DATA, PackSource.WORLD, validator)); // Paper - add validator
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PackRepository createVanillaTrustedRepository() {
|
||||||
|
- return new PackRepository(new ServerPacksSource(new DirectoryValidator(path -> true)));
|
||||||
|
+ return new PackRepository(new DirectoryValidator(path -> true), new ServerPacksSource(new DirectoryValidator(path -> true))); // Paper - add validator
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PackRepository createPackRepository(LevelStorageSource.LevelStorageAccess level) {
|
||||||
|
|||||||
@ -706,52 +706,44 @@
|
|||||||
|
|
||||||
public void awardKillScore(Entity entity, DamageSource damageSource) {
|
public void awardKillScore(Entity entity, DamageSource damageSource) {
|
||||||
if (entity instanceof ServerPlayer) {
|
if (entity instanceof ServerPlayer) {
|
||||||
@@ -1752,34 +_,70 @@
|
@@ -1752,15 +_,22 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean saveAsPassenger(CompoundTag compound) {
|
public boolean saveAsPassenger(CompoundTag compound) {
|
||||||
|
- if (this.removalReason != null && !this.removalReason.shouldSave()) {
|
||||||
+ // CraftBukkit start - allow excluding certain data when saving
|
+ // CraftBukkit start - allow excluding certain data when saving
|
||||||
+ return this.saveAsPassenger(compound, true);
|
+ // Paper start - Raw entity serialization API
|
||||||
|
+ return this.saveAsPassenger(compound, true, false, false);
|
||||||
+ }
|
+ }
|
||||||
+
|
+ public boolean saveAsPassenger(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) {
|
||||||
+ public boolean saveAsPassenger(CompoundTag compound, boolean includeAll) {
|
+ // Paper end - Raw entity serialization API
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
if (this.removalReason != null && !this.removalReason.shouldSave()) {
|
+ if (this.removalReason != null && !this.removalReason.shouldSave() && !forceSerialization) { // Paper - Raw entity serialization API
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
String encodeId = this.getEncodeId();
|
- String encodeId = this.getEncodeId();
|
||||||
- if (encodeId == null) {
|
- if (encodeId == null) {
|
||||||
+ if (!this.persist || encodeId == null) { // CraftBukkit - persist flag
|
+ String encodeId = this.getEncodeId(includeNonSaveable); // Paper - Raw entity serialization API
|
||||||
|
+ if ((!this.persist && !forceSerialization) || encodeId == null) { // CraftBukkit - persist flag // Paper - Raw entity serialization API
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
compound.putString("id", encodeId);
|
compound.putString("id", encodeId);
|
||||||
- this.saveWithoutId(compound);
|
- this.saveWithoutId(compound);
|
||||||
+ this.saveWithoutId(compound, includeAll); // CraftBukkit - pass on includeAll
|
+ this.saveWithoutId(compound, includeAll, includeNonSaveable, forceSerialization); // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
@@ -1771,15 +_,37 @@
|
||||||
+
|
|
||||||
+ // Paper start - Entity serialization api
|
|
||||||
+ public boolean serializeEntity(CompoundTag compound) {
|
|
||||||
+ List<Entity> pass = new java.util.ArrayList<>(this.getPassengers());
|
|
||||||
+ this.passengers = ImmutableList.of();
|
|
||||||
+ boolean result = save(compound);
|
|
||||||
+ this.passengers = ImmutableList.copyOf(pass);
|
|
||||||
+ return result;
|
|
||||||
+ }
|
|
||||||
+ // Paper end - Entity serialization api
|
|
||||||
|
|
||||||
public boolean save(CompoundTag compound) {
|
|
||||||
return !this.isPassenger() && this.saveAsPassenger(compound);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public CompoundTag saveWithoutId(CompoundTag compound) {
|
public CompoundTag saveWithoutId(CompoundTag compound) {
|
||||||
+ // CraftBukkit start - allow excluding certain data when saving
|
+ // CraftBukkit start - allow excluding certain data when saving
|
||||||
+ return this.saveWithoutId(compound, true);
|
+ // Paper start - Raw entity serialization API
|
||||||
|
+ return this.saveWithoutId(compound, true, false, false);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ public CompoundTag saveWithoutId(CompoundTag compound, boolean includeAll) {
|
+ public CompoundTag saveWithoutId(CompoundTag compound, boolean includeAll, boolean includeNonSaveable, boolean forceSerialization) {
|
||||||
|
+ // Paper end - Raw entity serialization API
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
try {
|
try {
|
||||||
- if (this.vehicle != null) {
|
- if (this.vehicle != null) {
|
||||||
@ -827,7 +819,7 @@
|
|||||||
for (Entity entity : this.getPassengers()) {
|
for (Entity entity : this.getPassengers()) {
|
||||||
CompoundTag compoundTag = new CompoundTag();
|
CompoundTag compoundTag = new CompoundTag();
|
||||||
- if (entity.saveAsPassenger(compoundTag)) {
|
- if (entity.saveAsPassenger(compoundTag)) {
|
||||||
+ if (entity.saveAsPassenger(compoundTag, includeAll)) { // CraftBukkit - pass on includeAll
|
+ if (entity.saveAsPassenger(compoundTag, includeAll, includeNonSaveable, forceSerialization)) { // CraftBukkit - pass on includeAll // Paper - Raw entity serialization API
|
||||||
listTag.add(compoundTag);
|
listTag.add(compoundTag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -935,19 +927,30 @@
|
|||||||
} catch (Throwable var17) {
|
} catch (Throwable var17) {
|
||||||
CrashReport crashReport = CrashReport.forThrowable(var17, "Loading entity NBT");
|
CrashReport crashReport = CrashReport.forThrowable(var17, "Loading entity NBT");
|
||||||
CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded");
|
CrashReportCategory crashReportCategory = crashReport.addCategory("Entity being loaded");
|
||||||
@@ -1949,6 +_,12 @@
|
@@ -1944,10 +_,21 @@
|
||||||
return type.canSerialize() && key != null ? key.toString() : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public final String getEncodeId() {
|
||||||
|
+ // Paper start - Raw entity serialization API
|
||||||
|
+ return getEncodeId(false);
|
||||||
|
+ }
|
||||||
|
+ public final @Nullable String getEncodeId(boolean includeNonSaveable) {
|
||||||
|
+ // Paper end - Raw entity serialization API
|
||||||
|
EntityType<?> type = this.getType();
|
||||||
|
ResourceLocation key = EntityType.getKey(type);
|
||||||
|
- return type.canSerialize() && key != null ? key.toString() : null;
|
||||||
|
- }
|
||||||
|
+ return (type.canSerialize() || includeNonSaveable) && key != null ? key.toString() : null; // Paper - Raw entity serialization API
|
||||||
|
+ }
|
||||||
|
+
|
||||||
+ // CraftBukkit start - allow excluding certain data when saving
|
+ // CraftBukkit start - allow excluding certain data when saving
|
||||||
+ protected void addAdditionalSaveData(CompoundTag tag, boolean includeAll) {
|
+ protected void addAdditionalSaveData(CompoundTag tag, boolean includeAll) {
|
||||||
+ this.addAdditionalSaveData(tag);
|
+ this.addAdditionalSaveData(tag);
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
|
||||||
protected abstract void readAdditionalSaveData(CompoundTag tag);
|
protected abstract void readAdditionalSaveData(CompoundTag tag);
|
||||||
|
|
||||||
protected abstract void addAdditionalSaveData(CompoundTag tag);
|
|
||||||
@@ -1990,11 +_,61 @@
|
@@ -1990,11 +_,61 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@ -48,7 +48,12 @@
|
|||||||
List<Entity> entities = this.level()
|
List<Entity> entities = this.level()
|
||||||
.getEntities(
|
.getEntities(
|
||||||
this,
|
this,
|
||||||
@@ -172,22 +_,30 @@
|
@@ -168,26 +_,34 @@
|
||||||
|
}
|
||||||
|
|
||||||
|
private void spawnFire(int extraIgnitions) {
|
||||||
|
- if (!this.visualOnly && this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) {
|
||||||
|
+ if (!this.visualOnly && !this.isEffect && this.level() instanceof ServerLevel serverLevel && serverLevel.getGameRules().getBoolean(GameRules.RULE_DOFIRETICK)) { // Paper - prevent any fire if only effect
|
||||||
BlockPos blockPos = this.blockPosition();
|
BlockPos blockPos = this.blockPosition();
|
||||||
BlockState state = BaseFireBlock.getState(this.level(), blockPos);
|
BlockState state = BaseFireBlock.getState(this.level(), blockPos);
|
||||||
if (this.level().getBlockState(blockPos).isAir() && state.canSurvive(this.level(), blockPos)) {
|
if (this.level().getBlockState(blockPos).isAir() && state.canSurvive(this.level(), blockPos)) {
|
||||||
|
|||||||
@ -112,16 +112,21 @@
|
|||||||
this.removeEntitiesOnShoulder();
|
this.removeEntitiesOnShoulder();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -717,6 +_,13 @@
|
@@ -717,6 +_,18 @@
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName) {
|
public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName) {
|
||||||
+ // CraftBukkit start - SPIGOT-2942: Add boolean to call event
|
+ // CraftBukkit start - SPIGOT-2942: Add boolean to call event
|
||||||
+ return this.drop(droppedItem, dropAround, includeThrowerName, true);
|
+ return this.drop(droppedItem, dropAround, includeThrowerName, true, null);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Nullable
|
+ @Nullable
|
||||||
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName, boolean callEvent) {
|
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName, boolean callEvent) {
|
||||||
|
+ return this.drop(droppedItem, dropAround, includeThrowerName, callEvent, null);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ @Nullable
|
||||||
|
+ public ItemEntity drop(ItemStack droppedItem, boolean dropAround, boolean includeThrowerName, boolean callEvent, @Nullable java.util.function.Consumer<org.bukkit.entity.Item> entityOperation) {
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
if (!droppedItem.isEmpty() && this.level().isClientSide) {
|
if (!droppedItem.isEmpty() && this.level().isClientSide) {
|
||||||
this.swing(InteractionHand.MAIN_HAND);
|
this.swing(InteractionHand.MAIN_HAND);
|
||||||
|
|||||||
@ -34,9 +34,9 @@
|
|||||||
- BlockState blockState = this.getBlockState(traversePos);
|
- BlockState blockState = this.getBlockState(traversePos);
|
||||||
- FluidState fluidState = this.getFluidState(traversePos);
|
- FluidState fluidState = this.getFluidState(traversePos);
|
||||||
+ // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
+ // CraftBukkit start - moved block handling into separate method for use by Block#rayTrace
|
||||||
+ default BlockHitResult clip(ClipContext raytrace1, BlockPos blockposition) {
|
+ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos) {
|
||||||
+ // Paper start - Add predicate for blocks when raytracing
|
+ // Paper start - Add predicate for blocks when raytracing
|
||||||
+ return clip(raytrace1, blockposition, null);
|
+ return clip(traverseContext, traversePos, null);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
+ default BlockHitResult clip(ClipContext traverseContext, BlockPos traversePos, java.util.function.Predicate<? super org.bukkit.block.Block> canCollide) {
|
||||||
|
|||||||
@ -5,11 +5,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
- if (!canSetSpawn(level)) {
|
- if (!canSetSpawn(level)) {
|
||||||
+ if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into EntityHuman
|
+ if (false && !canSetSpawn(level)) { // CraftBukkit - moved world and biome check into Player
|
||||||
level.removeBlock(pos, false);
|
level.removeBlock(pos, false);
|
||||||
BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||||
if (level.getBlockState(blockPos).is(this)) {
|
if (level.getBlockState(blockPos).is(this)) {
|
||||||
@@ -103,22 +_,62 @@
|
@@ -103,22 +_,56 @@
|
||||||
level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK);
|
level.explode(null, level.damageSources().badRespawnPointExplosion(center), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK);
|
||||||
return InteractionResult.SUCCESS_SERVER;
|
return InteractionResult.SUCCESS_SERVER;
|
||||||
} else if (state.getValue(OCCUPIED)) {
|
} else if (state.getValue(OCCUPIED)) {
|
||||||
@ -21,20 +21,20 @@
|
|||||||
return InteractionResult.SUCCESS_SERVER;
|
return InteractionResult.SUCCESS_SERVER;
|
||||||
} else {
|
} else {
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ BlockState finaliblockdata = state;
|
+ final BlockState finalBlockState = state;
|
||||||
+ BlockPos finalblockposition = pos;
|
+ final BlockPos finalBlockPos = pos;
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
player.startSleepInBed(pos).ifLeft(bedSleepingProblem -> {
|
player.startSleepInBed(pos).ifLeft(bedSleepingProblem -> {
|
||||||
+ // Paper start - PlayerBedFailEnterEvent
|
+ // Paper start - PlayerBedFailEnterEvent
|
||||||
+ if (bedSleepingProblem != null) {
|
+ if (bedSleepingProblem != null) {
|
||||||
+ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalblockposition), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage()));
|
+ io.papermc.paper.event.player.PlayerBedFailEnterEvent event = new io.papermc.paper.event.player.PlayerBedFailEnterEvent((org.bukkit.entity.Player) player.getBukkitEntity(), io.papermc.paper.event.player.PlayerBedFailEnterEvent.FailReason.values()[bedSleepingProblem.ordinal()], org.bukkit.craftbukkit.block.CraftBlock.at(level, finalBlockPos), !level.dimensionType().bedWorks(), io.papermc.paper.adventure.PaperAdventure.asAdventure(bedSleepingProblem.getMessage()));
|
||||||
+ if (!event.callEvent()) {
|
+ if (!event.callEvent()) {
|
||||||
+ return;
|
+ return;
|
||||||
+ }
|
+ }
|
||||||
+ // Paper end - PlayerBedFailEnterEvent
|
+ // Paper end - PlayerBedFailEnterEvent
|
||||||
+ // CraftBukkit start - handling bed explosion from below here
|
+ // CraftBukkit start - handling bed explosion from below here
|
||||||
+ if (event.getWillExplode()) { // Paper - PlayerBedFailEnterEvent
|
+ if (event.getWillExplode()) { // Paper - PlayerBedFailEnterEvent
|
||||||
+ this.explodeBed(finaliblockdata, level, finalblockposition);
|
+ this.explodeBed(finalBlockState, level, finalBlockPos);
|
||||||
+ } else
|
+ } else
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
if (bedSleepingProblem.getMessage() != null) {
|
if (bedSleepingProblem.getMessage() != null) {
|
||||||
@ -49,24 +49,18 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start - Copied from the above method
|
||||||
+ private InteractionResult explodeBed(BlockState iblockdata, Level world, BlockPos blockposition) {
|
+ private InteractionResult explodeBed(BlockState state, Level level, BlockPos pos) {
|
||||||
+ {
|
+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(level, pos).getState(); // CraftBukkit - capture BlockState before remove block
|
||||||
+ {
|
+ level.removeBlock(pos, false);
|
||||||
+ org.bukkit.block.BlockState blockState = org.bukkit.craftbukkit.block.CraftBlock.at(world, blockposition).getState(); // CraftBukkit - capture BlockState before remove block
|
+ BlockPos blockPos = pos.relative(state.getValue(FACING).getOpposite());
|
||||||
+ world.removeBlock(blockposition, false);
|
+ if (level.getBlockState(blockPos).is(this)) {
|
||||||
+ BlockPos blockposition1 = blockposition.relative(((Direction) iblockdata.getValue(BedBlock.FACING)).getOpposite());
|
+ level.removeBlock(blockPos, false);
|
||||||
+
|
|
||||||
+ if (world.getBlockState(blockposition1).getBlock() == this) {
|
|
||||||
+ world.removeBlock(blockposition1, false);
|
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ Vec3 vec3d = blockposition.getCenter();
|
+ Vec3 center = pos.getCenter();
|
||||||
+
|
+ level.explode(null, level.damageSources().badRespawnPointExplosion(center, blockState), null, center, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
|
||||||
+ world.explode(null, world.damageSources().badRespawnPointExplosion(vec3d, blockState), null, vec3d, 5.0F, true, Level.ExplosionInteraction.BLOCK); // CraftBukkit - add state
|
+ return InteractionResult.SUCCESS_SERVER;
|
||||||
+ return InteractionResult.SUCCESS;
|
|
||||||
+ }
|
|
||||||
+ }
|
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
+
|
+
|
||||||
|
|||||||
@ -19,8 +19,8 @@
|
|||||||
- this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null);
|
- this.setTiltAndScheduleTick(state, level, pos, Tilt.UNSTABLE, null);
|
||||||
+ // CraftBukkit start - tilt dripleaf
|
+ // CraftBukkit start - tilt dripleaf
|
||||||
+ org.bukkit.event.Cancellable cancellable;
|
+ org.bukkit.event.Cancellable cancellable;
|
||||||
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
|
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
|
||||||
+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((net.minecraft.world.entity.player.Player) entity, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null);
|
+ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(player, org.bukkit.event.block.Action.PHYSICAL, pos, null, null, null);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()));
|
+ cancellable = new org.bukkit.event.entity.EntityInteractEvent(entity.getBukkitEntity(), level.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()));
|
||||||
+ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable);
|
+ level.getCraftServer().getPluginManager().callEvent((org.bukkit.event.entity.EntityInteractEvent) cancellable);
|
||||||
|
|||||||
@ -133,7 +133,7 @@
|
|||||||
+ return 0; // CraftBukkit
|
+ return 0; // CraftBukkit
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
|
+ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
|
||||||
+ return 0;
|
+ return 0;
|
||||||
+ }
|
+ }
|
||||||
+ // CraftBukkit end
|
+ // CraftBukkit end
|
||||||
|
|||||||
@ -1,13 +1,5 @@
|
|||||||
--- a/net/minecraft/world/level/block/BushBlock.java
|
--- a/net/minecraft/world/level/block/BushBlock.java
|
||||||
+++ b/net/minecraft/world/level/block/BushBlock.java
|
+++ b/net/minecraft/world/level/block/BushBlock.java
|
||||||
@@ -6,6 +_,7 @@
|
|
||||||
import net.minecraft.tags.BlockTags;
|
|
||||||
import net.minecraft.util.RandomSource;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
+import net.minecraft.world.level.Level;
|
|
||||||
import net.minecraft.world.level.LevelReader;
|
|
||||||
import net.minecraft.world.level.ScheduledTickAccess;
|
|
||||||
import net.minecraft.world.level.block.state.BlockBehaviour;
|
|
||||||
@@ -35,9 +_,15 @@
|
@@ -35,9 +_,15 @@
|
||||||
BlockState neighborState,
|
BlockState neighborState,
|
||||||
RandomSource random
|
RandomSource random
|
||||||
@ -18,7 +10,7 @@
|
|||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (!state.canSurvive(level, pos)) {
|
+ if (!state.canSurvive(level, pos)) {
|
||||||
+ // Suppress during worldgen
|
+ // Suppress during worldgen
|
||||||
+ if (!(level instanceof net.minecraft.server.level.ServerLevel world1 && world1.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(world1, pos).isCancelled()) { // Paper
|
+ if (!(level instanceof net.minecraft.server.level.ServerLevel serverLevel && serverLevel.hasPhysicsEvent) || !org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPhysicsEvent(serverLevel, pos).isCancelled()) { // Paper
|
||||||
+ return Blocks.AIR.defaultBlockState();
|
+ return Blocks.AIR.defaultBlockState();
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
|
|||||||
@ -29,7 +29,7 @@
|
|||||||
- player.getFoodData().eat(2, 0.1F);
|
- player.getFoodData().eat(2, 0.1F);
|
||||||
- int bitesValue = state.getValue(BITES);
|
- int bitesValue = state.getValue(BITES);
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ // entityhuman.getFoodData().eat(2, 0.1F);
|
+ // player.getFoodData().eat(2, 0.1F);
|
||||||
+ int oldFoodLevel = player.getFoodData().foodLevel;
|
+ int oldFoodLevel = player.getFoodData().foodLevel;
|
||||||
+
|
+
|
||||||
+ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel);
|
+ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(player, 2 + oldFoodLevel);
|
||||||
|
|||||||
@ -10,8 +10,8 @@
|
|||||||
+ return InteractionResult.SUCCESS;
|
+ return InteractionResult.SUCCESS;
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ if (entity instanceof net.minecraft.world.entity.player.Player) {
|
+ if (entity instanceof net.minecraft.world.entity.player.Player player) {
|
||||||
+ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, (net.minecraft.world.entity.player.Player) entity, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1)));
|
+ org.bukkit.event.player.PlayerHarvestBlockEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerHarvestBlockEvent(level, pos, player, net.minecraft.world.InteractionHand.MAIN_HAND, java.util.Collections.singletonList(new ItemStack(Items.GLOW_BERRIES, 1)));
|
||||||
+ if (event.isCancelled()) {
|
+ if (event.isCancelled()) {
|
||||||
+ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block
|
+ return InteractionResult.SUCCESS; // We need to return a success either way, because making it PASS or FAIL will result in a bug where cancelling while harvesting w/ block in hand places block
|
||||||
+ }
|
+ }
|
||||||
|
|||||||
@ -39,8 +39,8 @@
|
|||||||
public static BlockState extractProduce(Entity entity, BlockState state, Level level, BlockPos pos) {
|
public static BlockState extractProduce(Entity entity, BlockState state, Level level, BlockPos pos) {
|
||||||
+ // CraftBukkit start
|
+ // CraftBukkit start
|
||||||
+ if (entity != null && !(entity instanceof Player)) {
|
+ if (entity != null && !(entity instanceof Player)) {
|
||||||
+ BlockState iblockdata1 = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos);
|
+ BlockState emptyState = ComposterBlock.empty(entity, state, org.bukkit.craftbukkit.util.DummyGeneratorAccess.INSTANCE, pos);
|
||||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, iblockdata1)) {
|
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, emptyState)) {
|
||||||
+ return state;
|
+ return state;
|
||||||
+ }
|
+ }
|
||||||
+ }
|
+ }
|
||||||
@ -100,9 +100,9 @@
|
|||||||
|
|
||||||
public static class EmptyContainer extends SimpleContainer implements WorldlyContainer {
|
public static class EmptyContainer extends SimpleContainer implements WorldlyContainer {
|
||||||
- public EmptyContainer() {
|
- public EmptyContainer() {
|
||||||
+ public EmptyContainer(LevelAccessor generatoraccess, BlockPos blockposition) { // CraftBukkit
|
+ public EmptyContainer(LevelAccessor levelAccessor, BlockPos blockPos) { // CraftBukkit
|
||||||
super(0);
|
super(0);
|
||||||
+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(generatoraccess, blockposition, this); // CraftBukkit
|
+ this.bukkitOwner = new org.bukkit.craftbukkit.inventory.CraftBlockInventoryHolder(levelAccessor, blockPos, this); // CraftBukkit
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -31,8 +31,8 @@
|
|||||||
+
|
+
|
||||||
+ org.bukkit.inventory.Inventory destinationInventory;
|
+ org.bukkit.inventory.Inventory destinationInventory;
|
||||||
+ // Have to special case large chests as they work oddly
|
+ // Have to special case large chests as they work oddly
|
||||||
+ if (containerAt instanceof CompoundContainer) {
|
+ if (containerAt instanceof CompoundContainer compoundContainer) {
|
||||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
|
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ destinationInventory = containerAt.getOwner().getInventory();
|
+ destinationInventory = containerAt.getOwner().getInventory();
|
||||||
+ }
|
+ }
|
||||||
@ -57,8 +57,8 @@
|
|||||||
+
|
+
|
||||||
+ org.bukkit.inventory.Inventory destinationInventory;
|
+ org.bukkit.inventory.Inventory destinationInventory;
|
||||||
+ // Have to special case large chests as they work oddly
|
+ // Have to special case large chests as they work oddly
|
||||||
+ if (containerAt instanceof CompoundContainer) {
|
+ if (containerAt instanceof CompoundContainer compoundContainer) {
|
||||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
|
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ destinationInventory = containerAt.getOwner().getInventory();
|
+ destinationInventory = containerAt.getOwner().getInventory();
|
||||||
+ }
|
+ }
|
||||||
|
|||||||
@ -4,16 +4,15 @@
|
|||||||
@Override
|
@Override
|
||||||
protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
|
protected void spawnAfterBreak(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
|
||||||
super.spawnAfterBreak(state, level, pos, stack, dropExperience);
|
super.spawnAfterBreak(state, level, pos, stack, dropExperience);
|
||||||
- if (dropExperience) {
|
|
||||||
- this.tryDropExperience(level, pos, stack, this.xpRange);
|
|
||||||
- }
|
|
||||||
+ // CraftBukkit start - Delegate to getExpDrop
|
+ // CraftBukkit start - Delegate to getExpDrop
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ @Override
|
+ @Override
|
||||||
+ public int getExpDrop(BlockState iblockdata, ServerLevel worldserver, BlockPos blockposition, ItemStack itemstack, boolean flag) {
|
+ public int getExpDrop(BlockState state, ServerLevel level, BlockPos pos, ItemStack stack, boolean dropExperience) {
|
||||||
+ if (flag) {
|
if (dropExperience) {
|
||||||
+ return this.tryDropExperience(worldserver, blockposition, itemstack, this.xpRange);
|
- this.tryDropExperience(level, pos, stack, this.xpRange);
|
||||||
|
- }
|
||||||
|
+ return this.tryDropExperience(level, pos, stack, this.xpRange);
|
||||||
+ }
|
+ }
|
||||||
+
|
+
|
||||||
+ return 0;
|
+ return 0;
|
||||||
|
|||||||
@ -39,8 +39,8 @@
|
|||||||
+
|
+
|
||||||
+ org.bukkit.inventory.Inventory destinationInventory;
|
+ org.bukkit.inventory.Inventory destinationInventory;
|
||||||
+ // Have to special case large chests as they work oddly
|
+ // Have to special case large chests as they work oddly
|
||||||
+ if (containerAt instanceof CompoundContainer) {
|
+ if (containerAt instanceof CompoundContainer compoundContainer) {
|
||||||
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((CompoundContainer) containerAt);
|
+ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest(compoundContainer);
|
||||||
+ } else {
|
+ } else {
|
||||||
+ destinationInventory = containerAt.getOwner().getInventory();
|
+ destinationInventory = containerAt.getOwner().getInventory();
|
||||||
+ }
|
+ }
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user