More more more more more more more more more more patches
This commit is contained in:
parent
2259098789
commit
beab8a32c1
35 changed files with 143 additions and 168 deletions
|
@ -1,24 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: u9g <winworkswow@gmail.com>
|
||||
Date: Mon, 3 Jan 2022 23:32:42 -0500
|
||||
Subject: [PATCH] Add new overload to PersistentDataContainer#has
|
||||
|
||||
Adds the new overload: PersistentDataContainer#has(NamespacedKey key)
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
index 2c59f09a9261a1690951161fd856a5848d9885b7..f0588bec9be09cb8273c310fb3de8bfe72dee9e5 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -161,5 +161,12 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
public void clear() {
|
||||
this.customDataTags.clear();
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean has(NamespacedKey key) {
|
||||
+ Validate.notNull(key, "The provided key for the custom value was null");
|
||||
+
|
||||
+ return this.customDataTags.containsKey(key.toString());
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,126 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Cryptite <cryptite@gmail.com>
|
||||
Date: Tue, 21 Sep 2021 18:17:33 -0500
|
||||
Subject: [PATCH] Multiple Entries with Scoreboards
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
index c5339618c195507c1d1482e4e77e262e8db240a5..fe01daf9f78dff51b97337af8cfd43f19bc4678e 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSetPlayerTeamPacket.java
|
||||
@@ -42,6 +42,12 @@ public class ClientboundSetPlayerTeamPacket implements Packet<ClientGamePacketLi
|
||||
return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), ImmutableList.of(playerName));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static ClientboundSetPlayerTeamPacket createMultiplePlayerPacket(PlayerTeam team, Collection<String> players, ClientboundSetPlayerTeamPacket.Action operation) {
|
||||
+ return new ClientboundSetPlayerTeamPacket(team.getName(), operation == ClientboundSetPlayerTeamPacket.Action.ADD ? 3 : 4, Optional.empty(), players);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ClientboundSetPlayerTeamPacket(FriendlyByteBuf buf) {
|
||||
this.name = buf.readUtf();
|
||||
this.method = buf.readByte();
|
||||
diff --git a/src/main/java/net/minecraft/server/ServerScoreboard.java b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
index 610d312b9c8f6c8d1f102e8ba2fe9fc2cc3e98c5..3a4a0727ad44322e3ba85512cd077808dab080b7 100644
|
||||
--- a/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
+++ b/src/main/java/net/minecraft/server/ServerScoreboard.java
|
||||
@@ -92,6 +92,25 @@ public class ServerScoreboard extends Scoreboard {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public boolean addPlayersToTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ boolean anyAdded = false;
|
||||
+ for (String playerName : players) {
|
||||
+ if (super.addPlayerToTeam(playerName, team)) {
|
||||
+ anyAdded = true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (anyAdded) {
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.ADD));
|
||||
+ this.setDirty();
|
||||
+ return true;
|
||||
+ } else {
|
||||
+ return false;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void removePlayerFromTeam(String playerName, PlayerTeam team) {
|
||||
super.removePlayerFromTeam(playerName, team);
|
||||
@@ -99,6 +118,17 @@ public class ServerScoreboard extends Scoreboard {
|
||||
this.setDirty();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public void removePlayersFromTeam(java.util.Collection<String> players, PlayerTeam team) {
|
||||
+ for (String playerName : players) {
|
||||
+ super.removePlayerFromTeam(playerName, team);
|
||||
+ }
|
||||
+
|
||||
+ this.broadcastAll(ClientboundSetPlayerTeamPacket.createMultiplePlayerPacket(team, players, ClientboundSetPlayerTeamPacket.Action.REMOVE));
|
||||
+ this.setDirty();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void onObjectiveAdded(Objective objective) {
|
||||
super.onObjectiveAdded(objective);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
index 4b64d6c5c987e127d1ed5edad0a78f7172370b9f..67efb0d38ae369ff5254f7b1ec85d32d4eee8291 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java
|
||||
@@ -234,6 +234,21 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
||||
scoreboard.board.addPlayerToTeam(entry, team);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void addEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
|
||||
+ this.addEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
||||
+ Validate.notNull(entries, "Entries cannot be null");
|
||||
+ CraftScoreboard scoreboard = this.checkState();
|
||||
+
|
||||
+ ((net.minecraft.server.ServerScoreboard) scoreboard.board).addPlayersToTeam(entries, this.team);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean removePlayer(OfflinePlayer player) throws IllegalStateException, IllegalArgumentException {
|
||||
Validate.notNull(player, "OfflinePlayer cannot be null");
|
||||
@@ -253,6 +268,28 @@ final class CraftTeam extends CraftScoreboardComponent implements Team {
|
||||
return true;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean removeEntities(java.util.Collection<org.bukkit.entity.Entity> entities) throws IllegalStateException, IllegalArgumentException {
|
||||
+ return this.removeEntries(entities.stream().map(entity -> ((org.bukkit.craftbukkit.entity.CraftEntity) entity).getHandle().getScoreboardName()).toList());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean removeEntries(java.util.Collection<String> entries) throws IllegalStateException, IllegalArgumentException {
|
||||
+ Validate.notNull(entries, "Entry cannot be null");
|
||||
+ CraftScoreboard scoreboard = this.checkState();
|
||||
+
|
||||
+ for (String entry : entries) {
|
||||
+ if (this.team.getPlayers().contains(entry)) {
|
||||
+ ((net.minecraft.server.ServerScoreboard) scoreboard.board).removePlayersFromTeam(entries, this.team);
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean hasPlayer(OfflinePlayer player) throws IllegalArgumentException, IllegalStateException {
|
||||
Validate.notNull(player, "OfflinePlayer cannot be null");
|
|
@ -1,38 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
||||
Date: Fri, 7 Jan 2022 11:45:15 +0100
|
||||
Subject: [PATCH] Reset placed block on exception
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 8175bb6331727440da2232998bdad068a1c47ae8..893d5bf448ddbccb30db0ee751c7f4a4e83634b9 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -78,6 +78,7 @@ public class BlockItem extends Item {
|
||||
if (this instanceof WaterLilyBlockItem || this instanceof SolidBucketItem) {
|
||||
blockstate = org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos());
|
||||
}
|
||||
+ final org.bukkit.block.BlockState oldBlockstate = blockstate != null ? blockstate : org.bukkit.craftbukkit.block.CraftBlockStates.getBlockState(blockactioncontext1.getLevel(), blockactioncontext1.getClickedPos()); // Paper
|
||||
// CraftBukkit end
|
||||
|
||||
if (iblockdata == null) {
|
||||
@@ -93,7 +94,19 @@ public class BlockItem extends Item {
|
||||
|
||||
if (iblockdata1.is(iblockdata.getBlock())) {
|
||||
iblockdata1 = this.updateBlockStateFromTag(blockposition, world, itemstack, iblockdata1);
|
||||
+ // Paper start - reset block on exception
|
||||
+ try {
|
||||
this.updateCustomBlockEntityTag(blockposition, world, entityhuman, itemstack, iblockdata1);
|
||||
+ } catch (Exception e) {
|
||||
+ oldBlockstate.update(true, false);
|
||||
+ if (entityhuman instanceof ServerPlayer player) {
|
||||
+ org.apache.logging.log4j.LogManager.getLogger().error("Player {} tried placing invalid block", player.getScoreboardName(), e);
|
||||
+ player.getBukkitEntity().kickPlayer("Packet processing error");
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ throw e; // Rethrow exception if not placed by a player
|
||||
+ }
|
||||
+ // Paper end
|
||||
iblockdata1.getBlock().setPlacedBy(world, blockposition, iblockdata1, entityhuman, itemstack);
|
||||
// CraftBukkit start
|
||||
if (blockstate != null) {
|
|
@ -1,56 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Doc <nachito94@msn.com>
|
||||
Date: Mon, 2 Aug 2021 11:24:39 -0400
|
||||
Subject: [PATCH] Add configurable height for slime spawn
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
index 100de7e366c4ea8ce158b0fc0258e4db0ee83249..b13d4dc311f25f9d3132697381e52beb06122b30 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
|
||||
@@ -464,6 +464,16 @@ public class PaperWorldConfig {
|
||||
allChunksAreSlimeChunks = getBoolean("all-chunks-are-slime-chunks", false);
|
||||
}
|
||||
|
||||
+ public double slimeMaxSpawnHeightInSwamp = 70;
|
||||
+ public double slimeMinSpawnHeightInSwamp = 50;
|
||||
+ public double slimeMaxSpawnHeightInSlimeChunks = 40;
|
||||
+ private void slimeSpawnHeight() {
|
||||
+ slimeMaxSpawnHeightInSwamp = getDouble("slime-spawn-height.swamp-biome.maximum", this.slimeMaxSpawnHeightInSwamp);
|
||||
+ slimeMinSpawnHeightInSwamp = getDouble("slime-spawn-height.swamp-biome.minimum", this.slimeMinSpawnHeightInSwamp);
|
||||
+ slimeMaxSpawnHeightInSlimeChunks = getDouble("slime-spawn-height.slime-chunk.maximum", this.slimeMaxSpawnHeightInSlimeChunks);
|
||||
+ }
|
||||
+
|
||||
+
|
||||
public int portalSearchRadius;
|
||||
public int portalCreateRadius;
|
||||
public boolean portalSearchVanillaDimensionScaling;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 85edba5de3ce6c1fce8872855544863de84e7759..b6e78e8145ea78d532f22707c7525829c5778076 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -325,7 +325,11 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
public static boolean checkSlimeSpawnRules(EntityType<Slime> type, LevelAccessor world, MobSpawnType spawnReason, BlockPos pos, Random random) {
|
||||
if (world.getDifficulty() != Difficulty.PEACEFUL) {
|
||||
- if (world.getBiome(pos).is(Biomes.SWAMP) && pos.getY() > 50 && pos.getY() < 70 && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
|
||||
+ // Paper start - Replace rules for Height in Swamp Biome
|
||||
+ final double maxHeightSwamp = world.getMinecraftWorld().paperConfig.slimeMaxSpawnHeightInSwamp;
|
||||
+ final double minHeightSwamp = world.getMinecraftWorld().paperConfig.slimeMinSpawnHeightInSwamp;
|
||||
+ if (world.getBiome(pos).is(Biomes.SWAMP) && pos.getY() > minHeightSwamp && pos.getY() < maxHeightSwamp && random.nextFloat() < 0.5F && random.nextFloat() < world.getMoonBrightness() && world.getMaxLocalRawBrightness(pos) <= random.nextInt(8)) {
|
||||
+ // Paper end
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
}
|
||||
|
||||
@@ -336,7 +340,10 @@ public class Slime extends Mob implements Enemy {
|
||||
ChunkPos chunkcoordintpair = new ChunkPos(pos);
|
||||
boolean flag = world.getMinecraftWorld().paperConfig.allChunksAreSlimeChunks || WorldgenRandom.seedSlimeChunk(chunkcoordintpair.x, chunkcoordintpair.z, ((WorldGenLevel) world).getSeed(), world.getMinecraftWorld().spigotConfig.slimeSeed).nextInt(10) == 0; // Spigot // Paper
|
||||
|
||||
- if (random.nextInt(10) == 0 && flag && pos.getY() < 40) {
|
||||
+ // Paper start - Replace rules for Height in Slime Chunks
|
||||
+ final double maxHeightSlimeChunk = world.getMinecraftWorld().paperConfig.slimeMaxSpawnHeightInSlimeChunks;
|
||||
+ if (random.nextInt(10) == 0 && flag && pos.getY() < maxHeightSlimeChunk) {
|
||||
+ // Paper end
|
||||
return checkMobSpawnRules(type, world, spawnReason, pos, random);
|
||||
}
|
||||
}
|
|
@ -1,19 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MCMDEV <john-m.1@gmx.de>
|
||||
Date: Fri, 24 Sep 2021 17:59:21 +0200
|
||||
Subject: [PATCH] Added getHostname to AsyncPlayerPreLoginEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 7065aa4522431d08018fec8e591ba7c255398140..befcb501b4b1b6330bf3cd53e00e30b01efade6f 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -395,7 +395,7 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
|
||||
|
||||
// Paper start
|
||||
com.destroystokyo.paper.profile.PlayerProfile profile = com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitMirror(ServerLoginPacketListenerImpl.this.gameProfile);
|
||||
- AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, rawAddress, uniqueId, profile); // Paper - add rawAddress
|
||||
+ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, rawAddress, uniqueId, profile, ServerLoginPacketListenerImpl.this.hostname); // Paper - add rawAddress & hostname
|
||||
server.getPluginManager().callEvent(asyncEvent);
|
||||
profile = asyncEvent.getPlayerProfile();
|
||||
profile.complete(true); // Paper - setPlayerProfileAPI
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 16 Jan 2022 10:34:02 -0800
|
||||
Subject: [PATCH] Fix xp reward for baby zombies
|
||||
|
||||
The field that tracks the xpReward was not
|
||||
getting reset if the death was cancelled
|
||||
so this resets it after each call to
|
||||
Zombie#getExperienceReward
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Zombie.java b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
index f9b7877ce5f66cc58ff1111d0fa72081a03c4f4e..cd88413f30632307faba63572915656b6a8469f7 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Zombie.java
|
||||
@@ -172,11 +172,16 @@ public class Zombie extends Monster {
|
||||
|
||||
@Override
|
||||
protected int getExperienceReward(Player player) {
|
||||
+ final int previousReward = this.xpReward; // Paper - store previous value to reset after calculating XP reward
|
||||
if (this.isBaby()) {
|
||||
this.xpReward = (int) ((double) this.xpReward * 2.5D);
|
||||
}
|
||||
|
||||
- return super.getExperienceReward(player);
|
||||
+ // Paper start - only change the XP reward for the calculations in the super method
|
||||
+ int reward = super.getExperienceReward(player);
|
||||
+ this.xpReward = previousReward;
|
||||
+ return reward;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
||||
Date: Mon, 17 Jan 2022 19:47:19 +0100
|
||||
Subject: [PATCH] Kick on main for illegal chars
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 1a15711e657c93965c2839dc130b7c53d86482b0..b42d4224d7f5c5de7e9fa8d6278af10f84d81245 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -2081,7 +2081,9 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
|
||||
|
||||
for (int i = 0; i < s.length(); ++i) {
|
||||
if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) {
|
||||
+ this.server.scheduleOnMain(() -> { // Paper - push to main for event firing
|
||||
this.disconnect(new TranslatableComponent("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause
|
||||
+ }); // Paper - push to main for event firing
|
||||
return;
|
||||
}
|
||||
}
|
|
@ -1,74 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brody Beckwith <brody@beckwith.dev>
|
||||
Date: Fri, 14 Jan 2022 00:41:11 -0500
|
||||
Subject: [PATCH] Multi Block Change API Implementation
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
index 82ea4fabd5732052a286d50bcff8bbcc2c4aa7d7..652bea6868a03a5315965f79c76172fb9dbb93fb 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ClientboundSectionBlocksUpdatePacket.java
|
||||
@@ -54,6 +54,15 @@ public class ClientboundSectionBlocksUpdatePacket implements Packet<ClientGamePa
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public ClientboundSectionBlocksUpdatePacket(SectionPos sectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<BlockState> blockChanges, boolean suppressLightUpdates) {
|
||||
+ this.sectionPos = sectionPos;
|
||||
+ this.positions = blockChanges.keySet().toShortArray();
|
||||
+ this.states = blockChanges.values().toArray(new BlockState[0]);
|
||||
+ this.suppressLightUpdates = suppressLightUpdates;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void write(FriendlyByteBuf buf) {
|
||||
buf.writeLong(this.sectionPos.asLong());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0978be96a4ef26dc0a2e3cc1bb10931496502413..f8039c0e62b8fa8f0491edb296054299e7e28bdf 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -30,6 +30,7 @@ import javax.annotation.Nullable;
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.advancements.AdvancementProgress;
|
||||
import net.minecraft.core.BlockPos;
|
||||
+import net.minecraft.core.SectionPos; // Paper
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.network.chat.ChatType;
|
||||
@@ -866,6 +867,35 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getHandle().connection.send(packet);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void sendMultiBlockChange(Map<Location, BlockData> blockChanges, boolean suppressLightUpdates) {
|
||||
+ if (this.getHandle().connection == null) return;
|
||||
+
|
||||
+ Map<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> sectionMap = new HashMap<>();
|
||||
+
|
||||
+ for (Map.Entry<Location, BlockData> entry : blockChanges.entrySet()) {
|
||||
+ Location location = entry.getKey();
|
||||
+ if (!location.getWorld().equals(this.getWorld())) continue;
|
||||
+
|
||||
+ BlockData blockData = entry.getValue();
|
||||
+ BlockPos blockPos = new BlockPos(location.getBlockX(), location.getBlockY(), location.getBlockZ());
|
||||
+ SectionPos sectionPos = SectionPos.of(blockPos);
|
||||
+
|
||||
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> sectionData = sectionMap.computeIfAbsent(sectionPos, key -> new it.unimi.dsi.fastutil.shorts.Short2ObjectArrayMap<>());
|
||||
+ sectionData.put(SectionPos.sectionRelativePos(blockPos), ((CraftBlockData) blockData).getState());
|
||||
+ }
|
||||
+
|
||||
+ for (Map.Entry<SectionPos, it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState>> entry : sectionMap.entrySet()) {
|
||||
+ SectionPos sectionPos = entry.getKey();
|
||||
+ it.unimi.dsi.fastutil.shorts.Short2ObjectMap<net.minecraft.world.level.block.state.BlockState> blockData = entry.getValue();
|
||||
+
|
||||
+ net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket packet = new net.minecraft.network.protocol.game.ClientboundSectionBlocksUpdatePacket(sectionPos, blockData, suppressLightUpdates);
|
||||
+ this.getHandle().connection.send(packet);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void sendBlockDamage(Location loc, float progress) {
|
||||
Preconditions.checkArgument(loc != null, "loc must not be null");
|
|
@ -1,40 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kieran Wallbanks <kieran.wallbanks@gmail.com>
|
||||
Date: Mon, 21 Jun 2021 14:23:50 +0100
|
||||
Subject: [PATCH] Fix NotePlayEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/NoteBlock.java b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
index 16e11e31077f160198e0b04abdfeabb97ed20c6f..0e106bcc1f882877a5e444a2621466c6e4696d42 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/NoteBlock.java
|
||||
@@ -60,10 +60,9 @@ public class NoteBlock extends Block {
|
||||
private void playNote(Level world, BlockPos blockposition, BlockState data) { // CraftBukkit
|
||||
if (world.getBlockState(blockposition.above()).isAir()) {
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, blockposition, data.getValue(NoteBlock.INSTRUMENT), data.getValue(NoteBlock.NOTE));
|
||||
- if (!event.isCancelled()) {
|
||||
+ // Paper start - move NotePlayEvent call to fix instrument/note changes
|
||||
world.blockEvent(blockposition, this, 0, 0);
|
||||
- }
|
||||
+ // Paper end
|
||||
// CraftBukkit end
|
||||
}
|
||||
|
||||
@@ -92,10 +91,14 @@ public class NoteBlock extends Block {
|
||||
|
||||
@Override
|
||||
public boolean triggerEvent(BlockState state, Level world, BlockPos pos, int type, int data) {
|
||||
- int k = (Integer) state.getValue(NoteBlock.NOTE);
|
||||
+ // Paper start - move NotePlayEvent call to fix instrument/note changes
|
||||
+ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(world, pos, state.getValue(INSTRUMENT), state.getValue(NOTE));
|
||||
+ if (event.isCancelled()) return false;
|
||||
+ int k = event.getNote().getId();
|
||||
float f = (float) Math.pow(2.0D, (double) (k - 12) / 12.0D);
|
||||
|
||||
- world.playSound((Player) null, pos, ((NoteBlockInstrument) state.getValue(NoteBlock.INSTRUMENT)).getSoundEvent(), SoundSource.RECORDS, 3.0F, f);
|
||||
+ world.playSound(null, pos, org.bukkit.craftbukkit.block.data.CraftBlockData.toNMS(event.getInstrument(), NoteBlockInstrument.class).getSoundEvent(), SoundSource.RECORDS, 3.0F, f);
|
||||
+ // Paper end
|
||||
world.addParticle(ParticleTypes.NOTE, (double) pos.getX() + 0.5D, (double) pos.getY() + 1.2D, (double) pos.getZ() + 0.5D, (double) k / 24.0D, 0.0D, 0.0D);
|
||||
return true;
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Sun, 26 Dec 2021 20:27:43 -0500
|
||||
Subject: [PATCH] Freeze Tick Lock API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 18294d7cdb4619bb128c626ef567622bae187c8d..ede2f5f00b59893cca354e5626938360347b0a36 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -335,6 +335,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
private org.bukkit.util.Vector origin;
|
||||
@javax.annotation.Nullable
|
||||
private UUID originWorld;
|
||||
+ public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
|
||||
|
||||
public void setOrigin(@javax.annotation.Nonnull Location location) {
|
||||
this.origin = location.toVector();
|
||||
@@ -762,7 +763,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.setRemainingFireTicks(this.remainingFireTicks - 1);
|
||||
}
|
||||
|
||||
- if (this.getTicksFrozen() > 0) {
|
||||
+ if (this.getTicksFrozen() > 0 && !freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
this.setTicksFrozen(0);
|
||||
this.level.levelEvent((Player) null, 1009, this.blockPosition, 1);
|
||||
}
|
||||
@@ -2163,6 +2164,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
if (fromNetherPortal) {
|
||||
nbt.putBoolean("Paper.FromNetherPortal", true);
|
||||
}
|
||||
+ if (freezeLocked) {
|
||||
+ nbt.putBoolean("Paper.FreezeLock", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return nbt;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -2325,6 +2329,9 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
if (spawnReason == null) {
|
||||
spawnReason = org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT;
|
||||
}
|
||||
+ if (nbt.contains("Paper.FreezeLock")) {
|
||||
+ freezeLocked = nbt.getBoolean("Paper.FreezeLock");
|
||||
+ }
|
||||
// Paper end
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 5ef73cf97df2949d308d4cc9213bfb173c15b4a5..c17b8c77b1a4d65afaefd9c4b32219d898882410 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -3319,7 +3319,7 @@ public abstract class LivingEntity extends Entity {
|
||||
boolean flag1 = this.getType().is(EntityTypeTags.FREEZE_HURTS_EXTRA_TYPES);
|
||||
int i;
|
||||
|
||||
- if (!this.level.isClientSide && !this.isDeadOrDying()) {
|
||||
+ if (!this.level.isClientSide && !this.isDeadOrDying() && !freezeLocked) { // Paper - Freeze Tick Lock API
|
||||
i = this.getTicksFrozen();
|
||||
if (this.isInPowderSnow && this.canFreeze()) {
|
||||
this.setTicksFrozen(Math.min(this.getTicksRequiredToFreeze(), i + 1));
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0a998832afacb25cbaf39737d14aa33eab6967b7..a92755211e3d42934b5efaa3f201c6c19ab7d2b4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -662,6 +662,17 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return this.getHandle().isFullyFrozen();
|
||||
}
|
||||
|
||||
+ // Paper Start - Freeze Tick Lock API
|
||||
+ @Override
|
||||
+ public boolean isFreezeTickingLocked() {
|
||||
+ return this.entity.freezeLocked;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void lockFreezeTicks(boolean locked) {
|
||||
+ this.entity.freezeLocked = locked;
|
||||
+ }
|
||||
+ // Paper end - Freeze Tick Lock API
|
||||
@Override
|
||||
public void remove() {
|
||||
this.entity.discard();
|
|
@ -1,45 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Tue, 7 Dec 2021 19:34:23 -0500
|
||||
Subject: [PATCH] Dolphin API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
|
||||
index 938e141f161acf5de5d3361382b514caea02c6fb..75919bf87b6f5cad06ca76888e284e2548594f00 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDolphin.java
|
||||
@@ -24,4 +24,34 @@ public class CraftDolphin extends CraftWaterMob implements Dolphin {
|
||||
public EntityType getType() {
|
||||
return EntityType.DOLPHIN;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMoistness() {
|
||||
+ return this.getHandle().getMoistnessLevel();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setMoistness(int moistness) {
|
||||
+ this.getHandle().setMoisntessLevel(moistness);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHasFish(boolean hasFish) {
|
||||
+ this.getHandle().setGotFish(hasFish);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasFish() {
|
||||
+ return this.getHandle().gotFish();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.Location getTreasureLocation() {
|
||||
+ return net.minecraft.server.MCUtil.toLocation(this.getHandle().level, this.getHandle().getTreasurePos());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTreasureLocation(org.bukkit.Location location) {
|
||||
+ this.getHandle().setTreasurePos(net.minecraft.server.MCUtil.toBlockPosition(location));
|
||||
+ }
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 27 May 2021 21:58:24 -0700
|
||||
Subject: [PATCH] More PotionEffectType API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
index fdd8e353bcbd2faace59288810d1a5121f174b56..82a6702a2ddc35222f5a416364de8c397c85d5bb 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java
|
||||
@@ -102,4 +102,46 @@ public class CraftPotionEffectType extends PotionEffectType {
|
||||
public Color getColor() {
|
||||
return Color.fromRGB(this.handle.getColor());
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public org.bukkit.NamespacedKey getKey() {
|
||||
+ return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(net.minecraft.core.Registry.MOB_EFFECT.getKey(this.handle));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Map<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> getEffectAttributes() {
|
||||
+ // re-create map each time because a nms MobEffect can have its attributes modified
|
||||
+ final java.util.Map<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> attributeMap = new java.util.HashMap<>();
|
||||
+ this.handle.getAttributeModifiers().forEach((attribute, attributeModifier) -> {
|
||||
+ attributeMap.put(org.bukkit.craftbukkit.attribute.CraftAttributeMap.fromMinecraft(attribute.toString()), org.bukkit.craftbukkit.attribute.CraftAttributeInstance.convert(attributeModifier));
|
||||
+ });
|
||||
+ return java.util.Map.copyOf(attributeMap);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public double getAttributeModifierAmount(org.bukkit.attribute.Attribute attribute, int effectAmplifier) {
|
||||
+ com.google.common.base.Preconditions.checkArgument(effectAmplifier >= 0, "effectAmplifier must be greater than or equal to 0");
|
||||
+ net.minecraft.world.entity.ai.attributes.Attribute nmsAttribute = org.bukkit.craftbukkit.attribute.CraftAttributeMap.toMinecraft(attribute);
|
||||
+ com.google.common.base.Preconditions.checkArgument(this.handle.getAttributeModifiers().containsKey(nmsAttribute), attribute + " is not present on " + this.getKey());
|
||||
+ return this.handle.getAttributeModifierValue(effectAmplifier, this.handle.getAttributeModifiers().get(nmsAttribute));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public PotionEffectType.Category getEffectCategory() {
|
||||
+ return fromNMS(handle.getCategory());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String translationKey() {
|
||||
+ return this.handle.getDescriptionId();
|
||||
+ }
|
||||
+
|
||||
+ public static PotionEffectType.Category fromNMS(net.minecraft.world.effect.MobEffectCategory mobEffectInfo) {
|
||||
+ return switch (mobEffectInfo) {
|
||||
+ case BENEFICIAL -> PotionEffectType.Category.BENEFICIAL;
|
||||
+ case HARMFUL -> PotionEffectType.Category.HARMFUL;
|
||||
+ case NEUTRAL -> PotionEffectType.Category.NEUTRAL;
|
||||
+ };
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java b/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..a5012bc0469ba03cde66749a11f4e7d93206bfd7
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/effects/EffectCategoryTest.java
|
||||
@@ -0,0 +1,28 @@
|
||||
+package io.papermc.paper.effects;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import net.minecraft.world.effect.MobEffectCategory;
|
||||
+import org.bukkit.craftbukkit.potion.CraftPotionEffectType;
|
||||
+import org.bukkit.potion.PotionEffectType;
|
||||
+import org.junit.Test;
|
||||
+
|
||||
+import static org.junit.Assert.assertEquals;
|
||||
+import static org.junit.Assert.assertNotNull;
|
||||
+
|
||||
+public class EffectCategoryTest {
|
||||
+
|
||||
+ @Test
|
||||
+ public void testEffectCategoriesExist() {
|
||||
+ for (MobEffectCategory mobEffectInfo : MobEffectCategory.values()) {
|
||||
+ assertNotNull(mobEffectInfo + " is missing a bukkit equivalent", CraftPotionEffectType.fromNMS(mobEffectInfo));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testCategoryHasEquivalentColors() {
|
||||
+ for (MobEffectCategory mobEffectInfo : MobEffectCategory.values()) {
|
||||
+ PotionEffectType.Category bukkitEffectCategory = CraftPotionEffectType.fromNMS(mobEffectInfo);
|
||||
+ assertEquals(mobEffectInfo.getTooltipFormatting().name() + " doesn't equal " + bukkitEffectCategory.getColor(), bukkitEffectCategory.getColor(), PaperAdventure.asAdventure(mobEffectInfo.getTooltipFormatting()));
|
||||
+ }
|
||||
+ }
|
||||
+}
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Mon, 12 Jul 2021 12:28:29 +0100
|
||||
Subject: [PATCH] Use a CHM for StructureTemplate.Pallete cache
|
||||
|
||||
fixes a CME due to this collection being shared across threads
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
index 129ebb095c2280376a59b54920e5ff90cf1f465a..c5827e4d870a0bba483649d54cae23072eab2b18 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/structure/templatesystem/StructureTemplate.java
|
||||
@@ -831,7 +831,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
|
||||
|
||||
Palette(List<StructureTemplate.StructureBlockInfo> infos) {
|
||||
this.blocks = infos;
|
|
@ -1,179 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Tue, 1 Feb 2022 15:51:55 -0700
|
||||
Subject: [PATCH] API for creating command sender which forwards feedback
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java b/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..ed3d488c6581df5eac425d9cccb8e741a52e91d5
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/commands/FeedbackForwardingSender.java
|
||||
@@ -0,0 +1,112 @@
|
||||
+package io.papermc.paper.commands;
|
||||
+
|
||||
+import io.papermc.paper.adventure.PaperAdventure;
|
||||
+import java.util.UUID;
|
||||
+import java.util.function.Consumer;
|
||||
+import net.kyori.adventure.audience.MessageType;
|
||||
+import net.kyori.adventure.identity.Identity;
|
||||
+import net.kyori.adventure.text.Component;
|
||||
+import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
+import net.minecraft.commands.CommandSource;
|
||||
+import net.minecraft.commands.CommandSourceStack;
|
||||
+import net.minecraft.network.chat.TextComponent;
|
||||
+import net.minecraft.server.level.ServerLevel;
|
||||
+import net.minecraft.world.phys.Vec2;
|
||||
+import net.minecraft.world.phys.Vec3;
|
||||
+import org.bukkit.command.CommandSender;
|
||||
+import org.bukkit.craftbukkit.CraftServer;
|
||||
+import org.bukkit.craftbukkit.command.ServerCommandSender;
|
||||
+import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
+import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
+import org.checkerframework.framework.qual.DefaultQualifier;
|
||||
+
|
||||
+@DefaultQualifier(NonNull.class)
|
||||
+public final class FeedbackForwardingSender extends ServerCommandSender {
|
||||
+ private final Consumer<? super Component> feedback;
|
||||
+ private final CraftServer server;
|
||||
+
|
||||
+ public FeedbackForwardingSender(final Consumer<? super Component> feedback, final CraftServer server) {
|
||||
+ super(((ServerCommandSender) server.getConsoleSender()).perm);
|
||||
+ this.server = server;
|
||||
+ this.feedback = feedback;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final String message) {
|
||||
+ this.sendMessage(LegacyComponentSerializer.legacySection().deserialize(message));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final String... messages) {
|
||||
+ for (final String message : messages) {
|
||||
+ this.sendMessage(message);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void sendMessage(final Identity identity, final Component message, final MessageType type) {
|
||||
+ this.feedback.accept(message);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public String getName() {
|
||||
+ return "FeedbackForwardingSender";
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Component name() {
|
||||
+ return Component.text(this.getName());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isOp() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setOp(final boolean value) {
|
||||
+ throw new UnsupportedOperationException("Cannot change operator status of " + this.getClass().getName());
|
||||
+ }
|
||||
+
|
||||
+ public CommandSourceStack asVanilla() {
|
||||
+ final @Nullable ServerLevel overworld = this.server.getServer().overworld();
|
||||
+ return new CommandSourceStack(
|
||||
+ new Source(this),
|
||||
+ overworld == null ? Vec3.ZERO : Vec3.atLowerCornerOf(overworld.getSharedSpawnPos()),
|
||||
+ Vec2.ZERO,
|
||||
+ overworld,
|
||||
+ 4,
|
||||
+ this.getName(),
|
||||
+ new TextComponent(this.getName()),
|
||||
+ this.server.getServer(),
|
||||
+ null
|
||||
+ );
|
||||
+ }
|
||||
+
|
||||
+ private record Source(FeedbackForwardingSender sender) implements CommandSource {
|
||||
+ @Override
|
||||
+ public void sendMessage(final net.minecraft.network.chat.Component message, final UUID sender) {
|
||||
+ this.sender.sendMessage(Identity.identity(sender), PaperAdventure.asAdventure(message));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean acceptsSuccess() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean acceptsFailure() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldInformAdmins() {
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public CommandSender getBukkitSender(final CommandSourceStack stack) {
|
||||
+ return this.sender;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index b4133f8dde5edb75b8d2d1008c50db7810276913..d9bfdeba8eaa8ab750b5037ff3d3a82a445adc2d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1988,6 +1988,13 @@ public final class CraftServer implements Server {
|
||||
return console.console;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public CommandSender createCommandSender(final java.util.function.Consumer<? super net.kyori.adventure.text.Component> feedback) {
|
||||
+ return new io.papermc.paper.commands.FeedbackForwardingSender(feedback, this);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public EntityMetadataStore getEntityMetadata() {
|
||||
return this.entityMetadata;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
index eaff8df6c8c12c64e005a68a02e2e35ed88f757c..1c638a4b1f2c841928d8b2a7ae43e4ebb1f7eac7 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java
|
||||
@@ -13,9 +13,15 @@ import org.bukkit.plugin.Plugin;
|
||||
|
||||
public abstract class ServerCommandSender implements CommandSender {
|
||||
private static PermissibleBase blockPermInst;
|
||||
- private final PermissibleBase perm;
|
||||
+ public final PermissibleBase perm; // Paper
|
||||
private net.kyori.adventure.pointer.Pointers adventure$pointers; // Paper - implement pointers
|
||||
|
||||
+ // Paper start
|
||||
+ public ServerCommandSender(final PermissibleBase permissibleBase) {
|
||||
+ this.perm = permissibleBase;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public ServerCommandSender() {
|
||||
if (this instanceof CraftBlockCommandSender) {
|
||||
if (ServerCommandSender.blockPermInst == null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
index 4aa1dc543950b5de64345b3403a6d0bc41c521df..4525fb3bc9b137bce3b59310a8aecca96d6ad5ba 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java
|
||||
@@ -84,6 +84,11 @@ public final class VanillaCommandWrapper extends BukkitCommand {
|
||||
if (sender instanceof ProxiedCommandSender) {
|
||||
return ((ProxiedNativeCommandSender) sender).getHandle();
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (sender instanceof io.papermc.paper.commands.FeedbackForwardingSender feedback) {
|
||||
+ return feedback.asVanilla();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
throw new IllegalArgumentException("Cannot make " + sender + " a vanilla command listener");
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 13 Jan 2022 23:05:53 -0800
|
||||
Subject: [PATCH] Add config for stronghold seed
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
index d5930d8ced9566c5494bed3685cf2d536eef6d50..daff5a9dd98e791b3f1dc898a082ff3e08adc92e 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/chunk/ChunkGenerator.java
|
||||
@@ -231,7 +231,13 @@ public abstract class ChunkGenerator implements BiomeManager.NoiseBiomeSource {
|
||||
int k = concentricringsstructureplacement.spread();
|
||||
Random random = new Random();
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.conf.strongholdSeed != null && this.structureSets.getResourceKey(holder).orElse(null) == net.minecraft.world.level.levelgen.structure.BuiltinStructureSets.STRONGHOLDS) {
|
||||
+ random.setSeed(this.conf.strongholdSeed);
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
random.setSeed(this.ringPlacementSeed);
|
||||
+ } // Paper
|
||||
double d0 = random.nextDouble() * 3.141592653589793D * 2.0D;
|
||||
int l = 0;
|
||||
int i1 = 0;
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index b498b027b127996976a394e9a86cfc90f8a8ed3b..31a447e6e156b7b244b2ac69a9c03c09c7ed388c 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -364,6 +364,7 @@ public class SpigotWorldConfig
|
||||
public int mansionSeed;
|
||||
public int fossilSeed;
|
||||
public int portalSeed;
|
||||
+ public Long strongholdSeed; // Paper
|
||||
private void initWorldGenSeeds()
|
||||
{
|
||||
this.villageSeed = this.getInt( "seed-village", 10387312 );
|
||||
@@ -381,6 +382,10 @@ public class SpigotWorldConfig
|
||||
this.mansionSeed = this.getInt( "seed-mansion", 10387319 );
|
||||
this.fossilSeed = this.getInt( "seed-fossil", 14357921 );
|
||||
this.portalSeed = this.getInt( "seed-portal", 34222645 );
|
||||
+ // Paper start
|
||||
+ final String strongholdSeedString = this.getString("seed-stronghold", "default");
|
||||
+ this.strongholdSeed = org.apache.commons.lang3.math.NumberUtils.isParsable(strongholdSeedString) ? Long.parseLong(strongholdSeedString) : null;
|
||||
+ // Paper end
|
||||
this.log( "Custom Map Seeds: Village: " + this.villageSeed + " Desert: " + this.desertSeed + " Igloo: " + this.iglooSeed + " Jungle: " + this.jungleSeed + " Swamp: " + this.swampSeed + " Monument: " + this.monumentSeed
|
||||
+ " Ocean: " + this.oceanSeed + " Shipwreck: " + this.shipwreckSeed + " End City: " + this.endCitySeed + " Slime: " + this.slimeSeed + " Nether: " + this.netherSeed + " Mansion: " + this.mansionSeed + " Fossil: " + this.fossilSeed + " Portal: " + this.portalSeed );
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
||||
Date: Mon, 31 Jan 2022 11:21:50 +0100
|
||||
Subject: [PATCH] Implement regenerateChunk
|
||||
|
||||
Co-authored-by: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 925907eff49e26cac48e895f44c55f80b9a6f81e..7414bb0ba5754b4e3be468d3986a2a979de7c983 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -133,6 +133,7 @@ import org.bukkit.util.Vector;
|
||||
public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public static final int CUSTOM_DIMENSION_OFFSET = 10;
|
||||
private static final CraftPersistentDataTypeRegistry DATA_TYPE_REGISTRY = new CraftPersistentDataTypeRegistry();
|
||||
+ private static final ChunkStatus[] REGEN_CHUNK_STATUSES = {ChunkStatus.BIOMES, ChunkStatus.NOISE, ChunkStatus.SURFACE, ChunkStatus.CARVERS, ChunkStatus.LIQUID_CARVERS, ChunkStatus.FEATURES}; // Paper - implement regenerate chunk method
|
||||
|
||||
private final ServerLevel world;
|
||||
private WorldBorder worldBorder;
|
||||
@@ -426,27 +427,61 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public boolean regenerateChunk(int x, int z) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk regenerate"); // Spigot
|
||||
- throw new UnsupportedOperationException("Not supported in this Minecraft version! Unless you can fix it, this is not a bug :)");
|
||||
- /*
|
||||
- if (!unloadChunk0(x, z, false)) {
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- final long chunkKey = ChunkCoordIntPair.pair(x, z);
|
||||
- world.getChunkProvider().unloadQueue.remove(chunkKey);
|
||||
+ // Paper start - implement regenerateChunk method
|
||||
+ final ServerLevel serverLevel = this.world;
|
||||
+ final net.minecraft.server.level.ServerChunkCache serverChunkCache = serverLevel.getChunkSource();
|
||||
+ final ChunkPos chunkPos = new ChunkPos(x, z);
|
||||
+ final net.minecraft.world.level.chunk.LevelChunk levelChunk = serverChunkCache.getChunk(chunkPos.x, chunkPos.z, true);
|
||||
+ for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
|
||||
+ levelChunk.removeBlockEntity(blockPos);
|
||||
+ serverLevel.setBlock(blockPos, net.minecraft.world.level.block.Blocks.AIR.defaultBlockState(), 16);
|
||||
+ }
|
||||
+
|
||||
+ for (final ChunkStatus chunkStatus : REGEN_CHUNK_STATUSES) {
|
||||
+ final List<ChunkAccess> list = new ArrayList<>();
|
||||
+ final int range = Math.max(1, chunkStatus.getRange());
|
||||
+ for (int chunkX = chunkPos.z - range; chunkX <= chunkPos.z + range; chunkX++) {
|
||||
+ for (int chunkZ = chunkPos.x - range; chunkZ <= chunkPos.x + range; chunkZ++) {
|
||||
+ ChunkAccess chunkAccess = serverChunkCache.getChunk(chunkZ, chunkX, chunkStatus.getParent(), true);
|
||||
+ if (chunkAccess instanceof ImposterProtoChunk accessProtoChunk) {
|
||||
+ chunkAccess = new ImposterProtoChunk(accessProtoChunk.getWrapped(), true);
|
||||
+ } else if (chunkAccess instanceof net.minecraft.world.level.chunk.LevelChunk accessLevelChunk) {
|
||||
+ chunkAccess = new ImposterProtoChunk(accessLevelChunk, true);
|
||||
+ }
|
||||
+ list.add(chunkAccess);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- net.minecraft.server.Chunk chunk = world.getChunkProvider().generateChunk(x, z);
|
||||
- PlayerChunk playerChunk = world.getPlayerChunkMap().getChunk(x, z);
|
||||
- if (playerChunk != null) {
|
||||
- playerChunk.chunk = chunk;
|
||||
+ final com.mojang.datafixers.util.Either<ChunkAccess, ChunkHolder.ChunkLoadingFailure> either = chunkStatus.generate(
|
||||
+ Runnable::run,
|
||||
+ serverLevel,
|
||||
+ serverChunkCache.getGenerator(),
|
||||
+ serverLevel.getStructureManager(),
|
||||
+ serverChunkCache.getLightEngine(),
|
||||
+ chunk -> {
|
||||
+ throw new UnsupportedOperationException("Not creating full chunks here");
|
||||
+ },
|
||||
+ list,
|
||||
+ true
|
||||
+ ).join();
|
||||
+ if (chunkStatus == ChunkStatus.NOISE) {
|
||||
+ either.left().ifPresent(chunk -> net.minecraft.world.level.levelgen.Heightmap.primeHeightmaps(chunk, ChunkStatus.POST_FEATURES));
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (chunk != null) {
|
||||
- refreshChunk(x, z);
|
||||
+ for (final BlockPos blockPos : BlockPos.betweenClosed(chunkPos.getMinBlockX(), serverLevel.getMinBuildHeight(), chunkPos.getMinBlockZ(), chunkPos.getMaxBlockX(), serverLevel.getMaxBuildHeight() - 1, chunkPos.getMaxBlockZ())) {
|
||||
+ serverChunkCache.blockChanged(blockPos);
|
||||
}
|
||||
|
||||
- return chunk != null;
|
||||
- */
|
||||
+ final Set<ChunkPos> chunksToRelight = new HashSet<>(9);
|
||||
+ for (int chunkX = chunkPos.x - 1; chunkX <= chunkPos.x + 1 ; chunkX++) {
|
||||
+ for (int chunkZ = chunkPos.z - 1; chunkZ <= chunkPos.z + 1 ; chunkZ++) {
|
||||
+ chunksToRelight.add(new ChunkPos(chunkX, chunkZ));
|
||||
+ }
|
||||
+ }
|
||||
+ serverChunkCache.getLightEngine().relight(chunksToRelight, pos -> {}, relit -> {});
|
||||
+ return true;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
|
@ -1,30 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Bjarne Koll <lynxplay101@gmail.com>
|
||||
Date: Sat, 12 Feb 2022 03:20:36 +0100
|
||||
Subject: [PATCH] Log exceptions thrown during chat processing
|
||||
|
||||
Previously the async chat executor service would take chat handling
|
||||
using the #submit method, which wraps the logic in a future task.
|
||||
The future takes full ownership of the task, including any potential
|
||||
exception, meaning that the uncaught exception handler never gets
|
||||
notified about potential exceptions thrown during async chat logic.
|
||||
|
||||
As the chat task does neither need to be cancelled nor returns something
|
||||
required later on, this commit moves from #submit to #execute, skipping
|
||||
any future task creation. This properly propagates any exception upwards
|
||||
to the worker thread in the executor service, allowing the server to
|
||||
catch and properly log the exception to the console.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
index 8a0ced3f9b9099913ade4b71181aff6cafbc4ee6..21588ce5a408fed3454c317b56c05439ad3af27d 100644
|
||||
--- a/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
+++ b/src/main/java/net/minecraft/network/protocol/game/ServerboundChatPacket.java
|
||||
@@ -31,7 +31,7 @@ public class ServerboundChatPacket implements Packet<ServerGamePacketListener> {
|
||||
public void handle(final ServerGamePacketListener listener) {
|
||||
if ( !this.message.startsWith("/") )
|
||||
{
|
||||
- ServerboundChatPacket.executors.submit( new Runnable()
|
||||
+ ServerboundChatPacket.executors.execute( new Runnable() // Paper - Use #execute to propagate exceptions up instead of swallowing them
|
||||
{
|
||||
|
||||
@Override
|
|
@ -1,43 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Fri, 8 Oct 2021 13:12:58 -0700
|
||||
Subject: [PATCH] Fix cancelled powdered snow bucket placement
|
||||
|
||||
Cancelling the placement of powdered snow from the powdered
|
||||
snow bucket didn't revert grass that became snowy because of the
|
||||
placement.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/BlockItem.java b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
index 893d5bf448ddbccb30db0ee751c7f4a4e83634b9..8f3b9b8784f0d7b137a1ad87655ee8bad801b59d 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/BlockItem.java
|
||||
@@ -115,6 +115,7 @@ public class BlockItem extends Item {
|
||||
blockstate.update(true, false);
|
||||
|
||||
if (this instanceof SolidBucketItem) {
|
||||
+ ((ServerPlayer) entityhuman).connection.send(new net.minecraft.network.protocol.game.ClientboundBlockUpdatePacket(world, blockposition.below())); // Paper - update block below
|
||||
((ServerPlayer) entityhuman).getBukkitEntity().updateInventory(); // SPIGOT-4541
|
||||
}
|
||||
return InteractionResult.FAIL;
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index a61a309bb921deba8b8022bc4e9fd04c2f8eba63..dc4639f905fb71435daf29c61f64621a3e2cc533 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -325,7 +325,7 @@ public final class ItemStack {
|
||||
int oldCount = this.getCount();
|
||||
ServerLevel world = (ServerLevel) itemactioncontext.getLevel();
|
||||
|
||||
- if (!(this.getItem() instanceof BucketItem || this.getItem() instanceof SolidBucketItem)) { // if not bucket
|
||||
+ if (!(this.getItem() instanceof BucketItem/* || this.getItem() instanceof SolidBucketItem*/)) { // if not bucket // Paper - capture block states for snow buckets
|
||||
world.captureBlockStates = true;
|
||||
// special case bonemeal
|
||||
if (this.getItem() == Items.BONE_MEAL) {
|
||||
@@ -379,7 +379,7 @@ public final class ItemStack {
|
||||
world.capturedBlockStates.clear();
|
||||
if (blocks.size() > 1) {
|
||||
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(world, entityhuman, enumhand, blocks, blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
- } else if (blocks.size() == 1) {
|
||||
+ } else if (blocks.size() == 1 && item != Items.POWDER_SNOW_BUCKET) { // Paper - don't call event twice for snow buckets
|
||||
placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(world, entityhuman, enumhand, blocks.get(0), blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
}
|
||||
|
|
@ -1,20 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Sat, 12 Feb 2022 12:40:50 -0700
|
||||
Subject: [PATCH] Add missing Validate calls to CraftServer#getSpawnLimit
|
||||
|
||||
Copies appropriate checks from CraftWorld#getSpawnLimit
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index d9bfdeba8eaa8ab750b5037ff3d3a82a445adc2d..fbd4ecab83955c3c56fa076da12b28399641bd50 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -2157,6 +2157,8 @@ public final class CraftServer implements Server {
|
||||
@Override
|
||||
public int getSpawnLimit(SpawnCategory spawnCategory) {
|
||||
// Paper start
|
||||
+ Validate.notNull(spawnCategory, "SpawnCategory cannot be null");
|
||||
+ Validate.isTrue(CraftSpawnCategory.isValidForLimits(spawnCategory), "SpawnCategory." + spawnCategory + " does not have a spawn limit.");
|
||||
return this.getSpawnLimitUnsafe(spawnCategory);
|
||||
}
|
||||
public int getSpawnLimitUnsafe(final SpawnCategory spawnCategory) {
|
|
@ -1,88 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sun, 3 Jan 2021 20:03:35 -0800
|
||||
Subject: [PATCH] Add GameEvent tags
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/CraftGameEventTag.java b/src/main/java/io/papermc/paper/CraftGameEventTag.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..cb78a3d4e21376ea24347187478525d5f0c24079
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/CraftGameEventTag.java
|
||||
@@ -0,0 +1,34 @@
|
||||
+package io.papermc.paper;
|
||||
+
|
||||
+import net.minecraft.core.Registry;
|
||||
+import net.minecraft.resources.ResourceKey;
|
||||
+import net.minecraft.tags.TagKey;
|
||||
+import org.bukkit.GameEvent;
|
||||
+import org.bukkit.craftbukkit.tag.CraftTag;
|
||||
+import org.bukkit.craftbukkit.util.CraftNamespacedKey;
|
||||
+import org.jetbrains.annotations.NotNull;
|
||||
+
|
||||
+import java.util.Collections;
|
||||
+import java.util.IdentityHashMap;
|
||||
+import java.util.Map;
|
||||
+import java.util.Objects;
|
||||
+import java.util.Set;
|
||||
+import java.util.stream.Collectors;
|
||||
+
|
||||
+public class CraftGameEventTag extends CraftTag<net.minecraft.world.level.gameevent.GameEvent, GameEvent> {
|
||||
+
|
||||
+ public CraftGameEventTag(net.minecraft.core.Registry<net.minecraft.world.level.gameevent.GameEvent> registry, TagKey<net.minecraft.world.level.gameevent.GameEvent> tag) {
|
||||
+ super(registry, tag);
|
||||
+ }
|
||||
+
|
||||
+ private static final Map<GameEvent, ResourceKey<net.minecraft.world.level.gameevent.GameEvent>> KEY_CACHE = Collections.synchronizedMap(new IdentityHashMap<>());
|
||||
+ @Override
|
||||
+ public boolean isTagged(@NotNull GameEvent gameEvent) {
|
||||
+ return registry.getHolderOrThrow(KEY_CACHE.computeIfAbsent(gameEvent, event -> ResourceKey.create(Registry.GAME_EVENT_REGISTRY, CraftNamespacedKey.toMinecraft(event.getKey())))).is(tag);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public @NotNull Set<GameEvent> getValues() {
|
||||
+ return getHandle().stream().map((nms) -> Objects.requireNonNull(GameEvent.getByKey(CraftNamespacedKey.fromMinecraft(Registry.GAME_EVENT.getKey(nms.value()))), nms + " is not a recognized game event")).collect(Collectors.toUnmodifiableSet());
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index fbd4ecab83955c3c56fa076da12b28399641bd50..2e0517aa65102af5c7aef08acbc25646b1a0afd8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -97,6 +97,7 @@ import net.minecraft.world.level.biome.BiomeSource;
|
||||
import net.minecraft.world.level.block.Block;
|
||||
import net.minecraft.world.level.dimension.DimensionType;
|
||||
import net.minecraft.world.level.dimension.LevelStem;
|
||||
+import net.minecraft.world.level.gameevent.GameEvent;
|
||||
import net.minecraft.world.level.levelgen.NoiseBasedChunkGenerator;
|
||||
import net.minecraft.world.level.levelgen.PatrolSpawner;
|
||||
import net.minecraft.world.level.levelgen.PhantomSpawner;
|
||||
@@ -2563,6 +2564,15 @@ public final class CraftServer implements Server {
|
||||
return (org.bukkit.Tag<T>) new CraftEntityTag(Registry.ENTITY_TYPE, entityTagKey);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
|
||||
+ Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class, "Game Event namespace must have GameEvent type");
|
||||
+ TagKey<GameEvent> gameEventTagKey = TagKey.create(Registry.GAME_EVENT_REGISTRY, key);
|
||||
+ if (Registry.GAME_EVENT.isKnownTagName(gameEventTagKey)) {
|
||||
+ return (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(Registry.GAME_EVENT, gameEventTagKey);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
@@ -2595,6 +2605,13 @@ public final class CraftServer implements Server {
|
||||
Registry<EntityType<?>> entityTags = Registry.ENTITY_TYPE;
|
||||
return entityTags.getTags().map(pair -> (org.bukkit.Tag<T>) new CraftEntityTag(entityTags, pair.getFirst())).collect(ImmutableList.toImmutableList());
|
||||
}
|
||||
+ // Paper start
|
||||
+ case org.bukkit.Tag.REGISTRY_GAME_EVENTS -> {
|
||||
+ Preconditions.checkArgument(clazz == org.bukkit.GameEvent.class);
|
||||
+ Registry<GameEvent> gameEvents = Registry.GAME_EVENT;
|
||||
+ return gameEvents.getTags().map(pair -> (org.bukkit.Tag<T>) new io.papermc.paper.CraftGameEventTag(gameEvents, pair.getFirst())).collect(ImmutableList.toImmutableList());
|
||||
+ // Paper end
|
||||
+ }
|
||||
default -> throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,37 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 28 Dec 2021 07:19:01 -0800
|
||||
Subject: [PATCH] Execute chunk tasks fairly for worlds while waiting for next
|
||||
tick
|
||||
|
||||
Currently, only the first world would have had tasks executed.
|
||||
This might result in chunks loading far slower in the nether,
|
||||
for example.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 01aefce226ae82d707b38b0d56d2580d411a3c9a..c2c1242bcf26c73b3520c797e77c3c2d430dfac7 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -1354,6 +1354,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.executeMidTickTasks(); // Paper - execute chunk tasks mid tick
|
||||
return true;
|
||||
} else {
|
||||
+ boolean ret = false; // Paper - force execution of all worlds, do not just bias the first
|
||||
if (this.haveTime()) {
|
||||
Iterator iterator = this.getAllLevels().iterator();
|
||||
|
||||
@@ -1361,12 +1362,12 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
ServerLevel worldserver = (ServerLevel) iterator.next();
|
||||
|
||||
if (worldserver.getChunkSource().pollTask()) {
|
||||
- return true;
|
||||
+ ret = true; // Paper - force execution of all worlds, do not just bias the first
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- return false;
|
||||
+ return ret; // Paper - force execution of all worlds, do not just bias the first
|
||||
}
|
||||
}
|
||||
|
|
@ -1,249 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 21 Mar 2021 16:25:42 -0700
|
||||
Subject: [PATCH] Replace ticket level propagator
|
||||
|
||||
Mojang's propagator is slow, and this isn't surprising
|
||||
given it's built on the same utilities the vanilla light engine
|
||||
is built on. The simple propagator I wrote is approximately 4x
|
||||
faster when simulating player movement. For a long time timing
|
||||
reports have shown this function take up significant tick, (
|
||||
approx 10% or more), and async sampling data shows the level
|
||||
propagation alone takes up a significant amount. So this
|
||||
should help with that. A big side effect is that mid-tick
|
||||
will be more effective, since more time will be allocated
|
||||
to actually processing chunk tasks vs the ticket level updates.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/DistanceManager.java b/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
index 3542b8b347b9a142c53f300251a05a11e421c36f..2c5cf08e16669d5be8ba7d6e3f9282c74f9ea295 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/DistanceManager.java
|
||||
@@ -38,6 +38,7 @@ import net.minecraft.world.level.chunk.ChunkStatus;
|
||||
import net.minecraft.world.level.chunk.LevelChunk;
|
||||
import org.slf4j.Logger;
|
||||
|
||||
+import it.unimi.dsi.fastutil.longs.Long2IntLinkedOpenHashMap; // Paper
|
||||
public abstract class DistanceManager {
|
||||
|
||||
static final Logger LOGGER = LogUtils.getLogger();
|
||||
@@ -48,7 +49,7 @@ public abstract class DistanceManager {
|
||||
private static final int BLOCK_TICKING_LEVEL_THRESHOLD = 33;
|
||||
final Long2ObjectMap<ObjectSet<ServerPlayer>> playersPerChunk = new Long2ObjectOpenHashMap();
|
||||
public final Long2ObjectOpenHashMap<SortedArraySet<Ticket<?>>> tickets = new Long2ObjectOpenHashMap();
|
||||
- private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker();
|
||||
+ //private final DistanceManager.ChunkTicketTracker ticketTracker = new DistanceManager.ChunkTicketTracker(); // Paper - replace ticket level propagator
|
||||
public static final int MOB_SPAWN_RANGE = 8; // private final ChunkMapDistance.b f = new ChunkMapDistance.b(8); // Paper - no longer used
|
||||
//private final TickingTracker tickingTicketsTracker = new TickingTracker(); // Paper - no longer used
|
||||
//private final DistanceManager.PlayerTicketTracker playerTicketManager = new DistanceManager.PlayerTicketTracker(33); // Paper - no longer used
|
||||
@@ -83,6 +84,46 @@ public abstract class DistanceManager {
|
||||
this.chunkMap = chunkMap; // Paper
|
||||
}
|
||||
|
||||
+ // Paper start - replace ticket level propagator
|
||||
+ protected final Long2IntLinkedOpenHashMap ticketLevelUpdates = new Long2IntLinkedOpenHashMap() {
|
||||
+ @Override
|
||||
+ protected void rehash(int newN) {
|
||||
+ // no downsizing allowed
|
||||
+ if (newN < this.n) {
|
||||
+ return;
|
||||
+ }
|
||||
+ super.rehash(newN);
|
||||
+ }
|
||||
+ };
|
||||
+ protected final io.papermc.paper.util.misc.Delayed8WayDistancePropagator2D ticketLevelPropagator = new io.papermc.paper.util.misc.Delayed8WayDistancePropagator2D(
|
||||
+ (long coordinate, byte oldLevel, byte newLevel) -> {
|
||||
+ DistanceManager.this.ticketLevelUpdates.putAndMoveToLast(coordinate, convertBetweenTicketLevels(newLevel));
|
||||
+ }
|
||||
+ );
|
||||
+ // function for converting between ticket levels and propagator levels and vice versa
|
||||
+ // the problem is the ticket level propagator will propagate from a set source down to zero, whereas mojang expects
|
||||
+ // levels to propagate from a set value up to a maximum value. so we need to convert the levels we put into the propagator
|
||||
+ // and the levels we get out of the propagator
|
||||
+
|
||||
+ // this maps so that GOLDEN_TICKET + 1 will be 0 in the propagator, GOLDEN_TICKET will be 1, and so on
|
||||
+ // we need GOLDEN_TICKET+1 as 0 because anything >= GOLDEN_TICKET+1 should be unloaded
|
||||
+ public static int convertBetweenTicketLevels(final int level) {
|
||||
+ return ChunkMap.MAX_CHUNK_DISTANCE - level + 1;
|
||||
+ }
|
||||
+
|
||||
+ protected final int getPropagatedTicketLevel(final long coordinate) {
|
||||
+ return convertBetweenTicketLevels(this.ticketLevelPropagator.getLevel(coordinate));
|
||||
+ }
|
||||
+
|
||||
+ protected final void updateTicketLevel(final long coordinate, final int ticketLevel) {
|
||||
+ if (ticketLevel > ChunkMap.MAX_CHUNK_DISTANCE) {
|
||||
+ this.ticketLevelPropagator.removeSource(coordinate);
|
||||
+ } else {
|
||||
+ this.ticketLevelPropagator.setSource(coordinate, convertBetweenTicketLevels(ticketLevel));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end - replace ticket level propagator
|
||||
+
|
||||
protected void purgeStaleTickets() {
|
||||
++this.ticketTickCounter;
|
||||
ObjectIterator objectiterator = this.tickets.long2ObjectEntrySet().fastIterator();
|
||||
@@ -117,7 +158,7 @@ public abstract class DistanceManager {
|
||||
}
|
||||
|
||||
if (flag) {
|
||||
- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt((SortedArraySet) entry.getValue()), false);
|
||||
+ this.updateTicketLevel(entry.getLongKey(), getTicketLevelAt(entry.getValue())); // Paper - replace ticket level propagator
|
||||
}
|
||||
|
||||
if (((SortedArraySet) entry.getValue()).isEmpty()) {
|
||||
@@ -140,61 +181,94 @@ public abstract class DistanceManager {
|
||||
@Nullable
|
||||
protected abstract ChunkHolder updateChunkScheduling(long pos, int level, @Nullable ChunkHolder holder, int k);
|
||||
|
||||
+ protected long ticketLevelUpdateCount; // Paper - replace ticket level propagator
|
||||
public boolean runAllUpdates(ChunkMap chunkStorage) {
|
||||
//this.f.a(); // Paper - no longer used
|
||||
//this.tickingTicketsTracker.runAllUpdates(); // Paper - no longer used
|
||||
org.spigotmc.AsyncCatcher.catchOp("DistanceManagerTick"); // Paper
|
||||
//this.playerTicketManager.runAllUpdates(); // Paper - no longer used
|
||||
- int i = Integer.MAX_VALUE - this.ticketTracker.runDistanceUpdates(Integer.MAX_VALUE);
|
||||
- boolean flag = i != 0;
|
||||
+ boolean flag = this.ticketLevelPropagator.propagateUpdates(); // Paper - replace ticket level propagator
|
||||
|
||||
if (flag) {
|
||||
;
|
||||
}
|
||||
|
||||
- // Paper start
|
||||
- if (!this.pendingChunkUpdates.isEmpty()) {
|
||||
- this.pollingPendingChunkUpdates = true; try { // Paper - Chunk priority
|
||||
- while(!this.pendingChunkUpdates.isEmpty()) {
|
||||
- ChunkHolder remove = this.pendingChunkUpdates.remove();
|
||||
- remove.isUpdateQueued = false;
|
||||
- remove.updateFutures(chunkStorage, this.mainThreadExecutor);
|
||||
- }
|
||||
- } finally { this.pollingPendingChunkUpdates = false; } // Paper - Chunk priority
|
||||
- // Paper end
|
||||
- return true;
|
||||
- } else {
|
||||
- if (!this.ticketsToRelease.isEmpty()) {
|
||||
- LongIterator longiterator = this.ticketsToRelease.iterator();
|
||||
+ // Paper start - replace level propagator
|
||||
+ ticket_update_loop:
|
||||
+ while (!this.ticketLevelUpdates.isEmpty()) {
|
||||
+ flag = true;
|
||||
|
||||
- while (longiterator.hasNext()) {
|
||||
- long j = longiterator.nextLong();
|
||||
+ boolean oldPolling = this.pollingPendingChunkUpdates;
|
||||
+ this.pollingPendingChunkUpdates = true;
|
||||
+ try {
|
||||
+ for (java.util.Iterator<Long2IntMap.Entry> iterator = this.ticketLevelUpdates.long2IntEntrySet().fastIterator(); iterator.hasNext();) {
|
||||
+ Long2IntMap.Entry entry = iterator.next();
|
||||
+ long key = entry.getLongKey();
|
||||
+ int newLevel = entry.getIntValue();
|
||||
+ ChunkHolder chunk = this.getChunk(key);
|
||||
+
|
||||
+ if (chunk == null && newLevel > ChunkMap.MAX_CHUNK_DISTANCE) {
|
||||
+ // not loaded and it shouldn't be loaded!
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- if (this.getTickets(j).stream().anyMatch((ticket) -> {
|
||||
- return ticket.getType() == TicketType.PLAYER;
|
||||
- })) {
|
||||
- ChunkHolder playerchunk = chunkStorage.getUpdatingChunkIfPresent(j);
|
||||
+ int currentLevel = chunk == null ? ChunkMap.MAX_CHUNK_DISTANCE + 1 : chunk.getTicketLevel();
|
||||
|
||||
- if (playerchunk == null) {
|
||||
- throw new IllegalStateException();
|
||||
+ if (currentLevel == newLevel) {
|
||||
+ // nothing to do
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ this.updateChunkScheduling(key, newLevel, chunk, currentLevel);
|
||||
+ }
|
||||
+
|
||||
+ long recursiveCheck = ++this.ticketLevelUpdateCount;
|
||||
+ while (!this.ticketLevelUpdates.isEmpty()) {
|
||||
+ long key = this.ticketLevelUpdates.firstLongKey();
|
||||
+ int newLevel = this.ticketLevelUpdates.removeFirstInt();
|
||||
+ ChunkHolder chunk = this.getChunk(key);
|
||||
+
|
||||
+ if (chunk == null) {
|
||||
+ if (newLevel <= ChunkMap.MAX_CHUNK_DISTANCE) {
|
||||
+ throw new IllegalStateException("Expected chunk holder to be created");
|
||||
}
|
||||
+ // not loaded and it shouldn't be loaded!
|
||||
+ continue;
|
||||
+ }
|
||||
|
||||
- CompletableFuture<Either<LevelChunk, ChunkHolder.ChunkLoadingFailure>> completablefuture = playerchunk.getEntityTickingChunkFuture();
|
||||
+ int currentLevel = chunk.oldTicketLevel;
|
||||
|
||||
- completablefuture.thenAccept((either) -> {
|
||||
- this.mainThreadExecutor.execute(() -> {
|
||||
- this.ticketThrottlerReleaser.tell(ChunkTaskPriorityQueueSorter.release(() -> {
|
||||
- }, j, false));
|
||||
- });
|
||||
- });
|
||||
+ if (currentLevel == newLevel) {
|
||||
+ // nothing to do
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ chunk.updateFutures(chunkStorage, this.mainThreadExecutor);
|
||||
+ if (recursiveCheck != this.ticketLevelUpdateCount) {
|
||||
+ // back to the start, we must create player chunks and update the ticket level fields before
|
||||
+ // processing the actual level updates
|
||||
+ continue ticket_update_loop;
|
||||
}
|
||||
}
|
||||
|
||||
- this.ticketsToRelease.clear();
|
||||
- }
|
||||
+ for (;;) {
|
||||
+ if (recursiveCheck != this.ticketLevelUpdateCount) {
|
||||
+ continue ticket_update_loop;
|
||||
+ }
|
||||
+ ChunkHolder pendingUpdate = this.pendingChunkUpdates.poll();
|
||||
+ if (pendingUpdate == null) {
|
||||
+ break;
|
||||
+ }
|
||||
|
||||
- return flag;
|
||||
+ pendingUpdate.updateFutures(chunkStorage, this.mainThreadExecutor);
|
||||
+ }
|
||||
+ } finally {
|
||||
+ this.pollingPendingChunkUpdates = oldPolling;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ return flag;
|
||||
+ // Paper end - replace level propagator
|
||||
}
|
||||
boolean pollingPendingChunkUpdates = false; // Paper - Chunk priority
|
||||
|
||||
@@ -206,7 +280,7 @@ public abstract class DistanceManager {
|
||||
|
||||
ticket1.setCreatedTick(this.ticketTickCounter);
|
||||
if (ticket.getTicketLevel() < j) {
|
||||
- this.ticketTracker.update(i, ticket.getTicketLevel(), true);
|
||||
+ this.updateTicketLevel(i, ticket.getTicketLevel()); // Paper - replace ticket level propagator
|
||||
}
|
||||
|
||||
return ticket == ticket1; // CraftBukkit
|
||||
@@ -250,7 +324,7 @@ public abstract class DistanceManager {
|
||||
// Paper start - Chunk priority
|
||||
int newLevel = getTicketLevelAt(arraysetsorted);
|
||||
if (newLevel > oldLevel) {
|
||||
- this.ticketTracker.update(i, newLevel, false);
|
||||
+ this.updateTicketLevel(i, newLevel); // Paper // Paper - replace ticket level propagator
|
||||
}
|
||||
// Paper end
|
||||
return removed; // CraftBukkit
|
||||
@@ -587,7 +661,7 @@ public abstract class DistanceManager {
|
||||
SortedArraySet<Ticket<?>> tickets = entry.getValue();
|
||||
if (tickets.remove(target)) {
|
||||
// copied from removeTicket
|
||||
- this.ticketTracker.update(entry.getLongKey(), DistanceManager.getTicketLevelAt(tickets), false);
|
||||
+ this.updateTicketLevel(entry.getLongKey(), getTicketLevelAt(tickets)); // Paper - replace ticket level propagator
|
||||
|
||||
// can't use entry after it's removed
|
||||
if (tickets.isEmpty()) {
|
|
@ -1,48 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 13 Jan 2022 15:20:47 -0800
|
||||
Subject: [PATCH] Furnace RecipesUsed API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
index 3da4616c904d47bbecae0d4cb6970496fbec9a8b..f49bb90e6c30dd928b352c867819b687e4557893 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java
|
||||
@@ -93,5 +93,37 @@ public abstract class CraftFurnace<T extends AbstractFurnaceBlockEntity> extends
|
||||
snapshot.cookSpeedMultiplier = multiplier;
|
||||
snapshot.cookingTotalTime = AbstractFurnaceBlockEntity.getTotalCookTime(this.isPlaced() ? this.world.getHandle() : null, snapshot.recipeType, snapshot, snapshot.cookSpeedMultiplier); // Update the snapshot's current total cook time to scale with the newly set multiplier
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) {
|
||||
+ return this.getSnapshot().getRecipesUsed().getInt(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasRecipeUsedCount(org.bukkit.NamespacedKey furnaceRecipe) {
|
||||
+ return this.getSnapshot().getRecipesUsed().containsKey(org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRecipeUsedCount(org.bukkit.inventory.CookingRecipe<?> furnaceRecipe, int count) {
|
||||
+ final net.minecraft.resources.ResourceLocation location = org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(furnaceRecipe.getKey());
|
||||
+ java.util.Optional<? extends net.minecraft.world.item.crafting.Recipe<?>> nmsRecipe = (this.isPlaced() ? this.world.getHandle().getRecipeManager() : net.minecraft.server.MinecraftServer.getServer().getRecipeManager()).byKey(location);
|
||||
+ com.google.common.base.Preconditions.checkArgument(nmsRecipe.isPresent() && nmsRecipe.get() instanceof net.minecraft.world.item.crafting.AbstractCookingRecipe, furnaceRecipe.getKey() + " is not recognized as a valid and registered furnace recipe");
|
||||
+ if (count > 0) {
|
||||
+ this.getSnapshot().getRecipesUsed().put(location, count);
|
||||
+ } else {
|
||||
+ this.getSnapshot().getRecipesUsed().removeInt(location);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRecipesUsed(java.util.Map<org.bukkit.inventory.CookingRecipe<?>, Integer> recipesUsed) {
|
||||
+ this.getSnapshot().getRecipesUsed().clear();
|
||||
+ recipesUsed.forEach((recipe, integer) -> {
|
||||
+ if (integer != null) {
|
||||
+ this.setRecipeUsedCount(recipe, integer);
|
||||
+ }
|
||||
+ });
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 19 Aug 2021 18:45:42 -0700
|
||||
Subject: [PATCH] Configurable sculk sensor listener range
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
index 2b1e61dacaf4338d7584dea197c7439251951d81..16506b950bbe12f28cf0217b6131128723019e54 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SculkSensorBlockEntity.java
|
||||
@@ -26,12 +26,15 @@ public class SculkSensorBlockEntity extends BlockEntity implements VibrationList
|
||||
public void load(CompoundTag nbt) {
|
||||
super.load(nbt);
|
||||
this.lastVibrationFrequency = nbt.getInt("last_vibration_frequency");
|
||||
+ if (nbt.contains(PAPER_LISTENER_RANGE_NBT_KEY)) this.listener.listenerRange = nbt.getInt(PAPER_LISTENER_RANGE_NBT_KEY); // Paper
|
||||
}
|
||||
|
||||
+ private static final String PAPER_LISTENER_RANGE_NBT_KEY = "Paper.ListenerRange"; // Paper
|
||||
@Override
|
||||
protected void saveAdditional(CompoundTag nbt) {
|
||||
super.saveAdditional(nbt);
|
||||
nbt.putInt("last_vibration_frequency", this.lastVibrationFrequency);
|
||||
+ if (this.listener.listenerRange != ((SculkSensorBlock) net.minecraft.world.level.block.Blocks.SCULK_SENSOR).getListenerRange()) nbt.putInt(PAPER_LISTENER_RANGE_NBT_KEY, this.listener.listenerRange); // Paper - only save if it's different from the default
|
||||
}
|
||||
|
||||
public VibrationListener getListener() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
index 2733154f569002e426690dfcf362ff20da8cba72..34362768f38fb3122abcbd5e63fee38a631b9ee3 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSculkSensor.java
|
||||
@@ -21,4 +21,16 @@ public class CraftSculkSensor extends CraftBlockEntityState<SculkSensorBlockEnti
|
||||
Preconditions.checkArgument(0 <= lastVibrationFrequency && lastVibrationFrequency <= 15, "Vibration frequency must be between 0-15");
|
||||
getSnapshot().lastVibrationFrequency = lastVibrationFrequency;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getListenerRange() {
|
||||
+ return this.getSnapshot().getListener().listenerRange;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setListenerRange(int range) {
|
||||
+ Preconditions.checkArgument(range > 0, "Vibration listener range must be greater than 0");
|
||||
+ this.getSnapshot().getListener().listenerRange = range;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 16 Oct 2021 22:57:31 -0700
|
||||
Subject: [PATCH] Add missing block data mins and maxes
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLeaves.java b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLeaves.java
|
||||
index 5b0da54982fc0879005fd1db104284eb3318bee8..3c5a2de56724bc784f619f3087140c72a42dc57b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLeaves.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/type/CraftLeaves.java
|
||||
@@ -3,7 +3,7 @@ package org.bukkit.craftbukkit.block.data.type;
|
||||
import org.bukkit.block.data.type.Leaves;
|
||||
import org.bukkit.craftbukkit.block.data.CraftBlockData;
|
||||
|
||||
-public class CraftLeaves extends CraftBlockData implements Leaves {
|
||||
+public abstract class CraftLeaves extends CraftBlockData implements Leaves { // Paper - make abstract (not used anyways)
|
||||
|
||||
private static final net.minecraft.world.level.block.state.properties.IntegerProperty DISTANCE = getInteger("distance");
|
||||
private static final net.minecraft.world.level.block.state.properties.BooleanProperty PERSISTENT = getBoolean("persistent");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
index 83f86725c00f0e175cb46c7e27705ca777f413ba..24d16825c10edfed6d22e8e37ddb9fd804b716c4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCandle.java
|
||||
@@ -31,6 +31,12 @@ public final class CraftCandle extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public int getMaximumCandles() {
|
||||
return getMax(CraftCandle.CANDLES);
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumCandles() {
|
||||
+ return getMin(CraftCandle.CANDLES);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// org.bukkit.craftbukkit.block.data.CraftLightable
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCauldron.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCauldron.java
|
||||
index e17a85182555b7b50b4b1e42af871462699dba06..ef90de836888caa0a56c9c34c15bcd0d6c2d16a8 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCauldron.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftCauldron.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftCauldron extends org.bukkit.craftbukkit.block.data.Craft
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftCauldron.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftCauldron.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
index 780b6a29592571f4a730a858734256f69519cca7..ef97e77b25562a8aed35d68d42ced4825d43a29d 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftComposter.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftComposter extends org.bukkit.craftbukkit.block.data.Craf
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftComposter.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftComposter.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
index f083cf727e7fd55f0749e85e3d034b5606121110..e40cda2f23d63e9d2029a8c8818103b6eeb6a925 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftFluids.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftFluids extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftFluids.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftFluids.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
index 0d08c81dd8582ef4f259f0e0db88e1b85d79f2a1..5b96ec73bf7bd4d90ce77cfe8ffec82580b20d2b 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLayeredCauldron.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftLayeredCauldron extends org.bukkit.craftbukkit.block.dat
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftLayeredCauldron.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftLayeredCauldron.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
index c4ac30e38bf786c491e0e1d47a9003f2b8e1d985..709812fd312f9eddfada21d3836eca6a696183fd 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLeaves.java
|
||||
@@ -37,4 +37,16 @@ public final class CraftLeaves extends org.bukkit.craftbukkit.block.data.CraftBl
|
||||
public void setDistance(int distance) {
|
||||
set(CraftLeaves.DISTANCE, distance);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMaximumDistance() {
|
||||
+ return getMax(CraftLeaves.DISTANCE);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getMinimumDistance() {
|
||||
+ return getMin(CraftLeaves.DISTANCE);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
index de882af105fae1166aced908cfe45b826a07f418..0d430382a05dfc0802a2569816c5ec876a053f16 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftLight.java
|
||||
@@ -32,6 +32,13 @@ public final class CraftLight extends org.bukkit.craftbukkit.block.data.CraftBlo
|
||||
return getMax(CraftLight.LEVEL);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftLight.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// org.bukkit.craftbukkit.block.data.CraftWaterlogged
|
||||
|
||||
private static final net.minecraft.world.level.block.state.properties.BooleanProperty WATERLOGGED = getBoolean(net.minecraft.world.level.block.LightBlock.class, "waterlogged");
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPowderSnowCauldron.java b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPowderSnowCauldron.java
|
||||
index c6bd91bdf6bf64701ffc69619174cc3b43b72d88..c6289306f0f933b67ff1f6db63ef976df7aa5438 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPowderSnowCauldron.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/impl/CraftPowderSnowCauldron.java
|
||||
@@ -31,4 +31,11 @@ public final class CraftPowderSnowCauldron extends org.bukkit.craftbukkit.block.
|
||||
public int getMaximumLevel() {
|
||||
return getMax(CraftPowderSnowCauldron.LEVEL);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMinimumLevel() {
|
||||
+ return getMin(CraftPowderSnowCauldron.LEVEL);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Sat, 19 Feb 2022 20:15:41 -0800
|
||||
Subject: [PATCH] Option to have default CustomSpawners in custom worlds
|
||||
|
||||
By default, only LevelStem's that specifically match the ResourceKey for
|
||||
OVERWORLD will have the 5 (currently) impls of CustomSpawner (for
|
||||
phantoms, wandering traders, etc.). This adds an option to instead of
|
||||
just looking at the LevelStem key, look at the DimensionType key which
|
||||
is one level below that. Defaults to off to keep vanilla behavior.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
index 66d360b2c4ae9e380ec6c452a263c04bd3aef4ff..1ac6cf51f2682d5eb14fe19646e79f6617d492dd 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
|
||||
@@ -683,4 +683,9 @@ public class PaperConfig {
|
||||
globalMaxConcurrentChunkLoads = getDouble("settings.chunk-loading.global-max-concurrent-loads", 500.0);
|
||||
playerMaxChunkLoadRate = getDouble("settings.chunk-loading.player-max-chunk-load-rate", -1.0);
|
||||
}
|
||||
+
|
||||
+ public static boolean useDimensionTypeForCustomSpawners;
|
||||
+ private static void useDimensionTypeForCustomSpawners() {
|
||||
+ useDimensionTypeForCustomSpawners = getBoolean("settings.use-dimension-type-for-custom-spawners", false);
|
||||
+ }
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index c2c1242bcf26c73b3520c797e77c3c2d430dfac7..443fb9cdce8bf542ca6216aa65c3e48c66dde654 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -617,7 +617,15 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.commandStorage = new CommandStorage(worldpersistentdata);
|
||||
} else {
|
||||
ChunkProgressListener worldloadlistener = this.progressListenerFactory.create(11);
|
||||
- world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, holder, worldloadlistener, chunkgenerator, flag, j, ImmutableList.of(), true, org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
|
||||
+ // Paper start - option to use the dimension_type to check if spawners should be added. I imagine mojang will add some datapack-y way of managing this in the future.
|
||||
+ final List<CustomSpawner> spawners;
|
||||
+ if (com.destroystokyo.paper.PaperConfig.useDimensionTypeForCustomSpawners && this.registryHolder.registryOrThrow(Registry.DIMENSION_TYPE_REGISTRY).getResourceKey(holder.value()).orElseThrow() == DimensionType.OVERWORLD_LOCATION) {
|
||||
+ spawners = list;
|
||||
+ } else {
|
||||
+ spawners = Collections.emptyList();
|
||||
+ }
|
||||
+ world = new ServerLevel(this, this.executor, worldSession, iworlddataserver, worldKey, holder, worldloadlistener, chunkgenerator, flag, j, spawners, true, org.bukkit.World.Environment.getEnvironment(dimension), gen, biomeProvider);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
|
|
@ -1,41 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Tue, 22 Feb 2022 14:21:35 -0800
|
||||
Subject: [PATCH] Put world into worldlist before initing the world
|
||||
|
||||
Some parts of legacy conversion will need the overworld
|
||||
to get the legacy structure data storage
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 443fb9cdce8bf542ca6216aa65c3e48c66dde654..e4461fb3485391ec0a9d902d5b896bb95e7512b5 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -629,9 +629,10 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
}
|
||||
|
||||
worlddata.setModdedInfo(this.getServerModName(), this.getModdedStatus().shouldReportAsModified());
|
||||
+ this.levels.put(world.dimension(), world); // Paper - move up
|
||||
this.initWorld(world, worlddata, worldData, worlddata.worldGenSettings());
|
||||
|
||||
- this.levels.put(world.dimension(), world);
|
||||
+ // Paper - move up
|
||||
this.getPlayerList().addWorldborderListener(world);
|
||||
|
||||
if (worlddata.getCustomBossEvents() != null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 2e0517aa65102af5c7aef08acbc25646b1a0afd8..810986cc3b349a66c02f2a682daac8b4422917ae 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -1255,10 +1255,11 @@ public final class CraftServer implements Server {
|
||||
return null;
|
||||
}
|
||||
|
||||
+ console.levels.put(internal.dimension(), internal); // Paper - move up
|
||||
this.console.initWorld(internal, worlddata, worlddata, worlddata.worldGenSettings());
|
||||
|
||||
internal.setSpawnSettings(true, true);
|
||||
- console.levels.put(internal.dimension(), internal);
|
||||
+ // Paper - move up
|
||||
|
||||
this.getServer().prepareLevels(internal.getChunkSource().chunkMap.progressListener, internal);
|
||||
internal.entityManager.tick(); // SPIGOT-6526: Load pending entities so they are available to the API
|
|
@ -1,34 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
|
||||
Date: Thu, 23 Dec 2021 23:59:12 -0500
|
||||
Subject: [PATCH] Fix Entity Position Desync
|
||||
|
||||
If entities were teleported in the first tick it would not be send to the client.
|
||||
|
||||
This excludes hanging entities, as this fix caused problematic behavior due to them having their own
|
||||
position field.
|
||||
|
||||
This also fixes desync caused be relatively teleporting paintings. (https://bugs.mojang.com/browse/MC-249169)
|
||||
This is caused by the fact that setPacketCoordinates isn't called on paintings when they are spawned (unlike every other entity, like XP orbs)
|
||||
on the client for some reason. This causes it to be relatively teleported to the world origin (0,0,0).
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
index fe29bf349b987d633b185b9d44d221053fa2cc83..f91e1a876ad4c46a7c92cead18947a941b4d9e68 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
|
||||
@@ -164,13 +164,14 @@ public class ServerEntity {
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
- if (this.tickCount > 0 || this.entity instanceof AbstractArrow) {
|
||||
+ if (!(this.entity instanceof net.minecraft.world.entity.decoration.HangingEntity) || this.tickCount > 0 || this.entity instanceof AbstractArrow) { // Paper - Always update position
|
||||
// Paper start - remove allocation of Vec3D here
|
||||
long k = ClientboundMoveEntityPacket.entityToPacket(vec3d_dx);
|
||||
long l = ClientboundMoveEntityPacket.entityToPacket(vec3d_dy);
|
||||
long i1 = ClientboundMoveEntityPacket.entityToPacket(vec3d_dz);
|
||||
// Paper end - remove allocation of Vec3D here
|
||||
boolean flag4 = k < -32768L || k > 32767L || l < -32768L || l > 32767L || i1 < -32768L || i1 > 32767L;
|
||||
+ if (this.entity instanceof net.minecraft.world.entity.decoration.Painting) {flag4 = true;} // Paper - Always send exact position for paintings
|
||||
|
||||
if (!flag4 && this.teleportDelay <= 400 && !this.wasRiding && this.wasOnGround == this.entity.isOnGround() && !(com.destroystokyo.paper.PaperConfig.sendFullPosForHardCollidingEntities && this.entity.hardCollides())) { // Paper - send full pos for hard colliding entities to prevent collision problems due to desync
|
||||
if ((!flag2 || !flag3) && !(this.entity instanceof AbstractArrow)) {
|
|
@ -1,239 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Thu, 7 Oct 2021 14:34:55 -0700
|
||||
Subject: [PATCH] Custom Potion Mixes
|
||||
|
||||
|
||||
diff --git a/src/main/java/io/papermc/paper/potion/PaperPotionMix.java b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..6b0bed550763f34e18c9e92f9a47ec0c945b2c8b
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/io/papermc/paper/potion/PaperPotionMix.java
|
||||
@@ -0,0 +1,13 @@
|
||||
+package io.papermc.paper.potion;
|
||||
+
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import net.minecraft.world.item.crafting.Ingredient;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftItemStack;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftRecipe;
|
||||
+
|
||||
+public record PaperPotionMix(ItemStack result, Ingredient input, Ingredient ingredient) {
|
||||
+
|
||||
+ public PaperPotionMix(PotionMix potionMix) {
|
||||
+ this(CraftItemStack.asNMSCopy(potionMix.getResult()), CraftRecipe.toIngredient(potionMix.getInput(), true), CraftRecipe.toIngredient(potionMix.getIngredient(), true));
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index e4461fb3485391ec0a9d902d5b896bb95e7512b5..b079677723ff65f64adec044e7d89656ecc49e4d 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2055,6 +2055,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.worldData.setDataPackConfig(MinecraftServer.getSelectedPacks(this.packRepository));
|
||||
this.resources.managers.updateRegistryTags(this.registryAccess());
|
||||
io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
|
||||
+ net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
|
||||
new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
|
||||
if (Thread.currentThread() != this.serverThread) return; // Paper
|
||||
//this.getPlayerList().saveAll(); // Paper - we don't need to do this
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
index a809e8a903f98fcbcea3184fac6dfd04adc735f9..13720c2df8ac37d020d4a785e48c45877edf74b9 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/BrewingStandMenu.java
|
||||
@@ -168,7 +168,7 @@ public class BrewingStandMenu extends AbstractContainerMenu {
|
||||
}
|
||||
|
||||
public static boolean mayPlaceItem(ItemStack stack) {
|
||||
- return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE);
|
||||
+ return stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || PotionBrewing.isCustomInput(stack); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
index eee96f87f68d9146b1d19d5923d073fb5c39d507..5d86895f93cadcf0b123263c2a6f718fedcb24ac 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/alchemy/PotionBrewing.java
|
||||
@@ -14,6 +14,7 @@ public class PotionBrewing {
|
||||
public static final int BREWING_TIME_SECONDS = 20;
|
||||
private static final List<PotionBrewing.Mix<Potion>> POTION_MIXES = Lists.newArrayList();
|
||||
private static final List<PotionBrewing.Mix<Item>> CONTAINER_MIXES = Lists.newArrayList();
|
||||
+ private static final it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<org.bukkit.NamespacedKey, io.papermc.paper.potion.PaperPotionMix> CUSTOM_MIXES = new it.unimi.dsi.fastutil.objects.Object2ObjectLinkedOpenHashMap<>(); // Paper
|
||||
private static final List<Ingredient> ALLOWED_CONTAINERS = Lists.newArrayList();
|
||||
private static final Predicate<ItemStack> ALLOWED_CONTAINER = (stack) -> {
|
||||
for(Ingredient ingredient : ALLOWED_CONTAINERS) {
|
||||
@@ -26,7 +27,7 @@ public class PotionBrewing {
|
||||
};
|
||||
|
||||
public static boolean isIngredient(ItemStack stack) {
|
||||
- return isContainerIngredient(stack) || isPotionIngredient(stack);
|
||||
+ return isContainerIngredient(stack) || isPotionIngredient(stack) || isCustomIngredient(stack); // Paper
|
||||
}
|
||||
|
||||
protected static boolean isContainerIngredient(ItemStack stack) {
|
||||
@@ -66,6 +67,11 @@ public class PotionBrewing {
|
||||
}
|
||||
|
||||
public static boolean hasMix(ItemStack input, ItemStack ingredient) {
|
||||
+ // Paper start
|
||||
+ if (hasCustomMix(input, ingredient)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (!ALLOWED_CONTAINER.test(input)) {
|
||||
return false;
|
||||
} else {
|
||||
@@ -103,6 +109,13 @@ public class PotionBrewing {
|
||||
|
||||
public static ItemStack mix(ItemStack ingredient, ItemStack input) {
|
||||
if (!input.isEmpty()) {
|
||||
+ // Paper start
|
||||
+ for (var mix : CUSTOM_MIXES.values()) {
|
||||
+ if (mix.input().test(input) && mix.ingredient().test(ingredient)) {
|
||||
+ return mix.result().copy();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
Potion potion = PotionUtils.getPotion(input);
|
||||
Item item = input.getItem();
|
||||
int i = 0;
|
||||
@@ -127,6 +140,54 @@ public class PotionBrewing {
|
||||
return input;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public static boolean isCustomIngredient(ItemStack stack) {
|
||||
+ for (var mix : CUSTOM_MIXES.values()) {
|
||||
+ if (mix.ingredient().test(stack)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public static boolean isCustomInput(ItemStack stack) {
|
||||
+ for (var mix : CUSTOM_MIXES.values()) {
|
||||
+ if (mix.input().test(stack)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ private static boolean hasCustomMix(ItemStack input, ItemStack ingredient) {
|
||||
+ for (var mix : CUSTOM_MIXES.values()) {
|
||||
+ if (mix.input().test(input) && mix.ingredient().test(ingredient)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ public static void addPotionMix(io.papermc.paper.potion.PotionMix mix) {
|
||||
+ if (CUSTOM_MIXES.containsKey(mix.getKey())) {
|
||||
+ throw new IllegalArgumentException("Duplicate recipe ignored with ID " + mix.getKey());
|
||||
+ }
|
||||
+ CUSTOM_MIXES.putAndMoveToFirst(mix.getKey(), new io.papermc.paper.potion.PaperPotionMix(mix));
|
||||
+ }
|
||||
+
|
||||
+ public static boolean removePotionMix(org.bukkit.NamespacedKey key) {
|
||||
+ return CUSTOM_MIXES.remove(key) != null;
|
||||
+ }
|
||||
+
|
||||
+ public static void reload() {
|
||||
+ POTION_MIXES.clear();
|
||||
+ CONTAINER_MIXES.clear();
|
||||
+ ALLOWED_CONTAINERS.clear();
|
||||
+ CUSTOM_MIXES.clear();
|
||||
+ bootStrap();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public static void bootStrap() {
|
||||
addContainer(Items.POTION);
|
||||
addContainer(Items.SPLASH_POTION);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
index 287205bce7f655f9a6b815f40d349c3db4c1e788..5c0f1488c8a8100cd39a03adeccded9984722249 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BrewingStandBlockEntity.java
|
||||
@@ -336,7 +336,7 @@ public class BrewingStandBlockEntity extends BaseContainerBlockEntity implements
|
||||
|
||||
@Override
|
||||
public boolean canPlaceItem(int slot, ItemStack stack) {
|
||||
- return slot == 3 ? PotionBrewing.isIngredient(stack) : (slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE)) && this.getItem(slot).isEmpty());
|
||||
+ return slot == 3 ? PotionBrewing.isIngredient(stack) : (slot == 4 ? stack.is(Items.BLAZE_POWDER) : (stack.is(Items.POTION) || stack.is(Items.SPLASH_POTION) || stack.is(Items.LINGERING_POTION) || stack.is(Items.GLASS_BOTTLE) || PotionBrewing.isCustomInput(stack)) && this.getItem(slot).isEmpty()); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 810986cc3b349a66c02f2a682daac8b4422917ae..6333688c49b8c9dd2476634ad3968b468b3d5147 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -285,6 +285,7 @@ public final class CraftServer implements Server {
|
||||
private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
|
||||
public static Exception excessiveVelEx; // Paper - Velocity warnings
|
||||
private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
|
||||
+ private final CraftPotionBrewer potionBrewer = new CraftPotionBrewer(); // Paper
|
||||
|
||||
static {
|
||||
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);
|
||||
@@ -311,7 +312,7 @@ public final class CraftServer implements Server {
|
||||
Enchantments.SHARPNESS.getClass();
|
||||
org.bukkit.enchantments.Enchantment.stopAcceptingRegistrations();
|
||||
|
||||
- Potion.setPotionBrewer(new CraftPotionBrewer());
|
||||
+ Potion.setPotionBrewer(potionBrewer); // Paper
|
||||
MobEffects.BLINDNESS.getClass();
|
||||
PotionEffectType.stopAcceptingRegistrations();
|
||||
// Ugly hack :(
|
||||
@@ -2877,5 +2878,10 @@ public final class CraftServer implements Server {
|
||||
return datapackManager;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public CraftPotionBrewer getPotionBrewer() {
|
||||
+ return this.potionBrewer;
|
||||
+ }
|
||||
+
|
||||
// Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
index 10ace7bb17c36bfefc584a6322841ab6ea4c866f..71486c08db28caf89f2366e082f6f6fab5609b71 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java
|
||||
@@ -13,6 +13,11 @@ public interface CraftRecipe extends Recipe {
|
||||
void addToCraftingManager();
|
||||
|
||||
default Ingredient toNMS(RecipeChoice bukkit, boolean requireNotEmpty) {
|
||||
+ // Paper start
|
||||
+ return toIngredient(bukkit, requireNotEmpty);
|
||||
+ }
|
||||
+ static Ingredient toIngredient(RecipeChoice bukkit, boolean requireNotEmpty) {
|
||||
+ // Paper end
|
||||
Ingredient stack;
|
||||
|
||||
if (bukkit == null) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
|
||||
index 8fdc9a3bb2f1b6bdc6c2c96f8ade7e9cd88ea4e0..a0b0c64b819b8f713eeea78210e276664e30e66e 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
|
||||
@@ -49,4 +49,21 @@ public class CraftPotionBrewer implements PotionBrewer {
|
||||
public PotionEffect createEffect(PotionEffectType potion, int duration, int amplifier) {
|
||||
return new PotionEffect(potion, potion.isInstant() ? 1 : (int) (duration * potion.getDurationModifier()), amplifier);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void addPotionMix(io.papermc.paper.potion.PotionMix potionMix) {
|
||||
+ net.minecraft.world.item.alchemy.PotionBrewing.addPotionMix(potionMix);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removePotionMix(org.bukkit.NamespacedKey key) {
|
||||
+ net.minecraft.world.item.alchemy.PotionBrewing.removePotionMix(key);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetPotionMixes() {
|
||||
+ net.minecraft.world.item.alchemy.PotionBrewing.reload();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 1 Mar 2022 12:45:50 -0800
|
||||
Subject: [PATCH] Fix Fluid tags isTagged method
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java b/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
|
||||
index 89cb1ec575c0f58e9934d98b056621348dbbe27a..cdd474e9b0363641839a66d3e61fec46c735879a 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/tag/CraftFluidTag.java
|
||||
@@ -16,7 +16,7 @@ public class CraftFluidTag extends CraftTag<net.minecraft.world.level.material.F
|
||||
|
||||
@Override
|
||||
public boolean isTagged(Fluid fluid) {
|
||||
- return CraftMagicNumbers.getFluid(fluid).is(tag);
|
||||
+ return registry.getHolderOrThrow(net.minecraft.resources.ResourceKey.create(net.minecraft.core.Registry.FLUID_REGISTRY, org.bukkit.craftbukkit.util.CraftNamespacedKey.toMinecraft(fluid.getKey()))).is(tag); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
index 5b05ef93a02e8a8525cf1558273d0f8963407862..88abd2d3a9626501b1800ee754b98c6c29c75fb9 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
|
||||
@@ -201,7 +201,7 @@ public final class CraftMagicNumbers implements UnsafeValues {
|
||||
return CraftMagicNumbers.MATERIAL_BLOCK.get(material);
|
||||
}
|
||||
|
||||
- public static net.minecraft.world.level.material.Fluid getFluid(Fluid fluid) {
|
||||
+ public static net.minecraft.world.level.material.Fluid getFluid(Material fluid) { // Paper - wrong type
|
||||
return CraftMagicNumbers.MATERIAL_FLUID.get(fluid);
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jake Potrebic <jake.m.potrebic@gmail.com>
|
||||
Date: Tue, 1 Mar 2022 14:12:17 -0800
|
||||
Subject: [PATCH] Fix World#locateNearestStructure
|
||||
|
||||
1.18.2 switched to TagKeys to reference tags of objects, and this method
|
||||
impl needs to be changed to reflect that
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index b079677723ff65f64adec044e7d89656ecc49e4d..583d2deffa819c1aa25e1937a7f709d0d6bab294 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -2056,6 +2056,11 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.resources.managers.updateRegistryTags(this.registryAccess());
|
||||
io.papermc.paper.registry.PaperRegistry.clearCaches(); // Paper
|
||||
net.minecraft.world.item.alchemy.PotionBrewing.reload(); // Paper
|
||||
+ // Paper start - clear cache cause datapacks can add more configured structures
|
||||
+ for (ServerLevel level : this.levels.values()) {
|
||||
+ level.getWorld().structureCache.clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
new io.papermc.paper.event.server.ServerResourcesReloadedEvent(cause).callEvent(); // Paper
|
||||
if (Thread.currentThread() != this.serverThread) return; // Paper
|
||||
//this.getPlayerList().saveAll(); // Paper - we don't need to do this
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 344c5bafe291a2542c4940e4d80232644de7b877..00e6f60e13f50c727530de37ab9692ad3683c11b 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -1793,7 +1793,16 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
if (optional.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
- Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair = this.getChunkSource().getGenerator().findNearestMapFeature(this, (HolderSet) optional.get(), pos, radius, skipExistingChunks);
|
||||
+ // Paper start
|
||||
+ return this.findNearestMapFeature(optional.get(), pos, radius, skipExistingChunks);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ public @Nullable BlockPos findNearestMapFeature(HolderSet<ConfiguredStructureFeature<?, ?>> holderSet, BlockPos pos, int radius, boolean skipExistingChunks) {
|
||||
+ {
|
||||
+ {
|
||||
+ Pair<BlockPos, Holder<ConfiguredStructureFeature<?, ?>>> pair = this.getChunkSource().getGenerator().findNearestMapFeature(this, holderSet, pos, radius, skipExistingChunks);
|
||||
+ // Paper end
|
||||
|
||||
return pair != null ? (BlockPos) pair.getFirst() : null;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index dd3aac2b8058f09fdd6dce9c1c683725b3594cfd..1a07887345f46582949090b685dae507aaba84f4 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -2060,10 +2060,22 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
}
|
||||
|
||||
+ public final Map<StructureType, List<Holder.Reference<net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature<?, ?>>>> structureCache = new java.util.HashMap<>(); // Paper
|
||||
@Override
|
||||
public Location locateNearestStructure(Location origin, StructureType structureType, int radius, boolean findUnexplored) {
|
||||
BlockPos originPos = new BlockPos(origin.getX(), origin.getY(), origin.getZ());
|
||||
- BlockPos nearest = this.getHandle().findNearestMapFeature(TagKey.create(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY, CraftNamespacedKey.toMinecraft(structureType.getKey())), originPos, radius, findUnexplored);
|
||||
+ // Paper start - fix because you can't just create random TagKeys
|
||||
+ if (!this.getHandle().serverLevelData.worldGenSettings().generateFeatures()) { // from ServerLevel#findNearestMapFeature
|
||||
+ return null;
|
||||
+ }
|
||||
+ final List<Holder.Reference<net.minecraft.world.level.levelgen.feature.ConfiguredStructureFeature<?, ?>>> features = this.structureCache.computeIfAbsent(structureType, (type) -> {
|
||||
+ final Registry<net.minecraft.world.level.levelgen.feature.StructureFeature<?>> structureFeatureRegistry = this.getHandle().registryAccess().registryOrThrow(Registry.STRUCTURE_FEATURE_REGISTRY);
|
||||
+ return this.getHandle().registryAccess().registryOrThrow(Registry.CONFIGURED_STRUCTURE_FEATURE_REGISTRY).holders().filter(holder -> {
|
||||
+ return structureType.getKey().equals(org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(Objects.requireNonNull(structureFeatureRegistry.getKey(holder.value().feature))));
|
||||
+ }).toList();
|
||||
+ });
|
||||
+ BlockPos nearest = this.getHandle().findNearestMapFeature(net.minecraft.core.HolderSet.direct(features), originPos, radius, findUnexplored);
|
||||
+ // Paper end
|
||||
return (nearest == null) ? null : new Location(this, nearest.getX(), nearest.getY(), nearest.getZ());
|
||||
}
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
||||
Date: Wed, 2 Mar 2022 09:45:56 +0100
|
||||
Subject: [PATCH] Force close world loading screen
|
||||
|
||||
Dead players would be stuck in the world loading screen and other players may
|
||||
miss messages and similar sent in the join event if chunk loading is slow.
|
||||
Paper already circumvents falling through the world before chunks are loaded,
|
||||
so we do not need that. The client only needs the chunk it is currently in to
|
||||
be loaded to close the loading screen, so we just send an empty one.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 3ffb0ae65ed530464462ec3b8cdb2db43c4d1b69..2a8c3082d07244f8f00d644e01e875b81264324d 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -422,6 +422,13 @@ public abstract class PlayerList {
|
||||
|
||||
// Paper start - move vehicle into method so it can be called above - short circuit around that code
|
||||
onPlayerJoinFinish(player, worldserver1, s1);
|
||||
+ // Send empty chunk, so players aren't stuck in the world loading screen
|
||||
+ net.minecraft.core.Holder<net.minecraft.world.level.biome.Biome> plains = worldserver1.registryAccess().registryOrThrow(net.minecraft.core.Registry.BIOME_REGISTRY)
|
||||
+ .getHolderOrThrow(net.minecraft.world.level.biome.Biomes.PLAINS);
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundLevelChunkWithLightPacket(
|
||||
+ new net.minecraft.world.level.chunk.EmptyLevelChunk(worldserver1, player.chunkPosition(), plains),
|
||||
+ worldserver1.getLightEngine(), null, null, true, false)
|
||||
+ );
|
||||
}
|
||||
private void mountSavedVehicle(ServerPlayer player, ServerLevel worldserver1, CompoundTag nbttagcompound) {
|
||||
// Paper end
|
|
@ -1,54 +0,0 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Nassim Jahnke <jahnke.nassim@gmail.com>
|
||||
Date: Fri, 4 Mar 2022 20:35:19 +0100
|
||||
Subject: [PATCH] Fix falling block spawn methods
|
||||
|
||||
Restores the API behavior from previous versions of the server
|
||||
- Do not call API events
|
||||
- Do not replace the existing block in the world
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index e996ffb6fd952208b1dabba8b470fd42f004919d..6e827ed6212915b187e4c610acf6c34037c9c994 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -549,7 +549,7 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
// Paper end
|
||||
} else if (FallingBlock.class.isAssignableFrom(clazz)) {
|
||||
BlockPos pos = new BlockPos(x, y, z);
|
||||
- entity = FallingBlockEntity.fall(world, pos, this.getHandle().getBlockState(pos));
|
||||
+ entity = new FallingBlockEntity(world, x, y, z, this.getHandle().getBlockState(pos)); // Paper
|
||||
} else if (Projectile.class.isAssignableFrom(clazz)) {
|
||||
if (Snowball.class.isAssignableFrom(clazz)) {
|
||||
entity = new net.minecraft.world.entity.projectile.Snowball(world, x, y, z);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 1a07887345f46582949090b685dae507aaba84f4..f5a6250350a5f0b6236c1fe0f149b1190de34880 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -1411,7 +1411,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Validate.notNull(material, "Material cannot be null");
|
||||
Validate.isTrue(material.isBlock(), "Material must be a block");
|
||||
|
||||
- FallingBlockEntity entity = FallingBlockEntity.fall(world, new BlockPos(location.getX(), location.getY(), location.getZ()), CraftMagicNumbers.getBlock(material).defaultBlockState(), SpawnReason.CUSTOM);
|
||||
+ // Paper start - restore API behavior for spawning falling blocks
|
||||
+ FallingBlockEntity entity = new FallingBlockEntity(this.world, location.getX(), location.getY(), location.getZ(), CraftMagicNumbers.getBlock(material).defaultBlockState()); // Paper
|
||||
+ entity.time = 1;
|
||||
+
|
||||
+ this.world.addFreshEntity(entity, SpawnReason.CUSTOM);
|
||||
+ // Paper end
|
||||
return (FallingBlock) entity.getBukkitEntity();
|
||||
}
|
||||
|
||||
@@ -1420,7 +1425,12 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
Validate.notNull(location, "Location cannot be null");
|
||||
Validate.notNull(data, "BlockData cannot be null");
|
||||
|
||||
- FallingBlockEntity entity = FallingBlockEntity.fall(world, new BlockPos(location.getX(), location.getY(), location.getZ()), ((CraftBlockData) data).getState(), SpawnReason.CUSTOM);
|
||||
+ // Paper start - restore API behavior for spawning falling blocks
|
||||
+ FallingBlockEntity entity = new FallingBlockEntity(this.world, location.getX(), location.getY(), location.getZ(), ((CraftBlockData) data).getState());
|
||||
+ entity.time = 1;
|
||||
+
|
||||
+ this.world.addFreshEntity(entity, SpawnReason.CUSTOM);
|
||||
+ // Paper end
|
||||
return (FallingBlock) entity.getBukkitEntity();
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue