Last per file patches

This commit is contained in:
Bjarne Koll
2025-05-31 14:44:19 +02:00
parent 4fe0ac240b
commit 19a36413c7
3 changed files with 451 additions and 464 deletions

View File

@@ -1,150 +0,0 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
index b7965fd610b90f5674aae3571ab9a35e29d3d4f5..bb8b5ca9044ecb33687e7f20cfb0acbf55f887c7 100644
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
@@ -73,6 +73,10 @@ public class StructureTemplate {
public final List<StructureTemplate.StructureEntityInfo> entityInfoList = Lists.newArrayList();
private Vec3i size = Vec3i.ZERO;
private String author = "?";
+ // CraftBukkit start - data containers
+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
+ public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(StructureTemplate.DATA_TYPE_REGISTRY);
+ // CraftBukkit end
public Vec3i getSize() {
return this.size;
@@ -247,6 +251,19 @@ public class StructureTemplate {
if (this.palettes.isEmpty()) {
return false;
} else {
+ // CraftBukkit start
+ // We only want the TransformerGeneratorAccess at certain locations because in here are many "block update" calls that shouldn't be transformed
+ ServerLevelAccessor wrappedAccess = serverLevel;
+ org.bukkit.craftbukkit.util.CraftStructureTransformer structureTransformer = null;
+ if (wrappedAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ serverLevel = transformerAccess.getDelegate();
+ structureTransformer = transformerAccess.getStructureTransformer();
+ // The structureTransformer is not needed if we can not transform blocks therefore we can save a little bit of performance doing this
+ if (structureTransformer != null && !structureTransformer.canTransformBlocks()) {
+ structureTransformer = null;
+ }
+ }
+ // CraftBukkit end
List<StructureTemplate.StructureBlockInfo> list = settings.getRandomPalette(this.palettes, offset).blocks();
if ((!list.isEmpty() || !settings.isIgnoreEntities() && !this.entityInfoList.isEmpty())
&& this.size.getX() >= 1
@@ -272,6 +289,21 @@ public class StructureTemplate {
serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820);
}
+ // CraftBukkit start
+ if (structureTransformer != null) {
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null);
+ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> entityState) {
+ entityState.loadData(structureBlockInfo.nbt);
+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable<?> craftLootable) {
+ craftLootable.setSeed(random.nextLong());
+ }
+ }
+ craftBlockState = structureTransformer.transformCraftState(craftBlockState);
+ blockState = craftBlockState.getHandle();
+ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null));
+ }
+ // CraftBukkit end
+
if (serverLevel.setBlock(blockPos, blockState, flags)) {
i = Math.min(i, blockPos.getX());
i1 = Math.min(i1, blockPos.getY());
@@ -283,7 +315,7 @@ public class StructureTemplate {
if (structureBlockInfo.nbt != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity != null) {
- if (blockEntity instanceof RandomizableContainer) {
+ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above
structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong());
}
@@ -366,7 +398,11 @@ public class StructureTemplate {
if (pair1.getSecond() != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4);
if (blockEntity != null) {
- blockEntity.setChanged();
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) {
+ blockEntity.setChanged();
+ }
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
}
}
}
@@ -374,7 +410,7 @@ public class StructureTemplate {
if (!settings.isIgnoreEntities()) {
this.placeEntities(
- serverLevel,
+ wrappedAccess, // CraftBukkit
offset,
settings.getMirror(),
settings.getRotation(),
@@ -488,14 +524,17 @@ public class StructureTemplate {
);
}
}
+
}
private static Optional<Entity> createEntityIgnoreException(ServerLevelAccessor level, CompoundTag tag) {
- try {
- return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE);
- } catch (Exception var3) {
- return Optional.empty();
- }
+ // CraftBukkit start
+ // try {
+ return EntityType.create(tag, level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation
+ // } catch (Exception var3) {
+ // return Optional.empty();
+ // }
+ // CraftBukkit end
}
public Vec3i getSize(Rotation rotation) {
@@ -688,6 +727,11 @@ public class StructureTemplate {
tag.put("entities", listTag3);
tag.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ()));
+ // CraftBukkit start - PDC
+ if (!this.persistentDataContainer.isEmpty()) {
+ tag.put("BukkitValues", this.persistentDataContainer.toTagCompound());
+ }
+ // CraftBukkit end
return NbtUtils.addCurrentDataVersion(tag);
}
@@ -718,6 +762,11 @@ public class StructureTemplate {
.ifPresent(compoundTag1 -> this.entityInfoList.add(new StructureTemplate.StructureEntityInfo(vec3, blockPos, compoundTag1)));
}
);
+ // CraftBukkit start - PDC
+ if (tag.get("BukkitValues") instanceof CompoundTag compoundTag) {
+ this.persistentDataContainer.putAll(compoundTag);
+ }
+ // CraftBukkit end
}
private void loadPalette(HolderGetter<Block> blockGetter, ListTag paletteTag, ListTag blocksTag) {
@@ -817,7 +866,7 @@ public class StructureTemplate {
public static final class Palette {
private final List<StructureTemplate.StructureBlockInfo> blocks;
- private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newHashMap();
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads
@Nullable
private List<StructureTemplate.JigsawBlockInfo> cachedJigsaws;

View File

@@ -1,14 +1,6 @@
From 09671551669244ef4f259d8b27547e463d6795d4 Mon Sep 17 00:00:00 2001
From: File <noreply+automated@papermc.io>
Date: Sun, 20 Apr 1997 15:37:42 +0200
Subject: [PATCH] paper File Patches
diff --git a/net/minecraft/server/players/PlayerList.java b/net/minecraft/server/players/PlayerList.java
index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6a3dc0dd0 100644
--- a/net/minecraft/server/players/PlayerList.java --- a/net/minecraft/server/players/PlayerList.java
+++ b/net/minecraft/server/players/PlayerList.java +++ b/net/minecraft/server/players/PlayerList.java
@@ -112,14 +112,16 @@ public abstract class PlayerList { @@ -111,14 +_,16 @@
private static final int SEND_PLAYER_INFO_INTERVAL = 600; private static final int SEND_PLAYER_INFO_INTERVAL = 600;
private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z"); private static final SimpleDateFormat BAN_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
private final MinecraftServer server; private final MinecraftServer server;
@@ -28,7 +20,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
public final PlayerDataStorage playerIo; public final PlayerDataStorage playerIo;
private boolean doWhiteList; private boolean doWhiteList;
private final LayeredRegistryAccess<RegistryLayer> registries; private final LayeredRegistryAccess<RegistryLayer> registries;
@@ -130,14 +132,26 @@ public abstract class PlayerList { @@ -129,14 +_,26 @@
private static final boolean ALLOW_LOGOUTIVATOR = false; private static final boolean ALLOW_LOGOUTIVATOR = false;
private int sendAllPlayerInfoIn; private int sendAllPlayerInfoIn;
@@ -55,24 +47,26 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
GameProfile gameProfile = player.getGameProfile(); GameProfile gameProfile = player.getGameProfile();
GameProfileCache profileCache = this.server.getProfileCache(); GameProfileCache profileCache = this.server.getProfileCache();
String string; String string;
@@ -150,30 +164,94 @@ public abstract class PlayerList { @@ -149,18 +_,69 @@
} }
Optional<CompoundTag> optional = this.load(player); try (ProblemReporter.ScopedCollector scopedCollector = new ProblemReporter.ScopedCollector(player.problemPath(), LOGGER)) {
- ResourceKey<Level> resourceKey = optional.<ResourceKey<Level>>flatMap( - Optional<ValueInput> optional1 = this.load(player, scopedCollector);
- compoundTag -> DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))).resultOrPartial(LOGGER::error) - ResourceKey<Level> resourceKey = optional1.<ResourceKey<Level>>flatMap(valueInput -> valueInput.read("Dimension", Level.RESOURCE_KEY_CODEC))
- .orElse(Level.OVERWORLD);
+ Optional<ValueInput> optional1 = this.load(player, scopedCollector); final Optional<ValueInput> loadedPlayerData = optional1; // Paper - OBFHELPER
+ // CraftBukkit start - Better rename detection + // CraftBukkit start - Better rename detection
+ if (optional.isPresent()) { + if (loadedPlayerData.isPresent()) {
+ string = optional.flatMap(t -> t.getCompound("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string); + string = loadedPlayerData.flatMap(t -> t.child("bukkit")).flatMap(t -> t.getString("lastKnownName")).orElse(string);
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+ // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found + // Paper start - move logic in Entity to here, to use bukkit supplied world UUID & reset to main world spawn if no valid world is found
+ ResourceKey<Level> resourceKey = null; // Paper + ResourceKey<Level> resourceKey = null; // Paper
+ boolean[] invalidPlayerWorld = {false}; + boolean[] invalidPlayerWorld = {false};
+ bukkitData: if (optional.isPresent()) { + bukkitData: if (loadedPlayerData.isPresent()) {
+ // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds + // The main way for bukkit worlds to store the world is the world UUID despite mojang adding custom worlds
+ final org.bukkit.World bWorld; + final org.bukkit.World bWorld;
+ final CompoundTag playerData = optional.get(); + final ValueInput playerData = loadedPlayerData.get();
+ // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first. + // TODO maybe convert this to a codec and use compoundTag#read, we need silent variants of that method first.
+ final Optional<Long> worldUUIDMost = playerData.getLong("WorldUUIDMost"); + final Optional<Long> worldUUIDMost = playerData.getLong("WorldUUIDMost");
+ final Optional<Long> worldUUIDLeast = playerData.getLong("WorldUUIDLeast"); + final Optional<Long> worldUUIDLeast = playerData.getLong("WorldUUIDLeast");
@@ -93,15 +87,13 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ } + }
+ if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data + if (resourceKey == null) { // only run the vanilla logic if we haven't found a world from the bukkit data
+ // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers + // Below is the vanilla way of getting the dimension, this is for migration from vanilla servers
+ resourceKey = optional.<ResourceKey<Level>>flatMap( + resourceKey = loadedPlayerData.<ResourceKey<Level>>flatMap(
+ compoundTag -> { + compoundTag -> {
+ com.mojang.serialization.DataResult<ResourceKey<Level>> dataResult = DimensionType.parseLegacy(new Dynamic<>(NbtOps.INSTANCE, compoundTag.get("Dimension"))); + Optional<ResourceKey<Level>> result = compoundTag.read("Dimension", Level.RESOURCE_KEY_CODEC);
+ final Optional<ResourceKey<Level>> result = dataResult.resultOrPartial(LOGGER::error);
+ invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found + invalidPlayerWorld[0] = result.isEmpty(); // reset to main world spawn if no valid world is found
+ return result; + return result;
+ } + }
) + )
- .orElse(Level.OVERWORLD);
+ .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed + .orElse(Level.OVERWORLD); // revert to vanilla default main world, this isn't an "invalid world" since no player data existed
+ } + }
+ // Paper end + // Paper end
@@ -116,16 +108,21 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
+ // Paper start - Entity#getEntitySpawnReason + // Paper start - Entity#getEntitySpawnReason
+ if (optional.isEmpty()) { + if (loadedPlayerData.isEmpty()) {
+ player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login + player.spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT; // set Player SpawnReason to DEFAULT on first login
+ // Paper start - reset to main world spawn if first spawn or invalid world + // Paper start - reset to main world spawn if first spawn or invalid world
+ } + }
+ if (optional.isEmpty() || invalidPlayerWorld[0]) { + if (loadedPlayerData.isEmpty() || invalidPlayerWorld[0]) {
+ // Paper end - reset to main world spawn if first spawn or invalid world + // Paper end - reset to main world spawn if first spawn or invalid world
+ player.snapTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored + player.snapTo(player.adjustSpawnLocation(serverLevel, serverLevel.getSharedSpawnPos()).getBottomCenter(), serverLevel.getSharedSpawnAngle(), 0.0F); // Paper - MC-200092 - fix first spawn pos yaw being ignored
+ } + }
+ // Paper end - Entity#getEntitySpawnReason + // Paper end - Entity#getEntitySpawnReason
player.setServerLevel(serverLevel); player.setServerLevel(serverLevel);
if (optional1.isEmpty()) {
player.snapTo(
@@ -170,15 +_,29 @@
serverLevel.waitForChunkAndEntities(player.chunkPosition(), 1);
String loggableAddress = connection.getLoggableAddress(this.server.logIPs()); String loggableAddress = connection.getLoggableAddress(this.server.logIPs());
- LOGGER.info( - LOGGER.info(
- "{}[{}] logged in with entity id {} at ({}, {}, {})", - "{}[{}] logged in with entity id {} at ({}, {}, {})",
@@ -160,9 +157,9 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ // player.getZ() + // player.getZ()
+ // ); + // );
LevelData levelData = serverLevel.getLevelData(); LevelData levelData = serverLevel.getLevelData();
player.loadGameTypes(optional.orElse(null)); player.loadGameTypes(optional1.orElse(null));
ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie); ServerGamePacketListenerImpl serverGamePacketListenerImpl = new ServerGamePacketListenerImpl(this.server, connection, player, cookie);
@@ -191,8 +269,8 @@ public abstract class PlayerList { @@ -196,8 +_,8 @@
levelData.isHardcore(), levelData.isHardcore(),
this.server.levelKeys(), this.server.levelKeys(),
this.getMaxPlayers(), this.getMaxPlayers(),
@@ -173,7 +170,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
_boolean1, _boolean1,
!_boolean, !_boolean,
_boolean2, _boolean2,
@@ -200,6 +278,7 @@ public abstract class PlayerList { @@ -205,6 +_,7 @@
this.server.enforceSecureProfile() this.server.enforceSecureProfile()
) )
); );
@@ -181,7 +178,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked())); serverGamePacketListenerImpl.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities())); serverGamePacketListenerImpl.send(new ClientboundPlayerAbilitiesPacket(player.getAbilities()));
serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); serverGamePacketListenerImpl.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
@@ -219,26 +298,119 @@ public abstract class PlayerList { @@ -224,26 +_,119 @@
mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string); mutableComponent = Component.translatable("multiplayer.player.joined.renamed", player.getDisplayName(), string);
} }
@@ -210,9 +207,9 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
- this.sendActivePlayerEffects(player); - this.sendActivePlayerEffects(player);
+ this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player); + this.server.getCustomBossEvents().onPlayerConnect(player); // see commented out section below serverLevel.addPlayerJoin(player);
+ // Paper end - Fire PlayerJoinEvent when Player is actually ready + // Paper end - Fire PlayerJoinEvent when Player is actually ready
optional.ifPresent(compoundTag -> { optional1.ifPresent(valueInput -> {
player.loadAndSpawnEnderPearls(compoundTag); player.loadAndSpawnEnderPearls(valueInput);
player.loadAndSpawnParentVehicle(compoundTag); player.loadAndSpawnParentVehicle(valueInput);
}); });
+ // CraftBukkit start + // CraftBukkit start
+ org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity(); + org.bukkit.craftbukkit.entity.CraftPlayer bukkitPlayer = player.getBukkitEntity();
@@ -280,7 +277,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ this.server.getCustomBossEvents().onPlayerConnect(player); + this.server.getCustomBossEvents().onPlayerConnect(player);
+ } + }
+ +
+ serverLevel = player.serverLevel(); // CraftBukkit - Update in case join event changed it + serverLevel = player.level(); // CraftBukkit - Update in case join event changed it
+ // CraftBukkit end + // CraftBukkit end
+ this.sendActivePlayerEffects(player); + this.sendActivePlayerEffects(player);
+ // Paper - move loading pearls / parent vehicle up + // Paper - move loading pearls / parent vehicle up
@@ -305,9 +302,9 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ } + }
+ // Paper end - Send empty chunk + // Paper end - Send empty chunk
} }
}
public void updateEntireScoreboard(ServerScoreboard scoreboard, ServerPlayer player) { @@ -267,30 +_,31 @@
@@ -261,30 +433,31 @@ public abstract class PlayerList {
} }
public void addWorldborderListener(ServerLevel level) { public void addWorldborderListener(ServerLevel level) {
@@ -344,7 +341,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
@Override @Override
@@ -312,56 +485,156 @@ public abstract class PlayerList { @@ -319,56 +_,156 @@
} }
protected void save(ServerPlayer player) { protected void save(ServerPlayer player) {
@@ -370,7 +367,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ } + }
+ public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) { + public @Nullable net.kyori.adventure.text.Component remove(ServerPlayer player, net.kyori.adventure.text.Component leaveMessage) {
+ // Paper end - Fix kick event leave message not being sent + // Paper end - Fix kick event leave message not being sent
ServerLevel serverLevel = player.serverLevel(); ServerLevel serverLevel = player.level();
player.awardStat(Stats.LEAVE_GAME); player.awardStat(Stats.LEAVE_GAME);
+ // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it + // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
+ // See SPIGOT-5799, SPIGOT-6145 + // See SPIGOT-5799, SPIGOT-6145
@@ -431,7 +428,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) { + if (!thrownEnderpearl.level().paperConfig().misc.legacyEnderPearlBehavior) {
+ thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause + thrownEnderpearl.setRemoved(Entity.RemovalReason.UNLOADED_WITH_PLAYER, org.bukkit.event.entity.EntityRemoveEvent.Cause.PLAYER_QUIT); // CraftBukkit - add Bukkit remove cause
+ } else { + } else {
+ thrownEnderpearl.cachedOwner = null; + thrownEnderpearl.setOwner(null);
+ } + }
+ // Paper end - Allow using old ender pearl behavior + // Paper end - Allow using old ender pearl behavior
} }
@@ -448,13 +445,15 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
this.playersByUUID.remove(uuid); this.playersByUUID.remove(uuid);
- this.stats.remove(uuid); - this.stats.remove(uuid);
- this.advancements.remove(uuid); - this.advancements.remove(uuid);
- }
-
- this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())));
+ // CraftBukkit start + // CraftBukkit start
+ // this.stats.remove(uuid); + // this.stats.remove(uuid);
+ // this.advancements.remove(uuid); + // this.advancements.remove(uuid);
+ // CraftBukkit end + // CraftBukkit end
} + }
+
- this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())));
+ // CraftBukkit start + // CraftBukkit start
+ // this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID()))); + // this.broadcastAll(new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())));
+ ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID())); + ClientboundPlayerInfoRemovePacket packet = new ClientboundPlayerInfoRemovePacket(List.of(player.getUUID()));
@@ -501,7 +500,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ // depending on the outcome. + // depending on the outcome.
+ SocketAddress socketAddress = loginlistener.connection.getRemoteAddress(); + SocketAddress socketAddress = loginlistener.connection.getRemoteAddress();
+ +
+ ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, ClientInformation.createDefault()); + ServerPlayer entity = new ServerPlayer(this.server, this.server.getLevel(Level.OVERWORLD), gameProfile, net.minecraft.server.level.ClientInformation.createDefault());
+ entity.transferCookieConnection = loginlistener; + entity.transferCookieConnection = loginlistener;
+ org.bukkit.entity.Player player = entity.getBukkitEntity(); + org.bukkit.entity.Player player = entity.getBukkitEntity();
+ org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress()); + org.bukkit.event.player.PlayerLoginEvent event = new org.bukkit.event.player.PlayerLoginEvent(player, loginlistener.connection.hostname, ((java.net.InetSocketAddress) socketAddress).getAddress(), ((java.net.InetSocketAddress) loginlistener.connection.channel.remoteAddress()).getAddress());
@@ -513,7 +512,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason()); MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned.reason", userBanListEntry.getReason());
if (userBanListEntry.getExpires() != null) { if (userBanListEntry.getExpires() != null) {
mutableComponent.append( mutableComponent.append(
@@ -369,10 +642,12 @@ public abstract class PlayerList { @@ -376,10 +_,12 @@
); );
} }
@@ -530,7 +529,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress); IpBanListEntry ipBanListEntry = this.ipBans.get(socketAddress);
MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason()); MutableComponent mutableComponent = Component.translatable("multiplayer.disconnect.banned_ip.reason", ipBanListEntry.getReason());
if (ipBanListEntry.getExpires() != null) { if (ipBanListEntry.getExpires() != null) {
@@ -381,69 +656,131 @@ public abstract class PlayerList { @@ -388,65 +_,124 @@
); );
} }
@@ -541,30 +540,9 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
- return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile) - return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)
- ? Component.translatable("multiplayer.disconnect.server_full") - ? Component.translatable("multiplayer.disconnect.server_full")
- : null; - : null;
+ // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile) - }
+ // ? Component.translatable("multiplayer.disconnect.server_full") - }
+ // : null; -
+ if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) {
+ event.disallow(org.bukkit.event.player.PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
+ }
+ }
+ this.cserver.getPluginManager().callEvent(event);
+ if (event.getResult() != org.bukkit.event.player.PlayerLoginEvent.Result.ALLOWED) {
+ loginlistener.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.kickMessage())); // Paper - Adventure
+ return null;
}
+ return entity;
}
- public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation) {
- return new ServerPlayer(this.server, this.server.overworld(), gameProfile, clientInformation);
+ // CraftBukkit start - added EntityPlayer
+ public ServerPlayer getPlayerForLogin(GameProfile gameProfile, ClientInformation clientInformation, ServerPlayer player) {
+ player.updateOptions(clientInformation);
+ return player;
+ // CraftBukkit end
}
- public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile) { - public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile) {
- UUID id = gameProfile.getId(); - UUID id = gameProfile.getId();
- Set<ServerPlayer> set = Sets.newIdentityHashSet(); - Set<ServerPlayer> set = Sets.newIdentityHashSet();
@@ -572,8 +550,13 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
- for (ServerPlayer serverPlayer : this.players) { - for (ServerPlayer serverPlayer : this.players) {
- if (serverPlayer.getUUID().equals(id)) { - if (serverPlayer.getUUID().equals(id)) {
- set.add(serverPlayer); - set.add(serverPlayer);
- } + // return this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)
- } + // ? Component.translatable("multiplayer.disconnect.server_full")
+ // : null;
+ if (this.players.size() >= this.maxPlayers && !this.canBypassPlayerLimit(gameProfile)) {
+ event.disallow(org.bukkit.event.player.PlayerLoginEvent.Result.KICK_FULL, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.serverFullMessage)); // Spigot // Paper - Adventure
}
}
- -
- ServerPlayer serverPlayer1 = this.playersByUUID.get(gameProfile.getId()); - ServerPlayer serverPlayer1 = this.playersByUUID.get(gameProfile.getId());
- if (serverPlayer1 != null) { - if (serverPlayer1 != null) {
@@ -583,6 +566,19 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
- for (ServerPlayer serverPlayer2 : set) { - for (ServerPlayer serverPlayer2 : set) {
- serverPlayer2.connection.disconnect(DUPLICATE_LOGIN_DISCONNECT_MESSAGE); - serverPlayer2.connection.disconnect(DUPLICATE_LOGIN_DISCONNECT_MESSAGE);
- } - }
-
- return !set.isEmpty();
- }
-
- public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason) {
+ this.cserver.getPluginManager().callEvent(event);
+ if (event.getResult() != org.bukkit.event.player.PlayerLoginEvent.Result.ALLOWED) {
+ loginlistener.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.kickMessage())); // Paper - Adventure
+ return null;
+ }
+ return entity;
+ }
+
+ public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile, ServerPlayer player) { // CraftBukkit - added ServerPlayer + public boolean disconnectAllPlayersWithProfile(GameProfile gameProfile, ServerPlayer player) { // CraftBukkit - added ServerPlayer
+ // CraftBukkit start - Moved up + // CraftBukkit start - Moved up
+ // UUID id = gameProfile.getId(); + // UUID id = gameProfile.getId();
@@ -607,19 +603,17 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ return player == null; + return player == null;
+ // CraftBukkit end + // CraftBukkit end
+ } + }
+
- return !set.isEmpty();
+ // CraftBukkit start + // CraftBukkit start
+ public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason) { + public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason) {
+ return this.respawn(player, keepInventory, reason, eventReason, null); + return this.respawn(player, keepInventory, reason, eventReason, null);
} + }
+
- public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason) {
+ public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, @Nullable org.bukkit.Location location) { + public ServerPlayer respawn(ServerPlayer player, boolean keepInventory, Entity.RemovalReason reason, @Nullable org.bukkit.event.player.PlayerRespawnEvent.RespawnReason eventReason, @Nullable org.bukkit.Location location) {
+ player.stopRiding(); // CraftBukkit + player.stopRiding(); // CraftBukkit
this.players.remove(player); this.players.remove(player);
+ this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot + this.playersByName.remove(player.getScoreboardName().toLowerCase(java.util.Locale.ROOT)); // Spigot
player.serverLevel().removePlayerImmediately(player, reason); player.level().removePlayerImmediately(player, reason);
- TeleportTransition teleportTransition = player.findRespawnPositionAndUseSpawnBlock(!keepInventory, TeleportTransition.DO_NOTHING); - TeleportTransition teleportTransition = player.findRespawnPositionAndUseSpawnBlock(!keepInventory, TeleportTransition.DO_NOTHING);
- ServerLevel level = teleportTransition.newLevel(); - ServerLevel level = teleportTransition.newLevel();
- ServerPlayer serverPlayer = new ServerPlayer(this.server, level, player.getGameProfile(), player.clientInformation()); - ServerPlayer serverPlayer = new ServerPlayer(this.server, level, player.getGameProfile(), player.clientInformation());
@@ -686,7 +680,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
byte b = (byte)(keepInventory ? 1 : 0); byte b = (byte)(keepInventory ? 1 : 0);
ServerLevel serverLevel = serverPlayer.serverLevel(); ServerLevel serverLevel = serverPlayer.level();
LevelData levelData = serverLevel.getLevelData(); LevelData levelData = serverLevel.getLevelData();
serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b)); serverPlayer.connection.send(new ClientboundRespawnPacket(serverPlayer.createCommonSpawnInfo(serverLevel), b));
- serverPlayer.connection.teleport(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ(), serverPlayer.getYRot(), serverPlayer.getXRot()); - serverPlayer.connection.teleport(serverPlayer.getX(), serverPlayer.getY(), serverPlayer.getZ(), serverPlayer.getYRot(), serverPlayer.getXRot());
@@ -697,7 +691,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle())); serverPlayer.connection.send(new ClientboundSetDefaultSpawnPositionPacket(level.getSharedSpawnPos(), level.getSharedSpawnAngle()));
serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked())); serverPlayer.connection.send(new ClientboundChangeDifficultyPacket(levelData.getDifficulty(), levelData.isDifficultyLocked()));
serverPlayer.connection serverPlayer.connection
@@ -451,10 +788,13 @@ public abstract class PlayerList { @@ -454,10 +_,13 @@
this.sendActivePlayerEffects(serverPlayer); this.sendActivePlayerEffects(serverPlayer);
this.sendLevelInfo(serverPlayer, level); this.sendLevelInfo(serverPlayer, level);
this.sendPlayerPermissionLevel(serverPlayer); this.sendPlayerPermissionLevel(serverPlayer);
@@ -715,7 +709,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
serverPlayer.setHealth(serverPlayer.getHealth()); serverPlayer.setHealth(serverPlayer.getHealth());
ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig(); ServerPlayer.RespawnConfig respawnConfig = serverPlayer.getRespawnConfig();
if (!keepInventory && respawnConfig != null) { if (!keepInventory && respawnConfig != null) {
@@ -477,8 +817,52 @@ public abstract class PlayerList { @@ -480,8 +_,52 @@
) )
); );
} }
@@ -768,7 +762,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
return serverPlayer; return serverPlayer;
} }
@@ -488,24 +872,59 @@ public abstract class PlayerList { @@ -491,24 +_,59 @@
} }
public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) { public void sendActiveEffects(LivingEntity entity, ServerGamePacketListenerImpl connection) {
@@ -831,7 +825,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
public void broadcastAll(Packet<?> packet) { public void broadcastAll(Packet<?> packet) {
for (ServerPlayer serverPlayer : this.players) { for (ServerPlayer serverPlayer : this.players) {
serverPlayer.connection.send(packet); serverPlayer.connection.send(packet);
@@ -581,6 +1000,12 @@ public abstract class PlayerList { @@ -584,6 +_,12 @@
} }
private void sendPlayerPermissionLevel(ServerPlayer player, int permLevel) { private void sendPlayerPermissionLevel(ServerPlayer player, int permLevel) {
@@ -844,7 +838,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
if (player.connection != null) { if (player.connection != null) {
byte b; byte b;
if (permLevel <= 0) { if (permLevel <= 0) {
@@ -594,11 +1019,33 @@ public abstract class PlayerList { @@ -597,11 +_,33 @@
player.connection.send(new ClientboundEntityEventPacket(player, b)); player.connection.send(new ClientboundEntityEventPacket(player, b));
} }
@@ -879,7 +873,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
public boolean isOp(GameProfile profile) { public boolean isOp(GameProfile profile) {
@@ -609,21 +1056,17 @@ public abstract class PlayerList { @@ -612,21 +_,17 @@
@Nullable @Nullable
public ServerPlayer getPlayerByName(String username) { public ServerPlayer getPlayerByName(String username) {
@@ -907,7 +901,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
if (serverPlayer != except && serverPlayer.level().dimension() == dimension) { if (serverPlayer != except && serverPlayer.level().dimension() == dimension) {
double d = x - serverPlayer.getX(); double d = x - serverPlayer.getX();
double d1 = y - serverPlayer.getY(); double d1 = y - serverPlayer.getY();
@@ -636,9 +1079,11 @@ public abstract class PlayerList { @@ -639,9 +_,11 @@
} }
public void saveAll() { public void saveAll() {
@@ -919,7 +913,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
public UserWhiteList getWhiteList() { public UserWhiteList getWhiteList() {
@@ -661,14 +1106,18 @@ public abstract class PlayerList { @@ -664,14 +_,18 @@
} }
public void sendLevelInfo(ServerPlayer player, ServerLevel level) { public void sendLevelInfo(ServerPlayer player, ServerLevel level) {
@@ -942,7 +936,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F)); player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.LEVEL_CHUNKS_LOAD_START, 0.0F));
@@ -677,8 +1126,21 @@ public abstract class PlayerList { @@ -680,8 +_,21 @@
public void sendAllPlayerInfo(ServerPlayer player) { public void sendAllPlayerInfo(ServerPlayer player) {
player.inventoryMenu.sendAllDataToRemote(); player.inventoryMenu.sendAllDataToRemote();
@@ -957,15 +951,15 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata + player.refreshEntityData(player); // CraftBukkit - SPIGOT-7218: sync metadata
player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot())); player.connection.send(new ClientboundSetHeldSlotPacket(player.getInventory().getSelectedSlot()));
+ // CraftBukkit start - from GameRules + // CraftBukkit start - from GameRules
+ int i = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23; + int i = player.level().getGameRules().getBoolean(GameRules.RULE_REDUCEDDEBUGINFO) ? 22 : 23;
+ player.connection.send(new ClientboundEntityEventPacket(player, (byte) i)); + player.connection.send(new ClientboundEntityEventPacket(player, (byte) i));
+ float immediateRespawn = player.serverLevel().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F; + float immediateRespawn = player.level().getGameRules().getBoolean(GameRules.RULE_DO_IMMEDIATE_RESPAWN) ? 1.0F: 0.0F;
+ player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, immediateRespawn)); + player.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.IMMEDIATE_RESPAWN, immediateRespawn));
+ // CraftBukkit end + // CraftBukkit end
} }
public int getPlayerCount() { public int getPlayerCount() {
@@ -694,6 +1156,7 @@ public abstract class PlayerList { @@ -697,6 +_,7 @@
} }
public void setUsingWhiteList(boolean whitelistEnabled) { public void setUsingWhiteList(boolean whitelistEnabled) {
@@ -973,12 +967,14 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
this.doWhiteList = whitelistEnabled; this.doWhiteList = whitelistEnabled;
} }
@@ -731,11 +1194,36 @@ public abstract class PlayerList { @@ -734,10 +_,35 @@
} }
public void removeAll() { public void removeAll() {
- for (int i = 0; i < this.players.size(); i++) { - for (int i = 0; i < this.players.size(); i++) {
- this.players.get(i).connection.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown")); - this.players.get(i).connection.disconnect(Component.translatable("multiplayer.disconnect.server_shutdown"));
- }
- }
+ // Paper start - Extract method to allow for restarting flag + // Paper start - Extract method to allow for restarting flag
+ this.removeAll(false); + this.removeAll(false);
+ } + }
@@ -989,7 +985,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ for (ServerPlayer player : this.players) { + for (ServerPlayer player : this.players) {
+ if (isRestarting) player.connection.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.restartMessage), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); else // Paper - kick event cause (cause is never used here) + if (isRestarting) player.connection.disconnect(net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.restartMessage), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); else // Paper - kick event cause (cause is never used here)
+ player.connection.disconnect(java.util.Objects.requireNonNullElseGet(this.server.server.shutdownMessage(), net.kyori.adventure.text.Component::empty)); // CraftBukkit - add custom shutdown message // Paper - Adventure + player.connection.disconnect(java.util.Objects.requireNonNullElseGet(this.server.server.shutdownMessage(), net.kyori.adventure.text.Component::empty)); // CraftBukkit - add custom shutdown message // Paper - Adventure
} + }
+ // CraftBukkit end + // CraftBukkit end
+ +
+ // Paper start - Configurable player collision; Remove collideRule team if it exists + // Paper start - Configurable player collision; Remove collideRule team if it exists
@@ -999,8 +995,8 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ if (team != null) scoreboard.removePlayerTeam(team); + if (team != null) scoreboard.removePlayerTeam(team);
+ } + }
+ // Paper end - Configurable player collision + // Paper end - Configurable player collision
} + }
+
+ // CraftBukkit start + // CraftBukkit start
+ public void broadcastMessage(Component[] iChatBaseComponents) { + public void broadcastMessage(Component[] iChatBaseComponents) {
+ for (Component component : iChatBaseComponents) { + for (Component component : iChatBaseComponents) {
@@ -1008,11 +1004,10 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
+ } + }
+ } + }
+ // CraftBukkit end + // CraftBukkit end
+
public void broadcastSystemMessage(Component message, boolean bypassHiddenChat) { public void broadcastSystemMessage(Component message, boolean bypassHiddenChat) {
this.broadcastSystemMessage(message, serverPlayer -> message, bypassHiddenChat); this.broadcastSystemMessage(message, serverPlayer -> message, bypassHiddenChat);
} @@ -759,20 +_,39 @@
@@ -756,20 +1244,39 @@ public abstract class PlayerList {
} }
public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound boundChatType) { public void broadcastChatMessage(PlayerChatMessage message, ServerPlayer sender, ChatType.Bound boundChatType) {
@@ -1055,7 +1050,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
flag1 |= flag2 && message.isFullyFiltered(); flag1 |= flag2 && message.isFullyFiltered();
} }
@@ -782,14 +1289,21 @@ public abstract class PlayerList { @@ -785,14 +_,21 @@
return message.hasSignature() && !message.hasExpiredServer(Instant.now()); return message.hasSignature() && !message.hasExpiredServer(Instant.now());
} }
@@ -1081,7 +1076,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
Path path = file2.toPath(); Path path = file2.toPath();
if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) { if (FileUtil.isPathNormalized(path) && FileUtil.isPathPortable(path) && path.startsWith(file.getPath()) && file2.isFile()) {
file2.renameTo(file1); file2.renameTo(file1);
@@ -797,7 +1311,7 @@ public abstract class PlayerList { @@ -800,7 +_,7 @@
} }
serverStatsCounter = new ServerStatsCounter(this.server, file1); serverStatsCounter = new ServerStatsCounter(this.server, file1);
@@ -1090,7 +1085,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
return serverStatsCounter; return serverStatsCounter;
@@ -805,11 +1319,11 @@ public abstract class PlayerList { @@ -808,11 +_,11 @@
public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) { public PlayerAdvancements getPlayerAdvancements(ServerPlayer player) {
UUID uuid = player.getUUID(); UUID uuid = player.getUUID();
@@ -1104,7 +1099,7 @@ index aa7b0ea3f5203aafa86a8d36cd01b661cd16147c..ed23e8e29d08d69ec1d0dca49193a3a6
} }
playerAdvancements.setPlayer(player); playerAdvancements.setPlayer(player);
@@ -852,11 +1366,34 @@ public abstract class PlayerList { @@ -855,11 +_,34 @@
} }
public void reloadResources() { public void reloadResources() {

View File

@@ -0,0 +1,142 @@
--- a/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
+++ b/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
@@ -79,6 +_,10 @@
public final List<StructureTemplate.StructureEntityInfo> entityInfoList = Lists.newArrayList();
private Vec3i size = Vec3i.ZERO;
private String author = "?";
+ // CraftBukkit start - data containers
+ private static final org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new org.bukkit.craftbukkit.persistence.CraftPersistentDataTypeRegistry();
+ public org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer persistentDataContainer = new org.bukkit.craftbukkit.persistence.CraftPersistentDataContainer(StructureTemplate.DATA_TYPE_REGISTRY);
+ // CraftBukkit end
public Vec3i getSize() {
return this.size;
@@ -255,6 +_,19 @@
if (this.palettes.isEmpty()) {
return false;
} else {
+ // CraftBukkit start
+ // We only want the TransformerGeneratorAccess at certain locations because in here are many "block update" calls that shouldn't be transformed
+ ServerLevelAccessor wrappedAccess = serverLevel;
+ org.bukkit.craftbukkit.util.CraftStructureTransformer structureTransformer = null;
+ if (wrappedAccess instanceof org.bukkit.craftbukkit.util.TransformerGeneratorAccess transformerAccess) {
+ serverLevel = transformerAccess.getDelegate();
+ structureTransformer = transformerAccess.getStructureTransformer();
+ // The structureTransformer is not needed if we can not transform blocks therefore we can save a little bit of performance doing this
+ if (structureTransformer != null && !structureTransformer.canTransformBlocks()) {
+ structureTransformer = null;
+ }
+ }
+ // CraftBukkit end
List<StructureTemplate.StructureBlockInfo> list = settings.getRandomPalette(this.palettes, offset).blocks();
if ((!list.isEmpty() || !settings.isIgnoreEntities() && !this.entityInfoList.isEmpty())
&& this.size.getX() >= 1
@@ -282,6 +_,21 @@
serverLevel.setBlock(blockPos, Blocks.BARRIER.defaultBlockState(), 820);
}
+ // CraftBukkit start
+ if (structureTransformer != null) {
+ org.bukkit.craftbukkit.block.CraftBlockState craftBlockState = (org.bukkit.craftbukkit.block.CraftBlockState) org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(serverLevel, blockPos, blockState, null);
+ if (structureBlockInfo.nbt != null && craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> entityState) {
+ entityState.loadData(structureBlockInfo.nbt);
+ if (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftLootable<?> craftLootable) {
+ craftLootable.setSeed(random.nextLong());
+ }
+ }
+ craftBlockState = structureTransformer.transformCraftState(craftBlockState);
+ blockState = craftBlockState.getHandle();
+ structureBlockInfo = new StructureTemplate.StructureBlockInfo(blockPos, blockState, (craftBlockState instanceof org.bukkit.craftbukkit.block.CraftBlockEntityState<?> craftBlockEntityState ? craftBlockEntityState.getSnapshotNBT() : null));
+ }
+ // CraftBukkit end
+
if (serverLevel.setBlock(blockPos, blockState, flags)) {
i = Math.min(i, blockPos.getX());
i1 = Math.min(i1, blockPos.getY());
@@ -293,7 +_,7 @@
if (structureBlockInfo.nbt != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos);
if (blockEntity != null) {
- if (blockEntity instanceof RandomizableContainer) {
+ if (structureTransformer == null && blockEntity instanceof RandomizableContainer) { // CraftBukkit - only process if don't have a transformer access (Was already set above) - SPIGOT-7520: Use structureTransformer as check, so that it is the same as above
structureBlockInfo.nbt.putLong("LootTableSeed", random.nextLong());
}
@@ -380,7 +_,11 @@
if (pair1.getSecond() != null) {
BlockEntity blockEntity = serverLevel.getBlockEntity(blockPos4);
if (blockEntity != null) {
- blockEntity.setChanged();
+ // Paper start - Fix NBT pieces overriding a block entity during worldgen deadlock
+ if (!(serverLevel instanceof net.minecraft.world.level.WorldGenLevel)) {
+ blockEntity.setChanged();
+ }
+ // Paper end - Fix NBT pieces overriding a block entity during worldgen deadlock
}
}
}
@@ -388,7 +_,7 @@
if (!settings.isIgnoreEntities()) {
this.placeEntities(
- serverLevel,
+ wrappedAccess, // CraftBukkit
offset,
settings.getMirror(),
settings.getRotation(),
@@ -499,14 +_,17 @@
});
}
}
+
}
private static Optional<Entity> createEntityIgnoreException(ProblemReporter problemReporter, ServerLevelAccessor level, CompoundTag tag) {
- try {
- return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE);
- } catch (Exception var4) {
- return Optional.empty();
- }
+ // CraftBukkit start
+ // try {
+ return EntityType.create(TagValueInput.create(problemReporter, level.registryAccess(), tag), level.getLevel(), EntitySpawnReason.STRUCTURE, true); // Paper - Don't fire sync event during generation
+ // } catch (Exception var4) {
+ // return Optional.empty();
+ // }
+ // CraftBukkit end
}
public Vec3i getSize(Rotation rotation) {
@@ -699,6 +_,11 @@
tag.put("entities", listTag3);
tag.put("size", this.newIntegerList(this.size.getX(), this.size.getY(), this.size.getZ()));
+ // CraftBukkit start - PDC
+ if (!this.persistentDataContainer.isEmpty()) {
+ tag.put("BukkitValues", this.persistentDataContainer.toTagCompound());
+ }
+ // CraftBukkit end
return NbtUtils.addCurrentDataVersion(tag);
}
@@ -729,6 +_,11 @@
.ifPresent(compoundTag1 -> this.entityInfoList.add(new StructureTemplate.StructureEntityInfo(vec3, blockPos, compoundTag1)));
}
);
+ // CraftBukkit start - PDC
+ if (tag.get("BukkitValues") instanceof CompoundTag compoundTag) {
+ this.persistentDataContainer.putAll(compoundTag);
+ }
+ // CraftBukkit end
}
private void loadPalette(HolderGetter<Block> blockGetter, ListTag paletteTag, ListTag blocksTag) {
@@ -828,7 +_,7 @@
public static final class Palette {
private final List<StructureTemplate.StructureBlockInfo> blocks;
- private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newHashMap();
+ private final Map<Block, List<StructureTemplate.StructureBlockInfo>> cache = Maps.newConcurrentMap(); // Paper - Fix CME due to this collection being shared across threads
@Nullable
private List<StructureTemplate.JigsawBlockInfo> cachedJigsaws;