mirror of
https://github.com/PaperMC/Paper.git
synced 2026-11-04 17:00:09 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
806b0db07c | ||
|
|
e13cf8870f | ||
|
|
cb1e4cc603 | ||
|
|
2fdccd0ddf | ||
|
|
755ecce274 |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
name: Release 26.3
|
||||
name: Release 26.4
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -11,7 +11,7 @@ permissions:
|
||||
|
||||
concurrency:
|
||||
cancel-in-progress: false
|
||||
group: release-26.3
|
||||
group: release-26.4
|
||||
|
||||
jobs:
|
||||
release:
|
||||
@@ -1,4 +1,4 @@
|
||||
Paper [](https://papermc.io/downloads/paper)
|
||||
[](https://github.com/PaperMC/Paper/actions)
|
||||
[](https://discord.gg/papermc)
|
||||
@@ -39,7 +39,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compileOnly("io.papermc.paper:paper-api:26.3.build.+")
|
||||
compileOnly("io.papermc.paper:paper-api:26.4.build.+")
|
||||
}
|
||||
|
||||
java {
|
||||
@@ -59,7 +59,7 @@ java {
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
<version>[26.3.build,)</version>
|
||||
<version>[26.4.build,)</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
+2
-1
@@ -630,14 +630,15 @@ public net.minecraft.world.level.dimension.end.EnderDragonFight spawnNewGateway(
|
||||
public net.minecraft.world.level.entity.PersistentEntitySectionManager ensureChunkQueuedForLoad(J)V
|
||||
public net.minecraft.world.level.entity.PersistentEntitySectionManager permanentStorage
|
||||
public net.minecraft.world.level.gamerules.GameRules rules
|
||||
public net.minecraft.world.level.levelgen.material.MaterialRuleContext context
|
||||
public net.minecraft.world.level.levelgen.structure.StructurePiece SHAPE_CHECK_BLOCKS
|
||||
public net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement exclusionZone
|
||||
public net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement frequency
|
||||
public net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement frequencyReductionMethod
|
||||
public net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement locateOffset
|
||||
public net.minecraft.world.level.levelgen.structure.placement.AbstractSpreadingStructurePlacement salt
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate <init>()V
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate entityInfoList
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate fillFromWorld(Lnet/minecraft/world/level/Level;Lnet/minecraft/core/BlockPos;Lnet/minecraft/core/Vec3i;ZLjava/util/List;)V
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplate palettes
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager resourceManagerSource
|
||||
public net.minecraft.world.level.levelgen.structure.templatesystem.StructureTemplateManager structureRepository
|
||||
|
||||
+4
-4
@@ -1,12 +1,12 @@
|
||||
group=io.papermc.paper
|
||||
mcVersion=26.3
|
||||
mcVersion=26.4-snapshot-5
|
||||
# This is the current API version for use in (paper-)plugin.yml files
|
||||
# During snapshot cycles this should be the anticipated version of the release target
|
||||
apiVersion=26.3
|
||||
channel=STABLE
|
||||
apiVersion=26.4
|
||||
channel=ALPHA
|
||||
|
||||
# Set to true while updating Minecraft version
|
||||
updatingMinecraft=false
|
||||
updatingMinecraft=true
|
||||
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.destroystokyo.paper.block;
|
||||
|
||||
import org.bukkit.Sound;
|
||||
import org.bukkit.block.Block;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Represents the sounds that a {@link Block} makes in certain situations
|
||||
* <p>
|
||||
* The sound group includes break, step, place, hit, and fall sounds.
|
||||
* @deprecated use {@link org.bukkit.SoundGroup}
|
||||
*/
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
public interface BlockSoundGroup {
|
||||
/**
|
||||
* Gets the sound that plays when breaking this block
|
||||
*
|
||||
* @return The break sound
|
||||
* @deprecated use {@link org.bukkit.SoundGroup#getBreakSound()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
Sound getBreakSound();
|
||||
|
||||
/**
|
||||
* Gets the sound that plays when stepping on this block
|
||||
*
|
||||
* @return The step sound
|
||||
* @deprecated use {@link org.bukkit.SoundGroup#getStepSound()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
Sound getStepSound();
|
||||
|
||||
/**
|
||||
* Gets the sound that plays when placing this block
|
||||
*
|
||||
* @return The place sound
|
||||
* @deprecated use {@link org.bukkit.SoundGroup#getPlaceSound()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
Sound getPlaceSound();
|
||||
|
||||
/**
|
||||
* Gets the sound that plays when hitting this block
|
||||
*
|
||||
* @return The hit sound
|
||||
* @deprecated use {@link org.bukkit.SoundGroup#getHitSound()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
Sound getHitSound();
|
||||
|
||||
/**
|
||||
* Gets the sound that plays when this block falls
|
||||
*
|
||||
* @return The fall sound
|
||||
* @deprecated use {@link org.bukkit.SoundGroup#getFallSound()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
Sound getFallSound();
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import org.checkerframework.checker.index.qual.NonNegative;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.Unmodifiable;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Holds the properties for this item for when it is consumed.
|
||||
@@ -30,7 +31,7 @@ public interface Consumable extends BuildableDataComponent<Consumable, Consumabl
|
||||
ItemUseAnimation animation();
|
||||
|
||||
@Contract(pure = true)
|
||||
Key sound();
|
||||
@Nullable Key sound();
|
||||
|
||||
@Contract(pure = true)
|
||||
boolean hasConsumeParticles();
|
||||
@@ -65,11 +66,11 @@ public interface Consumable extends BuildableDataComponent<Consumable, Consumabl
|
||||
/**
|
||||
* Sets the sound played when consuming the item.
|
||||
*
|
||||
* @param sound the {@link Key} representing the sound to be used
|
||||
* @param sound the {@link Key} representing the sound to be used, or {@code null} for no sound
|
||||
* @return the builder for chaining
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder sound(Key sound);
|
||||
Builder sound(@Nullable Key sound);
|
||||
|
||||
/**
|
||||
* Sets whether consuming the item results in particle effects.
|
||||
|
||||
@@ -39,10 +39,10 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
|
||||
/**
|
||||
* Gets the equip sound key.
|
||||
*
|
||||
* @return the equip sound key
|
||||
* @return the equip sound key, or {@code null} if none
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
Key equipSound();
|
||||
@Nullable Key equipSound();
|
||||
|
||||
/**
|
||||
* Gets the asset id if present.
|
||||
@@ -112,10 +112,10 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
|
||||
/**
|
||||
* Returns the sound that is played when shearing this equipment off an entity.
|
||||
*
|
||||
* @return shear sound
|
||||
* @return shear sound, or {@code null} if none
|
||||
*/
|
||||
@Contract(pure = true)
|
||||
Key shearSound();
|
||||
@Nullable Key shearSound();
|
||||
|
||||
/**
|
||||
* Builder for {@link Equippable}.
|
||||
@@ -126,11 +126,11 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
|
||||
/**
|
||||
* Sets the equip sound key for this item.
|
||||
*
|
||||
* @param sound the equip sound key
|
||||
* @param sound the equip sound key, or {@code null} for no sound
|
||||
* @return the builder for chaining
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder equipSound(Key sound);
|
||||
Builder equipSound(@Nullable Key sound);
|
||||
|
||||
/**
|
||||
* Sets the asset id for this item.
|
||||
@@ -207,10 +207,10 @@ public interface Equippable extends BuildableDataComponent<Equippable, Equippabl
|
||||
/**
|
||||
* Sets the sound that is played when shearing this equipment off an entity.
|
||||
*
|
||||
* @param shearSound the shear sound key
|
||||
* @param shearSound the shear sound key, or {@code null} for no sound
|
||||
* @return the builder for chaining
|
||||
*/
|
||||
@Contract(value = "_ -> this", mutates = "this")
|
||||
Builder shearSound(Key shearSound);
|
||||
Builder shearSound(@Nullable Key shearSound);
|
||||
}
|
||||
}
|
||||
+6
-6
@@ -182,16 +182,16 @@ public interface SulfurCubeArchetypeRegistryEntry {
|
||||
|
||||
// todo The sounds should take a RegistryHolder but need more thoughts on the create method
|
||||
/**
|
||||
* {@return the sound played once the sulfur cube is knocked}
|
||||
* {@return the sound played once the sulfur cube is knocked, or {@code null} if none}
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
TypedKey<Sound> hitSound();
|
||||
@Nullable TypedKey<Sound> hitSound();
|
||||
|
||||
/**
|
||||
* {@return the sound played once the sulfur cube is pushed}
|
||||
* {@return the sound played once the sulfur cube is pushed, or {@code null} if none}
|
||||
*/
|
||||
@ApiStatus.Experimental
|
||||
TypedKey<Sound> pushSound();
|
||||
@Nullable TypedKey<Sound> pushSound();
|
||||
|
||||
/**
|
||||
* {@return the smallest impulse required to play the push sound}
|
||||
@@ -214,8 +214,8 @@ public interface SulfurCubeArchetypeRegistryEntry {
|
||||
*/
|
||||
@Contract(value = "_, _, _, _ -> new", pure = true)
|
||||
@ApiStatus.Experimental
|
||||
static SoundSettings of(final TypedKey<Sound> hitSound, final TypedKey<Sound> pushSound, final float pushSoundImpulseThreshold, final float pushSoundCooldown) {
|
||||
record Impl(TypedKey<Sound> hitSound, TypedKey<Sound> pushSound, float pushSoundImpulseThreshold, float pushSoundCooldown) implements SoundSettings {
|
||||
static SoundSettings of(final @Nullable TypedKey<Sound> hitSound, final @Nullable TypedKey<Sound> pushSound, final float pushSoundImpulseThreshold, final float pushSoundCooldown) {
|
||||
record Impl(@Nullable TypedKey<Sound> hitSound, @Nullable TypedKey<Sound> pushSound, float pushSoundImpulseThreshold, float pushSoundCooldown) implements SoundSettings {
|
||||
}
|
||||
|
||||
return new Impl(hitSound, pushSound, pushSoundImpulseThreshold, pushSoundCooldown);
|
||||
|
||||
@@ -1,70 +1,112 @@
|
||||
package org.bukkit;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Represents a group of sounds for blocks that are played when various actions
|
||||
* happen (ie stepping, breaking, hitting, etc).
|
||||
* happen (ie stepping, breaking, hitting, etc.).
|
||||
*/
|
||||
@NullMarked
|
||||
public interface SoundGroup {
|
||||
|
||||
/**
|
||||
* Get the volume these sounds are played at.
|
||||
*
|
||||
* <p>
|
||||
* Note that this volume does not always represent the actual volume
|
||||
* received by the client.
|
||||
*
|
||||
* @return volume
|
||||
*/
|
||||
public float getVolume();
|
||||
float getVolume();
|
||||
|
||||
/**
|
||||
* Gets the pitch these sounds are played at.
|
||||
*
|
||||
* <p>
|
||||
* Note that this pitch does not always represent the actual pitch received
|
||||
* by the client.
|
||||
*
|
||||
* @return pitch
|
||||
*/
|
||||
public float getPitch();
|
||||
float getPitch();
|
||||
|
||||
/**
|
||||
* Gets the corresponding breaking sound for this group.
|
||||
*
|
||||
* @return the break sound
|
||||
* @return the break sound, or {@link Sound#BLOCK_STONE_BREAK} if this group has none
|
||||
* @deprecated sounds may now be nullable, use {@link #breakSound()} instead.
|
||||
*/
|
||||
@NotNull
|
||||
public Sound getBreakSound();
|
||||
@Deprecated(since = "26.4")
|
||||
Sound getBreakSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding step sound for this group.
|
||||
*
|
||||
* @return the step sound
|
||||
* @return the step sound, or {@link Sound#BLOCK_STONE_STEP} if this group has none
|
||||
* @deprecated sounds may now be nullable, use {@link #stepSound()} instead.
|
||||
*/
|
||||
@NotNull
|
||||
public Sound getStepSound();
|
||||
@Deprecated(since = "26.4")
|
||||
Sound getStepSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding place sound for this group.
|
||||
*
|
||||
* @return the place sound
|
||||
* @return the place sound, or {@link Sound#BLOCK_STONE_PLACE} if this group has none
|
||||
* @deprecated sounds may now be nullable, use {@link #placeSound()} instead.
|
||||
*/
|
||||
@NotNull
|
||||
public Sound getPlaceSound();
|
||||
@Deprecated(since = "26.4")
|
||||
Sound getPlaceSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding hit sound for this group.
|
||||
*
|
||||
* @return the hit sound
|
||||
* @return the hit sound, or {@link Sound#BLOCK_STONE_HIT} if this group has none
|
||||
* @deprecated sounds may now be nullable, use {@link #hitSound()} instead.
|
||||
*/
|
||||
@NotNull
|
||||
public Sound getHitSound();
|
||||
@Deprecated(since = "26.4")
|
||||
Sound getHitSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding fall sound for this group.
|
||||
*
|
||||
* @return the fall sound
|
||||
* @return the fall sound, or {@link Sound#BLOCK_STONE_FALL} if this group has none
|
||||
* @deprecated sounds may now be nullable, use {@link #fallSound()} instead.
|
||||
*/
|
||||
@NotNull
|
||||
public Sound getFallSound();
|
||||
@Deprecated(since = "26.4")
|
||||
Sound getFallSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding breaking sound for this group.
|
||||
*
|
||||
* @return the break sound, or {@code null} if this group has none
|
||||
*/
|
||||
@Nullable Sound breakSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding step sound for this group.
|
||||
*
|
||||
* @return the step sound, or {@code null} if this group has none
|
||||
*/
|
||||
@Nullable Sound stepSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding place sound for this group.
|
||||
*
|
||||
* @return the place sound, or {@code null} if this group has none
|
||||
*/
|
||||
@Nullable Sound placeSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding hit sound for this group.
|
||||
*
|
||||
* @return the hit sound, or {@code null} if this group has none
|
||||
*/
|
||||
@Nullable Sound hitSound();
|
||||
|
||||
/**
|
||||
* Gets the corresponding fall sound for this group.
|
||||
*
|
||||
* @return the fall sound, or {@code null} if this group has none
|
||||
*/
|
||||
@Nullable Sound fallSound();
|
||||
}
|
||||
@@ -778,19 +778,6 @@ public interface Block extends Metadatable, Translatable, net.kyori.adventure.tr
|
||||
*/
|
||||
boolean canPlace(@NotNull BlockData data);
|
||||
|
||||
// Paper start
|
||||
/**
|
||||
* Gets the {@link com.destroystokyo.paper.block.BlockSoundGroup} for this block.
|
||||
* <p>
|
||||
* This object contains the block, step, place, hit, and fall sounds.
|
||||
*
|
||||
* @return the sound group for this block
|
||||
* @deprecated use {@link #getBlockSoundGroup()}
|
||||
*/
|
||||
@NotNull
|
||||
@Deprecated(forRemoval = true, since = "1.18.2")
|
||||
com.destroystokyo.paper.block.BlockSoundGroup getSoundGroup();
|
||||
|
||||
/**
|
||||
* Gets the {@link org.bukkit.SoundGroup} for this block.
|
||||
*
|
||||
|
||||
+2
-2
@@ -35,9 +35,9 @@ public interface EquippableComponent extends ConfigurationSerializable {
|
||||
/**
|
||||
* Gets the sound to play when the item is equipped.
|
||||
*
|
||||
* @return the sound
|
||||
* @return the sound, or null if none
|
||||
*/
|
||||
@NotNull // Paper
|
||||
@Nullable
|
||||
Sound getEquipSound();
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,7 +14,7 @@ plugins {
|
||||
val paperMavenPublicUrl = "https://repo.papermc.io/repository/maven-public/"
|
||||
|
||||
dependencies {
|
||||
mache("io.papermc:mache:26.3+build.1")
|
||||
mache("io.papermc:mache:26.4-snapshot-5+build.2")
|
||||
paperclip("io.papermc:paperclip:3.0.4")
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ paperweight {
|
||||
gitFilePatches = false
|
||||
|
||||
updatingMinecraft {
|
||||
//oldPaperCommit = "e5fe71723e2ffde7cc9fafc085ac3bb73e63175e"
|
||||
oldPaperCommit = "8c0b8396d676f6abef3df8ab992ac726f6e01c9c"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+9
-9
@@ -1,25 +1,25 @@
|
||||
--- a/com/mojang/authlib/services/MinecraftServicesDiscoveryService.java
|
||||
+++ b/com/mojang/authlib/services/MinecraftServicesDiscoveryService.java
|
||||
@@ -37,7 +_,7 @@
|
||||
private final boolean servicesKeySetEnabled;
|
||||
@@ -40,7 +_,7 @@
|
||||
private final Supplier<DiscoveryResponse> discoverySupplier;
|
||||
private final String clientVersion;
|
||||
|
||||
- private MinecraftServicesDiscoveryService(
|
||||
+ protected MinecraftServicesDiscoveryService( // Paper - private->protected
|
||||
final Proxy proxy,
|
||||
final boolean servicesKeySetEnabled,
|
||||
final Supplier<DiscoveryResponse> discoverySupplier
|
||||
@@ -68,7 +_,7 @@
|
||||
final Supplier<DiscoveryResponse> discoverySupplier,
|
||||
@@ -75,7 +_,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
- private static Supplier<DiscoveryResponse> createDiscoverySupplier(final Proxy proxy, final Environment environment) {
|
||||
+ protected static Supplier<DiscoveryResponse> createDiscoverySupplier(final Proxy proxy, final Environment environment) { // Paper - private->protected
|
||||
final MinecraftClient client = MinecraftClient.unauthenticated(proxy);
|
||||
- private static Supplier<DiscoveryResponse> createDiscoverySupplier(final Proxy proxy, final Environment environment, final String clientVersion) {
|
||||
+ protected static Supplier<DiscoveryResponse> createDiscoverySupplier(final Proxy proxy, final Environment environment, final String clientVersion) { // Paper - private->protected
|
||||
final MinecraftClient client = MinecraftClient.unauthenticated(proxy, clientVersion);
|
||||
return RetryableFetch.fetch(
|
||||
() -> HttpDiscoveryService.constantURL(environment.discoveryUrl()),
|
||||
@@ -84,7 +_,7 @@
|
||||
return new MinecraftServicesDiscoveryService(proxy, false, DiscoveryResponse::offline);
|
||||
@@ -95,7 +_,7 @@
|
||||
return clientVersion;
|
||||
}
|
||||
|
||||
- private static Environment determineEnvironment() {
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
--- a/com/mojang/authlib/services/MinecraftServicesProfileRepository.java
|
||||
+++ b/com/mojang/authlib/services/MinecraftServicesProfileRepository.java
|
||||
@@ -42,6 +_,8 @@
|
||||
@@ -44,6 +_,8 @@
|
||||
.filter(name -> !Strings.isNullOrEmpty(name))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
for (final List<String> request : Iterables.partition(criteria, ENTRIES_PER_PAGE)) {
|
||||
final List<String> normalizedRequest = request.stream().map(MinecraftServicesProfileRepository::normalizeName).toList();
|
||||
|
||||
@@ -73,6 +_,13 @@
|
||||
@@ -75,6 +_,13 @@
|
||||
callback.onProfileLookupFailed(name, new ProfileNotFoundException("Server did not find the requested profile"));
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
try {
|
||||
Thread.sleep(DELAY_BETWEEN_PAGES);
|
||||
} catch (final InterruptedException ignored) {
|
||||
@@ -102,7 +_,15 @@
|
||||
@@ -104,7 +_,15 @@
|
||||
try {
|
||||
return Optional.ofNullable(client.get(HttpDiscoveryService.constantURL(discoveryService.getUrl(Service.PROFILES, "getByName").replace("{name}", normalizeName(name))), NameAndId.class));
|
||||
} catch (final MinecraftClientException e) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
this.nodes.remove(node.holder().id());
|
||||
}
|
||||
|
||||
@@ -46,7 +_,7 @@
|
||||
@@ -47,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -113,8 +113,8 @@
|
||||
|
||||
@Override
|
||||
public Collection<String> getOnlinePlayerNames() {
|
||||
- return Lists.newArrayList(this.server.getPlayerNames());
|
||||
+ return this.entity instanceof ServerPlayer sourcePlayer && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().name()).toList() : Lists.newArrayList(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players
|
||||
- return List.of(this.server.getPlayerNames());
|
||||
+ return this.entity instanceof ServerPlayer sourcePlayer && !sourcePlayer.getBukkitEntity().hasPermission("paper.bypass-visibility.tab-completion") ? this.getServer().getPlayerList().getPlayers().stream().filter(serverPlayer -> sourcePlayer.getBukkitEntity().canSee(serverPlayer.getBukkitEntity())).map(serverPlayer -> serverPlayer.getGameProfile().name()).toList() : List.of(this.server.getPlayerNames()); // Paper - Make CommandSourceStack respect hidden players
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/commands/Commands.java
|
||||
+++ b/net/minecraft/commands/Commands.java
|
||||
@@ -159,6 +_,7 @@
|
||||
@@ -160,6 +_,7 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public class Commands {
|
||||
@@ -8,7 +8,7 @@
|
||||
public static final String COMMAND_PREFIX = "/";
|
||||
private static final ThreadLocal<@Nullable ExecutionContext<CommandSourceStack>> CURRENT_EXECUTION_CONTEXT = new ThreadLocal<>();
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -183,6 +_,7 @@
|
||||
@@ -184,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public boolean isRestricted(final CommandNode<CommandSourceStack> node) {
|
||||
@@ -16,7 +16,7 @@
|
||||
Predicate<CommandSourceStack> requirement = node.getRequirement();
|
||||
return !requirement.test(this.noPermissionSource);
|
||||
}
|
||||
@@ -190,6 +_,11 @@
|
||||
@@ -191,6 +_,11 @@
|
||||
private final CommandDispatcher<CommandSourceStack> dispatcher = new CommandDispatcher<>();
|
||||
|
||||
public Commands(final Commands.CommandSelection commandSelection, final CommandBuildContext context) {
|
||||
@@ -28,7 +28,7 @@
|
||||
AdvancementCommands.register(this.dispatcher);
|
||||
AttributeCommand.register(this.dispatcher, context);
|
||||
ExecuteCommand.register(this.dispatcher, context);
|
||||
@@ -304,6 +_,42 @@
|
||||
@@ -305,6 +_,42 @@
|
||||
UnpublishCommand.register(this.dispatcher);
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
this.dispatcher.setConsumer(ExecutionCommandSource.resultConsumer());
|
||||
}
|
||||
|
||||
@@ -323,6 +_,13 @@
|
||||
@@ -324,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void performCommand(final ParseResults<CommandSourceStack> command, final String commandString) {
|
||||
@@ -85,7 +85,7 @@
|
||||
CommandSourceStack sender = command.getContext().getSource();
|
||||
Profiler.get().push(() -> "/" + commandString);
|
||||
ContextChain<CommandSourceStack> commandChain = finishParsing(command, commandString, sender);
|
||||
@@ -336,10 +_,12 @@
|
||||
@@ -337,10 +_,12 @@
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
StackTraceElement[] stackTrace = e.getStackTrace();
|
||||
|
||||
for (int i = 0; i < Math.min(stackTrace.length, 3); i++) {
|
||||
@@ -370,12 +_,16 @@
|
||||
@@ -371,12 +_,16 @@
|
||||
return ContextChain.tryFlatten(command.getContext().build(commandString))
|
||||
.orElseThrow(() -> CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(command.getReader()));
|
||||
} catch (CommandSyntaxException e) {
|
||||
@@ -120,7 +120,7 @@
|
||||
if (cursor > 10) {
|
||||
context.append(CommonComponents.ELLIPSIS);
|
||||
}
|
||||
@@ -387,7 +_,17 @@
|
||||
@@ -388,7 +_,17 @@
|
||||
}
|
||||
|
||||
context.append(Component.translatable("command.context.here").withStyle(ChatFormatting.RED, ChatFormatting.ITALIC));
|
||||
@@ -139,7 +139,7 @@
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -415,10 +_,65 @@
|
||||
@@ -416,10 +_,65 @@
|
||||
}
|
||||
|
||||
public void sendCommands(final ServerPlayer player) {
|
||||
@@ -207,7 +207,7 @@
|
||||
player.connection.send(new ClientboundCommandsPacket(root, COMMAND_NODE_INSPECTOR));
|
||||
}
|
||||
|
||||
@@ -426,8 +_,49 @@
|
||||
@@ -427,8 +_,49 @@
|
||||
final CommandNode<S> source, final CommandNode<S> target, final S commandFilter, final Map<CommandNode<S>, CommandNode<S>> converted
|
||||
) {
|
||||
for (CommandNode<S> child : source.getChildren()) {
|
||||
|
||||
+3
-3
@@ -4,8 +4,8 @@
|
||||
private final StringReader reader;
|
||||
private final boolean forTesting;
|
||||
private final boolean allowNbt;
|
||||
- private final Map<Property<?>, Comparable<?>> properties = Maps.newHashMap();
|
||||
+ private final Map<Property<?>, Comparable<?>> properties = Maps.newLinkedHashMap(); // CraftBukkit - stable
|
||||
private final Map<String, String> vagueProperties = Maps.newHashMap();
|
||||
- private final Map<Property<?>, Comparable<?>> properties = new HashMap<>();
|
||||
+ private final Map<Property<?>, Comparable<?>> properties = new java.util.LinkedHashMap<>(); // CraftBukkit - stable
|
||||
private final Map<String, String> vagueProperties = new HashMap<>();
|
||||
private Identifier id = Identifier.withDefaultNamespace("");
|
||||
private @Nullable StateDefinition<Block, BlockState> definition;
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/BlockPos.java
|
||||
+++ b/net/minecraft/core/BlockPos.java
|
||||
@@ -141,67 +_,84 @@
|
||||
@@ -139,67 +_,84 @@
|
||||
|
||||
@Override
|
||||
public BlockPos above() {
|
||||
@@ -98,7 +98,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -667,9 +_,9 @@
|
||||
@@ -698,9 +_,9 @@
|
||||
}
|
||||
|
||||
public BlockPos.MutableBlockPos set(final int x, final int y, final int z) {
|
||||
@@ -111,7 +111,7 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -727,19 +_,19 @@
|
||||
@@ -758,19 +_,19 @@
|
||||
|
||||
@Override
|
||||
public BlockPos.MutableBlockPos setX(final int x) {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
--- a/net/minecraft/core/Holder.java
|
||||
+++ b/net/minecraft/core/Holder.java
|
||||
@@ -252,7 +_,7 @@
|
||||
}
|
||||
|
||||
void bindTags(final Collection<TagKey<T>> tags) {
|
||||
- this.tags = Set.copyOf(tags);
|
||||
+ this.tags = it.unimi.dsi.fastutil.objects.ReferenceSets.unmodifiable(new it.unimi.dsi.fastutil.objects.ReferenceOpenHashSet<>(tags)); // Paper - use reference set because TagKey are interned
|
||||
}
|
||||
|
||||
public void bindComponents(final DataComponentMap components) {
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/net/minecraft/core/MappedRegistry.java
|
||||
@@ -33,17 +_,25 @@
|
||||
@@ -34,17 +_,25 @@
|
||||
public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
private final ResourceKey<? extends Registry<T>> key;
|
||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
@Override
|
||||
public Stream<HolderSet.Named<T>> listTags() {
|
||||
@@ -117,6 +_,7 @@
|
||||
@@ -118,6 +_,7 @@
|
||||
this.toId.put(value, newId);
|
||||
this.registrationInfos.put(key, registrationInfo);
|
||||
this.registryLifecycle = this.registryLifecycle.add(registrationInfo.lifecycle());
|
||||
@@ -39,7 +39,7 @@
|
||||
return holder;
|
||||
}
|
||||
|
||||
@@ -278,6 +_,7 @@
|
||||
@@ -279,6 +_,7 @@
|
||||
}
|
||||
|
||||
this.frozen = true;
|
||||
@@ -47,7 +47,7 @@
|
||||
this.byValue.forEach((value, holder) -> holder.bindValue((T)value));
|
||||
List<Identifier> unboundEntries = this.byKey
|
||||
.entrySet()
|
||||
@@ -517,4 +_,13 @@
|
||||
@@ -518,4 +_,13 @@
|
||||
|
||||
Stream<HolderSet.Named<T>> getTags();
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/Vec3i.java
|
||||
+++ b/net/minecraft/core/Vec3i.java
|
||||
@@ -22,9 +_,9 @@
|
||||
@@ -20,9 +_,9 @@
|
||||
ByteBufCodecs.VAR_INT, Vec3i::getX, ByteBufCodecs.VAR_INT, Vec3i::getY, ByteBufCodecs.VAR_INT, Vec3i::getZ, Vec3i::new
|
||||
);
|
||||
public static final Vec3i ZERO = new Vec3i(0, 0, 0);
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
public static Codec<Vec3i> offsetCodec(final int maxOffsetPerAxis) {
|
||||
return CODEC.validate(
|
||||
@@ -41,12 +_,12 @@
|
||||
@@ -39,12 +_,12 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -28,7 +28,7 @@
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -59,15 +_,15 @@
|
||||
@@ -57,15 +_,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@@ -251,4 +_,11 @@
|
||||
@@ -249,4 +_,11 @@
|
||||
public String toShortString() {
|
||||
return this.getX() + ", " + this.getY() + ", " + this.getZ();
|
||||
}
|
||||
|
||||
+2
-2
@@ -236,8 +236,8 @@
|
||||
hand,
|
||||
itemInHand,
|
||||
Blocks.POWDER_SNOW_CAULDRON.defaultBlockState().setValue(LayeredCauldronBlock.LEVEL, 3),
|
||||
- SoundEvents.BUCKET_EMPTY_POWDER_SNOW
|
||||
+ SoundEvents.BUCKET_EMPTY_POWDER_SNOW, hitDirection // Paper - add hitDirection
|
||||
- SoundEvents.BUCKET_EMPTY_POWDER_SNOW.value()
|
||||
+ SoundEvents.BUCKET_EMPTY_POWDER_SNOW.value(), hitDirection // Paper - add hitDirection
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/component/BlockTransformer.java
|
||||
+++ b/net/minecraft/core/component/BlockTransformer.java
|
||||
@@ -68,6 +_,14 @@
|
||||
@@ -64,6 +_,14 @@
|
||||
BlockState updatedShape = transformData.updateFromNeighbors ? Block.updateFromNeighbourShapes(newBlockState, level, pos) : newBlockState;
|
||||
Player player = context.getPlayer();
|
||||
ItemStack itemInHand = context.getItemInHand();
|
||||
|
||||
+23
-20
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/DispenseItemBehavior.java
|
||||
@@ -80,12 +_,38 @@
|
||||
@@ -83,13 +_,39 @@
|
||||
Direction direction = source.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos pos = source.pos().relative(direction);
|
||||
ServerLevel serverLevel = source.level();
|
||||
@@ -36,17 +36,17 @@
|
||||
);
|
||||
ArmorStand armorStand = EntityTypes.ARMOR_STAND.spawn(serverLevel, postSpawnConfig, pos, EntitySpawnReason.DISPENSER, false, false);
|
||||
if (armorStand != null) {
|
||||
ArmorStandItem.playSound(serverLevel, armorStand);
|
||||
- dispensed.shrink(1);
|
||||
+ if (shrink) dispensed.shrink(1); // Paper
|
||||
}
|
||||
|
||||
return dispensed;
|
||||
@@ -103,8 +_,33 @@
|
||||
@@ -107,9 +_,34 @@
|
||||
.getEntitiesOfClass(AbstractChestedHorse.class, new AABB(pos), entity -> entity.isAlive() && !entity.hasChest())) {
|
||||
if (abstractChestedHorse.isTamed()) {
|
||||
SlotAccess slot = abstractChestedHorse.getSlot(AbstractHorse.CHEST_SLOT_OFFSET);
|
||||
- if (slot != null && slot.set(dispensed)) {
|
||||
- dispensed.shrink(1);
|
||||
+ // CraftBukkit start
|
||||
+ if (slot != null/* && slot.set(dispensed)*/) {
|
||||
+ ItemStack singleCopy = dispensed.copyWithCount(1);
|
||||
@@ -72,12 +72,14 @@
|
||||
+ }
|
||||
+ slot.set(org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(event.getItem()));
|
||||
+ // CraftBukkit end
|
||||
abstractChestedHorse.playChestEquipsSound();
|
||||
- dispensed.shrink(1);
|
||||
+
|
||||
+ if (shrink) dispensed.shrink(1); // Paper - actually handle here
|
||||
this.setSuccess(true);
|
||||
return dispensed;
|
||||
}
|
||||
@@ -145,8 +_,45 @@
|
||||
@@ -150,8 +_,45 @@
|
||||
DispensibleContainerItem bucket = (DispensibleContainerItem)dispensed.getItem();
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
Level level = source.level();
|
||||
@@ -88,7 +90,7 @@
|
||||
+ /* Taken from SolidBucketItem#emptyContents */
|
||||
+ boolean willEmptyContentsSolidBucketItem = bucket instanceof net.minecraft.world.item.SolidBucketItem && level.isInWorldBounds(target) && state.isAir();
|
||||
+ /* Taken from BucketItem#emptyContents */
|
||||
+ boolean willEmptyBucketItem = bucket instanceof final net.minecraft.world.item.BucketItem bucketItem && bucketItem.getContent() instanceof net.minecraft.world.level.material.FlowingFluid && (state.isAir() || state.canBeReplaced(bucketItem.getContent()) || (state.getBlock() instanceof net.minecraft.world.level.block.LiquidBlockContainer liquidBlockContainer && liquidBlockContainer.canPlaceLiquid(null, level, target, state, bucketItem.getContent())));
|
||||
+ boolean willEmptyBucketItem = bucket instanceof final net.minecraft.world.item.BucketItem bucketItem && bucketItem.getContent() instanceof net.minecraft.world.level.material.FlowingFluid && (state.isAir() || state.canBeReplaced(bucketItem.getContent()) || (state.getBlock() instanceof net.minecraft.world.level.block.LiquidBlockContainer liquidBlockContainer && liquidBlockContainer.canPlaceLiquid(null, level, target, state, bucketItem.getContent().defaultFluidState())));
|
||||
+ if (willEmptyContentsSolidBucketItem || willEmptyBucketItem) {
|
||||
+ // Paper end - correctly check if the bucket place will succeed
|
||||
+ org.bukkit.block.Block block = org.bukkit.craftbukkit.block.CraftBlock.at(level, source.pos());
|
||||
@@ -124,7 +126,7 @@
|
||||
return this.consumeWithRemainder(source, dispensed, new ItemStack(Items.BUCKET));
|
||||
} else {
|
||||
return this.defaultDispenseItemBehavior.dispense(source, dispensed);
|
||||
@@ -170,13 +_,20 @@
|
||||
@@ -175,7 +_,7 @@
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
BlockState blockState = level.getBlockState(target);
|
||||
if (blockState.getBlock() instanceof BucketPickup bucket) {
|
||||
@@ -133,7 +135,8 @@
|
||||
if (pickup.isEmpty()) {
|
||||
return super.execute(source, dispensed);
|
||||
}
|
||||
|
||||
@@ -183,6 +_,13 @@
|
||||
bucket.getPickupSound().ifPresent(soundEvent -> level.playSound(null, target, soundEvent, SoundSource.BLOCKS));
|
||||
level.gameEvent(null, GameEvent.FLUID_PICKUP, target);
|
||||
Item targetType = pickup.getItem();
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
@@ -146,7 +149,7 @@
|
||||
return this.consumeWithRemainder(source, dispensed, new ItemStack(targetType));
|
||||
} else {
|
||||
return super.execute(source, dispensed);
|
||||
@@ -190,11 +_,54 @@
|
||||
@@ -196,11 +_,54 @@
|
||||
this.setSuccess(true);
|
||||
Level level = source.level();
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
@@ -201,7 +204,7 @@
|
||||
|
||||
return dispensed;
|
||||
}
|
||||
@@ -209,15 +_,41 @@
|
||||
@@ -215,15 +_,41 @@
|
||||
}
|
||||
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
@@ -250,7 +253,7 @@
|
||||
this.setSuccess(true);
|
||||
return dispensed;
|
||||
}
|
||||
@@ -230,6 +_,13 @@
|
||||
@@ -236,6 +_,13 @@
|
||||
Level level = source.level();
|
||||
Direction direction = source.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos target = source.pos().relative(direction);
|
||||
@@ -264,7 +267,7 @@
|
||||
if (level.isEmptyBlock(target) && WitherSkullBlock.canSpawnMob(level, target, dispensed)) {
|
||||
level.setBlockAndUpdate(
|
||||
target, Blocks.WITHER_SKELETON_SKULL.defaultBlockState().setValue(SkullBlock.ROTATION, RotationSegment.convertToSegment(direction))
|
||||
@@ -242,7 +_,7 @@
|
||||
@@ -248,7 +_,7 @@
|
||||
dispensed.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
@@ -273,7 +276,7 @@
|
||||
}
|
||||
|
||||
return dispensed;
|
||||
@@ -255,6 +_,13 @@
|
||||
@@ -261,6 +_,13 @@
|
||||
Level level = source.level();
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
CarvedPumpkinBlock pumpkinBlock = (CarvedPumpkinBlock)Blocks.CARVED_PUMPKIN;
|
||||
@@ -287,7 +290,7 @@
|
||||
if (level.isEmptyBlock(target) && pumpkinBlock.canSpawnGolem(level, target)) {
|
||||
if (!level.isClientSide()) {
|
||||
level.setBlockAndUpdate(target, pumpkinBlock.defaultBlockState());
|
||||
@@ -264,7 +_,7 @@
|
||||
@@ -270,7 +_,7 @@
|
||||
dispensed.shrink(1);
|
||||
this.setSuccess(true);
|
||||
} else {
|
||||
@@ -296,7 +299,7 @@
|
||||
}
|
||||
|
||||
return dispensed;
|
||||
@@ -287,6 +_,12 @@
|
||||
@@ -296,6 +_,12 @@
|
||||
ServerLevel level = source.level();
|
||||
BlockPos target = source.pos().relative(source.state().getValue(DispenserBlock.FACING));
|
||||
BlockState state = level.getBlockState(target);
|
||||
@@ -306,10 +309,10 @@
|
||||
+ return result;
|
||||
+ }
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
if (state.is(BlockTags.BEEHIVES, s -> s.hasProperty(BeehiveBlock.HONEY_LEVEL) && s.getBlock() instanceof BeehiveBlock)
|
||||
&& state.getValue(BeehiveBlock.HONEY_LEVEL) >= 5) {
|
||||
if (state.is(BlockTags.BEEHIVES, s -> s.getBlock() instanceof BeehiveBlock) && state.getValueOrElse(BeehiveBlock.HONEY_LEVEL, 0) >= 5) {
|
||||
((BeehiveBlock)state.getBlock())
|
||||
@@ -312,6 +_,13 @@
|
||||
.releaseBeesAndResetHoneyLevel(level, state, target, null, BeehiveBlockEntity.BeeReleaseStatus.BEE_RELEASED);
|
||||
@@ -320,6 +_,13 @@
|
||||
this.setSuccess(true);
|
||||
if (blockState.is(Blocks.RESPAWN_ANCHOR)) {
|
||||
if (blockState.getValue(RespawnAnchorBlock.CHARGE) != 4) {
|
||||
@@ -323,7 +326,7 @@
|
||||
RespawnAnchorBlock.charge(null, level, pos, blockState);
|
||||
dispensed.shrink(1);
|
||||
} else {
|
||||
@@ -336,6 +_,28 @@
|
||||
@@ -344,6 +_,28 @@
|
||||
return dispensed;
|
||||
}
|
||||
|
||||
@@ -352,7 +355,7 @@
|
||||
for (Armadillo armadillo : armadillos) {
|
||||
if (armadillo.brushOffScute(null, dispensed)) {
|
||||
dispensed.hurtAndBreak(16, level, null, item -> {});
|
||||
@@ -355,6 +_,13 @@
|
||||
@@ -363,6 +_,13 @@
|
||||
BlockState blockState = level.getBlockState(pos);
|
||||
Optional<BlockState> maybeWaxed = HoneycombItem.getWaxed(blockState);
|
||||
if (maybeWaxed.isPresent()) {
|
||||
@@ -366,7 +369,7 @@
|
||||
level.setBlockAndUpdate(pos, maybeWaxed.get());
|
||||
level.levelEvent(LevelEvent.PARTICLES_WAX_ON, pos, 0);
|
||||
level.playSound(null, pos, SoundEvents.HONEYCOMB_WAX_ON, SoundSource.BLOCKS, 1.0F, 1.0F);
|
||||
@@ -385,6 +_,12 @@
|
||||
@@ -393,6 +_,12 @@
|
||||
return this.defaultDispenseItemBehavior.dispense(source, dispensed);
|
||||
}
|
||||
|
||||
|
||||
+33
-19
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java
|
||||
+++ b/net/minecraft/core/dispenser/FlintAndSteelDispenseItemBehavior.java
|
||||
@@ -24,16 +_,27 @@
|
||||
this.setSuccess(true);
|
||||
@@ -24,8 +_,15 @@
|
||||
ServerLevel level = source.level();
|
||||
Direction facing = source.state().getValue(DispenserBlock.FACING);
|
||||
BlockPos targetPos = source.pos().relative(facing);
|
||||
+ // Paper start - Call BlockDispenseEvent
|
||||
@@ -12,20 +12,34 @@
|
||||
+ }
|
||||
+ // Paper end - Call BlockDispenseEvent
|
||||
BlockState target = level.getBlockState(targetPos);
|
||||
if (!tryIgniteExplosiveEntities(level, targetPos)) {
|
||||
if (BaseFireBlock.canBePlacedAt(level, targetPos, facing)) {
|
||||
+ // CraftBukkit start - Ignition by dispensing flint and steel
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, targetPos, source.pos()).isCancelled()) {
|
||||
level.setBlockAndUpdate(targetPos, BaseFireBlock.getState(level, targetPos));
|
||||
level.gameEvent(null, GameEvent.BLOCK_PLACE, targetPos);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
} else if (CampfireBlock.canLight(target) || CandleBlock.canLight(target) || CandleCakeBlock.canLight(target)) {
|
||||
level.setBlockAndUpdate(targetPos, target.setValue(BlockStateProperties.LIT, true));
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, targetPos);
|
||||
} else if (target.getBlock() instanceof TntBlock) {
|
||||
- if (TntBlock.prime(level, targetPos, null, dispensed)) {
|
||||
+ if (TntBlock.prime(level, targetPos, null, dispensed, () -> org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, targetPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.DISPENSER, null, source.pos()))) { // CraftBukkit - TNTPrimeEvent
|
||||
level.removeBlock(targetPos, false);
|
||||
} else {
|
||||
this.setSuccess(false);
|
||||
- boolean ignited = tryIgnite(dispensed, level, targetPos, facing, target);
|
||||
+ boolean ignited = tryIgnite(dispensed, level, targetPos, facing, target, source.pos()); // CraftBukkit
|
||||
this.setSuccess(ignited);
|
||||
if (this.isSuccess()) {
|
||||
FlintAndSteelItem.playSound(level, targetPos);
|
||||
@@ -36,19 +_,23 @@
|
||||
}
|
||||
|
||||
private static boolean tryIgnite(
|
||||
- final ItemStack dispensed, final ServerLevel level, final BlockPos targetPos, final Direction facing, final BlockState target
|
||||
+ final ItemStack dispensed, final ServerLevel level, final BlockPos targetPos, final Direction facing, final BlockState target, final BlockPos sourcePos // CraftBukkit
|
||||
) {
|
||||
if (tryIgniteExplosiveEntities(level, targetPos)) {
|
||||
return true;
|
||||
} else if (BaseFireBlock.canBePlacedAt(level, targetPos, facing)) {
|
||||
+ // CraftBukkit start - Ignition by dispensing flint and steel
|
||||
+ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(level, targetPos, sourcePos).isCancelled()) {
|
||||
level.setBlockAndUpdate(targetPos, BaseFireBlock.getState(level, targetPos));
|
||||
level.gameEvent(null, GameEvent.BLOCK_PLACE, targetPos);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
return true;
|
||||
} else if (CampfireBlock.canLight(target) || CandleBlock.canLight(target) || CandleCakeBlock.canLight(target)) {
|
||||
level.setBlockAndUpdate(targetPos, target.setValue(BlockStateProperties.LIT, true));
|
||||
level.gameEvent(null, GameEvent.BLOCK_CHANGE, targetPos);
|
||||
return true;
|
||||
- } else if (target.getBlock() instanceof TntBlock && TntBlock.prime(level, targetPos, null, dispensed)) {
|
||||
+ } else if (target.getBlock() instanceof TntBlock && TntBlock.prime(level, targetPos, null, dispensed, () -> org.bukkit.craftbukkit.event.CraftEventFactory.callTNTPrimeEvent(level, targetPos, org.bukkit.event.block.TNTPrimeEvent.PrimeCause.DISPENSER, null, sourcePos))) { // CraftBukkit - TNTPrimeEvent
|
||||
level.removeBlock(targetPos, false);
|
||||
return true;
|
||||
} else {
|
||||
+7
-49
@@ -1,65 +1,23 @@
|
||||
--- a/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
+++ b/net/minecraft/core/registries/BuiltInRegistries.java
|
||||
@@ -367,6 +_,11 @@
|
||||
public static final Registry<ContextKeySet> CONTEXT_KEY_SET = registerSimple(Registries.CONTEXT_KEY_SET, LootContextParamSets::bootstrap);
|
||||
public static final Registry<Consumer<GameTestHelper>> TEST_FUNCTION = registerSimple(Registries.TEST_FUNCTION, BuiltinTestFunctions::bootstrap);
|
||||
public static final Registry<? extends Registry<?>> REGISTRY = WRITABLE_REGISTRY;
|
||||
@@ -373,9 +_,19 @@
|
||||
public static final Registry<ContextKeySet> CONTEXT_KEY_SET = BUILDER.registerSimple(Registries.CONTEXT_KEY_SET, LootContextParamSets::bootstrap);
|
||||
public static final Registry<Consumer<GameTestHelper>> TEST_FUNCTION = BUILDER.registerSimple(Registries.TEST_FUNCTION, BuiltinTestFunctions::bootstrap);
|
||||
public static final Registry<? extends Registry<?>> REGISTRY = BUILDER.build();
|
||||
+ // Paper start - add built-in registry conversions
|
||||
+ public static final io.papermc.paper.registry.data.util.Conversions STATIC_ACCESS_CONVERSIONS = new io.papermc.paper.registry.data.util.Conversions(
|
||||
+ new net.minecraft.resources.RegistryOps.HolderLookupAdapter(net.minecraft.server.RegistryLayer.STATIC_ACCESS)
|
||||
+ );
|
||||
+ // Paper end - add built-in registry conversions
|
||||
|
||||
private static <T> Registry<T> registerSimple(final ResourceKey<? extends Registry<T>> name, final BuiltInRegistries.RegistryBootstrap<T> loader) {
|
||||
return internalRegister(name, new MappedRegistry<>(name, Lifecycle.stable(), false), loader);
|
||||
@@ -394,6 +_,7 @@
|
||||
final ResourceKey<? extends Registry<T>> name, final R registry, final BuiltInRegistries.RegistryBootstrap<T> loader
|
||||
) {
|
||||
Bootstrap.checkBootstrapCalled(() -> "registry " + name.identifier());
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry); // Paper - initialize API registry
|
||||
Identifier key = name.identifier();
|
||||
LOADERS.put(key, () -> loader.run(registry));
|
||||
WRITABLE_REGISTRY.register((ResourceKey)name, registry, RegistrationInfo.BUILT_IN);
|
||||
@@ -401,16 +_,34 @@
|
||||
}
|
||||
|
||||
public static void bootStrap() {
|
||||
- BUILDER.bootStrap();
|
||||
+ // Paper start
|
||||
+ bootStrap(() -> {});
|
||||
+ }
|
||||
+ public static void bootStrap(Runnable runnable) {
|
||||
+ BUILDER.bootStrap(runnable);
|
||||
+ // Paper end
|
||||
+ REGISTRY.freeze(); // Paper - freeze main registry early
|
||||
createContents();
|
||||
+ runnable.run(); // Paper
|
||||
freeze();
|
||||
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((key, value) -> {
|
||||
if (value.get() == null) {
|
||||
LOGGER.error("Unable to bootstrap registry '{}'", key);
|
||||
}
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().lockReferenceHolders(ResourceKey.createRegistryKey(key)); // Paper - lock reference holder creation
|
||||
});
|
||||
}
|
||||
|
||||
@@ -419,6 +_,7 @@
|
||||
|
||||
for (Registry<?> registry : REGISTRY) {
|
||||
bindBootstrappedTagsToEmpty(registry);
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), STATIC_ACCESS_CONVERSIONS); // Paper
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
public static <T> HolderGetter<T> acquireBootstrapRegistrationLookup(final Registry<T> registry) {
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
--- a/net/minecraft/core/registries/BuiltinRegistryBuilder.java
|
||||
+++ b/net/minecraft/core/registries/BuiltinRegistryBuilder.java
|
||||
@@ -53,6 +_,7 @@
|
||||
final ResourceKey<? extends Registry<T>> name, final R registry, final BuiltinRegistryBuilder.RegistryBootstrap<T> loader
|
||||
) {
|
||||
Bootstrap.checkBootstrapCalled(() -> "registry " + name.identifier());
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().registerRegistry(registry); // Paper - initialize API registry
|
||||
Identifier key = name.identifier();
|
||||
this.loaders.put(key, () -> loader.run(registry));
|
||||
this.registry.register((ResourceKey)name, registry, RegistrationInfo.BUILT_IN);
|
||||
@@ -60,16 +_,34 @@
|
||||
}
|
||||
|
||||
public void bootStrap() {
|
||||
+ // Paper start
|
||||
+ this.bootStrap(() -> {});
|
||||
+ }
|
||||
+ public void bootStrap(Runnable runnable) {
|
||||
+ // Paper end
|
||||
+ this.registry.freeze(); // Paper - freeze main registry early
|
||||
this.createContents();
|
||||
+ runnable.run(); // Paper
|
||||
this.freeze();
|
||||
validate(this.registry);
|
||||
}
|
||||
|
||||
private 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
|
||||
this.loaders.forEach((key, value) -> {
|
||||
if (value.get() == null) {
|
||||
LOGGER.error("Unable to bootstrap registry '{}'", key);
|
||||
}
|
||||
+ io.papermc.paper.registry.PaperRegistryAccess.instance().lockReferenceHolders(ResourceKey.createRegistryKey(key)); // Paper - lock reference holder creation
|
||||
});
|
||||
}
|
||||
|
||||
@@ -78,6 +_,7 @@
|
||||
|
||||
for (Registry<?> registry : this.registry) {
|
||||
bindBootstrappedTagsToEmpty(registry);
|
||||
+ io.papermc.paper.registry.PaperRegistryListenerManager.INSTANCE.runFreezeListeners(registry.key(), BuiltInRegistries.STATIC_ACCESS_CONVERSIONS); // Paper
|
||||
registry.freeze();
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/gametest/framework/GameTestInfo.java
|
||||
+++ b/net/minecraft/gametest/framework/GameTestInfo.java
|
||||
@@ -246,7 +_,7 @@
|
||||
@@ -247,7 +_,7 @@
|
||||
this.finish();
|
||||
AABB bounds = this.getStructureBounds();
|
||||
List<Entity> entities = this.getLevel().getEntitiesOfClass(Entity.class, bounds.inflate(1.0), mob -> !(mob instanceof Player));
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
--- a/net/minecraft/nbt/CompoundTag.java
|
||||
+++ b/net/minecraft/nbt/CompoundTag.java
|
||||
@@ -51,7 +_,7 @@
|
||||
@@ -50,7 +_,7 @@
|
||||
|
||||
private static CompoundTag loadCompound(final DataInput input, final NbtAccounter accounter) throws IOException {
|
||||
accounter.accountBytes(48L);
|
||||
- Map<String, Tag> values = Maps.newHashMap();
|
||||
- Map<String, Tag> values = new HashMap<>();
|
||||
+ it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<String, Tag> values = new it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap<>(8, 0.8f); // Paper - Reduce memory footprint of CompoundTag
|
||||
|
||||
byte tagType;
|
||||
while ((tagType = input.readByte()) != 0) {
|
||||
@@ -165,7 +_,7 @@
|
||||
@@ -164,7 +_,7 @@
|
||||
}
|
||||
|
||||
public CompoundTag() {
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -394,9 +_,16 @@
|
||||
@@ -393,9 +_,16 @@
|
||||
|
||||
@Override
|
||||
public CompoundTag copy() {
|
||||
@@ -38,7 +38,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -517,22 +_,47 @@
|
||||
@@ -516,22 +_,47 @@
|
||||
this.merge((CompoundTag)codec.encoder().encodeStart(ops, value).getOrThrow());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/nbt/SnbtGrammar.java
|
||||
+++ b/net/minecraft/nbt/SnbtGrammar.java
|
||||
@@ -619,7 +_,7 @@
|
||||
@@ -607,7 +_,7 @@
|
||||
mapEntries, Term.repeatedWithTrailingSeparator(mapEntryRule, mapEntries, StringReaderTerms.character(',')), scope -> scope.getOrThrow(mapEntries)
|
||||
);
|
||||
Atom<T> mapLiteral = Atom.of("map_literal");
|
||||
@@ -9,7 +9,7 @@
|
||||
List<Entry<String, T>> entries = scope.getOrThrow(mapEntries);
|
||||
if (entries.isEmpty()) {
|
||||
return emptyMapValue;
|
||||
@@ -660,9 +_,11 @@
|
||||
@@ -648,9 +_,11 @@
|
||||
listLiteral,
|
||||
Term.sequence(
|
||||
StringReaderTerms.character('['),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/network/Connection.java
|
||||
+++ b/net/minecraft/network/Connection.java
|
||||
@@ -67,6 +_,11 @@
|
||||
private final Queue<Consumer<Connection>> pendingActions = Queues.newConcurrentLinkedQueue();
|
||||
private final Queue<Consumer<Connection>> pendingActions = new ConcurrentLinkedQueue<>();
|
||||
public Channel channel;
|
||||
public SocketAddress address;
|
||||
+ // Spigot start
|
||||
@@ -112,20 +112,15 @@
|
||||
this.disconnect(Component.translatable("disconnect.timeout"));
|
||||
} else {
|
||||
Component reason = Component.translatable("disconnect.genericReason", "Internal Exception: " + cause);
|
||||
@@ -120,9 +_,11 @@
|
||||
@@ -120,6 +_,7 @@
|
||||
details = new DisconnectionDetails(reason);
|
||||
}
|
||||
|
||||
+ if (player != null) player.quitReason = org.bukkit.event.player.PlayerQuitEvent.QuitReason.ERRONEOUS_STATE; // Paper - Add API for quit reason
|
||||
if (isFirstFault) {
|
||||
LOGGER.debug("Failed to sent packet", cause);
|
||||
- if (this.getSending() == PacketFlow.CLIENTBOUND) {
|
||||
+ boolean doesDisconnectExist = this.packetListener.protocol() != ConnectionProtocol.STATUS && this.packetListener.protocol() != ConnectionProtocol.HANDSHAKING; // Paper
|
||||
+ if (this.getSending() == PacketFlow.CLIENTBOUND && doesDisconnectExist) { // Paper
|
||||
Packet<?> packet = this.sendLoginDisconnect
|
||||
? new ClientboundLoginDisconnectPacket(reason)
|
||||
: new ClientboundDisconnectPacket(reason);
|
||||
@@ -139,6 +_,7 @@
|
||||
Packet<?> disconnectPacket = null;
|
||||
@@ -145,6 +_,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -133,7 +128,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -148,11 +_,60 @@
|
||||
@@ -154,11 +_,60 @@
|
||||
if (packetListener == null) {
|
||||
throw new IllegalStateException("Received a packet before the packet listener was initialized");
|
||||
}
|
||||
@@ -195,7 +190,7 @@
|
||||
} catch (RejectedExecutionException ignored) {
|
||||
this.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
|
||||
} catch (ClassCastException exception) {
|
||||
@@ -295,6 +_,47 @@
|
||||
@@ -298,6 +_,47 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +238,7 @@
|
||||
private void sendPacket(final Packet<?> packet, final @Nullable ChannelFutureListener listener, final boolean flush) {
|
||||
this.sentPackets++;
|
||||
if (this.channel.eventLoop().inEventLoop()) {
|
||||
@@ -342,10 +_,30 @@
|
||||
@@ -345,10 +_,30 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +269,7 @@
|
||||
}
|
||||
|
||||
if (!this.isConnected() && !this.disconnectionHandled) {
|
||||
@@ -353,7 +_,7 @@
|
||||
@@ -356,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (this.channel != null) {
|
||||
@@ -283,7 +278,7 @@
|
||||
}
|
||||
|
||||
if (this.tickCount++ % 20 == 0) {
|
||||
@@ -389,6 +_,7 @@
|
||||
@@ -392,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void disconnect(final DisconnectionDetails details) {
|
||||
@@ -291,7 +286,7 @@
|
||||
if (this.channel == null) {
|
||||
this.delayedDisconnect = details;
|
||||
}
|
||||
@@ -541,6 +_,14 @@
|
||||
@@ -552,10 +_,19 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -305,16 +300,13 @@
|
||||
+
|
||||
public void setupCompression(final int threshold, final boolean validateDecompressed) {
|
||||
if (threshold >= 0) {
|
||||
if (this.channel.pipeline().get(HandlerNames.DECOMPRESS) instanceof CompressionDecoder compressionDecoder) {
|
||||
@@ -554,6 +_,7 @@
|
||||
} else {
|
||||
this.channel.pipeline().addAfter(HandlerNames.PREPENDER, HandlerNames.COMPRESS, new CompressionEncoder(threshold));
|
||||
}
|
||||
this.setupInboundCompression(threshold, validateDecompressed);
|
||||
this.setupOutboundCompression(threshold);
|
||||
+ this.channel.pipeline().fireUserEventTriggered(io.papermc.paper.network.ConnectionEvent.COMPRESSION_THRESHOLD_SET); // Paper - Add Channel initialization listeners
|
||||
} else {
|
||||
if (this.channel.pipeline().get(HandlerNames.DECOMPRESS) instanceof CompressionDecoder) {
|
||||
this.channel.pipeline().remove(HandlerNames.DECOMPRESS);
|
||||
@@ -562,6 +_,7 @@
|
||||
@@ -564,6 +_,7 @@
|
||||
if (this.channel.pipeline().get(HandlerNames.COMPRESS) instanceof CompressionEncoder) {
|
||||
this.channel.pipeline().remove(HandlerNames.COMPRESS);
|
||||
}
|
||||
@@ -322,7 +314,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -579,6 +_,26 @@
|
||||
@@ -597,6 +_,26 @@
|
||||
);
|
||||
disconnectListener.onDisconnect(details);
|
||||
}
|
||||
@@ -340,7 +332,7 @@
|
||||
+ case WAITING_FOR_DUPE_DISCONNECT:
|
||||
+ case PROTOCOL_SWITCHING:
|
||||
+ case ACCEPTED:
|
||||
+ final com.mojang.authlib.GameProfile profile = loginListener.authenticatedProfile; /* Should be non-null at this stage */
|
||||
+ final com.mojang.authlib.GameProfile profile = loginListener.resolvedUserProfile; /* Should be non-null at this stage */
|
||||
+ new com.destroystokyo.paper.event.player.PlayerConnectionCloseEvent(profile.id(), profile.name(),
|
||||
+ this.address, false).callEvent();
|
||||
+ }
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
return Thread.currentThread() == this.runningThread;
|
||||
}
|
||||
|
||||
public <T extends PacketListener> void scheduleIfPossible(final T listener, final Packet<T> packet) {
|
||||
public <T extends PacketListener & PacketProcessor.Handler> void scheduleIfPossible(final T listener, final Packet<? super T> packet) {
|
||||
if (this.closed) {
|
||||
- throw new RejectedExecutionException("Server already shutting down");
|
||||
- }
|
||||
@@ -47,8 +47,8 @@
|
||||
}
|
||||
|
||||
public void processQueuedPackets() {
|
||||
@@ -44,8 +_,28 @@
|
||||
this.closed = true;
|
||||
@@ -48,8 +_,28 @@
|
||||
void onPacketError(Packet<?> packet, Exception cause) throws ReportedException;
|
||||
}
|
||||
|
||||
+ // Paper start - detailed watchdog information
|
||||
@@ -69,14 +69,14 @@
|
||||
+ }
|
||||
+ // Paper end - detailed watchdog information
|
||||
+
|
||||
private record ListenerAndPacket<T extends PacketListener>(T listener, Packet<T> packet) {
|
||||
private record ListenerAndPacket<T extends PacketListener & PacketProcessor.Handler>(T listener, Packet<? super T> packet) {
|
||||
public void handle() {
|
||||
+ packetProcessing.push(this.listener); // Paper - detailed watchdog information
|
||||
+ try { // Paper - detailed watchdog information
|
||||
if (this.listener.shouldHandleMessage(this.packet)) {
|
||||
try {
|
||||
this.packet.handle(this.listener);
|
||||
@@ -59,6 +_,12 @@
|
||||
@@ -63,6 +_,12 @@
|
||||
} else {
|
||||
PacketProcessor.LOGGER.debug("Ignoring packet due to disconnection: {}", this.packet);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/chat/Component.java
|
||||
+++ b/net/minecraft/network/chat/Component.java
|
||||
@@ -27,7 +_,19 @@
|
||||
@@ -26,7 +_,19 @@
|
||||
import net.minecraft.world.level.ChunkPos;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
+++ b/net/minecraft/network/codec/ByteBufCodecs.java
|
||||
@@ -377,7 +_,13 @@
|
||||
@@ -378,7 +_,13 @@
|
||||
return new StreamCodec<ByteBuf, Tag>() {
|
||||
@Override
|
||||
public Tag decode(final ByteBuf input) {
|
||||
@@ -15,7 +15,7 @@
|
||||
if (result == null) {
|
||||
throw new DecoderException("Expected non-null compound tag");
|
||||
} else {
|
||||
@@ -424,7 +_,7 @@
|
||||
@@ -425,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void encode(final B output, final V value) {
|
||||
@@ -24,7 +24,7 @@
|
||||
original.encode(output, payload);
|
||||
}
|
||||
};
|
||||
@@ -454,13 +_,55 @@
|
||||
@@ -455,13 +_,55 @@
|
||||
|
||||
@Override
|
||||
public void encode(final RegistryFriendlyByteBuf output, final T value) {
|
||||
@@ -81,7 +81,7 @@
|
||||
static <B extends ByteBuf, V> StreamCodec<B, Optional<V>> optional(final StreamCodec<? super B, V> original) {
|
||||
return new StreamCodec<B, Optional<V>>() {
|
||||
@Override
|
||||
@@ -681,7 +_,7 @@
|
||||
@@ -682,7 +_,7 @@
|
||||
}
|
||||
|
||||
static <V> StreamCodec.CodecOperation<RegistryFriendlyByteBuf, V, V> registryFriendlyLengthPrefixed(final int maxSize) {
|
||||
|
||||
+7
-3
@@ -1,10 +1,14 @@
|
||||
--- a/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
|
||||
+++ b/net/minecraft/network/protocol/common/ServerboundCustomPayloadPacket.java
|
||||
@@ -14,7 +_,7 @@
|
||||
@@ -14,10 +_,8 @@
|
||||
public record ServerboundCustomPayloadPacket(CustomPacketPayload payload) implements Packet<ServerCommonPacketListener> {
|
||||
private static final int MAX_PAYLOAD_SIZE = 32767;
|
||||
public static final StreamCodec<FriendlyByteBuf, ServerboundCustomPayloadPacket> STREAM_CODEC = CustomPacketPayload.<FriendlyByteBuf>codec(
|
||||
id -> DiscardedPayload.codec(id, 32767),
|
||||
- Util.make(Lists.newArrayList(new CustomPacketPayload.TypeAndCodec<>(BrandPayload.TYPE, BrandPayload.STREAM_CODEC)), types -> {})
|
||||
- id -> DiscardedPayload.codec(id, 32767), Util.make(new ArrayList<>(), types -> {
|
||||
- types.add(new CustomPacketPayload.TypeAndCodec<>(BrandPayload.TYPE, BrandPayload.STREAM_CODEC));
|
||||
- types.add(new CustomPacketPayload.TypeAndCodec<>(ModListPayload.TYPE, ModListPayload.STREAM_CODEC));
|
||||
- })
|
||||
+ id -> DiscardedPayload.codec(id, 32767),
|
||||
+ java.util.Collections.emptyList() // CraftBukkit - treat all packets the same
|
||||
)
|
||||
.map(ServerboundCustomPayloadPacket::new, ServerboundCustomPayloadPacket::payload);
|
||||
|
||||
+5
-5
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
+++ b/net/minecraft/network/protocol/game/ClientboundPlayerInfoUpdatePacket.java
|
||||
@@ -42,6 +_,17 @@
|
||||
@@ -40,6 +_,17 @@
|
||||
this.actions = EnumSet.of(action);
|
||||
this.entries = List.of(new ClientboundPlayerInfoUpdatePacket.Entry(player));
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
public static ClientboundPlayerInfoUpdatePacket createPlayerInitializing(final Collection<ServerPlayer> players) {
|
||||
EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions = EnumSet.of(
|
||||
@@ -56,6 +_,46 @@
|
||||
@@ -54,6 +_,46 @@
|
||||
);
|
||||
return new ClientboundPlayerInfoUpdatePacket(actions, players);
|
||||
}
|
||||
@@ -65,7 +65,7 @@
|
||||
|
||||
private static StreamCodec<RegistryFriendlyByteBuf, ClientboundPlayerInfoUpdatePacket.Entry> entryCodec(
|
||||
final EnumSet<ClientboundPlayerInfoUpdatePacket.Action> actions
|
||||
@@ -127,7 +_,15 @@
|
||||
@@ -125,7 +_,15 @@
|
||||
INITIALIZE_CHAT(
|
||||
1,
|
||||
(entry, input) -> entry.chatSession = input.readNullable(RemoteChatSession.Data.STREAM_CODEC),
|
||||
@@ -82,7 +82,7 @@
|
||||
),
|
||||
UPDATE_GAME_MODE(
|
||||
2, (entry, input) -> entry.gameMode = GameType.STREAM_CODEC.decode(input), (output, entry) -> GameType.STREAM_CODEC.encode(output, entry.gameMode)
|
||||
@@ -177,10 +_,15 @@
|
||||
@@ -174,10 +_,15 @@
|
||||
RemoteChatSession.@Nullable Data chatSession
|
||||
) {
|
||||
private Entry(final ServerPlayer player) {
|
||||
@@ -99,7 +99,7 @@
|
||||
player.connection.latency(),
|
||||
player.gameMode(),
|
||||
player.getTabListDisplayName(),
|
||||
@@ -189,6 +_,11 @@
|
||||
@@ -186,6 +_,11 @@
|
||||
Optionull.map(player.getChatSession(), RemoteChatSession::asData)
|
||||
);
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,11 +1,11 @@
|
||||
--- a/net/minecraft/network/protocol/handshake/ClientIntentionPacket.java
|
||||
+++ b/net/minecraft/network/protocol/handshake/ClientIntentionPacket.java
|
||||
@@ -16,7 +_,7 @@
|
||||
}
|
||||
|
||||
private ClientIntentionPacket(final FriendlyByteBuf input) {
|
||||
- this(input.readVarInt(), input.readUtf(255), input.readUnsignedShort(), ClientIntent.byId(input.readVarInt()));
|
||||
+ this(input.readVarInt(), input.readUtf(Short.MAX_VALUE), input.readUnsignedShort(), ClientIntent.byId(input.readVarInt())); // Spigot - increase max hostName length
|
||||
}
|
||||
|
||||
private void write(final FriendlyByteBuf output) {
|
||||
@@ -11,7 +_,7 @@
|
||||
public static final StreamCodec<FriendlyByteBuf, ClientIntentionPacket> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.VAR_INT,
|
||||
ClientIntentionPacket::protocolVersion,
|
||||
- ByteBufCodecs.stringUtf8(1024),
|
||||
+ ByteBufCodecs.stringUtf8(Short.MAX_VALUE), // Spigot - increase max hostName length
|
||||
ClientIntentionPacket::hostName,
|
||||
ByteBufCodecs.UNSIGNED_SHORT,
|
||||
ClientIntentionPacket::port,
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/resources/RegistryDataLoader.java
|
||||
+++ b/net/minecraft/resources/RegistryDataLoader.java
|
||||
@@ -278,11 +_,21 @@
|
||||
@@ -281,11 +_,21 @@
|
||||
final Map<ResourceKey<? extends Registry<?>>, HolderGetter<?>> result = new HashMap<>();
|
||||
contextRegistries.forEach(e -> result.put(e.key(), e));
|
||||
newRegistriesAndLoaders.forEach(e -> result.put(e.registryKey(), e.concurrentRegistrationGetter));
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
--- a/net/minecraft/server/Bootstrap.java
|
||||
+++ b/net/minecraft/server/Bootstrap.java
|
||||
@@ -44,6 +_,7 @@
|
||||
if (!isBootstrapped) {
|
||||
@@ -47,6 +_,7 @@
|
||||
isBootstrapped = true;
|
||||
Instant start = Instant.now();
|
||||
SystemReport.setVersionDetails(SharedConstants.getCurrentVersion().name(), SharedConstants.getCurrentVersion().id(), "MC_DEBUG_");
|
||||
+ io.papermc.paper.plugin.entrypoint.LaunchEntryPointHandler.enterBootstrappers(); // Paper - Entrypoint for bootstrapping
|
||||
if (BuiltInRegistries.REGISTRY.keySet().isEmpty()) {
|
||||
throw new IllegalStateException("Unable to load registries");
|
||||
}
|
||||
@@ -56,11 +_,81 @@
|
||||
@@ -59,11 +_,81 @@
|
||||
EntitySelectorOptions.bootStrap();
|
||||
DispenseItemBehavior.bootStrap();
|
||||
CauldronInteractions.bootStrap();
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
OptionParser parser = new OptionParser();
|
||||
OptionSpec<Void> nogui = parser.accepts("nogui");
|
||||
OptionSpec<Void> initSettings = parser.accepts("initSettings", "Initializes 'server.properties' and 'eula.txt', then quits");
|
||||
@@ -92,41 +_,97 @@
|
||||
@@ -92,43 +_,99 @@
|
||||
parser.printHelpOn(System.err);
|
||||
return;
|
||||
}
|
||||
@@ -85,7 +85,6 @@
|
||||
}
|
||||
|
||||
- File universePath = new File(options.valueOf(universe));
|
||||
- Services services = Services.create(MinecraftServicesDiscoveryService.create(Proxy.NO_PROXY), universePath);
|
||||
+ // Paper start - Detect headless JRE
|
||||
+ String awtException = io.papermc.paper.util.ServerEnvironment.awtDependencyCheck();
|
||||
+ if (awtException != null) {
|
||||
@@ -110,7 +109,10 @@
|
||||
+ universePath = new File(bukkitConfiguration.getString("settings.world-container", "."));
|
||||
+ }
|
||||
+ // Paper end - fix SPIGOT-5824
|
||||
+ Services services = Services.create(com.destroystokyo.paper.profile.PaperServicesDiscoveryService.create(Proxy.NO_PROXY), universePath, userCacheFile, options); // Paper - pass OptionSet to load paper config files; override authentication service; fix world-container
|
||||
Services services = Services.create(
|
||||
- MinecraftServicesDiscoveryService.create(Proxy.NO_PROXY, SharedConstants.getCurrentVersion().id()), universePath
|
||||
+ com.destroystokyo.paper.profile.PaperServicesDiscoveryService.create(Proxy.NO_PROXY, SharedConstants.getCurrentVersion().id()), universePath, userCacheFile, options // Paper - pass OptionSet to load paper config files; override authentication service; fix world-container
|
||||
);
|
||||
NotificationManager notificationManager = new NotificationManager();
|
||||
ManagementServer jsonRpcServer = JsonRpc.create(settings, notificationManager);
|
||||
- String levelName = Optional.ofNullable(options.valueOf(worldName)).orElse(settings.getProperties().levelName);
|
||||
@@ -118,7 +120,7 @@
|
||||
LevelStorageSource levelStorageSource = LevelStorageSource.createDefault(universePath.toPath());
|
||||
LevelStorageSource.LevelStorageAccess access = levelStorageSource.validateAndCreateAccess(levelName);
|
||||
Dynamic<?> levelDataTag;
|
||||
@@ -154,13 +_,20 @@
|
||||
@@ -156,13 +_,20 @@
|
||||
} else {
|
||||
levelDataTag = null;
|
||||
}
|
||||
@@ -140,7 +142,7 @@
|
||||
|
||||
WorldStem worldStem;
|
||||
try {
|
||||
@@ -169,17 +_,31 @@
|
||||
@@ -171,17 +_,31 @@
|
||||
executor -> WorldLoader.load(
|
||||
worldLoadConfig,
|
||||
context -> {
|
||||
@@ -174,7 +176,7 @@
|
||||
}
|
||||
},
|
||||
WorldStem::new,
|
||||
@@ -195,6 +_,7 @@
|
||||
@@ -197,6 +_,7 @@
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -182,7 +184,7 @@
|
||||
RegistryAccess.Frozen registryHolder = worldStem.registries().compositeAccess();
|
||||
WorldData data = worldStem.worldDataAndGenSettings().data();
|
||||
boolean recreateRegionFilesValue = options.has(recreateRegionFiles);
|
||||
@@ -203,9 +_,12 @@
|
||||
@@ -205,9 +_,12 @@
|
||||
}
|
||||
|
||||
access.saveDataTag(data);
|
||||
@@ -195,7 +197,7 @@
|
||||
thread,
|
||||
access,
|
||||
packRepository,
|
||||
@@ -218,17 +_,35 @@
|
||||
@@ -220,17 +_,35 @@
|
||||
notificationManager
|
||||
);
|
||||
notificationManager.setServer(server);
|
||||
@@ -233,7 +235,7 @@
|
||||
Thread shutdownThread = new Thread("Server Shutdown Thread") {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -237,12 +_,13 @@
|
||||
@@ -239,12 +_,13 @@
|
||||
};
|
||||
shutdownThread.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER));
|
||||
Runtime.getRuntime().addShutdownHook(shutdownThread);
|
||||
@@ -248,7 +250,7 @@
|
||||
final DedicatedServerSettings settings,
|
||||
final WorldLoader.DataLoadContext context,
|
||||
final Registry<LevelStem> datapackDimensions,
|
||||
@@ -313,7 +_,11 @@
|
||||
@@ -315,7 +_,11 @@
|
||||
final RegistryAccess registryAccess,
|
||||
final boolean recreateRegionFiles
|
||||
) {
|
||||
@@ -261,7 +263,7 @@
|
||||
|
||||
try (WorldUpgrader upgrader = new WorldUpgrader(storageSource, fixerUpper, registryAccess, eraseCache, recreateRegionFiles)) {
|
||||
Component lastStatus = null;
|
||||
@@ -341,5 +_,6 @@
|
||||
@@ -343,5 +_,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/net/minecraft/server/MinecraftServer.java
|
||||
@@ -188,11 +_,13 @@
|
||||
@@ -189,11 +_,13 @@
|
||||
import org.slf4j.Logger;
|
||||
|
||||
public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTask> implements CommandSource, ServerInfo, ChunkIOErrorReporter {
|
||||
@@ -15,16 +15,16 @@
|
||||
private static final int OVERLOADED_TICKS_THRESHOLD = 20;
|
||||
private static final long OVERLOADED_WARNING_INTERVAL_NANOS = 10L * TimeUtil.NANOSECONDS_PER_SECOND;
|
||||
private static final int OVERLOADED_TICKS_WARNING_INTERVAL = 100;
|
||||
@@ -215,7 +_,7 @@
|
||||
@@ -216,7 +_,7 @@
|
||||
protected final PlayerDataStorage playerDataStorage;
|
||||
private final SavedDataStorage savedDataStorage;
|
||||
private final List<Runnable> tickables = Lists.newArrayList();
|
||||
private final List<Runnable> tickables = new ArrayList<>();
|
||||
- private final GameRules gameRules;
|
||||
+ // Paper - per-level GameRules
|
||||
private MetricsRecorder metricsRecorder = InactiveMetricsRecorder.INSTANCE;
|
||||
private Consumer<ProfileResults> onMetricsRecordingStopped = results -> this.stopRecordingMetrics();
|
||||
private Consumer<Path> onMetricsRecordingFinished = ignored -> {};
|
||||
@@ -223,7 +_,7 @@
|
||||
@@ -224,7 +_,7 @@
|
||||
private MinecraftServer.@Nullable TimeProfiler debugCommandProfiler;
|
||||
private boolean debugCommandProfilerDelayStart;
|
||||
private ServerConnectionListener connection;
|
||||
@@ -33,8 +33,8 @@
|
||||
private @Nullable ServerStatus status;
|
||||
private ServerStatus.@Nullable Favicon statusIcon;
|
||||
private final RandomSource random = RandomSource.create();
|
||||
@@ -234,13 +_,14 @@
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels = Maps.newLinkedHashMap();
|
||||
@@ -235,13 +_,14 @@
|
||||
private Map<ResourceKey<Level>, ServerLevel> levels = new LinkedHashMap<>();
|
||||
private PlayerList playerList;
|
||||
private volatile boolean running = true;
|
||||
+ private volatile boolean isRestarting = false; // Paper - flag to signify we're attempting to restart
|
||||
@@ -49,7 +49,7 @@
|
||||
private int playerIdleTimeout;
|
||||
private final long[] tickTimesNanos = new long[100];
|
||||
private long aggregatedTickTimesNanos = 0L;
|
||||
@@ -268,7 +_,7 @@
|
||||
@@ -269,7 +_,7 @@
|
||||
private @Nullable CommandStorage commandStorage;
|
||||
private final CustomBossEvents customBossEvents;
|
||||
private final RandomSequences randomSequences;
|
||||
@@ -58,7 +58,7 @@
|
||||
private final ServerFunctionManager functionManager;
|
||||
private boolean enforceWhitelist;
|
||||
private boolean usingWhitelist;
|
||||
@@ -286,13 +_,14 @@
|
||||
@@ -287,13 +_,14 @@
|
||||
private final SuppressedExceptionCollector suppressedExceptions = new SuppressedExceptionCollector();
|
||||
private final DiscontinuousFrame tickFrame;
|
||||
private final PacketProcessor packetProcessor;
|
||||
@@ -75,7 +75,7 @@
|
||||
if (Runtime.getRuntime().availableProcessors() > 4) {
|
||||
thread.setPriority(8);
|
||||
}
|
||||
@@ -303,7 +_,124 @@
|
||||
@@ -304,7 +_,124 @@
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
final Thread serverThread,
|
||||
final LevelStorageSource.LevelStorageAccess storageSource,
|
||||
final PackRepository packRepository,
|
||||
@@ -317,28 +_,28 @@
|
||||
@@ -318,28 +_,28 @@
|
||||
final NotificationManager notificationManager
|
||||
) {
|
||||
super("Server", propagatesCrashes);
|
||||
@@ -237,7 +237,7 @@
|
||||
this.fixerUpper = fixerUpper;
|
||||
this.functionManager = new ServerFunctionManager(this, this.resources.managers.getFunctionLibrary());
|
||||
HolderGetter<Block> blockLookup = this.registries.compositeAccess().lookupOrThrow(Registries.BLOCK).filterFeatures(this.worldData.enabledFeatures());
|
||||
@@ -353,7 +_,14 @@
|
||||
@@ -354,7 +_,14 @@
|
||||
this.clockManager = this.getDataStorage().computeIfAbsent(ServerClockManager.TYPE);
|
||||
this.clockManager.init(this);
|
||||
this.customBossEvents = this.savedDataStorage.computeIfAbsent(CustomBossEvents.TYPE);
|
||||
@@ -253,7 +253,7 @@
|
||||
}
|
||||
|
||||
protected abstract boolean initServer() throws IOException;
|
||||
@@ -386,15 +_,15 @@
|
||||
@@ -387,15 +_,15 @@
|
||||
};
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@
|
||||
if (profiledDuration != null) {
|
||||
profiledDuration.finish(true);
|
||||
}
|
||||
@@ -408,33 +_,150 @@
|
||||
@@ -409,31 +_,146 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -323,14 +323,12 @@
|
||||
+ final ResourceKey<Level> dimensionKey = loading.info().dimensionKey();
|
||||
+ final SavedDataStorage savedDataStorage = new SavedDataStorage(this.storageSource.getDimensionPath(dimensionKey).resolve(LevelResource.DATA.id()), this.getFixerUpper(), this.registryAccess());
|
||||
+ savedDataStorage.set(WorldGenSettings.TYPE, new WorldGenSettings(worldDataAndGenSettings.genSettings().options(), worldDataAndGenSettings.genSettings().dimensions()));
|
||||
long seed = worldOptions.seed();
|
||||
long biomeZoomSeed = BiomeManager.obfuscateSeed(seed);
|
||||
List<CustomSpawner> overworldCustomSpawners = ImmutableList.of(
|
||||
- new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(this.savedDataStorage)
|
||||
- );
|
||||
- LevelStem overworldData = dimensions.getValue(LevelStem.OVERWORLD);
|
||||
- ServerLevel overworld = new ServerLevel(
|
||||
- this, this.executor, this.storageSource, levelData, Level.OVERWORLD, overworldData, isDebug, biomeZoomSeed, overworldCustomSpawners, true
|
||||
- this, this.executor, this.storageSource, levelData, Level.OVERWORLD, overworldData, isDebug, overworldCustomSpawners, true
|
||||
- );
|
||||
- this.levels.put(Level.OVERWORLD, overworld);
|
||||
+ new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(savedDataStorage) // Paper - save to world data
|
||||
@@ -361,7 +359,6 @@
|
||||
+ dimensionKey,
|
||||
+ levelStem,
|
||||
+ worldDataAndGenSettings.data().isDebugWorld(),
|
||||
+ biomeZoomSeed,
|
||||
+ overworldCustomSpawners,
|
||||
+ true,
|
||||
+ loading.info().stemKey(),
|
||||
@@ -392,7 +389,6 @@
|
||||
+ dimensionKey,
|
||||
+ levelStem,
|
||||
+ this.worldData.isDebugWorld(),
|
||||
+ biomeZoomSeed,
|
||||
+ spawners,
|
||||
+ true,
|
||||
+ loading.info().stemKey(),
|
||||
@@ -439,7 +435,7 @@
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "Exception initializing level");
|
||||
@@ -451,25 +_,7 @@
|
||||
@@ -450,25 +_,7 @@
|
||||
}
|
||||
|
||||
GlobalPos focusPos = this.selectLevelLoadFocusPos();
|
||||
@@ -452,7 +448,7 @@
|
||||
- ResourceKey<Level> dimension = ResourceKey.create(Registries.DIMENSION, name.identifier());
|
||||
- DerivedLevelData derivedLevelData = new DerivedLevelData(this.worldData, levelData);
|
||||
- level = new ServerLevel(
|
||||
- this, this.executor, this.storageSource, derivedLevelData, dimension, entry.getValue(), isDebug, biomeZoomSeed, ImmutableList.of(), false
|
||||
- this, this.executor, this.storageSource, derivedLevelData, dimension, entry.getValue(), isDebug, ImmutableList.of(), false
|
||||
- );
|
||||
- this.levels.put(dimension, level);
|
||||
- } else {
|
||||
@@ -466,7 +462,7 @@
|
||||
}
|
||||
|
||||
private static void setInitialSpawn(
|
||||
@@ -485,6 +_,28 @@
|
||||
@@ -484,6 +_,28 @@
|
||||
levelData.setSpawn(LevelData.RespawnData.of(level.dimension(), BlockPos.ZERO.above(80), 0.0F, 0.0F));
|
||||
} else {
|
||||
ServerChunkCache chunkSource = level.getChunkSource();
|
||||
@@ -495,7 +491,7 @@
|
||||
ChunkPos spawnChunk = chunkSource.getGenerator().getOrigin(chunkSource.randomState());
|
||||
levelLoadListener.start(LevelLoadListener.Stage.PREPARE_GLOBAL_SPAWN, 0);
|
||||
levelLoadListener.updateFocus(level.dimension(), spawnChunk);
|
||||
@@ -530,19 +_,22 @@
|
||||
@@ -529,19 +_,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,7 +518,7 @@
|
||||
chunkLoadCounter.track(level, () -> {
|
||||
TicketStorage savedTickets = level.getDataStorage().get(TicketStorage.TYPE);
|
||||
if (savedTickets != null) {
|
||||
@@ -551,17 +_,19 @@
|
||||
@@ -550,17 +_,19 @@
|
||||
});
|
||||
}
|
||||
|
||||
@@ -548,7 +544,7 @@
|
||||
}
|
||||
|
||||
protected GlobalPos selectLevelLoadFocusPos() {
|
||||
@@ -623,19 +_,49 @@
|
||||
@@ -622,19 +_,49 @@
|
||||
this.stopServer();
|
||||
}
|
||||
|
||||
@@ -599,7 +595,7 @@
|
||||
}
|
||||
|
||||
LOGGER.info("Saving worlds");
|
||||
@@ -678,6 +_,20 @@
|
||||
@@ -677,6 +_,20 @@
|
||||
} catch (IOException e) {
|
||||
LOGGER.error("Failed to unlock level {}", this.storageSource.getLevelId(), e);
|
||||
}
|
||||
@@ -620,7 +616,7 @@
|
||||
}
|
||||
|
||||
public String getLocalIp() {
|
||||
@@ -693,6 +_,14 @@
|
||||
@@ -692,6 +_,14 @@
|
||||
}
|
||||
|
||||
public void halt(final boolean wait) {
|
||||
@@ -635,7 +631,7 @@
|
||||
this.running = false;
|
||||
if (wait) {
|
||||
try {
|
||||
@@ -703,6 +_,122 @@
|
||||
@@ -702,6 +_,122 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,7 +754,7 @@
|
||||
protected void runServer() {
|
||||
try {
|
||||
if (!this.initServer()) {
|
||||
@@ -710,30 +_,73 @@
|
||||
@@ -709,30 +_,73 @@
|
||||
}
|
||||
|
||||
this.nextTickTimeNanos = Util.getNanos();
|
||||
@@ -846,7 +842,7 @@
|
||||
|
||||
boolean sprinting = thisTickNanos == 0L;
|
||||
if (this.debugCommandProfilerDelayStart) {
|
||||
@@ -741,7 +_,7 @@
|
||||
@@ -740,7 +_,7 @@
|
||||
this.debugCommandProfiler = new MinecraftServer.TimeProfiler(Util.getNanos(), this.tickCount);
|
||||
}
|
||||
|
||||
@@ -855,7 +851,7 @@
|
||||
|
||||
try (Profiler.Scope ignored = Profiler.use(this.createProfiler())) {
|
||||
this.processPacketsAndTick(sprinting);
|
||||
@@ -750,7 +_,7 @@
|
||||
@@ -749,7 +_,7 @@
|
||||
this.mayHaveDelayedTasks = true;
|
||||
this.delayedTasksMaxNextTickTimeNanos = Math.max(Util.getNanos() + thisTickNanos, this.nextTickTimeNanos);
|
||||
this.startMeasuringTaskExecutionTime();
|
||||
@@ -864,7 +860,7 @@
|
||||
this.finishMeasuringTaskExecutionTime();
|
||||
if (sprinting) {
|
||||
this.tickRateManager.endTickWork();
|
||||
@@ -784,7 +_,7 @@
|
||||
@@ -783,7 +_,7 @@
|
||||
} catch (Throwable t) {
|
||||
LOGGER.error("Exception stopping the server", t);
|
||||
} finally {
|
||||
@@ -873,7 +869,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -836,7 +_,14 @@
|
||||
@@ -835,7 +_,14 @@
|
||||
}
|
||||
|
||||
private boolean haveTime() {
|
||||
@@ -889,7 +885,7 @@
|
||||
}
|
||||
|
||||
public NotificationManager notificationManager() {
|
||||
@@ -844,11 +_,11 @@
|
||||
@@ -843,11 +_,11 @@
|
||||
}
|
||||
|
||||
protected void waitUntilNextTick() {
|
||||
@@ -903,7 +899,7 @@
|
||||
} finally {
|
||||
this.waitingForNextTick = false;
|
||||
}
|
||||
@@ -866,18 +_,38 @@
|
||||
@@ -865,18 +_,38 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -946,7 +942,7 @@
|
||||
this.mayHaveDelayedTasks = mayHaveMoreTasks;
|
||||
return mayHaveMoreTasks;
|
||||
}
|
||||
@@ -887,15 +_,16 @@
|
||||
@@ -886,15 +_,16 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -965,7 +961,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -947,26 +_,44 @@
|
||||
@@ -946,26 +_,44 @@
|
||||
}
|
||||
|
||||
protected void tickServer(final BooleanSupplier haveTime) {
|
||||
@@ -1011,7 +1007,7 @@
|
||||
this.tickCount++;
|
||||
this.tickRateManager.tick();
|
||||
this.tickChildren(haveTime);
|
||||
@@ -976,11 +_,18 @@
|
||||
@@ -975,11 +_,18 @@
|
||||
}
|
||||
|
||||
this.ticksUntilAutosave--;
|
||||
@@ -1031,7 +1027,7 @@
|
||||
profiler.push("tallying");
|
||||
long tickTime = Util.getNanos() - nano;
|
||||
int tickIndex = this.tickCount % 100;
|
||||
@@ -996,16 +_,16 @@
|
||||
@@ -995,16 +_,16 @@
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("tick");
|
||||
this.tickFrame.start();
|
||||
@@ -1052,7 +1048,7 @@
|
||||
LOGGER.debug("Autosave started");
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("save");
|
||||
@@ -1047,7 +_,7 @@
|
||||
@@ -1046,7 +_,7 @@
|
||||
private ServerStatus buildServerStatus() {
|
||||
ServerStatus.Players players = this.buildPlayerStatus();
|
||||
return new ServerStatus(
|
||||
@@ -1184,14 +1180,14 @@
|
||||
+ // CraftBukkit start
|
||||
+ public void addLevel(ServerLevel level) {
|
||||
+ Map<ResourceKey<Level>, ServerLevel> oldLevels = this.levels;
|
||||
+ Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
|
||||
+ Map<ResourceKey<Level>, ServerLevel> newLevels = new LinkedHashMap<>(oldLevels);
|
||||
+ newLevels.put(level.dimension(), level);
|
||||
+ this.levels = Collections.unmodifiableMap(newLevels);
|
||||
+ }
|
||||
+
|
||||
+ public void removeLevel(ServerLevel level) {
|
||||
+ Map<ResourceKey<Level>, ServerLevel> oldLevels = this.levels;
|
||||
+ Map<ResourceKey<Level>, ServerLevel> newLevels = Maps.newLinkedHashMap(oldLevels);
|
||||
+ Map<ResourceKey<Level>, ServerLevel> newLevels = new LinkedHashMap<>(oldLevels);
|
||||
+ newLevels.remove(level.dimension());
|
||||
+ this.levels = Collections.unmodifiableMap(newLevels);
|
||||
+ }
|
||||
@@ -1209,7 +1205,7 @@
|
||||
}
|
||||
|
||||
public ServerClockManager clockManager() {
|
||||
@@ -1243,7 +_,12 @@
|
||||
@@ -1251,7 +_,12 @@
|
||||
|
||||
@Override
|
||||
public void sendSystemMessage(final Component message) {
|
||||
@@ -1223,7 +1219,7 @@
|
||||
}
|
||||
|
||||
public KeyPair getKeyPair() {
|
||||
@@ -1280,11 +_,17 @@
|
||||
@@ -1288,11 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1246,7 +1242,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1300,6 +_,11 @@
|
||||
@@ -1308,6 +_,11 @@
|
||||
|
||||
public void setDifficultyLocked(final boolean locked) {
|
||||
this.worldData.setDifficultyLocked(locked);
|
||||
@@ -1258,7 +1254,7 @@
|
||||
this.getPlayerList().getPlayers().forEach(this::sendDifficultyUpdate);
|
||||
}
|
||||
|
||||
@@ -1360,10 +_,20 @@
|
||||
@@ -1368,10 +_,20 @@
|
||||
|
||||
@Override
|
||||
public String getMotd() {
|
||||
@@ -1280,7 +1276,7 @@
|
||||
this.motd = motd;
|
||||
}
|
||||
|
||||
@@ -1393,16 +_,20 @@
|
||||
@@ -1401,16 +_,20 @@
|
||||
int count = 0;
|
||||
|
||||
for (ServerPlayer player : this.getPlayerList().getPlayers()) {
|
||||
@@ -1304,7 +1300,7 @@
|
||||
}
|
||||
|
||||
public boolean isReady() {
|
||||
@@ -1469,7 +_,7 @@
|
||||
@@ -1481,7 +_,7 @@
|
||||
@Override
|
||||
public void executeIfPossible(final Runnable command) {
|
||||
if (this.isStopped()) {
|
||||
@@ -1313,7 +1309,7 @@
|
||||
}
|
||||
|
||||
super.executeIfPossible(command);
|
||||
@@ -1504,7 +_,16 @@
|
||||
@@ -1520,7 +_,16 @@
|
||||
return this.functionManager;
|
||||
}
|
||||
|
||||
@@ -1330,7 +1326,7 @@
|
||||
CompletableFuture<Void> result = CompletableFuture.<ImmutableList>supplyAsync(
|
||||
() -> packsToEnable.stream()
|
||||
.map(this.packRepository::getPack)
|
||||
@@ -1516,7 +_,7 @@
|
||||
@@ -1532,7 +_,7 @@
|
||||
.thenCompose(
|
||||
packsToLoad -> {
|
||||
CloseableResourceManager resources = new MultiPackResourceManager(PackType.SERVER_DATA, packsToLoad);
|
||||
@@ -1339,7 +1335,7 @@
|
||||
return ReloadableServerResources.loadResources(
|
||||
resources,
|
||||
this.registries,
|
||||
@@ -1536,17 +_,35 @@
|
||||
@@ -1552,17 +_,35 @@
|
||||
}
|
||||
)
|
||||
.thenAcceptAsync(newResources -> {
|
||||
@@ -1377,7 +1373,7 @@
|
||||
}, this);
|
||||
if (this.isSameThread()) {
|
||||
this.managedBlock(result::isDone);
|
||||
@@ -1561,7 +_,7 @@
|
||||
@@ -1577,7 +_,7 @@
|
||||
DataPackConfig dataPackConfig = initialDataConfig.dataPacks();
|
||||
FeatureFlagSet forcedFeatures = initMode ? FeatureFlagSet.of() : initialDataConfig.enabledFeatures();
|
||||
FeatureFlagSet allowedFeatures = initMode ? FeatureFlags.REGISTRY.allFlags() : initialDataConfig.enabledFeatures();
|
||||
@@ -1386,7 +1382,7 @@
|
||||
if (safeMode) {
|
||||
return configureRepositoryWithSelection(packRepository, List.of("vanilla"), forcedFeatures, false);
|
||||
}
|
||||
@@ -1616,7 +_,7 @@
|
||||
@@ -1632,7 +_,7 @@
|
||||
private static WorldDataConfiguration configureRepositoryWithSelection(
|
||||
final PackRepository packRepository, final Collection<String> selected, final FeatureFlagSet forcedFeatures, final boolean disableInactive
|
||||
) {
|
||||
@@ -1395,7 +1391,7 @@
|
||||
enableForcedFeaturePacks(packRepository, forcedFeatures);
|
||||
DataPackConfig packConfig = getSelectedPacks(packRepository, disableInactive);
|
||||
FeatureFlagSet packRequestedFeatures = packRepository.getRequestedFeatureFlags().join(forcedFeatures);
|
||||
@@ -1648,7 +_,7 @@
|
||||
@@ -1664,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1404,10 +1400,10 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1665,8 +_,8 @@
|
||||
@@ -1681,8 +_,8 @@
|
||||
UserWhiteList whiteList = playerList.getWhiteList();
|
||||
|
||||
for (ServerPlayer player : Lists.newArrayList(playerList.getPlayers())) {
|
||||
for (ServerPlayer player : List.copyOf(playerList.getPlayers())) {
|
||||
- if (!whiteList.isWhiteListed(player.nameAndId())) {
|
||||
- player.connection.disconnect(Component.translatable("multiplayer.disconnect.not_whitelisted"));
|
||||
+ if (!whiteList.isWhiteListed(player.nameAndId()) && !this.getPlayerList().isOp(player.nameAndId())) { // Paper - Fix kicking ops when whitelist is reloaded (MC-171420)
|
||||
@@ -1415,7 +1411,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1688,12 +_,12 @@
|
||||
@@ -1704,12 +_,12 @@
|
||||
}
|
||||
|
||||
public ServerLevel findRespawnDimension() {
|
||||
@@ -1430,7 +1426,7 @@
|
||||
public void setRespawnData(final LevelData.RespawnData respawnData) {
|
||||
ServerLevelData levelData = this.worldData.overworldData();
|
||||
LevelData.RespawnData oldRespawnData = levelData.getRespawnData();
|
||||
@@ -1761,17 +_,20 @@
|
||||
@@ -1777,17 +_,20 @@
|
||||
return this.randomSequences;
|
||||
}
|
||||
|
||||
@@ -1456,16 +1452,16 @@
|
||||
}
|
||||
|
||||
public boolean isEnforceWhitelist() {
|
||||
@@ -1854,7 +_,7 @@
|
||||
@@ -1870,7 +_,7 @@
|
||||
private void dumpGameRules(final Path path) throws IOException {
|
||||
try (Writer output = Files.newBufferedWriter(path)) {
|
||||
final List<String> entries = Lists.newArrayList();
|
||||
final List<String> entries = new ArrayList<>();
|
||||
- final GameRules gameRules = this.getGameRules();
|
||||
+ final GameRules gameRules = this.overworld().getGameRules(); // Paper - per-level GameRules
|
||||
gameRules.visitGameRuleTypes(new GameRuleTypeVisitor() {
|
||||
@Override
|
||||
public <T> void visit(final GameRule<T> gameRule) {
|
||||
@@ -1911,6 +_,17 @@
|
||||
@@ -1927,6 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1483,7 +1479,7 @@
|
||||
private ProfilerFiller createProfiler() {
|
||||
if (this.willStartRecordingMetrics) {
|
||||
this.metricsRecorder = ActiveMetricsRecorder.createStarted(
|
||||
@@ -2038,16 +_,22 @@
|
||||
@@ -2054,16 +_,22 @@
|
||||
}
|
||||
|
||||
public void logChatMessage(final Component message, final ChatType.Bound chatType, final @Nullable String tag) {
|
||||
@@ -1510,7 +1506,7 @@
|
||||
}
|
||||
|
||||
public boolean logIPs() {
|
||||
@@ -2058,8 +_,9 @@
|
||||
@@ -2074,8 +_,9 @@
|
||||
LOGGER.debug("Received custom click action {} with payload {}", id, payload.orElse(null));
|
||||
}
|
||||
|
||||
@@ -1521,7 +1517,7 @@
|
||||
}
|
||||
|
||||
public boolean setAutoSave(final boolean enable) {
|
||||
@@ -2085,12 +_,14 @@
|
||||
@@ -2101,12 +_,14 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1539,7 +1535,7 @@
|
||||
player.connection.send(new ClientboundEntityEventPacket(player, event));
|
||||
}
|
||||
} else if (rule == GameRules.LIMITED_CRAFTING || rule == GameRules.IMMEDIATE_RESPAWN) {
|
||||
@@ -2098,20 +_,21 @@
|
||||
@@ -2114,20 +_,21 @@
|
||||
? ClientboundGameEventPacket.LIMITED_CRAFTING
|
||||
: ClientboundGameEventPacket.IMMEDIATE_RESPAWN;
|
||||
ClientboundGameEventPacket packet = new ClientboundGameEventPacket(eventType, (Boolean)value ? 1.0F : 0.0F);
|
||||
@@ -1566,7 +1562,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2124,12 +_,14 @@
|
||||
@@ -2140,12 +_,14 @@
|
||||
return this.savedDataStorage;
|
||||
}
|
||||
|
||||
@@ -1583,7 +1579,7 @@
|
||||
}
|
||||
|
||||
public boolean acceptsTransfers() {
|
||||
@@ -2288,4 +_,53 @@
|
||||
@@ -2309,4 +_,53 @@
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/bossevents/CustomBossEvent.java
|
||||
+++ b/net/minecraft/server/bossevents/CustomBossEvent.java
|
||||
@@ -24,6 +_,16 @@
|
||||
@@ -23,6 +_,16 @@
|
||||
private int value;
|
||||
private int max = 100;
|
||||
private final Runnable dirtyCallback;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/commands/PlaceCommand.java
|
||||
+++ b/net/minecraft/server/commands/PlaceCommand.java
|
||||
@@ -313,6 +_,7 @@
|
||||
@@ -312,6 +_,7 @@
|
||||
throw ERROR_STRUCTURE_FAILED.create();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
private static Collection<String> discoverNewPacks(final PackRepository packRepository, final WorldData worldData, final Collection<String> currentPacks) {
|
||||
- packRepository.reload();
|
||||
+ packRepository.reload(true); // Paper - will perform a full reload
|
||||
Collection<String> selected = Lists.newArrayList(currentPacks);
|
||||
Collection<String> selected = new ArrayList<>(currentPacks);
|
||||
Collection<String> disabled = worldData.getDataConfiguration().dataPacks().getDisabled();
|
||||
|
||||
@@ -36,6 +_,16 @@
|
||||
|
||||
+20
-20
@@ -1,10 +1,10 @@
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -76,9 +_,9 @@
|
||||
@@ -79,9 +_,9 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final int CONVERSION_RETRY_DELAY_MS = 5000;
|
||||
private static final int CONVERSION_RETRIES = 2;
|
||||
- private final List<ConsoleInput> consoleInput = Collections.synchronizedList(Lists.newArrayList());
|
||||
- private final List<ConsoleInput> consoleInput = Collections.synchronizedList(new ArrayList<>());
|
||||
+ private final java.util.Queue<ConsoleInput> serverCommandQueue = new java.util.concurrent.ConcurrentLinkedQueue<>(); // Paper - Perf: use a proper queue
|
||||
private @Nullable QueryThreadGs4 queryThreadGs4;
|
||||
- private final RconConsoleSource rconConsoleSource;
|
||||
@@ -12,7 +12,7 @@
|
||||
private @Nullable RconThread rconThread;
|
||||
public DedicatedServerSettings settings;
|
||||
private @Nullable MinecraftServerGui gui;
|
||||
@@ -90,6 +_,7 @@
|
||||
@@ -93,6 +_,7 @@
|
||||
private final @Nullable ManagementServer jsonRpcServer;
|
||||
|
||||
public DedicatedServer(
|
||||
@@ -20,7 +20,7 @@
|
||||
final Thread serverThread,
|
||||
final LevelStorageSource.LevelStorageAccess levelStorageSource,
|
||||
final PackRepository packRepository,
|
||||
@@ -102,6 +_,7 @@
|
||||
@@ -105,6 +_,7 @@
|
||||
final NotificationManager notificationManager
|
||||
) {
|
||||
super(
|
||||
@@ -28,7 +28,7 @@
|
||||
serverThread,
|
||||
levelStorageSource,
|
||||
packRepository,
|
||||
@@ -115,7 +_,8 @@
|
||||
@@ -118,7 +_,8 @@
|
||||
notificationManager
|
||||
);
|
||||
this.settings = settings;
|
||||
@@ -38,7 +38,7 @@
|
||||
this.serverTextFilter = ServerTextFilter.createFromConfig(settings.getProperties());
|
||||
this.jsonRpcServer = jsonRpcServer;
|
||||
this.serverLinks = createServerLinks(settings);
|
||||
@@ -167,6 +_,10 @@
|
||||
@@ -170,6 +_,10 @@
|
||||
Thread consoleThread = new Thread("Server console handler") {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -49,7 +49,7 @@
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));
|
||||
|
||||
String line;
|
||||
@@ -177,16 +_,41 @@
|
||||
@@ -180,16 +_,41 @@
|
||||
} catch (IOException e) {
|
||||
DedicatedServer.LOGGER.error("Exception handling console input", e);
|
||||
}
|
||||
@@ -92,7 +92,7 @@
|
||||
LOGGER.info("Loading properties");
|
||||
DedicatedServerProperties properties = this.settings.getProperties();
|
||||
if (this.isSingleplayer()) {
|
||||
@@ -197,8 +_,45 @@
|
||||
@@ -200,8 +_,45 @@
|
||||
this.setLocalIp(properties.serverIp);
|
||||
}
|
||||
|
||||
@@ -139,7 +139,7 @@
|
||||
InetAddress localAddress = null;
|
||||
if (!this.getLocalIp().isEmpty()) {
|
||||
localAddress = InetAddress.getByName(this.getLocalIp());
|
||||
@@ -207,47 +_,73 @@
|
||||
@@ -210,47 +_,73 @@
|
||||
if (this.getPort() < 0) {
|
||||
this.setPort(properties.serverPort);
|
||||
}
|
||||
@@ -221,7 +221,7 @@
|
||||
}
|
||||
|
||||
if (properties.enableQuery) {
|
||||
@@ -260,7 +_,7 @@
|
||||
@@ -263,7 +_,7 @@
|
||||
this.rconThread = RconThread.create(this);
|
||||
}
|
||||
|
||||
@@ -230,7 +230,7 @@
|
||||
Thread watchdog = new Thread(new ServerWatchdog(this), "Server Watchdog");
|
||||
watchdog.setUncaughtExceptionHandler(new DefaultUncaughtExceptionHandlerWithName(LOGGER));
|
||||
watchdog.setDaemon(true);
|
||||
@@ -277,6 +_,12 @@
|
||||
@@ -280,6 +_,12 @@
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@
|
||||
@Override
|
||||
public boolean isEnforceWhitelist() {
|
||||
return this.settings.getProperties().enforceWhitelist.get();
|
||||
@@ -294,6 +_,7 @@
|
||||
@@ -297,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void setUsingWhitelist(final boolean usingWhitelist) {
|
||||
@@ -251,7 +251,7 @@
|
||||
this.settings.update(p -> p.whiteList.update(this.registryAccess(), usingWhitelist));
|
||||
}
|
||||
|
||||
@@ -345,7 +_,7 @@
|
||||
@@ -348,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
protected void forceDifficulty() {
|
||||
@@ -260,7 +260,7 @@
|
||||
}
|
||||
|
||||
public int viewDistance() {
|
||||
@@ -403,11 +_,11 @@
|
||||
@@ -406,11 +_,11 @@
|
||||
}
|
||||
|
||||
if (this.rconThread != null) {
|
||||
@@ -274,7 +274,7 @@
|
||||
}
|
||||
|
||||
if (this.jsonRpcServer != null) {
|
||||
@@ -417,6 +_,9 @@
|
||||
@@ -420,6 +_,9 @@
|
||||
LOGGER.error("Interrupted while stopping the management server", e);
|
||||
}
|
||||
}
|
||||
@@ -284,7 +284,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -426,12 +_,20 @@
|
||||
@@ -429,12 +_,20 @@
|
||||
}
|
||||
|
||||
public void handleConsoleInput(final String msg, final CommandSourceStack source) {
|
||||
@@ -308,7 +308,7 @@
|
||||
this.getCommands().performPrefixedCommand(input.source, input.msg);
|
||||
}
|
||||
}
|
||||
@@ -592,12 +_,15 @@
|
||||
@@ -600,12 +_,15 @@
|
||||
|
||||
@Override
|
||||
public String getMotd() {
|
||||
@@ -326,7 +326,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -623,7 +_,11 @@
|
||||
@@ -631,7 +_,11 @@
|
||||
@Override
|
||||
public boolean enforceSecureProfile() {
|
||||
DedicatedServerProperties properties = this.getProperties();
|
||||
@@ -339,7 +339,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -708,21 +_,60 @@
|
||||
@@ -721,21 +_,60 @@
|
||||
|
||||
@Override
|
||||
public String getPluginNames() {
|
||||
@@ -405,7 +405,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -852,4 +_,15 @@
|
||||
@@ -871,4 +_,15 @@
|
||||
public Map<String, String> getCodeOfConducts() {
|
||||
return this.codeOfConductTexts;
|
||||
}
|
||||
|
||||
+6
-5
@@ -1,28 +1,29 @@
|
||||
--- a/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
+++ b/net/minecraft/server/dedicated/DedicatedServerProperties.java
|
||||
@@ -50,6 +_,7 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private static final Pattern SHA1 = Pattern.compile("^[a-fA-F0-9]{40}$");
|
||||
private static final Splitter COMMA_SPLITTER = Splitter.on(',').trimResults();
|
||||
private static final Splitter COMMA_SPLITTER_NO_EMPTY = COMMA_SPLITTER.omitEmptyStrings();
|
||||
+ public final boolean debug = this.get("debug", false); // CraftBukkit
|
||||
public static final String MANAGEMENT_SERVER_TLS_ENABLED_KEY = "management-server-tls-enabled";
|
||||
public static final String MANAGEMENT_SERVER_TLS_KEYSTORE_KEY = "management-server-tls-keystore";
|
||||
public static final String MANAGEMENT_SERVER_TLS_KEYSTORE_PASSWORD_KEY = "management-server-tls-keystore-password";
|
||||
@@ -108,7 +_,7 @@
|
||||
@@ -109,7 +_,7 @@
|
||||
public final boolean broadcastRconToOps = this.get("broadcast-rcon-to-ops", true);
|
||||
public final boolean broadcastConsoleToOps = this.get("broadcast-console-to-ops", true);
|
||||
public final int maxWorldSize = this.get("max-world-size", v -> Mth.clamp(v, 1, 29999984), 29999984);
|
||||
public final int maxWorldSize = this.get("max-world-size", v -> Math.clamp(v.intValue(), 1, 29999984), 29999984);
|
||||
- public final boolean syncChunkWrites = this.get("sync-chunk-writes", true);
|
||||
+ public final boolean syncChunkWrites = this.get("sync-chunk-writes", true) && Boolean.getBoolean("Paper.enable-sync-chunk-writes"); // Paper - Hide sync chunk writes behind flag
|
||||
public final String regionFileComression = this.get("region-file-compression", "deflate");
|
||||
public final boolean enableJmxMonitoring = this.get("enable-jmx-monitoring", false);
|
||||
public final Settings<DedicatedServerProperties>.MutableValue<Boolean> enableStatus = this.getMutable("enable-status", true);
|
||||
@@ -125,13 +_,16 @@
|
||||
@@ -127,14 +_,17 @@
|
||||
public final Settings<DedicatedServerProperties>.MutableValue<Boolean> whiteList = this.getMutable("white-list", true);
|
||||
public final boolean enforceSecureProfile = this.get("enforce-secure-profile", true);
|
||||
public final boolean logIPs = this.get("log-ips", true);
|
||||
- public final Settings<DedicatedServerProperties>.MutableValue<Integer> pauseWhenEmptySeconds = this.getMutable("pause-when-empty-seconds", 60);
|
||||
+ public final Settings<DedicatedServerProperties>.MutableValue<Integer> pauseWhenEmptySeconds = this.getMutable("pause-when-empty-seconds", -1); // Paper - disable tick sleeping by default
|
||||
public final String allowedConnectionIds = this.get("allowed-connection-ids", "");
|
||||
private final DedicatedServerProperties.WorldDimensionData worldDimensionData;
|
||||
public final WorldOptions worldOptions;
|
||||
public final Settings<DedicatedServerProperties>.MutableValue<Boolean> acceptsTransfers = this.getMutable("accepts-transfers", false);
|
||||
@@ -37,7 +38,7 @@
|
||||
String levelSeed = this.get("level-seed", "");
|
||||
boolean generateStructures = this.get("generate-structures", true);
|
||||
long seed = WorldOptions.parseSeed(levelSeed).orElse(WorldOptions.randomSeed());
|
||||
@@ -152,15 +_,23 @@
|
||||
@@ -155,15 +_,23 @@
|
||||
this.get("initial-enabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getEnabled())),
|
||||
this.get("initial-disabled-packs", String.join(",", WorldDataConfiguration.DEFAULT.dataPacks().getDisabled()))
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -151,6 +_,33 @@
|
||||
@@ -149,6 +_,33 @@
|
||||
public int serverViewDistance;
|
||||
private final WorldGenContext worldGenContext;
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
public ChunkMap(
|
||||
final ServerLevel level,
|
||||
final LevelStorageSource.LevelStorageAccess levelStorage,
|
||||
@@ -176,7 +_,13 @@
|
||||
@@ -174,13 +_,19 @@
|
||||
this.level = level;
|
||||
RegistryAccess registryAccess = level.registryAccess();
|
||||
long levelSeed = level.getSeed();
|
||||
@@ -48,9 +48,7 @@
|
||||
+ // CraftBukkit end
|
||||
this.randomState = RandomState.create(registryAccess.lookupOrThrow(Registries.NOISE), levelSeed, noiseGenerator.generatorSettings().value());
|
||||
} else {
|
||||
this.randomState = RandomState.create(
|
||||
@@ -184,7 +_,7 @@
|
||||
);
|
||||
this.randomState = RandomState.create(registryAccess.lookupOrThrow(Registries.NOISE), levelSeed, false, 63, NoiseRouterData.none());
|
||||
}
|
||||
|
||||
- this.chunkGeneratorState = generator.createState(registryAccess.lookupOrThrow(Registries.STRUCTURE_SET), this.randomState, levelSeed);
|
||||
@@ -58,7 +56,7 @@
|
||||
this.mainThreadExecutor = mainThreadExecutor;
|
||||
ConsecutiveExecutor worldgen = new ConsecutiveExecutor(executor, "worldgen");
|
||||
this.chunkStatusListener = chunkStatusListener;
|
||||
@@ -211,6 +_,12 @@
|
||||
@@ -206,6 +_,12 @@
|
||||
this.chunksToEagerlySave.add(chunkPos.pack());
|
||||
}
|
||||
|
||||
@@ -71,7 +69,7 @@
|
||||
protected ChunkGenerator generator() {
|
||||
return this.worldGenContext.generator();
|
||||
}
|
||||
@@ -347,9 +_,9 @@
|
||||
@@ -342,9 +_,9 @@
|
||||
}
|
||||
});
|
||||
sb.append("Updating:").append(System.lineSeparator());
|
||||
@@ -83,7 +81,7 @@
|
||||
CrashReport report = CrashReport.forThrowable(exception, "Chunk loading");
|
||||
CrashReportCategory category = report.addCategory("Chunk loading");
|
||||
category.setDetail("Details", details);
|
||||
@@ -385,6 +_,7 @@
|
||||
@@ -380,6 +_,7 @@
|
||||
chunk.setTicketLevel(level);
|
||||
} else {
|
||||
chunk = new ChunkHolder(ChunkPos.unpack(node), level, this.level, this.lightEngine, this::onLevelChange, this);
|
||||
@@ -91,7 +89,7 @@
|
||||
}
|
||||
|
||||
this.updatingChunkMap.put(node, chunk);
|
||||
@@ -412,8 +_,8 @@
|
||||
@@ -407,8 +_,8 @@
|
||||
|
||||
protected void saveAllChunks(final boolean flushStorage) {
|
||||
if (flushStorage) {
|
||||
@@ -102,7 +100,7 @@
|
||||
.stream()
|
||||
.filter(ChunkHolder::wasAccessibleSinceLastSave)
|
||||
.peek(ChunkHolder::refreshAccessibility)
|
||||
@@ -439,7 +_,7 @@
|
||||
@@ -434,7 +_,7 @@
|
||||
this.nextChunkSaveTime.clear();
|
||||
long now = Util.getMillis();
|
||||
|
||||
@@ -111,7 +109,7 @@
|
||||
this.saveChunkIfNeeded(chunk, now);
|
||||
}
|
||||
}
|
||||
@@ -460,6 +_,7 @@
|
||||
@@ -455,6 +_,7 @@
|
||||
public boolean hasWork() {
|
||||
return this.lightEngine.hasLightWork()
|
||||
|| !this.pendingUnloads.isEmpty()
|
||||
@@ -119,7 +117,7 @@
|
||||
|| !this.updatingChunkMap.isEmpty()
|
||||
|| this.poiManager.hasWork()
|
||||
|| !this.toDrop.isEmpty()
|
||||
@@ -518,7 +_,11 @@
|
||||
@@ -513,7 +_,11 @@
|
||||
this.scheduleUnload(pos, chunkHolder);
|
||||
} else {
|
||||
ChunkAccess chunk = chunkHolder.getLatestChunk();
|
||||
@@ -132,7 +130,7 @@
|
||||
if (chunk instanceof LevelChunk levelChunk) {
|
||||
levelChunk.setLoaded(false);
|
||||
}
|
||||
@@ -531,7 +_,9 @@
|
||||
@@ -526,7 +_,9 @@
|
||||
this.lightEngine.updateChunkStatus(chunk.getPos());
|
||||
this.lightEngine.tryScheduleUpdate();
|
||||
this.nextChunkSaveTime.remove(chunk.getPos().pack());
|
||||
@@ -143,7 +141,7 @@
|
||||
}
|
||||
}, this.unloadQueue::add).whenComplete((ignored, throwable) -> {
|
||||
if (throwable != null) {
|
||||
@@ -842,7 +_,7 @@
|
||||
@@ -835,7 +_,7 @@
|
||||
}
|
||||
|
||||
public int size() {
|
||||
@@ -152,7 +150,7 @@
|
||||
}
|
||||
|
||||
public net.minecraft.server.level.DistanceManager getDistanceManager() {
|
||||
@@ -869,10 +_,10 @@
|
||||
@@ -862,10 +_,10 @@
|
||||
.addColumn("fluid_ticks")
|
||||
.build(output);
|
||||
|
||||
@@ -167,7 +165,7 @@
|
||||
Optional<ChunkAccess> chunk = Optional.ofNullable(holder.getLatestChunk());
|
||||
Optional<LevelChunk> fullChunk = chunk.flatMap(
|
||||
chunkAccess -> chunkAccess instanceof LevelChunk levelChunk ? Optional.of(levelChunk) : Optional.empty()
|
||||
@@ -921,14 +_,15 @@
|
||||
@@ -914,14 +_,15 @@
|
||||
return this.upgradeChunkTag(
|
||||
tag,
|
||||
-1,
|
||||
@@ -186,7 +184,7 @@
|
||||
generatorIdentifier.ifPresent(identifier -> contextTag.putString("generator", identifier.toString()));
|
||||
return contextTag;
|
||||
}
|
||||
@@ -940,7 +_,7 @@
|
||||
@@ -933,7 +_,7 @@
|
||||
ChunkHolder holder = this.visibleChunkMap.get(spawnCandidateChunks.nextLong());
|
||||
if (holder != null) {
|
||||
LevelChunk chunk = holder.getTickingChunk();
|
||||
@@ -195,7 +193,7 @@
|
||||
output.add(chunk);
|
||||
}
|
||||
}
|
||||
@@ -960,8 +_,14 @@
|
||||
@@ -953,8 +_,14 @@
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughForSpawning(final ChunkPos pos) {
|
||||
@@ -211,7 +209,7 @@
|
||||
}
|
||||
|
||||
public boolean anyPlayerCloseEnoughTo(final BlockPos pos, final int maxDistance) {
|
||||
@@ -977,8 +_,24 @@
|
||||
@@ -970,8 +_,24 @@
|
||||
}
|
||||
|
||||
private boolean anyPlayerCloseEnoughForSpawningInternal(final ChunkPos pos) {
|
||||
@@ -237,7 +235,7 @@
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -995,7 +_,7 @@
|
||||
@@ -988,7 +_,7 @@
|
||||
Builder<ServerPlayer> builder = ImmutableList.builder();
|
||||
|
||||
for (ServerPlayer player : this.playerMap.getAllPlayers()) {
|
||||
@@ -246,7 +244,7 @@
|
||||
builder.add(player);
|
||||
}
|
||||
}
|
||||
@@ -1003,13 +_,13 @@
|
||||
@@ -996,13 +_,13 @@
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
@@ -262,7 +260,7 @@
|
||||
}
|
||||
|
||||
private boolean playerIsCloseEnoughTo(final ServerPlayer player, final Vec3 pos, final int maxDistance) {
|
||||
@@ -1141,9 +_,19 @@
|
||||
@@ -1134,9 +_,19 @@
|
||||
}
|
||||
|
||||
protected void addEntity(final Entity entity) {
|
||||
@@ -281,8 +279,8 @@
|
||||
+ range = org.spigotmc.TrackingRange.getEntityTrackingRange(entity, range); // Spigot
|
||||
if (range != 0) {
|
||||
if (this.entityMap.containsKey(entity.getId())) {
|
||||
throw (IllegalStateException)Util.pauseInIde(new IllegalStateException("Entity is already tracked!"));
|
||||
@@ -1167,6 +_,7 @@
|
||||
throw (IllegalStateException)DevUtil.pauseInIde(new IllegalStateException("Entity is already tracked!"));
|
||||
@@ -1160,6 +_,7 @@
|
||||
}
|
||||
|
||||
protected void removeEntity(final Entity entity) {
|
||||
@@ -290,7 +288,7 @@
|
||||
if (entity instanceof ServerPlayer player) {
|
||||
this.updatePlayerStatus(player, false);
|
||||
|
||||
@@ -1323,10 +_,10 @@
|
||||
@@ -1316,10 +_,10 @@
|
||||
private final Entity entity;
|
||||
private final int range;
|
||||
private SectionPos lastSectionPos;
|
||||
@@ -303,7 +301,7 @@
|
||||
this.entity = entity;
|
||||
this.range = range;
|
||||
this.lastSectionPos = SectionPos.of(entity);
|
||||
@@ -1373,6 +_,7 @@
|
||||
@@ -1366,6 +_,7 @@
|
||||
}
|
||||
|
||||
public void removePlayer(final ServerPlayer player) {
|
||||
@@ -311,7 +309,7 @@
|
||||
if (this.seenBy.remove(player.connection)) {
|
||||
this.serverEntity.removePairing(player);
|
||||
if (this.seenBy.isEmpty()) {
|
||||
@@ -1382,23 +_,47 @@
|
||||
@@ -1375,23 +_,47 @@
|
||||
}
|
||||
|
||||
public void updatePlayer(final ServerPlayer player) {
|
||||
@@ -362,7 +360,7 @@
|
||||
}
|
||||
} else {
|
||||
this.removePlayer(player);
|
||||
@@ -1415,6 +_,7 @@
|
||||
@@ -1408,6 +_,7 @@
|
||||
|
||||
for (Entity passenger : this.entity.getIndirectPassengers()) {
|
||||
int passengerRange = passenger.getType().clientTrackingRange() * 16;
|
||||
|
||||
+11
-11
@@ -1,19 +1,19 @@
|
||||
--- a/net/minecraft/server/level/DistanceManager.java
|
||||
+++ b/net/minecraft/server/level/DistanceManager.java
|
||||
@@ -72,6 +_,12 @@
|
||||
@@ -84,6 +_,12 @@
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!this.chunksToUpdateFutures.isEmpty()) {
|
||||
+ // CraftBukkit start - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
|
||||
+ for (final ChunkHolder chunksToUpdateFuture : this.chunksToUpdateFutures) {
|
||||
+ chunksToUpdateFuture.callEventIfUnloading(scheduler);
|
||||
+ }
|
||||
+ // CraftBukkit end - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
|
||||
+ // CraftBukkit start - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
|
||||
+ for (final ChunkHolder chunksToUpdateFuture : this.chunksToUpdateFutures) {
|
||||
+ chunksToUpdateFuture.callEventIfUnloading(scheduler);
|
||||
+ }
|
||||
+ // CraftBukkit end - SPIGOT-7780: Call chunk unload events before updateHighestAllowedStatus
|
||||
+
|
||||
for (ChunkHolder chunksToUpdateFuture : this.chunksToUpdateFutures) {
|
||||
chunksToUpdateFuture.updateHighestAllowedStatus(scheduler);
|
||||
}
|
||||
@@ -119,8 +_,10 @@
|
||||
for (ChunkHolder chunksToUpdateFuture : this.chunksToUpdateFutures) {
|
||||
chunksToUpdateFuture.updateHighestAllowedStatus(scheduler);
|
||||
}
|
||||
@@ -130,8 +_,10 @@
|
||||
ChunkPos chunk = pos.chunk();
|
||||
long chunkPos = chunk.pack();
|
||||
ObjectSet<ServerPlayer> chunkPlayers = this.playersPerChunk.get(chunkPos);
|
||||
|
||||
+13
-13
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -65,6 +_,7 @@
|
||||
@@ -66,6 +_,7 @@
|
||||
private final SavedDataStorage savedDataStorage;
|
||||
private final TicketStorage ticketStorage;
|
||||
public boolean spawnEnemies = true;
|
||||
@@ -8,7 +8,7 @@
|
||||
private static final int CACHE_SIZE = 4;
|
||||
private final long[] lastChunkPos = new long[4];
|
||||
private final @Nullable ChunkStatus[] lastChunkStatus = new ChunkStatus[4];
|
||||
@@ -73,6 +_,13 @@
|
||||
@@ -74,6 +_,13 @@
|
||||
private final Set<ChunkHolder> chunkHoldersToBroadcast = new ReferenceOpenHashSet<>();
|
||||
@VisibleForDebug
|
||||
private NaturalSpawner.@Nullable SpawnState lastSpawnState;
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
public ServerChunkCache(
|
||||
final ServerLevel level,
|
||||
@@ -85,6 +_,7 @@
|
||||
@@ -86,6 +_,7 @@
|
||||
final int simulationDistance,
|
||||
final boolean syncWrites,
|
||||
final ChunkStatusUpdateListener chunkStatusListener
|
||||
@@ -30,7 +30,7 @@
|
||||
) {
|
||||
this.level = level;
|
||||
this.mainThreadProcessor = new ServerChunkCache.MainThreadExecutor(level);
|
||||
@@ -97,7 +_,7 @@
|
||||
@@ -98,7 +_,7 @@
|
||||
LOGGER.error("Failed to create dimension data storage directory", e);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
this.ticketStorage = this.savedDataStorage.computeIfAbsent(TicketStorage.TYPE);
|
||||
this.chunkMap = new ChunkMap(
|
||||
level,
|
||||
@@ -119,6 +_,64 @@
|
||||
@@ -120,6 +_,64 @@
|
||||
this.clearCache();
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@
|
||||
@Override
|
||||
public ThreadedLevelLightEngine getLightEngine() {
|
||||
return this.lightEngine;
|
||||
@@ -153,7 +_,7 @@
|
||||
@@ -154,7 +_,7 @@
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (pos == this.lastChunkPos[i] && targetStatus == this.lastChunkStatus[i]) {
|
||||
ChunkAccess chunkAccess = this.lastChunk[i];
|
||||
@@ -113,7 +113,7 @@
|
||||
return chunkAccess;
|
||||
}
|
||||
}
|
||||
@@ -232,7 +_,15 @@
|
||||
@@ -233,7 +_,15 @@
|
||||
long key = pos.pack();
|
||||
int targetTicketLevel = ChunkLevel.byStatus(targetStatus);
|
||||
ChunkHolder chunkHolder = this.getVisibleChunkIfPresent(key);
|
||||
@@ -130,7 +130,7 @@
|
||||
this.addTicket(new Ticket(TicketType.UNKNOWN, targetTicketLevel), pos);
|
||||
if (this.chunkAbsent(chunkHolder, targetTicketLevel)) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
@@ -252,7 +_,7 @@
|
||||
@@ -253,7 +_,7 @@
|
||||
}
|
||||
|
||||
private boolean chunkAbsent(final @Nullable ChunkHolder chunkHolder, final int targetTicketLevel) {
|
||||
@@ -139,7 +139,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -306,17 +_,39 @@
|
||||
@@ -307,17 +_,39 @@
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
@@ -181,7 +181,7 @@
|
||||
this.ticketStorage.purgeStaleTickets(this.chunkMap);
|
||||
}
|
||||
|
||||
@@ -337,7 +_,7 @@
|
||||
@@ -338,7 +_,7 @@
|
||||
if (!this.level.isDebug()) {
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("pollingChunks");
|
||||
@@ -190,7 +190,7 @@
|
||||
profiler.push("tickingChunks");
|
||||
this.tickChunks(profiler);
|
||||
profiler.pop();
|
||||
@@ -367,12 +_,20 @@
|
||||
@@ -368,12 +_,20 @@
|
||||
int chunkCount = this.distanceManager.getNaturalSpawnChunkCount();
|
||||
NaturalSpawner.SpawnState spawnCookie = NaturalSpawner.createState(chunkCount, this.level, this::getFullChunk, new LocalMobCapCalculator(this.chunkMap));
|
||||
this.lastSpawnState = spawnCookie;
|
||||
@@ -215,7 +215,7 @@
|
||||
} else {
|
||||
spawningCategories = List.of();
|
||||
}
|
||||
@@ -557,7 +_,13 @@
|
||||
@@ -558,7 +_,13 @@
|
||||
|
||||
@Override
|
||||
public void setSpawnSettings(final boolean spawnEnemies) {
|
||||
@@ -229,7 +229,7 @@
|
||||
}
|
||||
|
||||
public String getChunkDebugData(final ChunkPos pos) {
|
||||
@@ -624,12 +_,18 @@
|
||||
@@ -625,12 +_,18 @@
|
||||
|
||||
@Override
|
||||
protected boolean pollTask() {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -72,10 +_,11 @@
|
||||
@@ -71,10 +_,11 @@
|
||||
private Vec3 lastSentMovement;
|
||||
private int tickCount;
|
||||
private int teleportDelay;
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
public ServerEntity(
|
||||
final ServerLevel level,
|
||||
@@ -83,7 +_,9 @@
|
||||
@@ -82,7 +_,9 @@
|
||||
final UpdateInterval updateInterval,
|
||||
final boolean trackDelta,
|
||||
final ServerEntity.Synchronizer synchronizer
|
||||
@@ -23,7 +23,7 @@
|
||||
this.level = level;
|
||||
this.synchronizer = synchronizer;
|
||||
this.entity = entity;
|
||||
@@ -104,16 +_,22 @@
|
||||
@@ -103,16 +_,22 @@
|
||||
List<Entity> passengers = this.entity.getPassengers();
|
||||
if (!passengers.equals(this.lastPassengers)) {
|
||||
this.synchronizer.sendToTrackingPlayers(new ClientboundSetPassengersPacket(this.entity));
|
||||
@@ -50,7 +50,7 @@
|
||||
data.tickCarriedBy(player, itemStack, frame);
|
||||
Packet<?> packet = data.getUpdatePacket(id, player);
|
||||
if (packet != null) {
|
||||
@@ -158,7 +_,13 @@
|
||||
@@ -157,7 +_,13 @@
|
||||
if (this.entity instanceof AbstractArrow) {
|
||||
packet = this.createMovePacket(position, yRotn, xRotn, true, true);
|
||||
} else {
|
||||
@@ -65,7 +65,7 @@
|
||||
boolean shouldSendPosition = positionChanged || this.tickCount % 60 == 0;
|
||||
packet = this.createMovePacket(position, yRotn, xRotn, shouldSendPosition, shouldSendRotation);
|
||||
}
|
||||
@@ -213,6 +_,25 @@
|
||||
@@ -212,6 +_,25 @@
|
||||
|
||||
this.tickCount++;
|
||||
if (this.entity.syncVelocity) {
|
||||
@@ -91,7 +91,7 @@
|
||||
this.entity.syncVelocity = false;
|
||||
this.synchronizer.sendToTrackingPlayersAndSelf(new ClientboundSetEntityMotionPacket(this.entity));
|
||||
}
|
||||
@@ -309,7 +_,10 @@
|
||||
@@ -308,7 +_,10 @@
|
||||
public void sendPairingData(final ServerPlayer player, final Consumer<Packet<ClientGamePacketListener>> broadcast) {
|
||||
this.entity.updateDataBeforeSync();
|
||||
if (this.entity.isRemoved()) {
|
||||
@@ -103,7 +103,7 @@
|
||||
}
|
||||
|
||||
Packet<ClientGamePacketListener> packet = this.entity.getAddEntityPacket(this);
|
||||
@@ -321,6 +_,11 @@
|
||||
@@ -320,6 +_,11 @@
|
||||
if (this.entity instanceof LivingEntity livingEntity) {
|
||||
Collection<AttributeInstance> attributes = livingEntity.getAttributes().getSyncableAttributes();
|
||||
if (!attributes.isEmpty()) {
|
||||
@@ -115,7 +115,7 @@
|
||||
broadcast.accept(new ClientboundUpdateAttributesPacket(this.entity.getId(), attributes));
|
||||
}
|
||||
}
|
||||
@@ -336,8 +_,9 @@
|
||||
@@ -335,8 +_,9 @@
|
||||
}
|
||||
|
||||
if (!slots.isEmpty()) {
|
||||
@@ -126,7 +126,7 @@
|
||||
}
|
||||
|
||||
if (!this.entity.getPassengers().isEmpty()) {
|
||||
@@ -384,6 +_,11 @@
|
||||
@@ -383,6 +_,11 @@
|
||||
if (this.entity instanceof LivingEntity livingEntity) {
|
||||
Set<AttributeInstance> attributes = livingEntity.getAttributes().getAttributesToSync();
|
||||
if (!attributes.isEmpty()) {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
--- a/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -196,7 +_,7 @@
|
||||
private final List<ServerPlayer> players = Lists.newArrayList();
|
||||
private final List<ServerPlayer> players = new ArrayList<>();
|
||||
private final ServerChunkCache chunkSource;
|
||||
private final MinecraftServer server;
|
||||
- public final ServerLevelData serverLevelData;
|
||||
@@ -9,7 +9,7 @@
|
||||
private final EntityTickList entityTickList = new EntityTickList();
|
||||
private final ServerWaypointManager waypointManager;
|
||||
private EnvironmentAttributeSystem environmentAttributes;
|
||||
@@ -224,24 +_,201 @@
|
||||
@@ -224,23 +_,200 @@
|
||||
private final boolean tickTime;
|
||||
private final LevelDebugSynchronizers debugSynchronizers = new LevelDebugSynchronizers(this);
|
||||
|
||||
@@ -151,7 +151,6 @@
|
||||
final ResourceKey<Level> dimension,
|
||||
final LevelStem levelStem,
|
||||
final boolean isDebug,
|
||||
final long biomeZoomSeed,
|
||||
final List<CustomSpawner> customSpawners,
|
||||
final boolean tickTime
|
||||
+ // Paper start - add parameters
|
||||
@@ -163,7 +162,7 @@
|
||||
+ io.papermc.paper.world.PaperWorldLoader.LoadedWorldData loadedWorldData
|
||||
+ // Paper end - add parameters
|
||||
) {
|
||||
- super(levelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates());
|
||||
- super(levelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, server.getMaxChainedNeighborUpdates());
|
||||
+ // CraftBukkit start
|
||||
+ final io.papermc.paper.world.saveddata.PaperLevelOverrides levelData = loadedWorldData.levelOverrides();
|
||||
+ savedDataStorage.set(io.papermc.paper.world.saveddata.PaperLevelOverrides.TYPE, levelData);
|
||||
@@ -171,7 +170,7 @@
|
||||
+ savedDataStorage.set(io.papermc.paper.world.saveddata.PaperWorldPDC.TYPE, loadedWorldData.pdc() == null ? io.papermc.paper.world.saveddata.PaperWorldPDC.TYPE.constructor().get() : loadedWorldData.pdc());
|
||||
+ final GameRules gameRules = new GameRules(server.getWorldData().enabledFeatures(), savedDataStorage.computeIfAbsent(net.minecraft.world.level.gamerules.GameRuleMap.TYPE));
|
||||
+ this.gameRules = gameRules;
|
||||
+ super(levelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, biomeZoomSeed, server.getMaxChainedNeighborUpdates(), loadedWorldData.bukkitName(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(server.storageSource.getDimensionPath(dimension), dimension.identifier(), spigotConfig, server.registryAccess(), gameRules))); // Paper - create paper world configs
|
||||
+ super(levelData, dimension, server.registryAccess(), levelStem.type(), false, isDebug, server.getMaxChainedNeighborUpdates(), loadedWorldData.bukkitName(), gen, biomeProvider, env, spigotConfig -> server.paperConfigurations.createWorldConfig(io.papermc.paper.configuration.PaperConfigurations.createWorldContextMap(server.storageSource.getDimensionPath(dimension), dimension.identifier(), spigotConfig, server.registryAccess(), gameRules))); // Paper - create paper world configs
|
||||
+ this.weatherData = savedDataStorage.computeIfAbsent(WeatherData.TYPE);
|
||||
+ this.weatherData.setLevel(this);
|
||||
+ this.typeKey = typeKey;
|
||||
@@ -213,7 +212,7 @@
|
||||
boolean syncWrites = server.forceSynchronousWrites();
|
||||
DataFixer fixerUpper = server.getFixerUpper();
|
||||
EntityPersistentStorage<Entity> entityStorage = new EntityStorage(
|
||||
@@ -263,15 +_,16 @@
|
||||
@@ -262,15 +_,16 @@
|
||||
server.getStructureTemplateManager(),
|
||||
executor,
|
||||
generator,
|
||||
@@ -233,7 +232,7 @@
|
||||
}
|
||||
|
||||
this.raids = this.getDataStorage().computeIfAbsent(Raids.TYPE);
|
||||
@@ -279,10 +_,10 @@
|
||||
@@ -278,10 +_,10 @@
|
||||
levelData.setGameType(server.getDefaultGameType());
|
||||
}
|
||||
|
||||
@@ -245,14 +244,16 @@
|
||||
this.chunkSource.chunkScanner(),
|
||||
this.registryAccess(),
|
||||
server.getStructureTemplateManager(),
|
||||
@@ -302,11 +_,19 @@
|
||||
@@ -301,13 +_,21 @@
|
||||
|
||||
this.sleepStatus = new SleepStatus();
|
||||
this.gameEventDispatcher = new GameEventDispatcher(this);
|
||||
- this.waypointManager = new ServerWaypointManager();
|
||||
+ this.waypointManager = new ServerWaypointManager(this); // Paper - optimize ServerWaypointManager with locator bar disabled
|
||||
this.environmentAttributes = EnvironmentAttributeSystem.builder().addDefaultLayers(this).build();
|
||||
this.uncachedBiomeResolver = this.getChunkSource().getGenerator().getBiomeSource().createUncachedResolver(this.getChunkSource().randomState());
|
||||
this.uncachedBiomeResolver = new BiomeManager(
|
||||
this.getChunkSource().getGenerator().getBiomeSource().createUncachedResolver(this.getChunkSource().randomState()), BiomeManager.obfuscateSeed(seed)
|
||||
);
|
||||
this.updateSkyBrightness();
|
||||
- }
|
||||
+ this.getCraftServer().addWorld(this.getWorld()); // CraftBukkit
|
||||
@@ -267,7 +268,7 @@
|
||||
|
||||
@Override
|
||||
public int getNextEntityId() {
|
||||
@@ -340,7 +_,7 @@
|
||||
@@ -337,7 +_,7 @@
|
||||
|
||||
@Override
|
||||
public ServerClockManager clockManager() {
|
||||
@@ -276,7 +277,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -373,11 +_,25 @@
|
||||
@@ -370,11 +_,25 @@
|
||||
int percentage = this.getGameRules().get(GameRules.PLAYERS_SLEEPING_PERCENTAGE);
|
||||
if (this.sleepStatus.areEnoughSleeping(percentage) && this.sleepStatus.areEnoughDeepSleeping(percentage, this.players)) {
|
||||
Optional<Holder<WorldClock>> defaultClock = this.dimensionType().defaultClock();
|
||||
@@ -304,7 +305,7 @@
|
||||
if (this.getGameRules().get(GameRules.ADVANCE_WEATHER) && this.isRaining()) {
|
||||
this.resetWeatherCycle();
|
||||
}
|
||||
@@ -392,9 +_,9 @@
|
||||
@@ -389,9 +_,9 @@
|
||||
if (!this.isDebug() && runs) {
|
||||
long tick = this.getGameTime();
|
||||
profiler.push("blockTicks");
|
||||
@@ -316,7 +317,7 @@
|
||||
profiler.pop();
|
||||
}
|
||||
|
||||
@@ -412,7 +_,7 @@
|
||||
@@ -409,7 +_,7 @@
|
||||
|
||||
this.handlingTick = false;
|
||||
profiler.pop();
|
||||
@@ -325,7 +326,7 @@
|
||||
if (isActive) {
|
||||
this.resetEmptyTime();
|
||||
}
|
||||
@@ -456,9 +_,12 @@
|
||||
@@ -453,9 +_,12 @@
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -338,7 +339,7 @@
|
||||
}
|
||||
|
||||
profiler.push("entityManagement");
|
||||
@@ -487,7 +_,7 @@
|
||||
@@ -484,7 +_,7 @@
|
||||
long time = this.levelData.getGameTime() + 1L;
|
||||
this.serverLevelData.setGameTime(time);
|
||||
Profiler.get().push("scheduledFunctions");
|
||||
@@ -347,7 +348,7 @@
|
||||
Profiler.get().pop();
|
||||
}
|
||||
}
|
||||
@@ -510,11 +_,13 @@
|
||||
@@ -507,11 +_,13 @@
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("iceandsnow");
|
||||
|
||||
@@ -361,7 +362,7 @@
|
||||
|
||||
profiler.popPush("tickBlocks");
|
||||
if (tickSpeed > 0) {
|
||||
@@ -555,12 +_,12 @@
|
||||
@@ -552,12 +_,12 @@
|
||||
int minZ = chunkPos.getMinBlockZ();
|
||||
ProfilerFiller profiler = Profiler.get();
|
||||
profiler.push("thunder");
|
||||
@@ -376,7 +377,7 @@
|
||||
&& !this.getBlockState(pos.below()).is(BlockTags.LIGHTNING_RODS);
|
||||
if (isTrap) {
|
||||
SkeletonHorse horse = EntityTypes.SKELETON_HORSE.create(this, EntitySpawnReason.EVENT);
|
||||
@@ -568,7 +_,7 @@
|
||||
@@ -565,7 +_,7 @@
|
||||
horse.setTrap(true);
|
||||
horse.setAge(0);
|
||||
horse.setPos(pos.getX(), pos.getY(), pos.getZ());
|
||||
@@ -385,7 +386,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -576,7 +_,7 @@
|
||||
@@ -573,7 +_,7 @@
|
||||
if (bolt != null) {
|
||||
bolt.snapTo(Vec3.atBottomCenterOf(pos));
|
||||
bolt.setVisualOnly(isTrap);
|
||||
@@ -394,7 +395,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -590,7 +_,7 @@
|
||||
@@ -587,7 +_,7 @@
|
||||
BlockPos belowPos = topPos.below();
|
||||
Biome biome = this.getBiome(topPos).value();
|
||||
if (biome.shouldFreeze(this, belowPos)) {
|
||||
@@ -403,7 +404,7 @@
|
||||
}
|
||||
|
||||
if (this.isRaining()) {
|
||||
@@ -602,10 +_,10 @@
|
||||
@@ -599,10 +_,10 @@
|
||||
if (currentLayers < Math.min(maxHeight, 8)) {
|
||||
BlockState newState = state.setValue(SnowLayerBlock.LAYERS, currentLayers + 1);
|
||||
Block.pushEntitiesUp(state, newState, this, topPos);
|
||||
@@ -416,7 +417,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -630,6 +_,13 @@
|
||||
@@ -627,6 +_,13 @@
|
||||
}
|
||||
|
||||
protected BlockPos findLightningTargetAround(final BlockPos pos) {
|
||||
@@ -430,7 +431,7 @@
|
||||
BlockPos center = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
|
||||
Optional<BlockPos> lightningRodTarget = this.findLightningRod(center);
|
||||
if (lightningRodTarget.isPresent()) {
|
||||
@@ -637,11 +_,12 @@
|
||||
@@ -634,11 +_,12 @@
|
||||
}
|
||||
|
||||
AABB search = AABB.encapsulatingFullBlocks(center, center.atY(this.getMaxY() + 1)).inflate(3.0);
|
||||
@@ -444,7 +445,7 @@
|
||||
if (center.getY() == this.getMinY() - 1) {
|
||||
center = center.above(2);
|
||||
}
|
||||
@@ -758,8 +_,8 @@
|
||||
@@ -755,8 +_,8 @@
|
||||
weatherData.setThunderTime(thunderTime);
|
||||
weatherData.setRainTime(rainTime);
|
||||
weatherData.setClearWeatherTime(clearWeatherTime);
|
||||
@@ -455,15 +456,15 @@
|
||||
}
|
||||
|
||||
this.oThunderLevel = this.thunderLevel;
|
||||
@@ -780,6 +_,7 @@
|
||||
this.rainLevel = Mth.clamp(this.rainLevel, 0.0F, 1.0F);
|
||||
@@ -777,6 +_,7 @@
|
||||
this.rainLevel = Math.clamp(this.rainLevel, 0.0F, 1.0F);
|
||||
}
|
||||
|
||||
+ /* CraftBukkit start
|
||||
if (this.oRainLevel != this.rainLevel) {
|
||||
this.server
|
||||
.getPlayerList()
|
||||
@@ -802,15 +_,48 @@
|
||||
@@ -799,15 +_,48 @@
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.RAIN_LEVEL_CHANGE, this.rainLevel));
|
||||
this.server.getPlayerList().broadcastAll(new ClientboundGameEventPacket(ClientboundGameEventPacket.THUNDER_LEVEL_CHANGE, this.thunderLevel));
|
||||
}
|
||||
@@ -516,7 +517,7 @@
|
||||
}
|
||||
|
||||
public void resetEmptyTime() {
|
||||
@@ -832,17 +_,44 @@
|
||||
@@ -829,17 +_,44 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -561,7 +562,7 @@
|
||||
}
|
||||
|
||||
private void tickPassenger(final Entity vehicle, final Entity entity) {
|
||||
@@ -854,6 +_,7 @@
|
||||
@@ -851,6 +_,7 @@
|
||||
profiler.incrementCounter("tickPassenger");
|
||||
entity.commonTick();
|
||||
entity.rideTick();
|
||||
@@ -569,7 +570,7 @@
|
||||
profiler.pop();
|
||||
|
||||
for (Entity passenger : entity.getPassengers()) {
|
||||
@@ -884,6 +_,7 @@
|
||||
@@ -881,6 +_,7 @@
|
||||
public void save(final @Nullable ProgressListener progressListener, final boolean flush, final boolean noSave) {
|
||||
ServerChunkCache chunkSource = this.getChunkSource();
|
||||
if (!noSave) {
|
||||
@@ -577,7 +578,7 @@
|
||||
if (progressListener != null) {
|
||||
progressListener.progressStartNoAbort(Component.translatable("menu.savingLevel"));
|
||||
}
|
||||
@@ -904,6 +_,7 @@
|
||||
@@ -901,6 +_,7 @@
|
||||
|
||||
private void saveLevelData(final boolean sync) {
|
||||
SavedDataStorage savedDataStorage = this.getChunkSource().getDataStorage();
|
||||
@@ -585,7 +586,7 @@
|
||||
if (sync) {
|
||||
savedDataStorage.saveAndJoin();
|
||||
} else {
|
||||
@@ -966,18 +_,40 @@
|
||||
@@ -963,18 +_,40 @@
|
||||
|
||||
@Override
|
||||
public boolean addFreshEntity(final Entity entity) {
|
||||
@@ -629,7 +630,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1000,42 +_,121 @@
|
||||
@@ -997,42 +_,121 @@
|
||||
this.entityManager.addNewEntity(player);
|
||||
}
|
||||
|
||||
@@ -690,7 +691,7 @@
|
||||
+ // Paper start - this area looks like it can load chunks, change the behavior
|
||||
+ // chests for example can apply physics to the world
|
||||
+ // so instead we just change the active container and call the event
|
||||
+ for (org.bukkit.entity.HumanEntity human : Lists.newArrayList(((net.minecraft.world.Container) blockEntity).getViewers())) {
|
||||
+ for (org.bukkit.entity.HumanEntity human : new ArrayList<>(((net.minecraft.world.Container) blockEntity).getViewers())) {
|
||||
+ ((org.bukkit.craftbukkit.entity.CraftHumanEntity) human).getHandle().closeUnloadedInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
+ }
|
||||
+ // Paper end - this area looks like it can load chunks, change the behavior
|
||||
@@ -736,7 +737,7 @@
|
||||
+ // If a plugin is using this method to send destroy packets for a client-side only entity id, no block progress occurred on the server.
|
||||
+ // Hence, do not call the event.
|
||||
+ if (entity != null) {
|
||||
+ float progressFloat = Mth.clamp(progress, 0, 10) / 10.0f;
|
||||
+ float progressFloat = Math.clamp(progress, 0, 10) / 10.0f;
|
||||
+ org.bukkit.craftbukkit.block.CraftBlock bukkitBlock = org.bukkit.craftbukkit.block.CraftBlock.at(this, blockPos);
|
||||
+ new io.papermc.paper.event.block.BlockBreakProgressUpdateEvent(bukkitBlock, progressFloat, entity.getBukkitEntity())
|
||||
+ .callEvent();
|
||||
@@ -756,7 +757,7 @@
|
||||
player.connection.send(new ClientboundBlockDestructionPacket(id, blockPos, progress));
|
||||
}
|
||||
}
|
||||
@@ -1123,7 +_,7 @@
|
||||
@@ -1120,7 +_,7 @@
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ(),
|
||||
@@ -765,7 +766,7 @@
|
||||
this.dimension(),
|
||||
new ClientboundLevelEventPacket(type, pos, data, false)
|
||||
);
|
||||
@@ -1135,6 +_,11 @@
|
||||
@@ -1132,6 +_,11 @@
|
||||
|
||||
@Override
|
||||
public void gameEvent(final Holder<GameEvent> gameEvent, final Vec3 position, final GameEvent.Context context) {
|
||||
@@ -777,7 +778,7 @@
|
||||
this.gameEventDispatcher.post(gameEvent, position, context);
|
||||
}
|
||||
|
||||
@@ -1147,17 +_,28 @@
|
||||
@@ -1144,17 +_,28 @@
|
||||
|
||||
this.getChunkSource().blockChanged(pos);
|
||||
this.pathTypesByPosCache.invalidate(pos);
|
||||
@@ -806,7 +807,7 @@
|
||||
|
||||
try {
|
||||
this.isUpdatingNavigations = true;
|
||||
@@ -1169,15 +_,23 @@
|
||||
@@ -1166,15 +_,23 @@
|
||||
this.isUpdatingNavigations = false;
|
||||
}
|
||||
}
|
||||
@@ -830,9 +831,9 @@
|
||||
this.neighborUpdater.updateNeighborsAtExceptFromFacing(pos, sourceBlock, null, orientation);
|
||||
}
|
||||
|
||||
@@ -1231,6 +_,44 @@
|
||||
@@ -1228,6 +_,44 @@
|
||||
final WeightedList<ExplosionParticleInfo> blockParticles,
|
||||
final Holder<SoundEvent> explosionSound
|
||||
final @Nullable Holder<SoundEvent> explosionSound
|
||||
) {
|
||||
+ // CraftBukkit start
|
||||
+ this.explode0(source, damageSource, damageCalculator, x, y, z, r, fire, interactionType, smallExplosionParticles, largeExplosionParticles, blockParticles, explosionSound);
|
||||
@@ -875,7 +876,7 @@
|
||||
Explosion.BlockInteraction blockInteraction = switch (interactionType) {
|
||||
case NONE -> Explosion.BlockInteraction.KEEP;
|
||||
case BLOCK -> this.getDestroyType(GameRules.BLOCK_EXPLOSION_DROP_DECAY);
|
||||
@@ -1239,10 +_,17 @@
|
||||
@@ -1236,10 +_,17 @@
|
||||
: Explosion.BlockInteraction.KEEP;
|
||||
case TNT -> this.getDestroyType(GameRules.TNT_EXPLOSION_DROP_DECAY);
|
||||
case TRIGGER -> Explosion.BlockInteraction.TRIGGER_BLOCK;
|
||||
@@ -890,11 +891,11 @@
|
||||
+ return explosion;
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
ParticleOptions explosionParticle = explosion.isSmall() ? smallExplosionParticles : largeExplosionParticles;
|
||||
Optional<ParticleOptions> explosionParticle = Optional.ofNullable(explosion.isSmall() ? smallExplosionParticles : largeExplosionParticles);
|
||||
Optional<Holder<SoundEvent>> effectiveExplosionSound = source != null && source.isSilent() ? Optional.empty() : Optional.ofNullable(explosionSound);
|
||||
|
||||
for (ServerPlayer player : this.players) {
|
||||
@@ -1256,6 +_,8 @@
|
||||
);
|
||||
@@ -1250,6 +_,8 @@
|
||||
.send(new ClientboundExplodePacket(center, r, blockCount, playerKnockback, explosionParticle, effectiveExplosionSound, blockParticles));
|
||||
}
|
||||
}
|
||||
+
|
||||
@@ -902,7 +903,7 @@
|
||||
}
|
||||
|
||||
private Explosion.BlockInteraction getDestroyType(final GameRule<Boolean> gameRule) {
|
||||
@@ -1333,73 +_,167 @@
|
||||
@@ -1327,73 +_,167 @@
|
||||
final double zDist,
|
||||
final double speed
|
||||
) {
|
||||
@@ -1136,7 +1137,7 @@
|
||||
particle,
|
||||
overrideLimiter,
|
||||
alwaysShow,
|
||||
@@ -1431,7 +_,27 @@
|
||||
@@ -1425,7 +_,27 @@
|
||||
final double speed,
|
||||
final ClientboundLevelParticlesPacket.RandomizationType randomizationType
|
||||
) {
|
||||
@@ -1165,7 +1166,7 @@
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(
|
||||
@@ -1450,6 +_,68 @@
|
||||
@@ -1444,6 +_,68 @@
|
||||
final double zSpeed,
|
||||
final ClientboundLevelParticlesPacket.RandomizationType randomizationType
|
||||
) {
|
||||
@@ -1234,7 +1235,7 @@
|
||||
ClientboundLevelParticlesPacket packet = new ClientboundLevelParticlesPacket(
|
||||
particle,
|
||||
overrideLimiter,
|
||||
@@ -1468,8 +_,9 @@
|
||||
@@ -1462,8 +_,9 @@
|
||||
);
|
||||
int result = 0;
|
||||
|
||||
@@ -1246,7 +1247,7 @@
|
||||
if (this.sendParticles(player, overrideLimiter, x, y, z, packet)) {
|
||||
result++;
|
||||
}
|
||||
@@ -1613,10 +_,36 @@
|
||||
@@ -1607,10 +_,36 @@
|
||||
|
||||
@Override
|
||||
public @Nullable MapItemSavedData getMapData(final MapId id) {
|
||||
@@ -1284,7 +1285,7 @@
|
||||
this.getServer().getDataStorage().set(MapItemSavedData.type(id), data);
|
||||
}
|
||||
|
||||
@@ -1626,7 +_,20 @@
|
||||
@@ -1620,7 +_,20 @@
|
||||
|
||||
@Override
|
||||
public void setRespawnData(final LevelData.RespawnData respawnData) {
|
||||
@@ -1306,7 +1307,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1663,6 +_,11 @@
|
||||
@@ -1657,6 +_,11 @@
|
||||
this.debugSynchronizers.dropPoi(immutable);
|
||||
}));
|
||||
newType.ifPresent(poiType -> this.getServer().execute(() -> {
|
||||
@@ -1318,7 +1319,7 @@
|
||||
PoiRecord record = this.getPoiManager().add(immutable, (Holder<PoiType>)poiType);
|
||||
if (record != null) {
|
||||
this.debugSynchronizers.registerPoi(record);
|
||||
@@ -1811,12 +_,12 @@
|
||||
@@ -1805,12 +_,12 @@
|
||||
}
|
||||
|
||||
public boolean isFlat() {
|
||||
@@ -1333,7 +1334,7 @@
|
||||
}
|
||||
|
||||
public @Nullable EnderDragonFight getDragonFight() {
|
||||
@@ -1824,7 +_,7 @@
|
||||
@@ -1818,7 +_,7 @@
|
||||
}
|
||||
|
||||
public WeatherData getWeatherData() {
|
||||
@@ -1342,7 +1343,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1871,6 +_,7 @@
|
||||
@@ -1865,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public LevelEntityGetter<Entity> getEntities() {
|
||||
@@ -1350,7 +1351,7 @@
|
||||
return this.entityManager.getEntityGetter();
|
||||
}
|
||||
|
||||
@@ -1963,8 +_,30 @@
|
||||
@@ -1961,8 +_,30 @@
|
||||
}
|
||||
|
||||
public GameRules getGameRules() {
|
||||
@@ -1383,7 +1384,7 @@
|
||||
|
||||
@Override
|
||||
public CrashReportCategory fillReportDetails(final CrashReport report) {
|
||||
@@ -2022,6 +_,7 @@
|
||||
@@ -2020,6 +_,7 @@
|
||||
if (entity instanceof WaypointTransmitter waypoint && waypoint.isTransmittingWaypoint()) {
|
||||
ServerLevel.this.getWaypointManager().trackWaypoint(waypoint);
|
||||
}
|
||||
@@ -1391,7 +1392,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2035,17 +_,24 @@
|
||||
@@ -2033,17 +_,24 @@
|
||||
|
||||
@Override
|
||||
public void onTickingStart(final Entity entity) {
|
||||
@@ -1417,16 +1418,16 @@
|
||||
if (entity instanceof ServerPlayer player) {
|
||||
ServerLevel.this.players.add(player);
|
||||
if (player.isReceivingWaypoints()) {
|
||||
@@ -2060,7 +_,7 @@
|
||||
@@ -2058,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (entity instanceof Mob mob) {
|
||||
- if (ServerLevel.this.isUpdatingNavigations) {
|
||||
+ if (false && ServerLevel.this.isUpdatingNavigations) { // Paper - Remove unnecessary onTrackingStart during navigation warning
|
||||
String message = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
DevUtil.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -2077,10 +_,51 @@
|
||||
@@ -2075,10 +_,51 @@
|
||||
}
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::add);
|
||||
@@ -1470,7 +1471,7 @@
|
||||
+ merchant.getTrader().closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED);
|
||||
+ }
|
||||
+ // Paper end - Fix merchant inventory not closing on entity removal
|
||||
+ for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
|
||||
+ for (org.bukkit.entity.HumanEntity h : new ArrayList<>(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper - Inventory close reason
|
||||
+ }
|
||||
+ }
|
||||
@@ -1478,16 +1479,16 @@
|
||||
ServerLevel.this.getChunkSource().removeEntity(entity);
|
||||
if (entity instanceof ServerPlayer player) {
|
||||
ServerLevel.this.players.remove(player);
|
||||
@@ -2089,7 +_,7 @@
|
||||
@@ -2087,7 +_,7 @@
|
||||
}
|
||||
|
||||
if (entity instanceof Mob mob) {
|
||||
- if (ServerLevel.this.isUpdatingNavigations) {
|
||||
+ if (false && ServerLevel.this.isUpdatingNavigations) { // Paper - Remove unnecessary onTrackingStart during navigation warning
|
||||
String message = "onTrackingStart called during navigation iteration";
|
||||
Util.logAndPauseIfInIde(
|
||||
DevUtil.logAndPauseIfInIde(
|
||||
"onTrackingStart called during navigation iteration", new IllegalStateException("onTrackingStart called during navigation iteration")
|
||||
@@ -2107,6 +_,15 @@
|
||||
@@ -2105,6 +_,15 @@
|
||||
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::remove);
|
||||
ServerLevel.this.debugSynchronizers.dropEntity(entity);
|
||||
@@ -1503,7 +1504,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2114,4 +_,28 @@
|
||||
@@ -2112,4 +_,28 @@
|
||||
entity.updateDynamicGameEventListener(DynamicGameEventListener::move);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -260,7 +_,8 @@
|
||||
@@ -259,7 +_,8 @@
|
||||
private int levitationStartTime;
|
||||
private boolean disconnected;
|
||||
private int requestedViewDistance = 2;
|
||||
@@ -10,7 +10,7 @@
|
||||
private @Nullable Vec3 startingToFallPosition;
|
||||
private @Nullable Vec3 enteredNetherPosition;
|
||||
private @Nullable Vec3 enteredLavaOnVehiclePosition;
|
||||
@@ -308,6 +_,13 @@
|
||||
@@ -307,6 +_,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
@Override
|
||||
public void sendSlotChange(final AbstractContainerMenu container, final int slotIndex, final ItemStack itemStack) {
|
||||
ServerPlayer.this.connection.send(new ClientboundContainerSetSlotPacket(container.containerId, container.incrementStateId(), slotIndex, itemStack));
|
||||
@@ -343,6 +_,32 @@
|
||||
@@ -342,6 +_,32 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
@Override
|
||||
public void dataChanged(final AbstractContainerMenu container, final int id, final int value) {
|
||||
}
|
||||
@@ -369,10 +_,43 @@
|
||||
@@ -368,10 +_,43 @@
|
||||
public void sendSystemMessage(final Component message) {
|
||||
ServerPlayer.this.sendSystemMessage(message);
|
||||
}
|
||||
@@ -101,7 +101,7 @@
|
||||
|
||||
public ServerPlayer(final MinecraftServer server, final ServerLevel level, final GameProfile gameProfile, final ClientInformation clientInformation) {
|
||||
super(level, gameProfile);
|
||||
@@ -383,8 +_,14 @@
|
||||
@@ -382,8 +_,14 @@
|
||||
this.recipeBook = new ServerRecipeBook((id, output) -> server.getRecipeManager().listDisplaysForRecipe(id, output));
|
||||
this.stats = server.getPlayerList().getPlayerStats(this);
|
||||
this.advancements = server.getPlayerList().getPlayerAdvancements(this);
|
||||
@@ -117,7 +117,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -403,6 +_,7 @@
|
||||
@@ -402,6 +_,7 @@
|
||||
this.seenCredits = input.getBooleanOr("seenCredits", false);
|
||||
input.read("recipeBook", ServerRecipeBook.Packed.CODEC)
|
||||
.ifPresent(p -> this.recipeBook.loadUntrusted(p, id -> this.server.getRecipeManager().byKey(id).isPresent()));
|
||||
@@ -125,7 +125,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleeping();
|
||||
}
|
||||
@@ -410,13 +_,27 @@
|
||||
@@ -409,13 +_,27 @@
|
||||
this.respawnConfig = input.read("respawn", ServerPlayer.RespawnConfig.CODEC).orElse(null);
|
||||
this.spawnExtraParticlesOnFall = input.getBooleanOr("spawn_extra_particles_on_fall", false);
|
||||
this.raidOmenPosition = input.read("raid_omen_position", BlockPos.CODEC).orElse(null);
|
||||
@@ -155,7 +155,7 @@
|
||||
@Override
|
||||
protected void addAdditionalSaveData(final ValueOutput output) {
|
||||
super.addAdditionalSaveData(output);
|
||||
@@ -440,12 +_,24 @@
|
||||
@@ -439,12 +_,24 @@
|
||||
if (!this.getShoulderEntityRight().isEmpty()) {
|
||||
output.store("ShoulderEntityRight", CompoundTag.CODEC, this.getShoulderEntityRight());
|
||||
}
|
||||
@@ -181,7 +181,7 @@
|
||||
ValueOutput vehicleWrapper = playerOutput.child("RootVehicle");
|
||||
vehicleWrapper.store("Attach", UUIDUtil.CODEC, vehicle.getUUID());
|
||||
rootVehicle.save(vehicleWrapper.child("Entity"));
|
||||
@@ -457,7 +_,7 @@
|
||||
@@ -456,7 +_,7 @@
|
||||
if (!rootTag.isEmpty()) {
|
||||
ServerLevel serverLevel = this.level();
|
||||
Entity vehicle = EntityType.loadEntityRecursive(
|
||||
@@ -190,7 +190,7 @@
|
||||
);
|
||||
if (vehicle != null) {
|
||||
UUID attachTo = rootTag.get().read("Attach", UUIDUtil.CODEC).orElse(null);
|
||||
@@ -474,10 +_,10 @@
|
||||
@@ -473,10 +_,10 @@
|
||||
|
||||
if (!this.isPassenger()) {
|
||||
LOGGER.warn("Couldn't reattach entity to player");
|
||||
@@ -203,7 +203,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -489,6 +_,7 @@
|
||||
@@ -488,6 +_,7 @@
|
||||
ValueOutput.ValueOutputList pearlsOutput = playerOutput.childrenList("ender_pearls");
|
||||
|
||||
for (ThrownEnderpearl enderPearl : this.enderPearls) {
|
||||
@@ -211,7 +211,7 @@
|
||||
if (enderPearl.isRemoved()) {
|
||||
LOGGER.warn("Trying to save removed ender pearl, skipping");
|
||||
} else {
|
||||
@@ -587,6 +_,11 @@
|
||||
@@ -586,6 +_,11 @@
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
@@ -223,7 +223,7 @@
|
||||
this.connection.tickClientLoadTimeout();
|
||||
this.gameMode.tick();
|
||||
this.wardenSpawnTracker.tick();
|
||||
@@ -594,9 +_,18 @@
|
||||
@@ -593,9 +_,18 @@
|
||||
this.damageCooldownTime--;
|
||||
}
|
||||
|
||||
@@ -245,7 +245,7 @@
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -658,10 +_,10 @@
|
||||
@@ -657,10 +_,10 @@
|
||||
|
||||
public void doTick() {
|
||||
try {
|
||||
@@ -258,7 +258,7 @@
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -691,7 +_,7 @@
|
||||
@@ -690,7 +_,7 @@
|
||||
if (this.getHealth() != this.lastSentHealth
|
||||
|| this.lastSentFood != this.foodData.getFoodLevel()
|
||||
|| this.foodData.getSaturationLevel() == 0.0F != this.lastFoodSaturationZero) {
|
||||
@@ -267,7 +267,7 @@
|
||||
this.lastSentHealth = this.getHealth();
|
||||
this.lastSentFood = this.foodData.getFoodLevel();
|
||||
this.lastFoodSaturationZero = this.foodData.getSaturationLevel() == 0.0F;
|
||||
@@ -722,6 +_,12 @@
|
||||
@@ -721,6 +_,12 @@
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.EXPERIENCE, Mth.ceil(this.lastRecordedExperience));
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@
|
||||
if (this.experienceLevel != this.lastRecordedLevel) {
|
||||
this.lastRecordedLevel = this.experienceLevel;
|
||||
this.updateScoreForCriteria(ObjectiveCriteria.LEVEL, Mth.ceil(this.lastRecordedLevel));
|
||||
@@ -735,6 +_,20 @@
|
||||
@@ -734,6 +_,20 @@
|
||||
if (this.tickCount % 20 == 0) {
|
||||
CriteriaTriggers.LOCATION.trigger(this);
|
||||
}
|
||||
@@ -301,7 +301,7 @@
|
||||
} catch (Throwable t) {
|
||||
CrashReport report = CrashReport.forThrowable(t, "Ticking player");
|
||||
CrashReportCategory category = report.addCategory("Player being ticked");
|
||||
@@ -759,7 +_,7 @@
|
||||
@@ -758,7 +_,7 @@
|
||||
if (this.level().getDifficulty() == Difficulty.PEACEFUL && this.level().getGameRules().get(GameRules.NATURAL_HEALTH_REGENERATION)) {
|
||||
if (this.tickCount % 20 == 0) {
|
||||
if (this.getHealth() < this.getMaxHealth()) {
|
||||
@@ -310,7 +310,7 @@
|
||||
}
|
||||
|
||||
float saturation = this.foodData.getSaturationLevel();
|
||||
@@ -779,6 +_,7 @@
|
||||
@@ -778,6 +_,7 @@
|
||||
this.playShoulderEntityAmbientSound(this.getShoulderEntityLeft());
|
||||
this.playShoulderEntityAmbientSound(this.getShoulderEntityRight());
|
||||
if (this.fallDistance > 0.5 || this.isInWater() || this.getAbilities().flying || this.isSleeping() || this.isInPowderSnow) {
|
||||
@@ -318,7 +318,7 @@
|
||||
this.removeEntitiesOnShoulder();
|
||||
}
|
||||
}
|
||||
@@ -823,32 +_,61 @@
|
||||
@@ -822,32 +_,61 @@
|
||||
@Override
|
||||
public void removeEntitiesOnShoulder() {
|
||||
if (this.timeEntitySatOnShoulder + 20L < this.level().getGameTime()) {
|
||||
@@ -387,7 +387,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -888,15 +_,37 @@
|
||||
@@ -887,15 +_,37 @@
|
||||
}
|
||||
|
||||
private void updateScoreForCriteria(final ObjectiveCriteria criteria, final int value) {
|
||||
@@ -434,7 +434,7 @@
|
||||
this.connection
|
||||
.send(
|
||||
new ClientboundPlayerCombatKillPacket(this.getId(), deathMessage),
|
||||
@@ -913,6 +_,65 @@
|
||||
@@ -912,6 +_,65 @@
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -500,7 +500,7 @@
|
||||
Team team = this.getTeam();
|
||||
if (team == null || team.getDeathMessageVisibility() == Team.Visibility.ALWAYS) {
|
||||
this.server.getPlayerList().broadcastSystemMessage(deathMessage, false);
|
||||
@@ -922,7 +_,7 @@
|
||||
@@ -921,7 +_,7 @@
|
||||
this.server.getPlayerList().broadcastSystemToAllExceptTeam(this, deathMessage);
|
||||
}
|
||||
} else {
|
||||
@@ -509,7 +509,7 @@
|
||||
}
|
||||
|
||||
this.removeEntitiesOnShoulder();
|
||||
@@ -930,11 +_,35 @@
|
||||
@@ -929,11 +_,35 @@
|
||||
this.tellNeutralMobsThatIDied();
|
||||
}
|
||||
|
||||
@@ -548,7 +548,7 @@
|
||||
LivingEntity killer = this.getKillCredit();
|
||||
if (killer != null) {
|
||||
this.awardStat(Stats.ENTITY_KILLED_BY.get(killer.getType()));
|
||||
@@ -968,10 +_,10 @@
|
||||
@@ -967,10 +_,10 @@
|
||||
if (victim != this) {
|
||||
super.awardKillScore(victim, killingBlow);
|
||||
Scoreboard scoreboard = this.level().getScoreboard();
|
||||
@@ -561,7 +561,7 @@
|
||||
} else {
|
||||
this.awardStat(Stats.MOB_KILLS);
|
||||
}
|
||||
@@ -984,11 +_,11 @@
|
||||
@@ -983,11 +_,11 @@
|
||||
|
||||
private void handleTeamKill(final ScoreHolder source, final ScoreHolder target, final Map<TeamColor, ObjectiveCriteria> criteriaByTeam) {
|
||||
Scoreboard scoreboard = this.level().getScoreboard();
|
||||
@@ -575,7 +575,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1000,9 +_,20 @@
|
||||
@@ -999,9 +_,20 @@
|
||||
}
|
||||
|
||||
Entity entity = source.getEntity();
|
||||
@@ -599,7 +599,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1014,24 +_,87 @@
|
||||
@@ -1013,24 +_,87 @@
|
||||
return this.level().isPvpAllowed();
|
||||
}
|
||||
|
||||
@@ -694,7 +694,7 @@
|
||||
}
|
||||
|
||||
public boolean isReceivingWaypoints() {
|
||||
@@ -1054,8 +_,21 @@
|
||||
@@ -1053,8 +_,21 @@
|
||||
|
||||
public void sendPostEffects() {
|
||||
this.postEffectsDirty = false;
|
||||
@@ -718,7 +718,7 @@
|
||||
|
||||
public boolean addPostEffect(final Identifier postEffect) {
|
||||
if (this.postEffects.contains(postEffect)) {
|
||||
@@ -1103,15 +_,17 @@
|
||||
@@ -1102,15 +_,17 @@
|
||||
if (block instanceof RespawnAnchorBlock && (forced || blockState.getValue(RespawnAnchorBlock.CHARGE) > 0) && RespawnAnchorBlock.canSetSpawn(level, pos)
|
||||
)
|
||||
{
|
||||
@@ -739,7 +739,7 @@
|
||||
} else {
|
||||
if (!forced) {
|
||||
return Optional.empty();
|
||||
@@ -1121,7 +_,7 @@
|
||||
@@ -1120,7 +_,7 @@
|
||||
BlockState topState = level.getBlockState(pos.above());
|
||||
boolean freeTop = topState.getBlock().isPossibleToRespawnInThis(topState);
|
||||
return freeBottom && freeTop
|
||||
@@ -748,7 +748,7 @@
|
||||
: Optional.empty();
|
||||
}
|
||||
}
|
||||
@@ -1137,7 +_,8 @@
|
||||
@@ -1136,7 +_,8 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -758,7 +758,7 @@
|
||||
if (this.isRemoved()) {
|
||||
return null;
|
||||
}
|
||||
@@ -1149,12 +_,36 @@
|
||||
@@ -1148,12 +_,36 @@
|
||||
ServerLevel newLevel = transition.newLevel();
|
||||
ServerLevel oldLevel = this.level();
|
||||
ResourceKey<Level> lastDimension = oldLevel.dimension();
|
||||
@@ -796,7 +796,7 @@
|
||||
this.connection.resetPosition();
|
||||
transition.postTeleportTransition().onTransition(this);
|
||||
return this;
|
||||
@@ -1162,22 +_,24 @@
|
||||
@@ -1161,22 +_,24 @@
|
||||
|
||||
this.isChangingDimension = true;
|
||||
LevelData levelData = newLevel.getLevelData();
|
||||
@@ -823,7 +823,7 @@
|
||||
this.connection.resetPosition();
|
||||
newLevel.addDuringTeleport(this);
|
||||
profiler.pop();
|
||||
@@ -1193,6 +_,15 @@
|
||||
@@ -1192,6 +_,15 @@
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
this.teleportSpectators(transition, oldLevel);
|
||||
@@ -839,7 +839,7 @@
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -1205,14 +_,29 @@
|
||||
@@ -1204,14 +_,29 @@
|
||||
public void triggerDimensionChangeTriggers(final ServerLevel oldLevel) {
|
||||
ResourceKey<Level> oldKey = oldLevel.dimension();
|
||||
ResourceKey<Level> newKey = this.level().dimension();
|
||||
@@ -872,7 +872,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1226,11 +_,10 @@
|
||||
@@ -1225,11 +_,10 @@
|
||||
this.containerMenu.broadcastChanges();
|
||||
}
|
||||
|
||||
@@ -888,7 +888,7 @@
|
||||
if (!this.isSleeping() && this.isAlive()) {
|
||||
boolean canSleep = rule.canSleep(this.level());
|
||||
boolean canSetSpawn = rule.canSetSpawn(this.level());
|
||||
@@ -1244,7 +_,7 @@
|
||||
@@ -1243,7 +_,7 @@
|
||||
|
||||
if (canSetSpawn) {
|
||||
this.setRespawnPosition(
|
||||
@@ -897,7 +897,7 @@
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1267,7 +_,36 @@
|
||||
@@ -1266,7 +_,36 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -935,7 +935,7 @@
|
||||
this.awardStat(bedBlock.getSleptInBedStatType());
|
||||
if (canSetSpawn) {
|
||||
CriteriaTriggers.SLEPT_IN_BED.trigger(this);
|
||||
@@ -1279,8 +_,6 @@
|
||||
@@ -1278,8 +_,6 @@
|
||||
|
||||
this.level().updateSleepingPlayerList();
|
||||
return result;
|
||||
@@ -944,7 +944,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1316,19 +_,30 @@
|
||||
@@ -1315,19 +_,30 @@
|
||||
|
||||
@Override
|
||||
public void stopSleepInBed(final boolean forcefulWakeUp, final boolean updateLevelList) {
|
||||
@@ -977,7 +977,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1377,8 +_,9 @@
|
||||
@@ -1376,8 +_,9 @@
|
||||
this.connection.send(new ClientboundShowDialogPacket(dialog));
|
||||
}
|
||||
|
||||
@@ -988,7 +988,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1387,12 +_,39 @@
|
||||
@@ -1386,12 +_,39 @@
|
||||
return OptionalInt.empty();
|
||||
}
|
||||
|
||||
@@ -1029,7 +1029,7 @@
|
||||
if (menu == null) {
|
||||
if (this.isSpectator()) {
|
||||
this.sendOverlayMessage(Component.translatable("container.spectatorCantOpen").withStyle(ChatFormatting.RED));
|
||||
@@ -1400,9 +_,14 @@
|
||||
@@ -1399,9 +_,14 @@
|
||||
|
||||
return OptionalInt.empty();
|
||||
} else {
|
||||
@@ -1046,7 +1046,7 @@
|
||||
return OptionalInt.of(this.containerCounter);
|
||||
}
|
||||
}
|
||||
@@ -1421,27 +_,49 @@
|
||||
@@ -1420,27 +_,49 @@
|
||||
|
||||
@Override
|
||||
public void openHorseInventory(final AbstractHorse horse, final Container container) {
|
||||
@@ -1101,7 +1101,7 @@
|
||||
this.initMenu(this.containerMenu);
|
||||
}
|
||||
|
||||
@@ -1463,10 +_,30 @@
|
||||
@@ -1462,10 +_,30 @@
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
@@ -1132,7 +1132,7 @@
|
||||
@Override
|
||||
public void doCloseContainer() {
|
||||
this.containerMenu.removed(this);
|
||||
@@ -1489,19 +_,19 @@
|
||||
@@ -1488,19 +_,19 @@
|
||||
int distance = Math.round((float)Math.sqrt(dx * dx + dy * dy + dz * dz) * 100.0F);
|
||||
if (distance > 0) {
|
||||
this.awardStat(Stats.SWIM_ONE_CM, distance);
|
||||
@@ -1155,7 +1155,7 @@
|
||||
}
|
||||
} else if (this.onClimbable()) {
|
||||
if (dy > 0.0) {
|
||||
@@ -1512,13 +_,13 @@
|
||||
@@ -1511,13 +_,13 @@
|
||||
if (horizontalDistance > 0) {
|
||||
if (this.isSprinting()) {
|
||||
this.awardStat(Stats.SPRINT_ONE_CM, horizontalDistance);
|
||||
@@ -1172,7 +1172,7 @@
|
||||
}
|
||||
}
|
||||
} else if (this.isFallFlying()) {
|
||||
@@ -1562,13 +_,13 @@
|
||||
@@ -1561,13 +_,13 @@
|
||||
@Override
|
||||
public void awardStat(final Stat<?> stat, final int count) {
|
||||
this.stats.increment(this, stat, count);
|
||||
@@ -1188,7 +1188,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1597,9 +_,9 @@
|
||||
@@ -1596,9 +_,9 @@
|
||||
super.jumpFromGround();
|
||||
this.awardStat(Stats.JUMP);
|
||||
if (this.isSprinting()) {
|
||||
@@ -1200,7 +1200,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1614,6 +_,13 @@
|
||||
@@ -1613,6 +_,13 @@
|
||||
public void disconnect() {
|
||||
this.disconnected = true;
|
||||
this.ejectPassengers();
|
||||
@@ -1214,7 +1214,7 @@
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, false);
|
||||
}
|
||||
@@ -1625,6 +_,7 @@
|
||||
@@ -1624,6 +_,7 @@
|
||||
|
||||
public void resetSentInfo() {
|
||||
this.lastSentHealth = -1.0E8F;
|
||||
@@ -1222,7 +1222,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1654,18 +_,18 @@
|
||||
@@ -1653,18 +_,18 @@
|
||||
this.onUpdateAbilities();
|
||||
this.getAttributes().assignBaseValues(oldPlayer.getAttributes());
|
||||
if (restoreAll) {
|
||||
@@ -1244,7 +1244,7 @@
|
||||
if (this.level().getGameRules().get(GameRules.KEEP_INVENTORY) || oldPlayer.isSpectator()) {
|
||||
this.transferInventoryXpAndScore(oldPlayer);
|
||||
}
|
||||
@@ -1677,7 +_,7 @@
|
||||
@@ -1676,7 +_,7 @@
|
||||
this.lastSentExp = -1;
|
||||
this.lastSentHealth = -1.0F;
|
||||
this.lastSentFood = -1;
|
||||
@@ -1253,7 +1253,7 @@
|
||||
this.seenCredits = oldPlayer.seenCredits;
|
||||
this.enteredNetherPosition = oldPlayer.enteredNetherPosition;
|
||||
this.currentExplosionImpactPos = oldPlayer.currentExplosionImpactPos;
|
||||
@@ -1731,9 +_,22 @@
|
||||
@@ -1730,9 +_,22 @@
|
||||
CriteriaTriggers.EFFECTS_CHANGED.trigger(this, null);
|
||||
}
|
||||
|
||||
@@ -1277,7 +1277,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1751,6 +_,7 @@
|
||||
@@ -1750,6 +_,7 @@
|
||||
final float newYRot,
|
||||
final float newXRot,
|
||||
final boolean resetCamera
|
||||
@@ -1285,7 +1285,7 @@
|
||||
) {
|
||||
if (this.isSleeping()) {
|
||||
this.stopSleepInBed(true, true);
|
||||
@@ -1760,7 +_,7 @@
|
||||
@@ -1759,7 +_,7 @@
|
||||
this.setCamera(this);
|
||||
}
|
||||
|
||||
@@ -1294,7 +1294,7 @@
|
||||
if (success) {
|
||||
this.setYHeadRot(relatives.contains(Relative.Y_ROT) ? this.getYHeadRot() + newYRot : newYRot);
|
||||
this.connection.resetFlyingTicks();
|
||||
@@ -1799,11 +_,16 @@
|
||||
@@ -1798,11 +_,16 @@
|
||||
}
|
||||
|
||||
public boolean setGameMode(final GameType mode) {
|
||||
@@ -1315,7 +1315,7 @@
|
||||
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, mode.getId()));
|
||||
if (mode == GameType.SPECTATOR) {
|
||||
this.removeEntitiesOnShoulder();
|
||||
@@ -1819,7 +_,7 @@
|
||||
@@ -1818,7 +_,7 @@
|
||||
|
||||
this.onUpdateAbilities();
|
||||
this.updateEffectVisibility();
|
||||
@@ -1324,7 +1324,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1877,8 +_,13 @@
|
||||
@@ -1876,8 +_,13 @@
|
||||
}
|
||||
|
||||
public void sendChatMessage(final OutgoingChatMessage message, final boolean filtered, final ChatType.Bound chatType) {
|
||||
@@ -1339,7 +1339,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1889,7 +_,42 @@
|
||||
@@ -1888,7 +_,42 @@
|
||||
}
|
||||
|
||||
public void updateOptions(final ClientInformation information) {
|
||||
@@ -1382,7 +1382,7 @@
|
||||
this.requestedViewDistance = information.viewDistance();
|
||||
this.chatVisibility = information.chatVisibility();
|
||||
this.canChatColor = information.chatColors();
|
||||
@@ -1974,8 +_,23 @@
|
||||
@@ -1978,8 +_,23 @@
|
||||
Entity oldCamera = this.getCamera();
|
||||
this.camera = newCamera == null ? this : newCamera;
|
||||
if (oldCamera != this.camera) {
|
||||
@@ -1407,7 +1407,7 @@
|
||||
}
|
||||
|
||||
if (newCamera != null) {
|
||||
@@ -1999,11 +_,11 @@
|
||||
@@ -2003,11 +_,11 @@
|
||||
}
|
||||
|
||||
public @Nullable Component getTabListDisplayName() {
|
||||
@@ -1421,7 +1421,7 @@
|
||||
}
|
||||
|
||||
public boolean isChangingDimension() {
|
||||
@@ -2027,11 +_,60 @@
|
||||
@@ -2031,11 +_,60 @@
|
||||
}
|
||||
|
||||
public void setRespawnPosition(final ServerPlayer.@Nullable RespawnConfig respawnConfig, final boolean showMessage) {
|
||||
@@ -1484,7 +1484,7 @@
|
||||
}
|
||||
|
||||
public SectionPos getLastSectionPos() {
|
||||
@@ -2051,16 +_,23 @@
|
||||
@@ -2055,16 +_,23 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1513,7 +1513,7 @@
|
||||
return entity;
|
||||
}
|
||||
|
||||
@@ -2113,7 +_,7 @@
|
||||
@@ -2117,7 +_,7 @@
|
||||
super.updateUsingItem(useItem);
|
||||
}
|
||||
|
||||
@@ -1522,7 +1522,7 @@
|
||||
Inventory inventory = this.getInventory();
|
||||
ItemStack removed = inventory.removeFromSelected(all);
|
||||
this.containerMenu
|
||||
@@ -2123,8 +_,9 @@
|
||||
@@ -2127,8 +_,9 @@
|
||||
this.stopUsingItem();
|
||||
}
|
||||
|
||||
@@ -1533,7 +1533,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2186,9 +_,9 @@
|
||||
@@ -2190,9 +_,9 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1545,7 +1545,7 @@
|
||||
if (oldVehicle instanceof LivingEntity livingEntity) {
|
||||
for (MobEffectInstance effect : livingEntity.getActiveEffects()) {
|
||||
this.connection.send(new ClientboundRemoveMobEffectPacket(oldVehicle.getId(), effect.getEffect()));
|
||||
@@ -2310,7 +_,7 @@
|
||||
@@ -2313,7 +_,7 @@
|
||||
}
|
||||
|
||||
public static long placeEnderPearlTicket(final ServerLevel level, final ChunkPos chunk) {
|
||||
@@ -1554,7 +1554,7 @@
|
||||
return TicketType.ENDER_PEARL.timeout();
|
||||
}
|
||||
|
||||
@@ -2347,9 +_,11 @@
|
||||
@@ -2350,9 +_,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1569,7 +1569,7 @@
|
||||
}
|
||||
|
||||
private static float calculateLookAtYaw(final Vec3 position, final BlockPos lookAtBlockPos) {
|
||||
@@ -2369,4 +_,135 @@
|
||||
@@ -2372,4 +_,135 @@
|
||||
);
|
||||
public static final ServerPlayer.SavedPosition EMPTY = new ServerPlayer.SavedPosition(Optional.empty(), Optional.empty(), Optional.empty());
|
||||
}
|
||||
@@ -1641,7 +1641,7 @@
|
||||
+ this.pluginRainPosition -= 0.01F;
|
||||
+ }
|
||||
+
|
||||
+ this.pluginRainPosition = Mth.clamp(this.pluginRainPosition, 0.0F, 1.0F);
|
||||
+ this.pluginRainPosition = Math.clamp(this.pluginRainPosition, 0.0F, 1.0F);
|
||||
+ }
|
||||
+
|
||||
+ public void resetPlayerWeather() {
|
||||
|
||||
+11
-11
@@ -91,7 +91,7 @@
|
||||
if (blockState.isAir()) {
|
||||
this.level.destroyBlockProgress(this.player.getId(), this.destroyPos, -1);
|
||||
this.lastSentState = -1;
|
||||
@@ -165,6 +_,7 @@
|
||||
@@ -167,6 +_,7 @@
|
||||
final BlockPos pos, final ServerboundPlayerActionPacket.Action action, final Direction direction, final int maxY, final int sequence
|
||||
) {
|
||||
if (!this.player.isWithinBlockInteractionRange(pos, 1.0)) {
|
||||
@@ -99,7 +99,7 @@
|
||||
if (this.isDestroyingBlock && action == ServerboundPlayerActionPacket.Action.ABORT_DESTROY_BLOCK) {
|
||||
this.abortDestroyBlock(pos, sequence);
|
||||
}
|
||||
@@ -182,16 +_,35 @@
|
||||
@@ -184,16 +_,35 @@
|
||||
}
|
||||
|
||||
if (!this.level.mayInteract(this.player, pos)) {
|
||||
@@ -137,7 +137,7 @@
|
||||
if (this.player.blockActionRestricted(this.level, pos, this.gameModeForPlayer)) {
|
||||
this.player.connection.send(new ClientboundBlockUpdatePacket(pos, this.level.getBlockState(pos)));
|
||||
this.debugLogging(pos, false, sequence, "block action restricted");
|
||||
@@ -201,7 +_,7 @@
|
||||
@@ -203,7 +_,7 @@
|
||||
this.destroyProgressStart = this.gameTicks;
|
||||
float progress = 1.0F;
|
||||
BlockState blockState = this.level.getBlockState(pos);
|
||||
@@ -146,7 +146,7 @@
|
||||
EnchantmentHelper.onHitBlock(
|
||||
this.level,
|
||||
this.player.getMainHandItem(),
|
||||
@@ -216,6 +_,23 @@
|
||||
@@ -218,6 +_,23 @@
|
||||
progress = blockState.getDestroyProgress(this.player, this.player.level(), pos);
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@
|
||||
if (!blockState.isAir() && progress >= 1.0F) {
|
||||
this.destroyAndAck(pos, sequence, "insta mine");
|
||||
} else {
|
||||
@@ -265,14 +_,22 @@
|
||||
@@ -267,14 +_,22 @@
|
||||
|
||||
private void abortDestroyBlock(final BlockPos pos, final int sequence) {
|
||||
this.isDestroyingBlock = false;
|
||||
@@ -195,7 +195,7 @@
|
||||
}
|
||||
|
||||
public void destroyAndAck(final BlockPos pos, final int sequence, final String exitId) {
|
||||
@@ -286,21 +_,70 @@
|
||||
@@ -288,21 +_,70 @@
|
||||
|
||||
public boolean destroyBlock(final BlockPos pos) {
|
||||
BlockState state = this.level.getBlockState(pos);
|
||||
@@ -270,7 +270,7 @@
|
||||
BlockState adjustedState = block.playerWillDestroy(this.level, pos, state, this.player);
|
||||
boolean changed = this.level.removeBlock(pos, false);
|
||||
if (SharedConstants.DEBUG_BLOCK_BREAK) {
|
||||
@@ -311,17 +_,38 @@
|
||||
@@ -313,17 +_,38 @@
|
||||
block.destroy(this.level, pos, adjustedState);
|
||||
}
|
||||
|
||||
@@ -316,7 +316,7 @@
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -337,6 +_,7 @@
|
||||
@@ -339,6 +_,7 @@
|
||||
|
||||
int oldCount = itemStack.getCount();
|
||||
int oldDamage = itemStack.getDamageValue();
|
||||
@@ -324,7 +324,7 @@
|
||||
InteractionResult result = itemStack.use(level, player, hand);
|
||||
ItemStack resultStack;
|
||||
if (result instanceof InteractionResult.Success success) {
|
||||
@@ -365,25 +_,70 @@
|
||||
@@ -367,25 +_,70 @@
|
||||
}
|
||||
|
||||
if (!player.isUsingItem()) {
|
||||
@@ -398,7 +398,7 @@
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
|
||||
@@ -424,7 +_,7 @@
|
||||
@@ -426,7 +_,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@
|
||||
UseOnContext context = new UseOnContext(player, hand, hitResult);
|
||||
InteractionResult result;
|
||||
if (player.hasInfiniteMaterials()) {
|
||||
@@ -447,6 +_,11 @@
|
||||
@@ -449,6 +_,11 @@
|
||||
|
||||
return result;
|
||||
} else {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/level/WorldGenRegion.java
|
||||
+++ b/net/minecraft/server/level/WorldGenRegion.java
|
||||
@@ -164,6 +_,28 @@
|
||||
@@ -158,6 +_,28 @@
|
||||
return distance < this.generatingStep.directDependencies().size();
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
@Override
|
||||
public BlockState getBlockState(final BlockPos pos) {
|
||||
int chunkX = SectionPos.blockToSectionCoord(pos.getX());
|
||||
@@ -295,11 +_,14 @@
|
||||
@@ -284,11 +_,14 @@
|
||||
return Math.abs(this.centerChunkX - chunkX) <= this.writeRadius && Math.abs(this.centerChunkZ - chunkZ) <= this.writeRadius;
|
||||
}
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
int chunkZ = SectionPos.blockToSectionCoord(pos.getZ());
|
||||
+ // Paper start - Buffer OOB setBlock calls
|
||||
+ if (!hasSetFarWarned) {
|
||||
Util.logAndPauseIfInIde(
|
||||
DevUtil.logAndPauseIfInIde(
|
||||
"Detected setBlock in a far chunk ["
|
||||
+ chunkX
|
||||
@@ -311,6 +_,12 @@
|
||||
@@ -300,6 +_,12 @@
|
||||
+ this.generatingStep.targetStatus()
|
||||
+ (this.currentlyGenerating == null ? "" : ", currently generating: " + this.currentlyGenerating.get())
|
||||
);
|
||||
@@ -57,7 +57,7 @@
|
||||
return false;
|
||||
} else if (this.center.isUpgrading()) {
|
||||
LevelHeightAccessor levelHeightAccessor = this.center.getHeightAccessorForGeneration();
|
||||
@@ -328,7 +_,7 @@
|
||||
@@ -317,7 +_,7 @@
|
||||
|
||||
ChunkAccess chunk = this.getChunk(pos);
|
||||
BlockState oldState = chunk.setBlockState(pos, blockState, updateFlags);
|
||||
@@ -66,7 +66,7 @@
|
||||
this.level.updatePOIOnBlockStateChange(pos, oldState, blockState);
|
||||
}
|
||||
|
||||
@@ -341,6 +_,17 @@
|
||||
@@ -330,6 +_,17 @@
|
||||
chunk.removeBlockEntity(pos);
|
||||
}
|
||||
} else {
|
||||
@@ -84,7 +84,7 @@
|
||||
CompoundTag tag = new CompoundTag();
|
||||
tag.putInt("x", pos.getX());
|
||||
tag.putInt("y", pos.getY());
|
||||
@@ -368,6 +_,13 @@
|
||||
@@ -357,6 +_,13 @@
|
||||
|
||||
@Override
|
||||
public boolean addFreshEntity(final Entity entity) {
|
||||
|
||||
+4
-4
@@ -4,10 +4,10 @@
|
||||
import com.mojang.authlib.GameProfile;
|
||||
import net.minecraft.server.level.ClientInformation;
|
||||
|
||||
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred) {
|
||||
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, @org.jspecify.annotations.Nullable String clientBrand, java.util.Set<String> channels) { // Paper
|
||||
-public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, ClientDebugInfo debugInfo) {
|
||||
+public record CommonListenerCookie(GameProfile gameProfile, int latency, ClientInformation clientInformation, boolean transferred, ClientDebugInfo debugInfo, @org.jspecify.annotations.Nullable String clientBrand, java.util.Set<String> channels) { // Paper
|
||||
public static CommonListenerCookie createInitial(final GameProfile gameProfile, final boolean transferred) {
|
||||
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred);
|
||||
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, null, new java.util.HashSet<>()); // Paper
|
||||
- return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, new ClientDebugInfo());
|
||||
+ return new CommonListenerCookie(gameProfile, 0, ClientInformation.createDefault(), transferred, new ClientDebugInfo(), null, new java.util.HashSet<>()); // Paper
|
||||
}
|
||||
}
|
||||
+55
-20
@@ -1,14 +1,14 @@
|
||||
--- a/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -14,6 +_,7 @@
|
||||
public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
@@ -20,6 +_,7 @@
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final ServerInfo server;
|
||||
private final Connection connection;
|
||||
+ private ByteBuf buf; // Paper
|
||||
|
||||
public LegacyQueryHandler(final ServerInfo server) {
|
||||
public LegacyQueryHandler(final ServerInfo server, final Connection connection) {
|
||||
this.server = server;
|
||||
@@ -22,6 +_,17 @@
|
||||
@@ -29,6 +_,17 @@
|
||||
@Override
|
||||
public void channelRead(final ChannelHandlerContext ctx, final Object msg) {
|
||||
ByteBuf in = (ByteBuf)msg;
|
||||
@@ -26,15 +26,27 @@
|
||||
in.markReaderIndex();
|
||||
boolean connectNormally = true;
|
||||
|
||||
@@ -33,9 +_,19 @@
|
||||
@@ -40,14 +_,27 @@
|
||||
|
||||
SocketAddress socket = ctx.channel().remoteAddress();
|
||||
int length = in.readableBytes();
|
||||
+ String body = null; // Paper
|
||||
if (length == 0) {
|
||||
- LOGGER.debug("Ping: (<1.3.x) from {}", socket);
|
||||
- String body = createVersion0Response(this.server);
|
||||
- if (this.server.acceptsConnection(this.connection, UNKNOWN_SERVER_DETAILS)) {
|
||||
- String body = createVersion0Response(this.server);
|
||||
- sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
- } else {
|
||||
- ctx.close();
|
||||
- }
|
||||
+ LOGGER.debug("Ping: (<1.3.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socket : "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
+ if (!this.server.acceptsConnection(this.connection, UNKNOWN_SERVER_DETAILS)) {
|
||||
+ ctx.close();
|
||||
+ in.release();
|
||||
+ connectNormally = false;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), socket, 39, null);
|
||||
+ if (event == null) {
|
||||
@@ -45,35 +57,52 @@
|
||||
+ }
|
||||
+ body = String.format(Locale.ROOT, "%s§%d§%d", com.destroystokyo.paper.network.PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers());
|
||||
+ // Paper end - Call PaperServerListPingEvent and use results
|
||||
sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
+ sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
} else {
|
||||
if (in.readUnsignedByte() != 1) {
|
||||
@@ -43,16 +_,39 @@
|
||||
}
|
||||
return;
|
||||
@@ -55,23 +_,47 @@
|
||||
|
||||
ServerConnectionDetails connectionDetails;
|
||||
if (in.isReadable()) {
|
||||
- if (!readCustomPayloadPacket(in)) {
|
||||
- connectionDetails = readCustomPayloadPacket(in);
|
||||
- if (connectionDetails == null) {
|
||||
- return;
|
||||
- }
|
||||
-
|
||||
- LOGGER.debug("Ping: (1.6) from {}, host: {}", socket, connectionDetails);
|
||||
- } else {
|
||||
- LOGGER.debug("Ping: (1.4-1.5.x) from {}", socket);
|
||||
- connectionDetails = UNKNOWN_SERVER_DETAILS;
|
||||
- }
|
||||
-
|
||||
- if (this.server.acceptsConnection(this.connection, connectionDetails)) {
|
||||
- String body = createVersion1Response(this.server);
|
||||
- sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
- } else {
|
||||
- ctx.close();
|
||||
- }
|
||||
+ // Paper start - Replace below
|
||||
+ if (in.readUnsignedByte() != LegacyProtocolUtils.CUSTOM_PAYLOAD_PACKET_ID) {
|
||||
+ body = this.readLegacy1_6(ctx, in);
|
||||
+ if (body == null) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- LOGGER.debug("Ping: (1.6) from {}", socket);
|
||||
+ }
|
||||
+ // Paper end - Replace below
|
||||
} else {
|
||||
- LOGGER.debug("Ping: (1.4-1.5.x) from {}", socket);
|
||||
- }
|
||||
-
|
||||
- String body = createVersion1Response(this.server);
|
||||
+ } else {
|
||||
+ LOGGER.debug("Ping: (1.4-1.5.x) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? socket : "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
+ }
|
||||
+
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ if (body == null) {
|
||||
+ if (!this.server.acceptsConnection(this.connection, UNKNOWN_SERVER_DETAILS)) {
|
||||
+ ctx.close();
|
||||
+ in.release();
|
||||
+ connectNormally = false;
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), socket, 127, null); // Paper
|
||||
+ if (event == null) {
|
||||
+ ctx.close();
|
||||
@@ -93,10 +122,11 @@
|
||||
+ );
|
||||
+ }
|
||||
+ // Paper end - Call PaperServerListPingEvent and use results
|
||||
sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
+ sendFlushAndClose(ctx, createLegacyDisconnectPacket(ctx.alloc(), body));
|
||||
}
|
||||
|
||||
@@ -110,6 +_,96 @@
|
||||
in.release();
|
||||
@@ -128,6 +_,101 @@
|
||||
server.getMaxPlayers()
|
||||
);
|
||||
}
|
||||
@@ -161,6 +191,11 @@
|
||||
+
|
||||
+ LOGGER.debug("Ping: (1.6) from {}", net.minecraft.server.MinecraftServer.getServer().logIPs() ? ctx.channel().remoteAddress() : "<ip address withheld>"); // Paper - Respect logIPs option
|
||||
+
|
||||
+ if (!this.server.acceptsConnection(this.connection, ServerConnectionDetails.fromIntentPacket(host, port))) {
|
||||
+ ctx.close();
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.server.MinecraftServer server = net.minecraft.server.MinecraftServer.getServer();
|
||||
+ java.net.InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(server, ctx.channel().remoteAddress(), protocolVersion, virtualHost);
|
||||
|
||||
+24
-15
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerCommonPacketListenerImpl.java
|
||||
@@ -37,7 +_,7 @@
|
||||
@@ -42,7 +_,7 @@
|
||||
private static final Component TIMEOUT_DISCONNECTION_MESSAGE = Component.translatable("disconnect.timeout");
|
||||
static final Component DISCONNECT_UNEXPECTED_QUERY = Component.translatable("multiplayer.disconnect.unexpected_query_response");
|
||||
protected final MinecraftServer server;
|
||||
@@ -9,10 +9,10 @@
|
||||
private final boolean transferred;
|
||||
private long keepAliveTime;
|
||||
private boolean keepAlivePending;
|
||||
@@ -46,6 +_,16 @@
|
||||
private boolean closed = false;
|
||||
@@ -52,6 +_,16 @@
|
||||
private int latency;
|
||||
private volatile boolean suspendFlushingOnServerThread = false;
|
||||
private final ClientDebugInfo debugInfo;
|
||||
+ // CraftBukkit start
|
||||
+ public final org.bukkit.craftbukkit.CraftServer cserver;
|
||||
+ // CraftBukkit end
|
||||
@@ -26,10 +26,10 @@
|
||||
|
||||
public ServerCommonPacketListenerImpl(final MinecraftServer server, final Connection connection, final CommonListenerCookie cookie) {
|
||||
this.server = server;
|
||||
@@ -53,7 +_,18 @@
|
||||
this.keepAliveTime = Util.getMillis();
|
||||
@@ -60,7 +_,18 @@
|
||||
this.latency = cookie.latency();
|
||||
this.transferred = cookie.transferred();
|
||||
this.debugInfo = cookie.debugInfo();
|
||||
+ // Paper start
|
||||
+ this.clientBrand = cookie.clientBrand();
|
||||
+ this.cserver = server.server;
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
private void close() {
|
||||
if (!this.closed) {
|
||||
@@ -83,7 +_,7 @@
|
||||
@@ -91,7 +_,7 @@
|
||||
this.latency = (this.latency * 3 + time) / 4;
|
||||
this.keepAlivePending = false;
|
||||
} else if (!this.isSingleplayerOwner()) {
|
||||
@@ -54,7 +54,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,14 +_,88 @@
|
||||
@@ -99,24 +_,88 @@
|
||||
public void handlePong(final ServerboundPongPacket serverboundPongPacket) {
|
||||
}
|
||||
|
||||
@@ -65,6 +65,16 @@
|
||||
+
|
||||
@Override
|
||||
public void handleCustomPayload(final ServerboundCustomPayloadPacket packet) {
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.server.packetProcessor());
|
||||
- switch (packet.payload()) {
|
||||
- case BrandPayload(String brand):
|
||||
- this.debugInfo.setBrand(brand);
|
||||
- break;
|
||||
- case ModListPayload(Map<Identifier, PropertyMap> entries):
|
||||
- this.debugInfo.appendModInfo(entries);
|
||||
- break;
|
||||
- default:
|
||||
- }
|
||||
+ // Paper start
|
||||
+ if (!(packet.payload() instanceof final net.minecraft.network.protocol.common.custom.DiscardedPayload discardedPayload)) {
|
||||
+ return;
|
||||
@@ -143,7 +153,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -106,21 +_,46 @@
|
||||
@@ -124,21 +_,46 @@
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.server.packetProcessor());
|
||||
if (packet.action() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
|
||||
LOGGER.info("Disconnecting {} due to resource pack {} rejection", this.playerProfile().name(), packet.id());
|
||||
@@ -195,7 +205,7 @@
|
||||
} else if (this.checkIfClosed(now)) {
|
||||
this.keepAlivePending = true;
|
||||
this.keepAliveTime = now;
|
||||
@@ -135,7 +_,7 @@
|
||||
@@ -153,7 +_,7 @@
|
||||
private boolean checkIfClosed(final long now) {
|
||||
if (this.closed) {
|
||||
if (now - this.closedListenerTime >= 15000L) {
|
||||
@@ -204,7 +214,7 @@
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -158,6 +_,13 @@
|
||||
@@ -176,6 +_,13 @@
|
||||
}
|
||||
|
||||
public void send(final Packet<?> packet, final @Nullable ChannelFutureListener listener) {
|
||||
@@ -218,7 +228,7 @@
|
||||
if (packet.isTerminal()) {
|
||||
this.close();
|
||||
}
|
||||
@@ -174,15 +_,108 @@
|
||||
@@ -192,14 +_,108 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +314,6 @@
|
||||
+ private void disconnect0(final DisconnectionDetails details) {
|
||||
this.connection.send(new ClientboundDisconnectPacket(details.reason()), PacketSendListener.thenRun(() -> this.connection.disconnect(details)));
|
||||
this.connection.setReadOnly();
|
||||
- this.server.executeBlocking(this.connection::handleDisconnection);
|
||||
- }
|
||||
+ this.connection.handleConnectionDisconnectOnNextTick = true; // Paper - Force kill connection ticking. Let this close the connection
|
||||
+ }
|
||||
@@ -330,11 +339,11 @@
|
||||
|
||||
protected boolean isSingleplayerOwner() {
|
||||
return this.server.isSingleplayerOwner(new NameAndId(this.playerProfile()));
|
||||
@@ -200,6 +_,6 @@
|
||||
@@ -221,6 +_,6 @@
|
||||
}
|
||||
|
||||
protected CommonListenerCookie createCookie(final ClientInformation clientInformation) {
|
||||
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred);
|
||||
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.clientBrand, this.pluginMessagerChannels); // Paper
|
||||
- return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.debugInfo);
|
||||
+ return new CommonListenerCookie(this.playerProfile(), this.latency, clientInformation, this.transferred, this.debugInfo, this.clientBrand, this.pluginMessagerChannels); // Paper
|
||||
}
|
||||
}
|
||||
+8
-8
@@ -26,10 +26,10 @@
|
||||
.childHandler(
|
||||
new ChannelInitializer<Channel>() {
|
||||
@Override
|
||||
@@ -82,22 +_,63 @@
|
||||
Connection connection = rateLimitPacketsPerSecond > 0
|
||||
? new RateKickingConnection(rateLimitPacketsPerSecond)
|
||||
: new Connection(PacketFlow.SERVERBOUND);
|
||||
@@ -84,22 +_,63 @@
|
||||
}
|
||||
|
||||
Connection.configureSerialization(pipeline, PacketFlow.SERVERBOUND, false, null);
|
||||
+ // Paper start - Add support for Proxy Protocol
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.proxyProtocol) {
|
||||
+ channel.pipeline().addAfter(HandlerNames.TIMEOUT, "haproxy-decoder", new io.netty.handler.codec.haproxy.HAProxyMessageDecoder());
|
||||
@@ -91,7 +91,7 @@
|
||||
public SocketAddress startMemoryChannel() {
|
||||
ChannelFuture newChannel;
|
||||
synchronized (this.channels) {
|
||||
@@ -138,9 +_,26 @@
|
||||
@@ -140,9 +_,26 @@
|
||||
public void stop() {
|
||||
this.running = false;
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
} catch (InterruptedException ignored) {
|
||||
LOGGER.error("Interrupted whilst closing channel");
|
||||
}
|
||||
@@ -169,12 +_,25 @@
|
||||
@@ -171,12 +_,25 @@
|
||||
public void tick() {
|
||||
synchronized (this.connections) {
|
||||
this.addPendingConnections();
|
||||
@@ -145,7 +145,7 @@
|
||||
try {
|
||||
connection.tick();
|
||||
} catch (Exception e) {
|
||||
@@ -188,6 +_,7 @@
|
||||
@@ -190,6 +_,7 @@
|
||||
connection.setReadOnly();
|
||||
}
|
||||
} else {
|
||||
@@ -153,7 +153,7 @@
|
||||
iterator.remove();
|
||||
connection.handleDisconnection();
|
||||
}
|
||||
@@ -201,6 +_,28 @@
|
||||
@@ -203,6 +_,28 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-17
@@ -656,7 +656,7 @@
|
||||
+ // CraftBukkit end
|
||||
int slot = packet.slot();
|
||||
if (Inventory.isHotbarSlot(slot) || slot == 40) {
|
||||
List<String> contents = Lists.newArrayList();
|
||||
List<String> contents = new ArrayList<>();
|
||||
@@ -1012,10 +_,14 @@
|
||||
}
|
||||
|
||||
@@ -735,7 +735,7 @@
|
||||
if (this.player.isSleeping()) {
|
||||
if (movedDist > 1.0) {
|
||||
this.teleport(this.player.getX(), this.player.getY(), this.player.getZ(), targetYRot, targetXRot);
|
||||
@@ -1149,28 +_,79 @@
|
||||
@@ -1149,32 +_,89 @@
|
||||
if (level.tickRateManager().runsNormally()) {
|
||||
this.receivedMovePacketCount++;
|
||||
int deltaPackets = this.receivedMovePacketCount - this.knownMovePacketCount;
|
||||
@@ -821,9 +821,6 @@
|
||||
}
|
||||
|
||||
boolean playerStandsOnSomething = this.player.verticalCollisionBelow;
|
||||
@@ -1179,6 +_,12 @@
|
||||
}
|
||||
|
||||
this.player.move(MoverType.PLAYER, new Vec3(xDist, yDist, zDist));
|
||||
+ this.player.onGround = isOnGround; // CraftBukkit - SPIGOT-5810, SPIGOT-5835, SPIGOT-6828: reset by this.player.move
|
||||
+ // Paper start - prevent position desync
|
||||
@@ -831,9 +828,9 @@
|
||||
+ return; // ... thanks Mojang for letting move calls teleport across dimensions.
|
||||
+ }
|
||||
+ // Paper end - prevent position desync
|
||||
double oyDist = yDist;
|
||||
xDist = targetX - this.player.getX();
|
||||
yDist = targetY - this.player.getY();
|
||||
if (isOnGround && !playerStandsOnSomething) {
|
||||
this.forceSendPlayerSupportBlocks();
|
||||
}
|
||||
@@ -1188,21 +_,88 @@
|
||||
|
||||
zDist = targetZ - this.player.getZ();
|
||||
@@ -2529,7 +2526,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -2250,27 +_,32 @@
|
||||
@@ -2250,16 +_,19 @@
|
||||
|
||||
private void resetPlayerChatState(final RemoteChatSession chatSession) {
|
||||
this.chatSession = chatSession;
|
||||
@@ -2550,12 +2547,7 @@
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleCustomPayload(final ServerboundCustomPayloadPacket packet) {
|
||||
+ super.handleCustomPayload(packet); // Paper
|
||||
}
|
||||
|
||||
@@ -2273,6 +_,7 @@
|
||||
@Override
|
||||
public void handleClientTickEnd(final ServerboundClientTickEndPacket packet) {
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.level());
|
||||
@@ -2563,7 +2555,7 @@
|
||||
if (!this.receivedMovementThisTick) {
|
||||
this.player.setKnownMovement(Vec3.ZERO);
|
||||
}
|
||||
@@ -2308,12 +_,23 @@
|
||||
@@ -2310,12 +_,23 @@
|
||||
}
|
||||
|
||||
public void tickClientLoadTimeout() {
|
||||
@@ -2589,7 +2581,7 @@
|
||||
this.clientLoadedTimeoutTimer = 0;
|
||||
}
|
||||
|
||||
@@ -2325,4 +_,80 @@
|
||||
@@ -2327,4 +_,80 @@
|
||||
this.waitingForRespawn = false;
|
||||
this.clientLoadedTimeoutTimer = 60;
|
||||
}
|
||||
|
||||
+9
-9
@@ -1,9 +1,9 @@
|
||||
--- a/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -14,9 +_,20 @@
|
||||
|
||||
@@ -16,9 +_,20 @@
|
||||
public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketListener {
|
||||
private static final Component IGNORE_STATUS_REASON = Component.translatable("disconnect.ignoring_status_request");
|
||||
private static final Component CONNECTION_REJECTED_REASON = Component.translatable("multiplayer.disconnect.rejected");
|
||||
+ // Spigot start
|
||||
+ private static final com.google.gson.Gson gson = new com.google.gson.Gson();
|
||||
+ static final java.util.regex.Pattern HOST_PATTERN = java.util.regex.Pattern.compile("[0-9a-f\\.:]{0,45}");
|
||||
@@ -21,17 +21,17 @@
|
||||
public ServerHandshakePacketListenerImpl(final MinecraftServer server, final Connection connection) {
|
||||
this.server = server;
|
||||
this.connection = connection;
|
||||
@@ -24,6 +_,7 @@
|
||||
@@ -26,6 +_,7 @@
|
||||
|
||||
@Override
|
||||
public void handleIntention(final ClientIntentionPacket packet) {
|
||||
+ this.connection.hostname = packet.hostName() + ":" + packet.port(); // CraftBukkit - set hostname
|
||||
switch (packet.intention()) {
|
||||
case LOGIN:
|
||||
this.beginLogin(packet, false);
|
||||
@@ -50,22 +_,119 @@
|
||||
default:
|
||||
throw new UnsupportedOperationException("Invalid intention " + packet.intention());
|
||||
ServerConnectionDetails details = ServerConnectionDetails.fromIntentPacket(packet);
|
||||
if (!this.server.acceptsConnection(this.connection, details)) {
|
||||
this.connection.disconnect(CONNECTION_REJECTED_REASON);
|
||||
@@ -57,22 +_,119 @@
|
||||
throw new UnsupportedOperationException("Invalid intention " + packet.intention());
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start - NetworkClient implementation
|
||||
|
||||
+70
-54
@@ -1,32 +1,36 @@
|
||||
--- a/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -45,9 +_,16 @@
|
||||
@@ -49,9 +_,16 @@
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
-public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, TickablePacketListener {
|
||||
+// CraftBukkit start
|
||||
+import org.bukkit.craftbukkit.entity.CraftPlayer;
|
||||
+import org.bukkit.craftbukkit.util.Waitable;
|
||||
+import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||
+import org.bukkit.event.player.PlayerPreLoginEvent;
|
||||
+
|
||||
public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, TickablePacketListener {
|
||||
+public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener, TickablePacketListener, net.minecraft.network.PacketProcessor.Handler { // CraftBukkit
|
||||
private static final AtomicInteger UNIQUE_THREAD_ID = new AtomicInteger(0);
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
+ private static final java.util.concurrent.ExecutorService authenticatorPool = java.util.concurrent.Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name("User Authenticator #", 0).uncaughtExceptionHandler(new DefaultUncaughtExceptionHandler(LOGGER)).factory()); // Paper - Virtual authenticator threads
|
||||
private static final int MAX_TICKS_BEFORE_LOGIN = 600;
|
||||
private static final String PROTOCOL_ERROR_MESSAGE = "Protocol error";
|
||||
private final byte[] challenge;
|
||||
private final MinecraftServer server;
|
||||
@@ -55,10 +_,14 @@
|
||||
@@ -60,12 +_,16 @@
|
||||
private final ServerActivityMonitor serverActivityMonitor;
|
||||
public volatile ServerLoginPacketListenerImpl.State state = ServerLoginPacketListenerImpl.State.HELLO;
|
||||
private int tick;
|
||||
- private @Nullable String requestedUsername;
|
||||
- private @Nullable GameProfile resolvedUserProfile;
|
||||
+ public @Nullable String requestedUsername; // Paper - public
|
||||
public @Nullable GameProfile authenticatedProfile;
|
||||
+ public @Nullable GameProfile resolvedUserProfile; // Paper - public
|
||||
private final String serverId = "";
|
||||
- private final boolean transferred;
|
||||
+ public final boolean transferred; // Paper
|
||||
+ public final boolean transferred; // Paper - public
|
||||
private final OptionalInt requestedCompressionThreshold;
|
||||
private @Nullable SecretKey pendingSecretKey;
|
||||
+ public boolean iKnowThisMayNotBeTheBestIdeaButPleaseDisableUsernameValidation = false; // Paper - username validation overriding
|
||||
+ private int velocityLoginMessageId = -1; // Paper - Add Velocity IP Forwarding Support
|
||||
+ public java.util.@Nullable UUID requestedUuid; // Paper
|
||||
@@ -34,10 +38,10 @@
|
||||
|
||||
public ServerLoginPacketListenerImpl(final MinecraftServer minecraftserver, final Connection connection, final boolean transferred) {
|
||||
this.server = minecraftserver;
|
||||
@@ -66,10 +_,19 @@
|
||||
this.serverActivityMonitor = this.server.getServerActivityMonitor();
|
||||
this.challenge = Ints.toByteArray(RandomSource.create().nextInt());
|
||||
this.transferred = transferred;
|
||||
@@ -77,10 +_,19 @@
|
||||
this.requestedCompressionThreshold = !connection.isMemoryConnection() && compressionThreshold >= 0
|
||||
? OptionalInt.of(compressionThreshold)
|
||||
: OptionalInt.empty();
|
||||
+ this.paperLoginConnection = new io.papermc.paper.connection.PaperPlayerLoginConnection(this); // Paper
|
||||
}
|
||||
|
||||
@@ -52,10 +56,10 @@
|
||||
+ // Paper end - login cookie API
|
||||
+
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
|
||||
this.verifyLoginAndFinishConnectionSetup(Objects.requireNonNull(this.authenticatedProfile));
|
||||
this.verifyLoginAndFinishConnectionSetup(Objects.requireNonNull(this.resolvedUserProfile));
|
||||
}
|
||||
@@ -79,16 +_,39 @@
|
||||
this.finishLoginAndWaitForClient(this.authenticatedProfile);
|
||||
@@ -90,16 +_,39 @@
|
||||
this.finishLoginAndWaitForClient(this.resolvedUserProfile);
|
||||
}
|
||||
|
||||
+ // Paper start - login cookie API
|
||||
@@ -85,7 +89,7 @@
|
||||
+ public void disconnectAsync(Component reason) {
|
||||
+ try {
|
||||
+ LOGGER.info("Disconnecting {}: {}", this.getUserName(), reason.getString());
|
||||
+ this.connection.send(new ClientboundLoginDisconnectPacket(reason), PacketSendListener.thenRun(() -> this.connection.disconnect(reason)));
|
||||
+ this.connection.send(new ClientboundLoginDisconnectPacket(reason), net.minecraft.network.PacketSendListener.thenRun(() -> this.connection.disconnect(reason)));
|
||||
+ this.connection.handleConnectionDisconnectOnNextTick = true;
|
||||
+ } catch (Exception var3) {
|
||||
+ LOGGER.error("Error whilst disconnecting player", (Throwable)var3);
|
||||
@@ -95,7 +99,7 @@
|
||||
public void disconnect(final Component component) {
|
||||
try {
|
||||
LOGGER.info("Disconnecting {}: {}", this.getUserName(), component.getString());
|
||||
@@ -116,7 +_,14 @@
|
||||
@@ -127,7 +_,14 @@
|
||||
@Override
|
||||
public void handleHello(final ServerboundHelloPacket packet) {
|
||||
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.HELLO, "Unexpected hello packet");
|
||||
@@ -111,11 +115,11 @@
|
||||
this.requestedUsername = packet.name();
|
||||
GameProfile singleplayerProfile = this.server.getSingleplayerProfile();
|
||||
if (singleplayerProfile != null && this.requestedUsername.equalsIgnoreCase(singleplayerProfile.name())) {
|
||||
@@ -126,7 +_,30 @@
|
||||
@@ -137,7 +_,30 @@
|
||||
this.state = ServerLoginPacketListenerImpl.State.KEY;
|
||||
this.connection.send(new ClientboundHelloPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
|
||||
this.connection.send(new ClientboundKeyPacket("", this.server.getKeyPair().getPublic().getEncoded(), this.challenge, true));
|
||||
} else {
|
||||
- this.startClientVerification(UUIDUtil.createOfflineProfile(this.requestedUsername));
|
||||
- this.startOfflineClientVerification(UUIDUtil.createOfflineProfile(this.requestedUsername));
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().proxies.velocity.enabled) {
|
||||
+ this.velocityLoginMessageId = java.util.concurrent.ThreadLocalRandom.current().nextInt();
|
||||
@@ -133,7 +137,7 @@
|
||||
+
|
||||
+ gameprofile = ServerLoginPacketListenerImpl.this.callPlayerPreLoginEvents(gameprofile); // Paper - Add more fields to AsyncPlayerPreLoginEvent
|
||||
+ ServerLoginPacketListenerImpl.LOGGER.info("UUID of player {} is {}", gameprofile.name(), gameprofile.id());
|
||||
+ ServerLoginPacketListenerImpl.this.startClientVerification(gameprofile);
|
||||
+ ServerLoginPacketListenerImpl.this.startOfflineClientVerification(gameprofile);
|
||||
+ } catch (Exception ex) {
|
||||
+ ServerLoginPacketListenerImpl.this.disconnect("Failed to verify username!");
|
||||
+ ServerLoginPacketListenerImpl.this.server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + ServerLoginPacketListenerImpl.this.requestedUsername, ex);
|
||||
@@ -143,7 +147,7 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,19 +_,23 @@
|
||||
@@ -149,15 +_,15 @@
|
||||
|
||||
private void verifyLoginAndFinishConnectionSetup(final GameProfile profile) {
|
||||
PlayerList playerList = this.server.getPlayerList();
|
||||
@@ -153,21 +157,8 @@
|
||||
- this.disconnect(error);
|
||||
+ this.disconnectAsync(error); // Paper
|
||||
} else {
|
||||
if (this.server.getCompressionThreshold() >= 0 && !this.connection.isMemoryConnection()) {
|
||||
- this.connection
|
||||
- .send(
|
||||
- new ClientboundLoginCompressionPacket(this.server.getCompressionThreshold()),
|
||||
- PacketSendListener.thenRun(() -> this.connection.setupCompression(this.server.getCompressionThreshold(), true))
|
||||
- );
|
||||
+ // Paper start - Keep compression packet write and setup in the same Netty task
|
||||
+ final int compressionThreshold = this.server.getCompressionThreshold();
|
||||
+ this.connection.sendPacketAndScheduleNettyTask(
|
||||
+ new ClientboundLoginCompressionPacket(compressionThreshold), true,
|
||||
+ () -> {
|
||||
+ this.connection.setupCompression(compressionThreshold, true);
|
||||
+ }
|
||||
+ );
|
||||
+ // Paper end - Keep compression packet write and setup in the same Netty task
|
||||
if (this.requestedCompressionThreshold.isPresent()) {
|
||||
this.connection.send(new ClientboundSetupCompressionPacket(this.requestedCompressionThreshold.getAsInt()));
|
||||
}
|
||||
|
||||
- boolean waitForDisconnection = playerList.disconnectAllPlayersWithProfile(profile.id());
|
||||
@@ -175,15 +166,15 @@
|
||||
if (waitForDisconnection) {
|
||||
this.state = ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT;
|
||||
} else {
|
||||
@@ -162,6 +_,7 @@
|
||||
private void finishLoginAndWaitForClient(final GameProfile gameProfile) {
|
||||
@@ -170,6 +_,7 @@
|
||||
byte optionsToEnable = this.loginFinishedPacketEnableOptions();
|
||||
this.state = ServerLoginPacketListenerImpl.State.PROTOCOL_SWITCHING;
|
||||
this.connection.send(new ClientboundLoginFinishedPacket(gameProfile, this.server.getConnection().getSessionId()));
|
||||
this.connection.send(new ClientboundLoginFinishedPacket(gameProfile, this.server.getConnection().getSessionId(), optionsToEnable));
|
||||
+ this.server.services().paper().filledProfileCache().add(gameProfile); // Paper - update profile cache
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -185,7 +_,8 @@
|
||||
private @ConnectionOptionsPacket.Flags byte loginFinishedPacketEnableOptions() {
|
||||
@@ -196,7 +_,8 @@
|
||||
throw new IllegalStateException("Protocol error", e);
|
||||
}
|
||||
|
||||
@@ -193,7 +184,7 @@
|
||||
@Override
|
||||
public void run() {
|
||||
String name = Objects.requireNonNull(ServerLoginPacketListenerImpl.this.requestedUsername, "Player name not initialized");
|
||||
@@ -197,12 +_,18 @@
|
||||
@@ -208,12 +_,18 @@
|
||||
.hasJoinedServer(name, digest, this.getAddress());
|
||||
if (result != null) {
|
||||
GameProfile profile = result.profile();
|
||||
@@ -205,20 +196,20 @@
|
||||
+ // CraftBukkit end
|
||||
ServerLoginPacketListenerImpl.LOGGER.info("UUID of player {} is {}", profile.name(), profile.id());
|
||||
ServerLoginPacketListenerImpl.this.serverActivityMonitor.reportLoginActivity();
|
||||
ServerLoginPacketListenerImpl.this.startClientVerification(profile);
|
||||
ServerLoginPacketListenerImpl.this.applyConnectionEncryption(profile, secretKey);
|
||||
} else if (ServerLoginPacketListenerImpl.this.server.isSingleplayer()) {
|
||||
ServerLoginPacketListenerImpl.LOGGER.warn("Failed to verify username but will let them in anyway!");
|
||||
- ServerLoginPacketListenerImpl.this.startClientVerification(UUIDUtil.createOfflineProfile(name));
|
||||
+ ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(name)); // Spigot
|
||||
- ServerLoginPacketListenerImpl.this.applyConnectionEncryption(UUIDUtil.createOfflineProfile(name), secretKey);
|
||||
+ ServerLoginPacketListenerImpl.this.applyConnectionEncryption(ServerLoginPacketListenerImpl.this.createOfflineProfile(name), secretKey); // Spigot
|
||||
} else {
|
||||
ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.unverified_username"));
|
||||
ServerLoginPacketListenerImpl.LOGGER.error("Username '{}' tried to join with an invalid session", name);
|
||||
@@ -210,11 +_,16 @@
|
||||
@@ -221,11 +_,16 @@
|
||||
} catch (AuthenticationUnavailableException ignored) {
|
||||
if (ServerLoginPacketListenerImpl.this.server.isSingleplayer()) {
|
||||
ServerLoginPacketListenerImpl.LOGGER.warn("Authentication servers are down but will let them in anyway!");
|
||||
- ServerLoginPacketListenerImpl.this.startClientVerification(UUIDUtil.createOfflineProfile(name));
|
||||
+ ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(name)); // Spigot
|
||||
- ServerLoginPacketListenerImpl.this.applyConnectionEncryption(UUIDUtil.createOfflineProfile(name), secretKey);
|
||||
+ ServerLoginPacketListenerImpl.this.applyConnectionEncryption(ServerLoginPacketListenerImpl.this.createOfflineProfile(name), secretKey); // Spigot
|
||||
} else {
|
||||
- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down"));
|
||||
+ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper - Configurable kick message
|
||||
@@ -232,7 +223,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,18 +_,123 @@
|
||||
@@ -235,10 +_,60 @@
|
||||
? inetSocketAddress.getAddress()
|
||||
: null;
|
||||
}
|
||||
@@ -295,6 +286,10 @@
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
|
||||
private void applyConnectionEncryption(final GameProfile authenticatedGameProfile, final SecretKey secretKey) {
|
||||
this.resolvedUserProfile = authenticatedGameProfile;
|
||||
@@ -279,12 +_,71 @@
|
||||
|
||||
@Override
|
||||
public void handleCustomQueryPacket(final ServerboundCustomQueryAnswerPacket packet) {
|
||||
+ // Paper start - Add Velocity IP Forwarding Support
|
||||
@@ -333,19 +328,19 @@
|
||||
+ }
|
||||
+ this.connection.address = new java.net.InetSocketAddress(com.destroystokyo.paper.proxy.VelocityProxy.readAddress(buf), port);
|
||||
+
|
||||
+ this.authenticatedProfile = com.destroystokyo.paper.proxy.VelocityProxy.createProfile(buf);
|
||||
+ this.resolvedUserProfile = com.destroystokyo.paper.proxy.VelocityProxy.createProfile(buf);
|
||||
+
|
||||
+ //TODO Update handling for lazy sessions, might not even have to do anything?
|
||||
+
|
||||
+ // Proceed with login
|
||||
+ authenticatorPool.execute(() -> {
|
||||
+ try {
|
||||
+ final GameProfile gameprofile = this.callPlayerPreLoginEvents(this.authenticatedProfile);
|
||||
+ final GameProfile gameprofile = this.callPlayerPreLoginEvents(this.resolvedUserProfile);
|
||||
+ ServerLoginPacketListenerImpl.LOGGER.info("UUID of player {} is {}", gameprofile.name(), gameprofile.id());
|
||||
+ ServerLoginPacketListenerImpl.this.startClientVerification(gameprofile);
|
||||
+ ServerLoginPacketListenerImpl.this.startOfflineClientVerification(gameprofile);
|
||||
+ } catch (Exception ex) {
|
||||
+ disconnect("Failed to verify username!");
|
||||
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + this.authenticatedProfile.name(), ex);
|
||||
+ server.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + this.resolvedUserProfile.name(), ex);
|
||||
+ }
|
||||
+ });
|
||||
+ return;
|
||||
@@ -356,11 +351,32 @@
|
||||
|
||||
@Override
|
||||
public void handleLoginAcknowledgement(final ServerboundLoginAcknowledgedPacket packet) {
|
||||
- this.applyConnectionOptions(this.loginFinishedPacketEnableOptions());
|
||||
+ // Paper start - apply connection options on the network thread before rescheduling
|
||||
+ if (!this.server.packetProcessor().isSameThread()) {
|
||||
+ this.applyConnectionOptions(this.loginFinishedPacketEnableOptions());
|
||||
+ }
|
||||
+ // Paper end - apply connection options on the network thread before rescheduling
|
||||
+ net.minecraft.network.protocol.PacketUtils.ensureRunningOnSameThread(packet, this, this.server.packetProcessor()); // CraftBukkit
|
||||
Validate.validState(this.state == ServerLoginPacketListenerImpl.State.PROTOCOL_SWITCHING, "Unexpected login acknowledgement packet");
|
||||
this.connection.setupOutboundProtocol(ConfigurationProtocols.CLIENTBOUND);
|
||||
CommonListenerCookie cookie = CommonListenerCookie.createInitial(Objects.requireNonNull(this.authenticatedProfile), this.transferred);
|
||||
@@ -252,8 +_,31 @@
|
||||
CommonListenerCookie cookie = CommonListenerCookie.createInitial(Objects.requireNonNull(this.resolvedUserProfile), this.transferred);
|
||||
@@ -294,6 +_,14 @@
|
||||
this.state = ServerLoginPacketListenerImpl.State.ACCEPTED;
|
||||
}
|
||||
|
||||
+ // CraftBukkit start
|
||||
+ @Override
|
||||
+ public void onPacketError(final net.minecraft.network.protocol.Packet<?> packet, final Exception e) {
|
||||
+ LOGGER.error("Failed to handle packet {}, suppressing error", packet, e);
|
||||
+ this.disconnect(Connection.PACKET_HANDLER_ERROR_DISCONNECT_REASON);
|
||||
+ }
|
||||
+ // CraftBukkit end
|
||||
+
|
||||
@Override
|
||||
public void fillListenerSpecificCrashDetails(final CrashReport report, final CrashReportCategory connectionDetails) {
|
||||
connectionDetails.setDetail("Login phase", () -> this.state.toString());
|
||||
@@ -301,8 +_,31 @@
|
||||
|
||||
@Override
|
||||
public void handleCookieResponse(final ServerboundCookieResponsePacket packet) {
|
||||
|
||||
+10
-10
@@ -1,6 +1,6 @@
|
||||
--- a/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
+++ b/net/minecraft/server/players/CachedUserNameToIdResolver.java
|
||||
@@ -46,6 +_,10 @@
|
||||
@@ -47,6 +_,10 @@
|
||||
private final Gson gson = new GsonBuilder().create();
|
||||
private final File file;
|
||||
private final AtomicLong operationCount = new AtomicLong();
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
public CachedUserNameToIdResolver(final GameProfileRepository profileRepository, final File file) {
|
||||
this.profileRepository = profileRepository;
|
||||
@@ -54,10 +_,12 @@
|
||||
@@ -55,10 +_,12 @@
|
||||
}
|
||||
|
||||
private void safeAdd(final CachedUserNameToIdResolver.GameProfileInfo profileInfo) {
|
||||
@@ -24,7 +24,7 @@
|
||||
}
|
||||
|
||||
private Optional<NameAndId> lookupGameProfile(final GameProfileRepository profileRepository, final String name) {
|
||||
@@ -65,12 +_,14 @@
|
||||
@@ -66,12 +_,14 @@
|
||||
return this.createUnknownProfile(name);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -90,7 +_,7 @@
|
||||
@@ -91,7 +_,7 @@
|
||||
Date expirationDate = c.getTime();
|
||||
CachedUserNameToIdResolver.GameProfileInfo profileInfo = new CachedUserNameToIdResolver.GameProfileInfo(profile, expirationDate);
|
||||
this.safeAdd(profileInfo);
|
||||
@@ -50,7 +50,7 @@
|
||||
return profileInfo;
|
||||
}
|
||||
|
||||
@@ -98,9 +_,24 @@
|
||||
@@ -99,9 +_,24 @@
|
||||
return this.operationCount.incrementAndGet();
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
CachedUserNameToIdResolver.GameProfileInfo profileInfo = this.profilesByName.get(userName);
|
||||
boolean needsSave = false;
|
||||
if (profileInfo != null && new Date().getTime() >= profileInfo.expirationDate.getTime()) {
|
||||
@@ -114,8 +_,13 @@
|
||||
@@ -115,8 +_,13 @@
|
||||
if (profileInfo != null) {
|
||||
profileInfo.setLastAccess(this.getNextOperation());
|
||||
result = Optional.of(profileInfo.nameAndId());
|
||||
@@ -90,7 +90,7 @@
|
||||
if (profile.isPresent()) {
|
||||
result = Optional.of(this.addInternal(profile.get()).nameAndId());
|
||||
needsSave = false;
|
||||
@@ -124,15 +_,17 @@
|
||||
@@ -125,15 +_,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@
|
||||
CachedUserNameToIdResolver.GameProfileInfo profileInfo = this.profilesByUUID.get(id);
|
||||
if (profileInfo == null) {
|
||||
return Optional.empty();
|
||||
@@ -140,6 +_,7 @@
|
||||
@@ -141,6 +_,7 @@
|
||||
|
||||
profileInfo.setLastAccess(this.getNextOperation());
|
||||
return Optional.of(profileInfo.nameAndId());
|
||||
@@ -118,7 +118,7 @@
|
||||
}
|
||||
|
||||
private static DateFormat createDateFormat() {
|
||||
@@ -158,6 +_,11 @@
|
||||
@@ -159,6 +_,11 @@
|
||||
DateFormat dateFormat = createDateFormat();
|
||||
entryList.forEach(element -> readGameProfile(element, dateFormat).ifPresent(result::add));
|
||||
} catch (FileNotFoundException var7) {
|
||||
@@ -130,7 +130,7 @@
|
||||
} catch (IOException | JsonParseException e) {
|
||||
LOGGER.warn("Failed to load profile cache {}", this.file, e);
|
||||
}
|
||||
@@ -167,23 +_,51 @@
|
||||
@@ -168,23 +_,51 @@
|
||||
|
||||
@Override
|
||||
public void save() {
|
||||
|
||||
Loaded 100 of 322 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user