more patches

This commit is contained in:
Jake 2021-11-24 13:30:53 -08:00 committed by MiniDigger | Martin
parent 35aeb0ddeb
commit 5a2d3b2b29
38 changed files with 177 additions and 170 deletions

View file

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Mon, 5 Apr 2021 18:12:29 -0400
Subject: [PATCH] Add EntityBlockStorage#clearEntities()
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
index cdf7778f4bfd576e87fe41096414ca8dcdbdf35b..9fcd835d219aafbe113ebb1b796052e07bf2b046 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/BeehiveBlockEntity.java
@@ -135,6 +135,11 @@ public class BeehiveBlockEntity extends BlockEntity {
return this.stored.size();
}
+ // Paper start - Add EntityBlockStorage clearEntities
+ public void clearBees() {
+ this.stored.clear();
+ }
+ // Paper end
public static int getHoneyLevel(BlockState state) {
return (Integer) state.getValue(BeehiveBlock.HONEY_LEVEL);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java
index ee4d7f5558ed76e8d8b56133da729a5303d1d823..e00210950cbf005b0e65aed68dfbb7c281aefd87 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBeehive.java
@@ -80,4 +80,10 @@ public class CraftBeehive extends CraftBlockEntityState<BeehiveBlockEntity> impl
getSnapshot().addOccupant(((CraftBee) entity).getHandle(), false);
}
+ // Paper start - Add EntityBlockStorage clearEntities
+ @Override
+ public void clearEntities() {
+ getSnapshot().clearBees();
+ }
+ // Paper end
}

View file

@ -0,0 +1,32 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Alvinn8 <42838560+Alvinn8@users.noreply.github.com>
Date: Fri, 8 Jan 2021 20:31:13 +0100
Subject: [PATCH] Add Adventure message to PlayerAdvancementDoneEvent
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
index 3ff6995d34914720d353fdbe1aa981bfab9f6040..f7959fe8d5247504dd79a18010470d98781c7cfe 100644
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
@@ -290,10 +290,18 @@ public class PlayerAdvancements {
this.progressChanged.add(advancement);
flag = true;
if (!flag1 && advancementprogress.isDone()) {
- this.player.level.getCraftServer().getPluginManager().callEvent(new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.bukkit)); // CraftBukkit
+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent
+ boolean announceToChat = advancement.getDisplay() != null && advancement.getDisplay().shouldAnnounceChat();
+ net.kyori.adventure.text.Component message = announceToChat ? io.papermc.paper.adventure.PaperAdventure.asAdventure(new TranslatableComponent("chat.type.advancement." + advancement.getDisplay().getFrame().getName(), this.player.getDisplayName(), advancement.getChatComponent())) : null;
+ org.bukkit.event.player.PlayerAdvancementDoneEvent event = new org.bukkit.event.player.PlayerAdvancementDoneEvent(this.player.getBukkitEntity(), advancement.bukkit, message);
+ this.player.level.getCraftServer().getPluginManager().callEvent(event);
+ message = event.message();
+ // Paper end
advancement.getRewards().grant(this.player);
- if (advancement.getDisplay() != null && advancement.getDisplay().shouldAnnounceChat() && this.player.level.getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
- this.playerList.broadcastMessage(new TranslatableComponent("chat.type.advancement." + advancement.getDisplay().getFrame().getName(), new Object[]{this.player.getDisplayName(), advancement.getChatComponent()}), ChatType.SYSTEM, Util.NIL_UUID);
+ // Paper start - Add Adventure message to PlayerAdvancementDoneEvent
+ if (message != null && this.player.level.getGameRules().getBoolean(GameRules.RULE_ANNOUNCE_ADVANCEMENTS)) {
+ this.playerList.broadcastMessage(io.papermc.paper.adventure.PaperAdventure.asVanilla(message), ChatType.SYSTEM, Util.NIL_UUID);
+ // Paper end
}
}
}

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Connor Linfoot <connorlinfoot@me.com>
Date: Wed, 12 May 2021 08:09:19 +0100
Subject: [PATCH] Add raw address 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 8dc1e8bba37986c75966e321614ebb6366729c29..45db764f4499ee71bef691d37b604f21da120fe7 100644
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
@@ -352,12 +352,13 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener
// Paper end
String playerName = ServerLoginPacketListenerImpl.this.gameProfile.getName();
java.net.InetAddress address = ((java.net.InetSocketAddress) ServerLoginPacketListenerImpl.this.connection.getRemoteAddress()).getAddress();
+ java.net.InetAddress rawAddress = ((java.net.InetSocketAddress) connection.getRawAddress()).getAddress(); // Paper
java.util.UUID uniqueId = ServerLoginPacketListenerImpl.this.gameProfile.getId();
final org.bukkit.craftbukkit.CraftServer server = ServerLoginPacketListenerImpl.this.server.server;
// Paper start
PlayerProfile profile = CraftPlayerProfile.asBukkitMirror(ServerLoginPacketListenerImpl.this.gameProfile);
- AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile);
+ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, rawAddress, uniqueId, profile);
server.getPluginManager().callEvent(asyncEvent);
profile = asyncEvent.getPlayerProfile();
profile.complete(true);

View file

@ -0,0 +1,25 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 11 May 2021 14:54:56 -0700
Subject: [PATCH] Inventory#close
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
index 7d8f29335d4c5188527cad66be39cedb34c26f50..396a4ae3d5a829eda78ef98561333aea300aa722 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
@@ -448,6 +448,14 @@ public class CraftInventory implements Inventory {
this.clear(i);
}
}
+ // Paper start
+ @Override
+ public int close() {
+ int count = this.inventory.getViewers().size();
+ com.google.common.collect.Lists.newArrayList(this.inventory.getViewers()).forEach(HumanEntity::closeInventory);
+ return count;
+ }
+ // Paper end
@Override
public ListIterator<ItemStack> iterator() {

View file

@ -0,0 +1,33 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 12 May 2021 03:21:22 -0700
Subject: [PATCH] call PortalCreateEvent players and end platform
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index f8805dad18a5b9fa37b4f2c214acb17d59167f9d..3650036d18d66194fad37610e8a4de7a2eac97d7 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1178,15 +1178,21 @@ public class ServerPlayer extends Player {
private void createEndPlatform(ServerLevel world, BlockPos centerPos) {
BlockPos.MutableBlockPos blockposition_mutableblockposition = centerPos.mutable();
+ org.bukkit.craftbukkit.util.BlockStateListPopulator blockList = new org.bukkit.craftbukkit.util.BlockStateListPopulator(world); // Paper
for (int i = -2; i <= 2; ++i) {
for (int j = -2; j <= 2; ++j) {
for (int k = -1; k < 3; ++k) {
BlockState iblockdata = k == -1 ? Blocks.OBSIDIAN.defaultBlockState() : Blocks.AIR.defaultBlockState();
- world.setBlockAndUpdate(blockposition_mutableblockposition.set(centerPos).move(j, k, i), iblockdata);
+ blockList.setBlock(blockposition_mutableblockposition.set(centerPos).move(j, k, i), iblockdata, 3); // Paper
}
}
}
+ // Paper start
+ if (new org.bukkit.event.world.PortalCreateEvent((List< org.bukkit.block.BlockState>) (List) blockList.getList(), world.getWorld(), this.getBukkitEntity(), org.bukkit.event.world.PortalCreateEvent.CreateReason.END_PLATFORM).callEvent()) {
+ blockList.updateList();
+ }
+ // Paper end
}

View file

@ -0,0 +1,132 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: MeFisto94 <MeFisto94@users.noreply.github.com>
Date: Tue, 11 May 2021 00:48:33 +0200
Subject: [PATCH] Add a "should burn in sunlight" API for Phantoms and
Skeletons
diff --git a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
index ecf12ed5014202181e78af051e4a9ca88a275794..e23fe546291e670f89447398507d08a0a07efa85 100644
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
@@ -96,9 +96,15 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
return MobType.UNDEAD;
}
+ // Paper start
+ private boolean shouldBurnInDay = true;
+ public boolean shouldBurnInDay() { return shouldBurnInDay; }
+ public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
+ // Paper end
+
@Override
public void aiStep() {
- boolean flag = this.isSunBurnTick();
+ boolean flag = shouldBurnInDay && this.isSunBurnTick(); // Paper - Configurable Burning
if (flag) {
ItemStack itemstack = this.getItemBySlot(EquipmentSlot.HEAD);
@@ -222,7 +228,20 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
public void readAdditionalSaveData(CompoundTag nbt) {
super.readAdditionalSaveData(nbt);
this.reassessWeaponGoal();
+ // Paper start
+ if (nbt.contains("Paper.ShouldBurnInDay")) {
+ this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
+ }
+ // Paper end
+ }
+
+ // Paper start
+ @Override
+ public void addAdditionalSaveData(CompoundTag nbt) {
+ super.addAdditionalSaveData(nbt);
+ nbt.putBoolean("Paper.ShouldBurnInDay", this.shouldBurnInDay);
}
+ // Paper end
@Override
public void setItemSlot(EquipmentSlot slot, ItemStack stack) {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Phantom.java b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
index 7344301e1cdeccd95375b77f6955edb508362a7b..4442db77e1a0b517aab3a7dc74a4aaac5afc32e0 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
@@ -144,7 +144,7 @@ public class Phantom extends FlyingMob implements Enemy {
@Override
public void aiStep() {
- if (this.isAlive() && this.isSunBurnTick()) {
+ if (this.isAlive() && shouldBurnInDay && this.isSunBurnTick()) { // Paper - Configurable Burning
this.setSecondsOnFire(8);
}
@@ -175,6 +175,9 @@ public class Phantom extends FlyingMob implements Enemy {
if (nbt.hasUUID("Paper.SpawningEntity")) {
this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
}
+ if (nbt.contains("Paper.ShouldBurnInDay")) {
+ this.shouldBurnInDay = nbt.getBoolean("Paper.ShouldBurnInDay");
+ }
// Paper end
}
@@ -189,6 +192,7 @@ public class Phantom extends FlyingMob implements Enemy {
if (this.spawningEntity != null) {
nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
}
+ nbt.putBoolean("Paper.ShouldBurnInDay", shouldBurnInDay);
// Paper end
}
@@ -248,6 +252,10 @@ public class Phantom extends FlyingMob implements Enemy {
return spawningEntity;
}
public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
+
+ private boolean shouldBurnInDay = true;
+ public boolean shouldBurnInDay() { return shouldBurnInDay; }
+ public void setShouldBurnInDay(boolean shouldBurnInDay) { this.shouldBurnInDay = shouldBurnInDay; }
// Paper end
private static enum AttackPhase {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
index c9dab70b0b284fe1c1daafd3c1f5bd08b14fa35d..dce23f3878b1588c26b6116d80e597d08070edbc 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
@@ -40,5 +40,15 @@ public class CraftPhantom extends CraftFlying implements Phantom {
public java.util.UUID getSpawningEntity() {
return getHandle().getSpawningEntity();
}
+
+ @Override
+ public boolean shouldBurnInDay() {
+ return getHandle().shouldBurnInDay();
+ }
+
+ @Override
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
+ getHandle().setShouldBurnInDay(shouldBurnInDay);
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
index 90f34d75f99f31f5c98c499df209979a03e23191..0e8e1a85697bbe9ca92466ca0a39e4e9478f31bf 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java
@@ -51,4 +51,16 @@ public class CraftSkeleton extends CraftAbstractSkeleton implements Skeleton {
public SkeletonType getSkeletonType() {
return SkeletonType.NORMAL;
}
+
+ // Paper start
+ @Override
+ public boolean shouldBurnInDay() {
+ return getHandle().shouldBurnInDay();
+ }
+
+ @Override
+ public void setShouldBurnInDay(boolean shouldBurnInDay) {
+ getHandle().setShouldBurnInDay(shouldBurnInDay);
+ }
+ // Paper end
}

View file

@ -0,0 +1,44 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Sceri <scerimail@gmail.com>
Date: Fri, 14 May 2021 19:06:51 +0500
Subject: [PATCH] Fix CraftPotionBrewer cache
diff --git a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
index 1e4bc0d9f9d2e45157929af685f116988cbb8c03..8fdc9a3bb2f1b6bdc6c2c96f8ade7e9cd88ea4e0 100644
--- a/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
+++ b/src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java
@@ -15,12 +15,18 @@ import org.bukkit.potion.PotionEffectType;
import org.bukkit.potion.PotionType;
public class CraftPotionBrewer implements PotionBrewer {
- private static final Map<PotionType, Collection<PotionEffect>> cache = Maps.newHashMap();
+ private static final Map<Integer, Collection<PotionEffect>> cache = Maps.newHashMap(); // Paper
@Override
public Collection<PotionEffect> getEffects(PotionType damage, boolean upgraded, boolean extended) {
- if (CraftPotionBrewer.cache.containsKey(damage))
- return CraftPotionBrewer.cache.get(damage);
+ // Paper start
+ int key = damage.ordinal() << 2;
+ key |= (upgraded ? 1 : 0) << 1;
+ key |= extended ? 1 : 0;
+
+ if (CraftPotionBrewer.cache.containsKey(key))
+ return CraftPotionBrewer.cache.get(key);
+ // Paper end
List<MobEffectInstance> mcEffects = Potion.byName(CraftPotionUtil.fromBukkit(new PotionData(damage, extended, upgraded))).getEffects();
@@ -29,9 +35,9 @@ public class CraftPotionBrewer implements PotionBrewer {
builder.add(CraftPotionUtil.toBukkit(effect));
}
- CraftPotionBrewer.cache.put(damage, builder.build());
+ CraftPotionBrewer.cache.put(key, builder.build()); // Paper
- return CraftPotionBrewer.cache.get(damage);
+ return CraftPotionBrewer.cache.get(key); // Paper
}
@Override

View file

@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Connor Linfoot <connorlinfoot@me.com>
Date: Sun, 16 May 2021 15:07:34 +0100
Subject: [PATCH] Add basic Datapack API
diff --git a/src/main/java/io/papermc/paper/datapack/PaperDatapack.java b/src/main/java/io/papermc/paper/datapack/PaperDatapack.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b7dd8a0fba4547f5268b3f99e21ddbe6b5bf566
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapack.java
@@ -0,0 +1,50 @@
+package io.papermc.paper.datapack;
+
+import io.papermc.paper.event.server.ServerResourcesReloadedEvent;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.server.packs.repository.Pack;
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class PaperDatapack implements Datapack {
+ private final String name;
+ private final Compatibility compatibility;
+ private final boolean enabled;
+
+ PaperDatapack(Pack loader, boolean enabled) {
+ this.name = loader.getId();
+ this.compatibility = Compatibility.valueOf(loader.getCompatibility().name());
+ this.enabled = enabled;
+ }
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Compatibility getCompatibility() {
+ return compatibility;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public void setEnabled(boolean enabled) {
+ if (enabled == this.enabled) {
+ return;
+ }
+
+ MinecraftServer server = MinecraftServer.getServer();
+ List<String> enabledKeys = server.getPackRepository().getSelectedPacks().stream().map(Pack::getId).collect(Collectors.toList());
+ if (enabled) {
+ enabledKeys.add(this.name);
+ } else {
+ enabledKeys.remove(this.name);
+ }
+ server.reloadResources(enabledKeys, ServerResourcesReloadedEvent.Cause.PLUGIN);
+ }
+}
diff --git a/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java b/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java
new file mode 100644
index 0000000000000000000000000000000000000000..cf4374493c11057451a62a655514415cf6b298e0
--- /dev/null
+++ b/src/main/java/io/papermc/paper/datapack/PaperDatapackManager.java
@@ -0,0 +1,25 @@
+package io.papermc.paper.datapack;
+
+import java.util.Collection;
+import java.util.stream.Collectors;
+import net.minecraft.server.packs.repository.Pack;
+import net.minecraft.server.packs.repository.PackRepository;
+
+public class PaperDatapackManager implements DatapackManager {
+ private final PackRepository repository;
+
+ public PaperDatapackManager(PackRepository repository) {
+ this.repository = repository;
+ }
+
+ @Override
+ public Collection<Datapack> getPacks() {
+ Collection<Pack> enabledPacks = repository.getSelectedPacks();
+ return repository.getAvailablePacks().stream().map(loader -> new PaperDatapack(loader, enabledPacks.contains(loader))).collect(Collectors.toList());
+ }
+
+ @Override
+ public Collection<Datapack> getEnabledPacks() {
+ return repository.getSelectedPacks().stream().map(loader -> new PaperDatapack(loader, true)).collect(Collectors.toList());
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 9d77ecf330d93b3c2925d097b753c887838cb1ec..3d3913686727af7367377deaf35681de6900aa22 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -292,6 +292,7 @@ public final class CraftServer implements Server {
public boolean ignoreVanillaPermissions = false;
private final List<CraftPlayer> playerView;
public int reloadCount;
+ private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
public static Exception excessiveVelEx; // Paper - Velocity warnings
static {
@@ -376,6 +377,7 @@ public final class CraftServer implements Server {
TicketType.PLUGIN.timeout = Math.min(20, this.configuration.getInt("chunk-gc.period-in-ticks")); // Paper - cap plugin loads to 1 second
this.minimumAPI = this.configuration.getString("settings.minimum-api");
this.loadIcon();
+ datapackManager = new io.papermc.paper.datapack.PaperDatapackManager(console.getPackRepository()); // Paper
}
public boolean getCommandBlockOverride(String command) {
@@ -2689,5 +2691,11 @@ public final class CraftServer implements Server {
public com.destroystokyo.paper.entity.ai.MobGoals getMobGoals() {
return mobGoals;
}
+
+ @Override
+ public io.papermc.paper.datapack.PaperDatapackManager getDatapackManager() {
+ return datapackManager;
+ }
+
// Paper end
}

View file

@ -0,0 +1,18 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Riley Park <riley.park@meino.net>
Date: Mon, 17 May 2021 00:34:55 -0700
Subject: [PATCH] Add environment variable to disable server gui
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
index bb85bfb074830d771be8527f6c25ebb578578f18..f685ab3cc6e4fd76e8dec3d2d3627a13715cda44 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -249,6 +249,7 @@ public class Main {
*/
boolean flag1 = !optionset.has("nogui") && !optionset.nonOptionArguments().contains("nogui");
+ if(!Boolean.parseBoolean(System.getenv().getOrDefault("PAPER_DISABLE_SERVER_GUI", String.valueOf(false)))) // Paper
if (flag1 && !GraphicsEnvironment.isHeadless()) {
dedicatedserver1.showGui();
}

View file

@ -0,0 +1,153 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 15 May 2021 10:04:43 -0700
Subject: [PATCH] additions to PlayerGameModeChangeEvent
diff --git a/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java b/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java
index d25a27f3a6775ca86092ea8bdeab4abdd8909d35..7d9ec435f3821f95d3bed893c4e46d5a2531cd58 100644
--- a/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java
+++ b/src/main/java/net/minecraft/server/commands/DefaultGameModeCommands.java
@@ -31,9 +31,13 @@ public class DefaultGameModeCommands {
GameType gameType = minecraftServer.getForcedGameType();
if (gameType != null) {
for(ServerPlayer serverPlayer : minecraftServer.getPlayerList().getPlayers()) {
- if (serverPlayer.setGameMode(gameType)) {
- ++i;
+ // Paper start - extend PlayerGameModeChangeEvent
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameType, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, net.kyori.adventure.text.Component.empty());
+ if (event != null && event.isCancelled()) {
+ source.sendSuccess(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), false);
}
+ // Paper end
+ ++i;
}
}
diff --git a/src/main/java/net/minecraft/server/commands/GameModeCommand.java b/src/main/java/net/minecraft/server/commands/GameModeCommand.java
index d75f78d2e3fb1376e8f6a8668c98a04a693c99e1..79f6089b934124c3309c6bee2e48b36b937252e0 100644
--- a/src/main/java/net/minecraft/server/commands/GameModeCommand.java
+++ b/src/main/java/net/minecraft/server/commands/GameModeCommand.java
@@ -52,9 +52,14 @@ public class GameModeCommand {
int i = 0;
for(ServerPlayer serverPlayer : targets) {
- if (serverPlayer.setGameMode(gameMode)) {
+ // Paper start - extend PlayerGameModeChangeEvent
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = serverPlayer.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.COMMAND, net.kyori.adventure.text.Component.empty());
+ if (event != null && !event.isCancelled()) {
logGamemodeChange(context.getSource(), serverPlayer, gameMode);
++i;
+ } else if (event != null && event.cancelMessage() != null) {
+ context.getSource().sendSuccess(io.papermc.paper.adventure.PaperAdventure.asVanilla(event.cancelMessage()), true);
+ // Paper end
}
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 3650036d18d66194fad37610e8a4de7a2eac97d7..aec3fd5bd9103af17eb476d5411b84d76f72bfe4 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1787,8 +1787,15 @@ public class ServerPlayer extends Player {
}
public boolean setGameMode(GameType gameMode) {
- if (!this.gameMode.changeGameModeForPlayer(gameMode)) {
- return false;
+ // Paper start - Add cause and nullable message to event
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = this.setGameMode(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.UNKNOWN, null);
+ return event == null ? false : event.isCancelled();
+ }
+ public org.bukkit.event.player.PlayerGameModeChangeEvent setGameMode(GameType gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause cause, net.kyori.adventure.text.Component message) {
+ org.bukkit.event.player.PlayerGameModeChangeEvent event = this.gameMode.changeGameModeForPlayer(gameMode, cause, message);
+ if (event == null || event.isCancelled()) {
+ // Paper end
+ return null;
} else {
this.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.CHANGE_GAME_MODE, (float) gameMode.getId()));
if (gameMode == GameType.SPECTATOR) {
@@ -1800,7 +1807,7 @@ public class ServerPlayer extends Player {
this.onUpdateAbilities();
this.updateEffectVisibility();
- return true;
+ return event; // Paper
}
}
@@ -2182,6 +2189,16 @@ public class ServerPlayer extends Player {
}
public void loadGameTypes(@Nullable CompoundTag nbt) {
+ // Paper start
+ if (this.server.getForcedGameType() != null && this.server.getForcedGameType() != ServerPlayer.readPlayerMode(nbt, "playerGameType")) {
+ if (new org.bukkit.event.player.PlayerGameModeChangeEvent(this.getBukkitEntity(), org.bukkit.GameMode.getByValue(this.server.getDefaultGameType().getId()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.DEFAULT_GAMEMODE, null).callEvent()) {
+ this.gameMode.setGameModeForPlayer(this.server.getForcedGameType(), GameType.DEFAULT_MODE);
+ } else {
+ this.gameMode.setGameModeForPlayer(ServerPlayer.readPlayerMode(nbt,"playerGameType"), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType"));
+ }
+ return;
+ }
+ // Paper end
this.gameMode.setGameModeForPlayer(this.calculateGameModeForNewPlayer(ServerPlayer.readPlayerMode(nbt, "playerGameType")), ServerPlayer.readPlayerMode(nbt, "previousPlayerGameType"));
}
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
index 9fbd88027933242348d9f4fea8b45e96fd01c343..3ab74a721d9d9bec82a68a30bf523292a3038587 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
@@ -72,18 +72,24 @@ public class ServerPlayerGameMode {
}
public boolean changeGameModeForPlayer(GameType gameMode) {
+ // Paper end
+ PlayerGameModeChangeEvent event = this.changeGameModeForPlayer(gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.UNKNOWN, null);
+ return event == null ? false : event.isCancelled();
+ }
+ public PlayerGameModeChangeEvent changeGameModeForPlayer(GameType gameMode, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause cause, net.kyori.adventure.text.Component cancelMessage) {
+ // Paper end
if (gameMode == this.gameModeForPlayer) {
- return false;
+ return null; // Paper
} else {
// CraftBukkit start
- PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this.player.getBukkitEntity(), GameMode.getByValue(gameMode.getId()));
+ PlayerGameModeChangeEvent event = new PlayerGameModeChangeEvent(this.player.getBukkitEntity(), GameMode.getByValue(gameMode.getId()), cause, cancelMessage); // Paper
this.level.getCraftServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
- return false;
+ return event; // Paper
}
// CraftBukkit end
this.setGameModeForPlayer(gameMode, this.gameModeForPlayer);
- return true;
+ return event; // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 9daad376b7c837ac5dcda5f54d520e2adfda0481..311df240858d4416306a795d893bdf7da403e90b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2479,7 +2479,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.player = this.server.getPlayerList().respawn(this.player, false);
if (this.server.isHardcore()) {
- this.player.setGameMode(GameType.SPECTATOR);
+ this.player.setGameMode(GameType.SPECTATOR, org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.HARDCORE_DEATH, null); // Paper
((GameRules.BooleanValue) this.player.getLevel().getGameRules().getRule(GameRules.RULE_SPECTATORSGENERATECHUNKS)).set(false, this.server);
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 87ed5271d623f239c94d18464458469c8e789bba..4c1430a6499dd44bb07c9d13de511d365a93db58 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1257,7 +1257,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
throw new IllegalArgumentException("Mode cannot be null");
}
- this.getHandle().setGameMode(GameType.byId(mode.getValue()));
+ this.getHandle().setGameMode(GameType.byId(mode.getValue()), org.bukkit.event.player.PlayerGameModeChangeEvent.Cause.PLUGIN, null); // Paper
}
@Override

View file

@ -0,0 +1,79 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 15 May 2021 22:11:11 -0700
Subject: [PATCH] ItemStack repair check API
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index e567e9ccd6017e3c95e868efb78388030ee0f676..5e6941963f12a7f11603884a1b0bf844ea3a3514 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -491,6 +491,14 @@ public final class CraftMagicNumbers implements UnsafeValues {
return io.papermc.paper.inventory.ItemRarity.values()[getItem(itemStack.getType()).getRarity(CraftItemStack.asNMSCopy(itemStack)).ordinal()];
}
+ @Override
+ public boolean isValidRepairItemStack(org.bukkit.inventory.ItemStack itemToBeRepaired, org.bukkit.inventory.ItemStack repairMaterial) {
+ if (!itemToBeRepaired.getType().isItem() || !repairMaterial.getType().isItem()) {
+ return false;
+ }
+ return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial));
+ }
+
@Override
public int getProtocolVersion() {
return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion();
diff --git a/src/test/java/io/papermc/paper/util/ItemStackRepairCheckTest.java b/src/test/java/io/papermc/paper/util/ItemStackRepairCheckTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..8d9c9b3bd53d407391d4fcb7fc773153d1a7b402
--- /dev/null
+++ b/src/test/java/io/papermc/paper/util/ItemStackRepairCheckTest.java
@@ -0,0 +1,48 @@
+package io.papermc.paper.util;
+
+import org.bukkit.Material;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.support.AbstractTestingBase;
+import org.junit.Test;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertThrows;
+import static org.junit.Assert.assertTrue;
+
+public class ItemStackRepairCheckTest extends AbstractTestingBase {
+
+ @Test
+ public void testIsRepariableBy() {
+ ItemStack diamondPick = new ItemStack(Material.DIAMOND_PICKAXE);
+
+ assertTrue("diamond pick isn't repairable by a diamond", diamondPick.isRepairableBy(new ItemStack(Material.DIAMOND)));
+ }
+
+ @Test
+ public void testCanRepair() {
+ ItemStack diamond = new ItemStack(Material.DIAMOND);
+
+ assertTrue("diamond can't repair a diamond axe", diamond.canRepair(new ItemStack(Material.DIAMOND_AXE)));
+ }
+
+ @Test
+ public void testIsNotRepairableBy() {
+ ItemStack notDiamondPick = new ItemStack(Material.ACACIA_SAPLING);
+
+ assertFalse("acacia sapling is repairable by a diamond", notDiamondPick.isRepairableBy(new ItemStack(Material.DIAMOND)));
+ }
+
+ @Test
+ public void testCanNotRepair() {
+ ItemStack diamond = new ItemStack(Material.DIAMOND);
+
+ assertFalse("diamond can repair oak button", diamond.canRepair(new ItemStack(Material.OAK_BUTTON)));
+ }
+
+ @Test
+ public void testInvalidItem() {
+ ItemStack badItemStack = new ItemStack(Material.ACACIA_WALL_SIGN);
+
+ assertFalse("acacia wall sign is repairable by diamond", badItemStack.isRepairableBy(new ItemStack(Material.DIAMOND)));
+ }
+}

View file

@ -0,0 +1,155 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 6 May 2021 19:57:58 -0700
Subject: [PATCH] More Enchantment API
diff --git a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
index c536eceef3365a7b726cd970df345ba1d055207d..11c1eb0e0bc326b28dc0cab16f67c413cc52e98c 100644
--- a/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
+++ b/src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java
@@ -71,7 +71,7 @@ public class CraftEnchantment extends Enchantment {
@Override
public boolean isCursed() {
- return this.target instanceof BindingCurseEnchantment || this.target instanceof VanishingCurseEnchantment;
+ return this.target.isCurse(); // Paper
}
@Override
@@ -197,6 +197,45 @@ public class CraftEnchantment extends Enchantment {
public String translationKey() {
return this.target.getDescriptionId();
}
+
+ @Override
+ public boolean isTradeable() {
+ return target.isTradeable();
+ }
+
+ @Override
+ public boolean isDiscoverable() {
+ return target.isDiscoverable();
+ }
+
+ @Override
+ public io.papermc.paper.enchantments.EnchantmentRarity getRarity() {
+ return fromNMSRarity(target.getRarity());
+ }
+
+ @Override
+ public float getDamageIncrease(int level, org.bukkit.entity.EntityCategory entityCategory) {
+ return target.getDamageBonus(level, org.bukkit.craftbukkit.entity.CraftLivingEntity.fromBukkitEntityCategory(entityCategory));
+ }
+
+ @Override
+ public java.util.Set<org.bukkit.inventory.EquipmentSlot> getActiveSlots() {
+ return java.util.stream.Stream.of(target.slots).map(org.bukkit.craftbukkit.CraftEquipmentSlot::getSlot).collect(java.util.stream.Collectors.toSet());
+ }
+
+ public static io.papermc.paper.enchantments.EnchantmentRarity fromNMSRarity(net.minecraft.world.item.enchantment.Enchantment.Rarity nmsRarity) {
+ if (nmsRarity == net.minecraft.world.item.enchantment.Enchantment.Rarity.COMMON) {
+ return io.papermc.paper.enchantments.EnchantmentRarity.COMMON;
+ } else if (nmsRarity == net.minecraft.world.item.enchantment.Enchantment.Rarity.UNCOMMON) {
+ return io.papermc.paper.enchantments.EnchantmentRarity.UNCOMMON;
+ } else if (nmsRarity == net.minecraft.world.item.enchantment.Enchantment.Rarity.RARE) {
+ return io.papermc.paper.enchantments.EnchantmentRarity.RARE;
+ } else if (nmsRarity == net.minecraft.world.item.enchantment.Enchantment.Rarity.VERY_RARE) {
+ return io.papermc.paper.enchantments.EnchantmentRarity.VERY_RARE;
+ }
+
+ throw new IllegalArgumentException(String.format("Unable to convert %s to a enum value of %s.", nmsRarity, io.papermc.paper.enchantments.EnchantmentRarity.class));
+ }
// Paper end
public net.minecraft.world.item.enchantment.Enchantment getHandle() {
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 6555db49ff57bba13a7eb3c0bf7ecb66d7828dce..8fe1f5deddfee329c020d93c990dc686fe2b458e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -867,5 +867,21 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
public void setHurtDirection(float hurtDirection) {
getHandle().hurtDir = hurtDirection;
}
+
+ public static MobType fromBukkitEntityCategory(EntityCategory entityCategory) {
+ switch (entityCategory) {
+ case NONE:
+ return MobType.UNDEFINED;
+ case UNDEAD:
+ return MobType.UNDEAD;
+ case ARTHROPOD:
+ return MobType.ARTHROPOD;
+ case ILLAGER:
+ return MobType.ILLAGER;
+ case WATER:
+ return MobType.WATER;
+ }
+ throw new IllegalArgumentException(entityCategory + " is an unrecognized entity category");
+ }
// Paper end
}
diff --git a/src/test/java/io/papermc/paper/enchantments/EnchantmentRarityTest.java b/src/test/java/io/papermc/paper/enchantments/EnchantmentRarityTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..62b56b5b43696b03fc72cac59f986d006edc3f76
--- /dev/null
+++ b/src/test/java/io/papermc/paper/enchantments/EnchantmentRarityTest.java
@@ -0,0 +1,18 @@
+package io.papermc.paper.enchantments;
+
+import net.minecraft.world.item.enchantment.Enchantment.Rarity;
+import org.bukkit.craftbukkit.enchantments.CraftEnchantment;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotNull;
+
+public class EnchantmentRarityTest {
+
+ @Test
+ public void test() {
+ for (Rarity nmsRarity : Rarity.values()) {
+ // Will throw exception if a bukkit counterpart is not found
+ CraftEnchantment.fromNMSRarity(nmsRarity);
+ }
+ }
+}
diff --git a/src/test/java/io/papermc/paper/entity/EntityCategoryTest.java b/src/test/java/io/papermc/paper/entity/EntityCategoryTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b9824b1f9491304ceb91be18f4f3b3068526bb33
--- /dev/null
+++ b/src/test/java/io/papermc/paper/entity/EntityCategoryTest.java
@@ -0,0 +1,34 @@
+package io.papermc.paper.entity;
+
+import com.google.common.base.Joiner;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import net.minecraft.world.entity.MobType;
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
+import org.bukkit.entity.EntityCategory;
+import org.junit.Test;
+
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertTrue;
+
+public class EntityCategoryTest {
+
+ @Test
+ public void test() throws IllegalAccessException {
+
+ Map<MobType, String> enumMonsterTypeFieldMap = Maps.newHashMap();
+ for (Field field : MobType.class.getDeclaredFields()) {
+ if (field.getType() == MobType.class) {
+ enumMonsterTypeFieldMap.put( (MobType) field.get(null), field.getName());
+ }
+ }
+
+ for (EntityCategory entityCategory : EntityCategory.values()) {
+ enumMonsterTypeFieldMap.remove(CraftLivingEntity.fromBukkitEntityCategory(entityCategory));
+ }
+ assertTrue(MobType.class.getName() + " instance(s): " + Joiner.on(", ").join(enumMonsterTypeFieldMap.values()) + " do not have bukkit equivalents", enumMonsterTypeFieldMap.size() == 0);
+ }
+}

View file

@ -0,0 +1,393 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Thu, 20 May 2021 07:02:22 -0700
Subject: [PATCH] Fix and optimise world force upgrading
The WorldUpgrader class was incorrectly modified by
CB. It will store an IChunkLoader instance for all
dimension types in the world, but obviously with how
CB shifts around worlds only one dimension type exists
per world. But this would be OK if CB did this
change correctly. All IChunkLoader instances
will point to the same regionfiles. And all
IChunkLoader instances are going to be read from.
This problem hasn't really been reported because
it relies on the persistent legacy data to be converted
as well to cause corruption. Why? Because the legacy
data is also shared, it will result in different
outputs from conversion (as once conversion for legacy
persistent data takes place, it is REMOVED - so the next
convert will _not_ have the data). Which means different
sizes on disk. Which means different regionfile sector
allocations. Which means there are 3 different possible
regionfile sector allocations in memory, and none of them
are going to be correct.
I've fixed this by writing a world upgrader suited to
CB's changes to world folder format. It was brain dead
easy to add threading, so I did.
diff --git a/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java
new file mode 100644
index 0000000000000000000000000000000000000000..748e6923338d40d67e31251e9ab6001674963690
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/ThreadedWorldUpgrader.java
@@ -0,0 +1,211 @@
+package io.papermc.paper.world;
+
+import com.mojang.datafixers.DataFixer;
+import com.mojang.serialization.Codec;
+import net.minecraft.SharedConstants;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.resources.ResourceKey;
+import net.minecraft.util.worldupdate.WorldUpgrader;
+import net.minecraft.world.level.ChunkPos;
+import net.minecraft.world.level.Level;
+import net.minecraft.world.level.chunk.ChunkGenerator;
+import net.minecraft.world.level.chunk.storage.ChunkStorage;
+import net.minecraft.world.level.chunk.storage.RegionFileStorage;
+import net.minecraft.world.level.dimension.DimensionType;
+import net.minecraft.world.level.dimension.LevelStem;
+import net.minecraft.world.level.levelgen.WorldGenSettings;
+import net.minecraft.world.level.storage.DimensionDataStorage;
+import net.minecraft.world.level.storage.LevelStorageSource;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import java.io.File;
+import java.io.IOException;
+import java.text.DecimalFormat;
+import java.util.Optional;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
+
+public class ThreadedWorldUpgrader {
+
+ private static final Logger LOGGER = LogManager.getLogger();
+
+ private final ResourceKey<LevelStem> dimensionType;
+ private final ResourceKey<DimensionType> worldKey;
+ private final String worldName;
+ private final File worldDir;
+ private final ExecutorService threadPool;
+ private final DataFixer dataFixer;
+ private final Optional<ResourceKey<Codec<? extends ChunkGenerator>>> generatorKey;
+ private final boolean removeCaches;
+
+ public ThreadedWorldUpgrader(final ResourceKey<LevelStem> dimensionType, final ResourceKey<DimensionType> worldKey, final String worldName, final File worldDir, final int threads,
+ final DataFixer dataFixer, final Optional<ResourceKey<Codec<? extends ChunkGenerator>>> generatorKey, final boolean removeCaches) {
+ this.dimensionType = dimensionType;
+ this.worldKey = worldKey;
+ this.worldName = worldName;
+ this.worldDir = worldDir;
+ this.threadPool = Executors.newFixedThreadPool(Math.max(1, threads), new ThreadFactory() {
+ private final AtomicInteger threadCounter = new AtomicInteger();
+
+ @Override
+ public Thread newThread(final Runnable run) {
+ final Thread ret = new Thread(run);
+
+ ret.setName("World upgrader thread for world " + ThreadedWorldUpgrader.this.worldName + " #" + this.threadCounter.getAndIncrement());
+ ret.setUncaughtExceptionHandler((thread, throwable) -> {
+ LOGGER.fatal("Error upgrading world", throwable);
+ });
+
+ return ret;
+ }
+ });
+ this.dataFixer = dataFixer;
+ this.generatorKey = generatorKey;
+ this.removeCaches = removeCaches;
+ }
+
+ public void convert() {
+ final File worldFolder = LevelStorageSource.getStorageFolder(this.worldDir.toPath(), this.dimensionType).toFile();
+ final DimensionDataStorage worldPersistentData = new DimensionDataStorage(new File(worldFolder, "data"), this.dataFixer);
+
+ final File regionFolder = new File(worldFolder, "region");
+
+ LOGGER.info("Force upgrading " + this.worldName);
+ LOGGER.info("Counting regionfiles for " + this.worldName);
+ final File[] regionFiles = regionFolder.listFiles((final File dir, final String name) -> {
+ return WorldUpgrader.REGEX.matcher(name).matches();
+ });
+ if (regionFiles == null) {
+ LOGGER.info("Found no regionfiles to convert for world " + this.worldName);
+ return;
+ }
+ LOGGER.info("Found " + regionFiles.length + " regionfiles to convert");
+ LOGGER.info("Starting conversion now for world " + this.worldName);
+
+ final WorldInfo info = new WorldInfo(() -> worldPersistentData,
+ new ChunkStorage(regionFolder.toPath(), this.dataFixer, false), this.removeCaches, this.dimensionType, this.generatorKey);
+
+ long expectedChunks = (long)regionFiles.length * (32L * 32L);
+
+ for (final File regionFile : regionFiles) {
+ final ChunkPos regionPos = RegionFileStorage.getRegionFileCoordinates(regionFile.toPath());
+ if (regionPos == null) {
+ expectedChunks -= (32L * 32L);
+ continue;
+ }
+
+ this.threadPool.execute(new ConvertTask(info, regionPos.x >> 5, regionPos.z >> 5));
+ }
+ this.threadPool.shutdown();
+
+ final DecimalFormat format = new DecimalFormat("#0.00");
+
+ final long start = System.nanoTime();
+
+ while (!this.threadPool.isTerminated()) {
+ final long current = info.convertedChunks.get();
+
+ LOGGER.info("{}% completed ({} / {} chunks)...", format.format((double)current / (double)expectedChunks * 100.0), current, expectedChunks);
+
+ try {
+ Thread.sleep(1000L);
+ } catch (final InterruptedException ignore) {}
+ }
+
+ final long end = System.nanoTime();
+
+ try {
+ info.loader.close();
+ } catch (final IOException ex) {
+ LOGGER.fatal("Failed to close chunk loader", ex);
+ }
+ LOGGER.info("Completed conversion. Took {}s, {} out of {} chunks needed to be converted/modified ({}%)",
+ (int)Math.ceil((end - start) * 1.0e-9), info.modifiedChunks.get(), expectedChunks, format.format((double)info.modifiedChunks.get() / (double)expectedChunks * 100.0));
+ }
+
+ private static final class WorldInfo {
+
+ public final Supplier<DimensionDataStorage> persistentDataSupplier;
+ public final ChunkStorage loader;
+ public final boolean removeCaches;
+ public final ResourceKey<LevelStem> worldKey;
+ public final Optional<ResourceKey<Codec<? extends ChunkGenerator>>> generatorKey;
+ public final AtomicLong convertedChunks = new AtomicLong();
+ public final AtomicLong modifiedChunks = new AtomicLong();
+
+ private WorldInfo(final Supplier<DimensionDataStorage> persistentDataSupplier, final ChunkStorage loader, final boolean removeCaches,
+ final ResourceKey<LevelStem> worldKey, Optional<ResourceKey<Codec<? extends ChunkGenerator>>> generatorKey) {
+ this.persistentDataSupplier = persistentDataSupplier;
+ this.loader = loader;
+ this.removeCaches = removeCaches;
+ this.worldKey = worldKey;
+ this.generatorKey = generatorKey;
+ }
+ }
+
+ private static final class ConvertTask implements Runnable {
+
+ private final WorldInfo worldInfo;
+ private final int regionX;
+ private final int regionZ;
+
+ public ConvertTask(final WorldInfo worldInfo, final int regionX, final int regionZ) {
+ this.worldInfo = worldInfo;
+ this.regionX = regionX;
+ this.regionZ = regionZ;
+ }
+
+ @Override
+ public void run() {
+ final int regionCX = this.regionX << 5;
+ final int regionCZ = this.regionZ << 5;
+
+ final Supplier<DimensionDataStorage> persistentDataSupplier = this.worldInfo.persistentDataSupplier;
+ final ChunkStorage loader = this.worldInfo.loader;
+ final boolean removeCaches = this.worldInfo.removeCaches;
+ final ResourceKey<LevelStem> worldKey = this.worldInfo.worldKey;
+
+ for (int cz = regionCZ; cz < (regionCZ + 32); ++cz) {
+ for (int cx = regionCX; cx < (regionCX + 32); ++cx) {
+ final ChunkPos chunkPos = new ChunkPos(cx, cz);
+ try {
+ // no need to check the coordinate of the chunk, the regionfilecache does that for us
+
+ CompoundTag chunkNBT = loader.read(chunkPos);
+
+ if (chunkNBT == null) {
+ continue;
+ }
+
+ final int versionBefore = ChunkStorage.getVersion(chunkNBT);
+
+ chunkNBT = loader.upgradeChunkTag(worldKey, persistentDataSupplier, chunkNBT, this.worldInfo.generatorKey, chunkPos, null);
+
+ boolean modified = versionBefore < SharedConstants.getCurrentVersion().getWorldVersion();
+
+ if (removeCaches) {
+ final CompoundTag level = chunkNBT.getCompound("Level");
+ modified |= level.contains("Heightmaps");
+ level.remove("Heightmaps");
+ modified |= level.contains("isLightOn");
+ level.remove("isLightOn");
+ }
+
+ if (modified) {
+ this.worldInfo.modifiedChunks.getAndIncrement();
+ loader.write(chunkPos, chunkNBT);
+ }
+ } catch (final Exception ex) {
+ LOGGER.error("Error upgrading chunk {}", chunkPos, ex);
+ } finally {
+ this.worldInfo.convertedChunks.getAndIncrement();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/main/java/net/minecraft/server/Main.java b/src/main/java/net/minecraft/server/Main.java
index f685ab3cc6e4fd76e8dec3d2d3627a13715cda44..36a1d58dd238c835ce3cc9c2376a86a04915d098 100644
--- a/src/main/java/net/minecraft/server/Main.java
+++ b/src/main/java/net/minecraft/server/Main.java
@@ -13,6 +13,7 @@ import java.nio.file.Paths;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.BooleanSupplier;
+import io.papermc.paper.world.ThreadedWorldUpgrader;
import joptsimple.NonOptionArgumentSpec;
import joptsimple.OptionParser;
import joptsimple.OptionSet;
@@ -293,6 +294,15 @@ public class Main {
}
// Paper end
+ // Paper start - fix and optimise world upgrading
+ public static void convertWorldButItWorks(net.minecraft.resources.ResourceKey<net.minecraft.world.level.dimension.LevelStem> dimensionType, net.minecraft.resources.ResourceKey<net.minecraft.world.level.dimension.DimensionType> worldKey, net.minecraft.world.level.storage.LevelStorageSource.LevelStorageAccess worldSession,
+ DataFixer dataFixer, Optional<net.minecraft.resources.ResourceKey<com.mojang.serialization.Codec<? extends net.minecraft.world.level.chunk.ChunkGenerator>>> generatorKey, boolean removeCaches) {
+ int threads = Runtime.getRuntime().availableProcessors() * 3 / 8;
+ final ThreadedWorldUpgrader worldUpgrader = new ThreadedWorldUpgrader(dimensionType, worldKey, worldSession.getLevelId(), worldSession.levelPath.toFile(), threads, dataFixer, generatorKey, removeCaches);
+ worldUpgrader.convert();
+ }
+ // Paper end - fix and optimise world upgrading
+
public static void forceUpgrade(LevelStorageSource.LevelStorageAccess session, DataFixer dataFixer, boolean eraseCache, BooleanSupplier continueCheck, WorldGenSettings generatorOptions) {
Main.LOGGER.info("Forcing world upgrade! {}", session.getLevelId()); // CraftBukkit
WorldUpgrader worldupgrader = new WorldUpgrader(session, dataFixer, generatorOptions, eraseCache);
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index 478eb61a9e5aab8b004e75c264eca9ca79e51fbb..d93e6d987e013bce37d511ac6c5b2481d86b9235 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -556,11 +556,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
worlddata = new PrimaryLevelData(worldsettings, generatorsettings, Lifecycle.stable());
}
worlddata.checkName(name); // CraftBukkit - Migration did not rewrite the level.dat; This forces 1.8 to take the last loaded world as respawn (in this case the end)
- if (this.options.has("forceUpgrade")) {
- net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), this.options.has("eraseCache"), () -> {
- return true;
- }, worlddata.worldGenSettings());
- }
+ // Paper - move down
ServerLevelData iworlddataserver = worlddata;
WorldGenSettings generatorsettings = worlddata.worldGenSettings();
@@ -592,6 +588,14 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
}
}
+ // Paper start - fix and optimise world upgrading
+ if (options.has("forceUpgrade")) {
+ net.minecraft.server.Main.convertWorldButItWorks(
+ dimensionKey, Level.getDimensionKey(dimensionmanager), worldSession, DataFixers.getDataFixer(), chunkgenerator.getTypeNameForDataFixer(), options.has("eraseCache")
+ );
+ }
+ // Paper end - fix and optimise world upgrading
+
ResourceKey<Level> worldKey = ResourceKey.create(Registry.DIMENSION_REGISTRY, dimensionKey.location());
if (dimensionKey == LevelStem.OVERWORLD) {
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index c68cb2ee352325d3f0ef98827df04b0c7bf1b293..b4d750dcb1df5852fa4a6c7b7ca8037bc06607fb 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -176,6 +176,15 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
public final Map<Explosion.CacheKey, Float> explosionDensityCache = new HashMap<>(); // Paper - Optimize explosions
public java.util.ArrayDeque<net.minecraft.world.level.block.RedstoneTorchBlock.Toggle> redstoneUpdateInfos; // Paper - Move from Map in BlockRedstoneTorch to here
+ // Paper start - fix and optimise world upgrading
+ // copied from below
+ public static ResourceKey<DimensionType> getDimensionKey(DimensionType manager) {
+ return ((org.bukkit.craftbukkit.CraftServer)org.bukkit.Bukkit.getServer()).getHandle().getServer().registryHolder.ownedRegistryOrThrow(net.minecraft.core.Registry.DIMENSION_TYPE_REGISTRY).getResourceKey(manager).orElseThrow(() -> {
+ return new IllegalStateException("Unregistered dimension type: " + manager);
+ });
+ }
+ // Paper end - fix and optimise world upgrading
+
public CraftWorld getWorld() {
return this.world;
}
diff --git a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
index 91cf5878dc13e1abca0c301d1346248bda251cbf..0c5f5b2960f1a0d4bbd41c3c3baf101b4c388c43 100644
--- a/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
+++ b/src/main/java/net/minecraft/world/level/chunk/storage/RegionFileStorage.java
@@ -32,6 +32,28 @@ public class RegionFileStorage implements AutoCloseable {
}
// Paper start
+ public static @Nullable ChunkPos getRegionFileCoordinates(Path file) {
+ String fileName = file.getFileName().toString();
+ if (!fileName.startsWith("r.") || !fileName.endsWith(".mca")) {
+ return null;
+ }
+
+ String[] split = fileName.split("\\.");
+
+ if (split.length != 4) {
+ return null;
+ }
+
+ try {
+ int x = Integer.parseInt(split[1]);
+ int z = Integer.parseInt(split[2]);
+
+ return new ChunkPos(x << 5, z << 5);
+ } catch (NumberFormatException ex) {
+ return null;
+ }
+ }
+
public synchronized RegionFile getRegionFileIfLoaded(ChunkPos chunkcoordintpair) {
return this.regionCache.getAndMoveToFirst(ChunkPos.asLong(chunkcoordintpair.getRegionX(), chunkcoordintpair.getRegionZ()));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index 3d3913686727af7367377deaf35681de6900aa22..9f69e1874caa087778e1de637c93719b43ac5a23 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -1200,12 +1200,7 @@ public final class CraftServer implements Server {
}
worlddata.checkName(name);
worlddata.setModdedInfo(this.console.getServerModName(), this.console.getModdedStatus().shouldReportAsModified());
-
- if (console.options.has("forceUpgrade")) {
- net.minecraft.server.Main.forceUpgrade(worldSession, DataFixers.getDataFixer(), console.options.has("eraseCache"), () -> {
- return true;
- }, worlddata.worldGenSettings());
- }
+ // Paper - move down
long j = BiomeManager.obfuscateSeed(creator.seed());
List<CustomSpawner> list = ImmutableList.of(new PhantomSpawner(), new PatrolSpawner(), new CatSpawner(), new VillageSiege(), new WanderingTraderSpawner(worlddata));
@@ -1234,6 +1229,14 @@ public final class CraftServer implements Server {
}
}
+ // Paper start - fix and optimise world upgrading
+ if (console.options.has("forceUpgrade")) {
+ net.minecraft.server.Main.convertWorldButItWorks(
+ actualDimension, net.minecraft.world.level.Level.getDimensionKey(dimensionmanager), worldSession, DataFixers.getDataFixer(), chunkgenerator.getTypeNameForDataFixer(), console.options.has("eraseCache")
+ );
+ }
+ // Paper end - fix and optimise world upgrading
+
ResourceKey<net.minecraft.world.level.Level> worldKey;
String levelName = this.getServer().getProperties().levelName;
if (name.equals(levelName + "_nether")) {

View file

@ -0,0 +1,64 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: BillyGalbreath <blake.galbreath@gmail.com>
Date: Fri, 14 May 2021 13:42:17 -0500
Subject: [PATCH] Add Mob#lookAt API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
index d7bc601f2cb4e22565eeebb2d8ebe051748de92a..0613ab9979a32a005fa2cbf24125022713daca3a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
@@ -86,5 +86,53 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
public boolean isInDaylight() {
return getHandle().isSunBurnTick();
}
+
+ @Override
+ public void lookAt(@org.jetbrains.annotations.NotNull org.bukkit.Location location) {
+ com.google.common.base.Preconditions.checkNotNull(location, "location cannot be null");
+ com.google.common.base.Preconditions.checkArgument(location.getWorld().equals(getWorld()), "location in a different world");
+ getHandle().getLookControl().setLookAt(location.getX(), location.getY(), location.getZ());
+ }
+
+ @Override
+ public void lookAt(@org.jetbrains.annotations.NotNull org.bukkit.Location location, float headRotationSpeed, float maxHeadPitch) {
+ com.google.common.base.Preconditions.checkNotNull(location, "location cannot be null");
+ com.google.common.base.Preconditions.checkArgument(location.getWorld().equals(getWorld()), "location in a different world");
+ getHandle().getLookControl().setLookAt(location.getX(), location.getY(), location.getZ(), headRotationSpeed, maxHeadPitch);
+ }
+
+ @Override
+ public void lookAt(@org.jetbrains.annotations.NotNull org.bukkit.entity.Entity entity) {
+ com.google.common.base.Preconditions.checkNotNull(entity, "entity cannot be null");
+ com.google.common.base.Preconditions.checkArgument(entity.getWorld().equals(getWorld()), "entity in a different world");
+ getHandle().getLookControl().setLookAt(((CraftEntity) entity).getHandle());
+ }
+
+ @Override
+ public void lookAt(@org.jetbrains.annotations.NotNull org.bukkit.entity.Entity entity, float headRotationSpeed, float maxHeadPitch) {
+ com.google.common.base.Preconditions.checkNotNull(entity, "entity cannot be null");
+ com.google.common.base.Preconditions.checkArgument(entity.getWorld().equals(getWorld()), "entity in a different world");
+ getHandle().getLookControl().setLookAt(((CraftEntity) entity).getHandle(), headRotationSpeed, maxHeadPitch);
+ }
+
+ @Override
+ public void lookAt(double x, double y, double z) {
+ getHandle().getLookControl().setLookAt(x, y, z);
+ }
+
+ @Override
+ public void lookAt(double x, double y, double z, float headRotationSpeed, float maxHeadPitch) {
+ getHandle().getLookControl().setLookAt(x, y, z, headRotationSpeed, maxHeadPitch);
+ }
+
+ @Override
+ public int getHeadRotationSpeed() {
+ return getHandle().getHeadRotSpeed();
+ }
+
+ @Override
+ public int getMaxHeadPitch() {
+ return getHandle().getMaxHeadXRot();
+ }
// Paper end
}

View file

@ -0,0 +1,141 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Tue, 11 May 2021 17:39:22 -0400
Subject: [PATCH] Add Unix domain socket support
For Windows and ARM support, JEP-380 is required:
https://inside.java/2021/02/03/jep380-unix-domain-sockets-channels/
This will be possible as of the Minecraft 1.17 Java version bump.
Tested-by: Mariell Hoversholm <proximyst@proximyst.com>
Reviewed-by: Mariell Hoversholm <proximyst@proximyst.com>
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
index a6eadf71957b37e2acc5d09f0ce4ee961810891f..16954170ffeeedf18d8f8079b5e75915e0c682ba 100644
--- a/src/main/java/net/minecraft/network/Connection.java
+++ b/src/main/java/net/minecraft/network/Connection.java
@@ -614,6 +614,11 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
// Spigot Start
public SocketAddress getRawAddress()
{
+ // Paper start - this can be nullable in the case of a Unix domain socket, so if it is, fake something
+ if (this.channel.remoteAddress() == null) {
+ return new java.net.InetSocketAddress(java.net.InetAddress.getLoopbackAddress(), 0);
+ }
+ // Paper end
return this.channel.remoteAddress();
}
// Spigot End
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
index 331c85d236922d7a4b5732cb09aa708830e1393c..82cee660a029547eda8abdf4188b9d1fb4ba0d53 100644
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
@@ -231,6 +231,20 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
this.setEnforceWhitelist(dedicatedserverproperties.enforceWhitelist);
// this.worldData.setGameType(dedicatedserverproperties.gamemode); // CraftBukkit - moved to world loading
DedicatedServer.LOGGER.info("Default game type: {}", dedicatedserverproperties.gamemode);
+ // Paper start - Unix domain socket support
+ java.net.SocketAddress bindAddress;
+ if (this.getLocalIp().startsWith("unix:")) {
+ if (!io.netty.channel.epoll.Epoll.isAvailable()) {
+ DedicatedServer.LOGGER.fatal("**** INVALID CONFIGURATION!");
+ DedicatedServer.LOGGER.fatal("You are trying to use a Unix domain socket but you're not on a supported OS.");
+ return false;
+ } else if (!com.destroystokyo.paper.PaperConfig.velocitySupport && !org.spigotmc.SpigotConfig.bungee) {
+ DedicatedServer.LOGGER.fatal("**** INVALID CONFIGURATION!");
+ DedicatedServer.LOGGER.fatal("Unix domain sockets require IPs to be forwarded from a proxy.");
+ return false;
+ }
+ bindAddress = new io.netty.channel.unix.DomainSocketAddress(this.getLocalIp().substring("unix:".length()));
+ } else {
InetAddress inetaddress = null;
if (!this.getLocalIp().isEmpty()) {
@@ -240,12 +254,15 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
if (this.getPort() < 0) {
this.setPort(dedicatedserverproperties.serverPort);
}
+ bindAddress = new java.net.InetSocketAddress(inetaddress, this.getPort());
+ }
+ // Paper end
this.initializeKeyPair();
DedicatedServer.LOGGER.info("Starting Minecraft server on {}:{}", this.getLocalIp().isEmpty() ? "*" : this.getLocalIp(), this.getPort());
try {
- this.getConnection().startTcpServerListener(inetaddress, this.getPort());
+ this.getConnection().bind(bindAddress); // Paper - Unix domain socket support
} catch (IOException ioexception) {
DedicatedServer.LOGGER.warn("**** FAILED TO BIND TO PORT!");
DedicatedServer.LOGGER.warn("The exception was: {}", ioexception.toString());
diff --git a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
index 940b52e0b22b009f819de0dc05436a1820390bde..f7aa0125e4724f1efddf28814f926289c1ae37d4 100644
--- a/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
+++ b/src/main/java/net/minecraft/server/network/ServerConnectionListener.java
@@ -78,7 +78,12 @@ public class ServerConnectionListener {
this.running = true;
}
+ // Paper start
public void startTcpServerListener(@Nullable InetAddress address, int port) throws IOException {
+ bind(new java.net.InetSocketAddress(address, port));
+ }
+ public void bind(java.net.SocketAddress address) throws IOException {
+ // Paper end
List list = this.channels;
synchronized (this.channels) {
@@ -86,7 +91,11 @@ public class ServerConnectionListener {
LazyLoadedValue lazyinitvar;
if (Epoll.isAvailable() && this.server.isEpollEnabled()) {
+ if (address instanceof io.netty.channel.unix.DomainSocketAddress) {
+ oclass = io.netty.channel.epoll.EpollServerDomainSocketChannel.class;
+ } else {
oclass = EpollServerSocketChannel.class;
+ }
lazyinitvar = ServerConnectionListener.SERVER_EPOLL_EVENT_GROUP;
ServerConnectionListener.LOGGER.info("Using epoll channel type");
} else {
@@ -114,7 +123,7 @@ public class ServerConnectionListener {
((Connection) object).setListener(new ServerHandshakePacketListenerImpl(ServerConnectionListener.this.server, (Connection) object));
io.papermc.paper.network.ChannelInitializeListenerHolder.callListeners(channel); // Paper
}
- }).group((EventLoopGroup) lazyinitvar.get()).localAddress(address, port)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit
+ }).group((EventLoopGroup) lazyinitvar.get()).localAddress(address)).option(ChannelOption.AUTO_READ, false).bind().syncUninterruptibly()); // CraftBukkit // Paper
}
}
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
index 4c44f06ba18cfa2d889d0dd57fdd7eb79971c8c6..e0cd786f130e34b3401d40663e1548fc0076f74a 100644
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
@@ -44,6 +44,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
this.connection.setProtocol(ConnectionProtocol.LOGIN);
// CraftBukkit start - Connection throttle
try {
+ if (!(this.connection.channel.localAddress() instanceof io.netty.channel.unix.DomainSocketAddress)) { // Paper - the connection throttle is useless when you have a Unix domain socket
long currentTime = System.currentTimeMillis();
long connectionThrottle = this.server.server.getConnectionThrottle();
InetAddress address = ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getAddress();
@@ -72,6 +73,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
}
}
}
+ } // Paper - add closing bracket for if check above
} catch (Throwable t) {
org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t);
}
@@ -120,8 +122,11 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
//if (org.spigotmc.SpigotConfig.bungee) { // Paper - comment out, we check above!
String[] split = packet.hostName.split("\00");
if ( ( split.length == 3 || split.length == 4 ) && ( ServerHandshakePacketListenerImpl.BYPASS_HOSTCHECK || ServerHandshakePacketListenerImpl.HOST_PATTERN.matcher( split[1] ).matches() ) ) { // Paper
+ // Paper start - Unix domain socket support
+ java.net.SocketAddress socketAddress = connection.getRemoteAddress();
packet.hostName = split[0];
- connection.address = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) this.connection.getRemoteAddress()).getPort());
+ connection.address = new java.net.InetSocketAddress(split[1], socketAddress instanceof java.net.InetSocketAddress ? ((java.net.InetSocketAddress) socketAddress).getPort() : 0);
+ // Paper end
connection.spoofedUUID = com.mojang.util.UUIDTypeAdapter.fromString( split[2] );
} else
{

View file

@ -0,0 +1,258 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 8 May 2021 18:02:36 -0700
Subject: [PATCH] Add EntityInsideBlockEvent
diff --git a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
index ed216f0b6cf031883c4ca4123d82c9fc542b915e..4d1f94c576b65e067efce95d5ef8c0078453b494 100644
--- a/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BaseFireBlock.java
@@ -121,6 +121,7 @@ public abstract class BaseFireBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!entity.fireImmune()) {
entity.setRemainingFireTicks(entity.getRemainingFireTicks() + 1);
if (entity.getRemainingFireTicks() == 0) {
diff --git a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
index 7cc20edb0cc3994a6c23ae99801bb254869e424f..2036006b934ba1f27da606320b4c456af019a361 100644
--- a/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BasePressurePlateBlock.java
@@ -67,6 +67,7 @@ public abstract class BasePressurePlateBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide) {
int i = this.getSignalForState(state);
diff --git a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
index bc472d86ae79437dab87454caa60d64399a14715..3f434ac77611a81889b15c118a0fca57cc10a6bb 100644
--- a/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BigDripleafBlock.java
@@ -171,6 +171,7 @@ public class BigDripleafBlock extends HorizontalDirectionalBlock implements Bone
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide) {
if (state.getValue(BigDripleafBlock.TILT) == Tilt.NONE && BigDripleafBlock.canEntityTilt(pos, entity) && !world.hasNeighborSignal(pos)) {
// CraftBukkit start - tilt dripleaf
diff --git a/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java b/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java
index d99399eca5e30423f007c0e0665e8c14374c503c..ee3045133965da67611f180835fa111998f918b4 100644
--- a/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/BubbleColumnBlock.java
@@ -38,6 +38,7 @@ public class BubbleColumnBlock extends Block implements BucketPickup {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
BlockState blockState = world.getBlockState(pos.above());
if (blockState.isAir()) {
entity.onAboveBubbleCol(state.getValue(DRAG_DOWN));
diff --git a/src/main/java/net/minecraft/world/level/block/ButtonBlock.java b/src/main/java/net/minecraft/world/level/block/ButtonBlock.java
index 70161d554163779ba53ad278c6af95b9da87edce..b7f37475192bf79252482314080c9ba08e9aefdb 100644
--- a/src/main/java/net/minecraft/world/level/block/ButtonBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/ButtonBlock.java
@@ -186,6 +186,7 @@ public abstract class ButtonBlock extends FaceAttachedHorizontalDirectionalBlock
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide && this.sensitive && !(Boolean) state.getValue(ButtonBlock.POWERED)) {
this.checkPressed(state, world, pos);
}
diff --git a/src/main/java/net/minecraft/world/level/block/CactusBlock.java b/src/main/java/net/minecraft/world/level/block/CactusBlock.java
index 00ada22889dafb7ae8e8740cd3eb8370fbb417eb..fa36ad3bb63764778aa7201d90e331e64292c7b4 100644
--- a/src/main/java/net/minecraft/world/level/block/CactusBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CactusBlock.java
@@ -117,6 +117,7 @@ public class CactusBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
CraftEventFactory.blockDamage = world.getWorld().getBlockAt(pos.getX(), pos.getY(), pos.getZ()); // CraftBukkit
entity.hurt(DamageSource.CACTUS, 1.0F);
CraftEventFactory.blockDamage = null; // CraftBukkit
diff --git a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java
index eeb729428356b116f650d54f44dacf5694969f7d..0b60b545271e62df86a0eb3c1f0f315a014b24cd 100644
--- a/src/main/java/net/minecraft/world/level/block/CampfireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CampfireBlock.java
@@ -94,6 +94,7 @@ public class CampfireBlock extends BaseEntityBlock implements SimpleWaterloggedB
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!entity.fireImmune() && (Boolean) state.getValue(CampfireBlock.LIT) && entity instanceof LivingEntity && !EnchantmentHelper.hasFrostWalker((LivingEntity) entity)) {
org.bukkit.craftbukkit.event.CraftEventFactory.blockDamage = CraftBlock.at(world, pos); // CraftBukkit
entity.hurt(DamageSource.IN_FIRE, (float) this.fireDamage);
diff --git a/src/main/java/net/minecraft/world/level/block/CropBlock.java b/src/main/java/net/minecraft/world/level/block/CropBlock.java
index 75dc5d9a750a49b6ad9fd2aba99b9f84c2663e10..b4fd9af8805f451c87a91f319c15fa132b91faf7 100644
--- a/src/main/java/net/minecraft/world/level/block/CropBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/CropBlock.java
@@ -163,6 +163,7 @@ public class CropBlock extends BushBlock implements BonemealableBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (entity instanceof Ravager && !CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState(), !world.getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)).isCancelled()) { // CraftBukkit
world.destroyBlock(pos, true, entity);
}
diff --git a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
index b68e3ced407a9e6b386cbd379e58c86f195eb17a..4dc92fafc3ea593afd19cfc7c5e6b1591408d095 100644
--- a/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/DetectorRailBlock.java
@@ -44,6 +44,7 @@ public class DetectorRailBlock extends BaseRailBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide) {
if (!(Boolean) state.getValue(DetectorRailBlock.POWERED)) {
this.checkPressed(world, pos, state);
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
index 40fe9e093f32c65947973daa21afec58ca7976f8..b8305112c759ecb62ef9ad972e57ff85ceff20dc 100644
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
@@ -44,6 +44,7 @@ public class EndPortalBlock extends BaseEntityBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (world instanceof ServerLevel && !entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions() && Shapes.joinIsNotEmpty(Shapes.create(entity.getBoundingBox().move((double) (-pos.getX()), (double) (-pos.getY()), (double) (-pos.getZ()))), state.getShape(world, pos), BooleanOp.AND)) {
ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
ServerLevel worldserver = ((ServerLevel) world).getServer().getLevel(resourcekey);
diff --git a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java
index 0549256cbd7028c82bf82ccc4ff64219df7e0906..683f24251baf8ef3bef8f32ba83dc7f0e8ed7d70 100644
--- a/src/main/java/net/minecraft/world/level/block/HoneyBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/HoneyBlock.java
@@ -55,6 +55,7 @@ public class HoneyBlock extends HalfTransparentBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (this.isSlidingDown(pos, entity)) {
this.maybeDoSlideAchievement(entity, pos);
this.doSlideMovement(entity);
diff --git a/src/main/java/net/minecraft/world/level/block/HopperBlock.java b/src/main/java/net/minecraft/world/level/block/HopperBlock.java
index 9a58f017bbaa742cbb892c804011cc9396b8607c..386c3e458babc31ad3bf2b51c20d1cfde08647ac 100644
--- a/src/main/java/net/minecraft/world/level/block/HopperBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/HopperBlock.java
@@ -200,6 +200,7 @@ public class HopperBlock extends BaseEntityBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
BlockEntity blockEntity = world.getBlockEntity(pos);
if (blockEntity instanceof HopperBlockEntity) {
HopperBlockEntity.entityInside(world, pos, state, entity, (HopperBlockEntity)blockEntity);
diff --git a/src/main/java/net/minecraft/world/level/block/LavaCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LavaCauldronBlock.java
index f0a3ef0529951e7732602d358ddea1782001db7e..6588b207d93d96934e72176874ba60c81e9a098c 100644
--- a/src/main/java/net/minecraft/world/level/block/LavaCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LavaCauldronBlock.java
@@ -24,6 +24,7 @@ public class LavaCauldronBlock extends AbstractCauldronBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (this.isEntityInsideContent(state, pos, entity)) {
entity.lavaHurt();
}
diff --git a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
index f0a4c52b9cba6ebf7712950852aba4b2e0083f3d..e6ea389350cf391a87c4c388ed9a6325bdceb90d 100644
--- a/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/LayeredCauldronBlock.java
@@ -59,6 +59,7 @@ public class LayeredCauldronBlock extends AbstractCauldronBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide && entity.isOnFire() && this.isEntityInsideContent(state, pos, entity)) {
// CraftBukkit start
if (entity.mayInteract(world, pos)) {
diff --git a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
index d2b82872f6f8c3febb6c4b6468fd39f3549b1ed8..82c132bc90381aab6a29d50319ff40e7383eb7f2 100644
--- a/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/NetherPortalBlock.java
@@ -85,6 +85,7 @@ public class NetherPortalBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!entity.isPassenger() && !entity.isVehicle() && entity.canChangeDimensions()) {
// CraftBukkit start - Entity in portal
EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
diff --git a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
index dcdcbb1a2acffab2c5b389e6ecb853364f689021..5e22a1cd1a0902d63f091bbfb8ae518b12c66f09 100644
--- a/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/PowderSnowBlock.java
@@ -55,6 +55,7 @@ public class PowderSnowBlock extends Block implements BucketPickup {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!(entity instanceof LivingEntity) || entity.getFeetBlockState().is((Block) this)) {
entity.makeStuckInBlock(state, new Vec3(0.8999999761581421D, 1.5D, 0.8999999761581421D));
if (world.isClientSide) {
diff --git a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java
index 1a5590ff8e5122b5c7587347fcc38d73671c2747..71abf800e623336124bd9a955e07db4950286516 100644
--- a/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/SweetBerryBushBlock.java
@@ -73,6 +73,7 @@ public class SweetBerryBushBlock extends BushBlock implements BonemealableBlock
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (entity instanceof LivingEntity && entity.getType() != EntityType.FOX && entity.getType() != EntityType.BEE) {
entity.makeStuckInBlock(state, new Vec3(0.800000011920929D, 0.75D, 0.800000011920929D));
if (!world.isClientSide && (Integer) state.getValue(SweetBerryBushBlock.AGE) > 0 && (entity.xOld != entity.getX() || entity.zOld != entity.getZ())) {
diff --git a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
index 0c24c025e537b501f583aa3de920e18abc6ca259..6b40bf94fbaa18605b59b92ad1582e8dc3a6a9cd 100644
--- a/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/TripWireBlock.java
@@ -121,6 +121,7 @@ public class TripWireBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide) {
if (!(Boolean) state.getValue(TripWireBlock.POWERED)) {
this.checkPressed(world, pos);
diff --git a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
index 2b2a28d0383ccc8c0e7debd90331570b02b5e65f..bd4295f8d24ca9fd8c3af31abcd13da24db1c5d5 100644
--- a/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/WaterlilyBlock.java
@@ -25,6 +25,7 @@ public class WaterlilyBlock extends BushBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
super.entityInside(state, world, pos, entity);
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (world instanceof ServerLevel && entity instanceof Boat && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityChangeBlockEvent(entity, pos, Blocks.AIR.defaultBlockState()).isCancelled()) { // CraftBukkit
world.destroyBlock(new BlockPos(pos), true, entity);
}
diff --git a/src/main/java/net/minecraft/world/level/block/WebBlock.java b/src/main/java/net/minecraft/world/level/block/WebBlock.java
index 6964308822ebf8a7027ce426062ba43a70c20c15..763fa221c562e96c2abd09c7055e91a86ac03d43 100644
--- a/src/main/java/net/minecraft/world/level/block/WebBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/WebBlock.java
@@ -14,6 +14,7 @@ public class WebBlock extends Block {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
entity.makeStuckInBlock(state, new Vec3(0.25D, (double)0.05F, 0.25D));
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java b/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java
index 02779f3695c6609f07db326334b3c270cd7bf8e6..bb322ffd3dddb14d97884c0cc78d098577daad05 100644
--- a/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/WitherRoseBlock.java
@@ -46,6 +46,7 @@ public class WitherRoseBlock extends FlowerBlock {
@Override
public void entityInside(BlockState state, Level world, BlockPos pos, Entity entity) {
+ if (!new io.papermc.paper.event.entity.EntityInsideBlockEvent(entity.getBukkitEntity(), org.bukkit.craftbukkit.block.CraftBlock.at(world, pos)).callEvent()) { return; } // Paper
if (!world.isClientSide && world.getDifficulty() != Difficulty.PEACEFUL) {
if (entity instanceof LivingEntity) {
LivingEntity entityliving = (LivingEntity) entity;

View file

@ -0,0 +1,45 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 8 May 2021 15:01:54 -0700
Subject: [PATCH] Attributes API for item defaults
diff --git a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
index 7e3826b271b2db3b48e6e21ac2e66911bf8993aa..393a19335c52b6e63d37aacdfbeff93e1795c421 100644
--- a/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
+++ b/src/main/java/org/bukkit/craftbukkit/attribute/CraftAttributeInstance.java
@@ -72,4 +72,10 @@ public class CraftAttributeInstance implements AttributeInstance {
public static AttributeModifier convert(net.minecraft.world.entity.ai.attributes.AttributeModifier nms) {
return new AttributeModifier(nms.getId(), nms.getName(), nms.getAmount(), AttributeModifier.Operation.values()[nms.getOperation().ordinal()]);
}
+
+ // Paper start - construct using slot
+ public static AttributeModifier convert(net.minecraft.world.entity.ai.attributes.AttributeModifier nms, org.bukkit.inventory.EquipmentSlot slot) {
+ return new AttributeModifier(nms.getId(), nms.getName(), nms.getAmount(), AttributeModifier.Operation.values()[nms.getOperation().ordinal()], slot);
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 5e6941963f12a7f11603884a1b0bf844ea3a3514..5996e8b3eea10aabdd2374356016207a44a77f72 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -499,6 +499,19 @@ public final class CraftMagicNumbers implements UnsafeValues {
return CraftMagicNumbers.getItem(itemToBeRepaired.getType()).isValidRepairItem(CraftItemStack.asNMSCopy(itemToBeRepaired), CraftItemStack.asNMSCopy(repairMaterial));
}
+ @Override
+ public com.google.common.collect.Multimap<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> getItemAttributes(org.bukkit.Material material, org.bukkit.inventory.EquipmentSlot equipmentSlot) {
+ Item item = CraftMagicNumbers.getItem(material);
+ if (item == null) {
+ throw new IllegalArgumentException(material + " is not an item and therefore does not have attributes");
+ }
+ com.google.common.collect.ImmutableMultimap.Builder<org.bukkit.attribute.Attribute, org.bukkit.attribute.AttributeModifier> attributeMapBuilder = com.google.common.collect.ImmutableMultimap.builder();
+ item.getDefaultAttributeModifiers(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(equipmentSlot)).forEach((attributeBase, attributeModifier) -> {
+ attributeMapBuilder.put(org.bukkit.Registry.ATTRIBUTE.get(CraftNamespacedKey.fromMinecraft(net.minecraft.core.Registry.ATTRIBUTE.getKey(attributeBase))), org.bukkit.craftbukkit.attribute.CraftAttributeInstance.convert(attributeModifier, equipmentSlot));
+ });
+ return attributeMapBuilder.build();
+ }
+
@Override
public int getProtocolVersion() {
return net.minecraft.SharedConstants.getCurrentVersion().getProtocolVersion();

View file

@ -0,0 +1,118 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 2 Dec 2020 18:23:26 -0800
Subject: [PATCH] Add cause to Weather/ThunderChangeEvents
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index d09a9886a6fa8a7e180ab0c1c4a5b437b621f236..ddfd7eaf71f870037989024ae37322d25a221499 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -468,8 +468,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setClearWeatherTime(clearDuration);
this.serverLevelData.setRainTime(rainDuration);
this.serverLevelData.setThunderTime(rainDuration);
- this.serverLevelData.setRaining(raining);
- this.serverLevelData.setThundering(thundering);
+ this.serverLevelData.setRaining(raining, org.bukkit.event.weather.WeatherChangeEvent.Cause.COMMAND); // Paper
+ this.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.COMMAND); // Paper
}
@Override
@@ -859,8 +859,8 @@ public class ServerLevel extends Level implements WorldGenLevel {
this.serverLevelData.setThunderTime(j);
this.serverLevelData.setRainTime(k);
this.serverLevelData.setClearWeatherTime(i);
- this.serverLevelData.setThundering(flag1);
- this.serverLevelData.setRaining(flag2);
+ this.serverLevelData.setThundering(flag1, org.bukkit.event.weather.ThunderChangeEvent.Cause.NATURAL); // Paper
+ this.serverLevelData.setRaining(flag2, org.bukkit.event.weather.WeatherChangeEvent.Cause.NATURAL); // Paper
}
this.oThunderLevel = this.thunderLevel;
@@ -926,14 +926,14 @@ public class ServerLevel extends Level implements WorldGenLevel {
private void resetWeatherCycle() {
// CraftBukkit start
- this.serverLevelData.setRaining(false);
+ this.serverLevelData.setRaining(false, org.bukkit.event.weather.WeatherChangeEvent.Cause.SLEEP); // Paper - when passing the night
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
// Not that everyone ever manages to get the whole server to sleep at the same time....
if (!this.serverLevelData.isRaining()) {
this.serverLevelData.setRainTime(0);
}
// CraftBukkit end
- this.serverLevelData.setThundering(false);
+ this.serverLevelData.setThundering(false, org.bukkit.event.weather.ThunderChangeEvent.Cause.SLEEP); // Paper - when passing the night
// CraftBukkit start
// If we stop due to everyone sleeping we should reset the weather duration to some other random value.
// Not that everyone ever manages to get the whole server to sleep at the same time....
diff --git a/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java b/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java
index d88003a29d382d8952964257601f93c5fe95fa8b..30cd6dc004ef1d1518c9a10304ea2a20c0616831 100644
--- a/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java
+++ b/src/main/java/net/minecraft/world/level/storage/PrimaryLevelData.java
@@ -331,6 +331,11 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
@Override
public void setThundering(boolean thundering) {
+ // Paper start
+ this.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.UNKNOWN);
+ }
+ public void setThundering(boolean thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause cause) {
+ // Paper end
// CraftBukkit start
if (this.thundering == thundering) {
return;
@@ -338,7 +343,7 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
org.bukkit.World world = Bukkit.getWorld(this.getLevelName());
if (world != null) {
- ThunderChangeEvent thunder = new ThunderChangeEvent(world, thundering);
+ ThunderChangeEvent thunder = new ThunderChangeEvent(world, thundering, cause); // Paper
Bukkit.getServer().getPluginManager().callEvent(thunder);
if (thunder.isCancelled()) {
return;
@@ -365,6 +370,12 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
@Override
public void setRaining(boolean raining) {
+ // Paper start
+ this.setRaining(raining, org.bukkit.event.weather.WeatherChangeEvent.Cause.UNKNOWN);
+ }
+
+ public void setRaining(boolean raining, org.bukkit.event.weather.WeatherChangeEvent.Cause cause) {
+ // Paper end
// CraftBukkit start
if (this.raining == raining) {
return;
@@ -372,7 +383,7 @@ public class PrimaryLevelData implements ServerLevelData, WorldData {
org.bukkit.World world = Bukkit.getWorld(this.getLevelName());
if (world != null) {
- WeatherChangeEvent weather = new WeatherChangeEvent(world, raining);
+ WeatherChangeEvent weather = new WeatherChangeEvent(world, raining, cause); // Paper
Bukkit.getServer().getPluginManager().callEvent(weather);
if (weather.isCancelled()) {
return;
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 35b3e76cde3449b805435e6af8e8a296fee905d7..ddaf83de1392c631e7c7a8aa13a8a2e02d2ec04d 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -1170,7 +1170,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setStorm(boolean hasStorm) {
- world.levelData.setRaining(hasStorm);
+ world.serverLevelData.setRaining(hasStorm, org.bukkit.event.weather.WeatherChangeEvent.Cause.PLUGIN); // Paper
this.setWeatherDuration(0); // Reset weather duration (legacy behaviour)
this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands)
}
@@ -1192,7 +1192,7 @@ public class CraftWorld extends CraftRegionAccessor implements World {
@Override
public void setThundering(boolean thundering) {
- world.serverLevelData.setThundering(thundering);
+ world.serverLevelData.setThundering(thundering, org.bukkit.event.weather.ThunderChangeEvent.Cause.PLUGIN); // Paper
this.setThunderDuration(0); // Reset weather duration (legacy behaviour)
this.setClearWeatherDuration(0); // Reset clear weather duration (reset "/weather clear" commands)
}

View file

@ -0,0 +1,97 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: LemonCaramel <admin@caramel.moe>
Date: Sun, 23 May 2021 17:49:51 +0900
Subject: [PATCH] More Lidded Block API
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java
index 9d0c272b1d89a96b0b63603fa8e4649f11fb6c51..d5fdf4504a0ca76fb0483f4ae5861c93fb622b2d 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBarrel.java
@@ -58,4 +58,11 @@ public class CraftBarrel extends CraftLootable<BarrelBlockEntity> implements Bar
}
getTileEntity().openersCounter.opened = false;
}
+
+ // Paper start - More Lidded Block API
+ @Override
+ public boolean isOpen() {
+ return getTileEntity().openersCounter.opened;
+ }
+ // Paper end - More Lidded Block API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
index 9796e2d3cd9601416124ad5c36f962ed3f8682e8..03edde8c3b429d541b30d5ee9d15aa03bfb88d38 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftChest.java
@@ -75,4 +75,11 @@ public class CraftChest extends CraftLootable<ChestBlockEntity> implements Chest
}
getTileEntity().openersCounter.opened = false;
}
+
+ // Paper start - More Lidded Block API
+ @Override
+ public boolean isOpen() {
+ return getTileEntity().openersCounter.opened;
+ }
+ // Paper end - More Lidded Block API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
index 950066001b23e7b9aec48b2369163d6196979640..c48d7ec19603962855962c6ae6e1275c1552c906 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftEnderChest.java
@@ -9,4 +9,33 @@ public class CraftEnderChest extends CraftBlockEntityState<EnderChestBlockEntity
public CraftEnderChest(World world, EnderChestBlockEntity tileEntity) {
super(world, tileEntity);
}
+
+ // Paper start - More Lidded Block API
+ @Override
+ public void open() {
+ requirePlaced();
+ if (!getTileEntity().openersCounter.opened) {
+ net.minecraft.world.level.Level world = getTileEntity().getLevel();
+ world.blockEvent(getTileEntity().getBlockPos(), getTileEntity().getBlockState().getBlock(), 1, getTileEntity().openersCounter.getOpenerCount() + 1);
+ world.playSound(null, getPosition(), net.minecraft.sounds.SoundEvents.ENDER_CHEST_OPEN, net.minecraft.sounds.SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+ }
+ getTileEntity().openersCounter.opened = true;
+ }
+
+ @Override
+ public void close() {
+ requirePlaced();
+ if (getTileEntity().openersCounter.opened) {
+ net.minecraft.world.level.Level world = getTileEntity().getLevel();
+ world.blockEvent(getTileEntity().getBlockPos(), getTileEntity().getBlockState().getBlock(), 1, 0);
+ world.playSound(null, getPosition(), net.minecraft.sounds.SoundEvents.ENDER_CHEST_CLOSE, net.minecraft.sounds.SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+ }
+ getTileEntity().openersCounter.opened = false;
+ }
+
+ @Override
+ public boolean isOpen() {
+ return getTileEntity().openersCounter.opened;
+ }
+ // Paper end - More Lidded Block API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java
index 2d5205a9adfa66545f40a13bf0e37dc62ac0fdb9..72074b4c0feea8136e80589345538552ce28a2ea 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftShulkerBox.java
@@ -55,8 +55,15 @@ public class CraftShulkerBox extends CraftLootable<ShulkerBoxBlockEntity> implem
if (getTileEntity().opened && getWorldHandle() instanceof net.minecraft.world.level.Level) {
net.minecraft.world.level.Level world = getTileEntity().getLevel();
world.blockEvent(getPosition(), getTileEntity().getBlockState().getBlock(), 1, 0);
- world.playSound(null, getPosition(), SoundEvents.SHULKER_BOX_OPEN, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F);
+ world.playSound(null, getPosition(), SoundEvents.SHULKER_BOX_CLOSE, SoundSource.BLOCKS, 0.5F, world.random.nextFloat() * 0.1F + 0.9F); // Paper - More Lidded Block API (Wrong sound)
}
getTileEntity().opened = false;
}
+
+ // Paper start - More Lidded Block API
+ @Override
+ public boolean isOpen() {
+ return getTileEntity().opened;
+ }
+ // Paper end - More Lidded Block API
}

View file

@ -0,0 +1,37 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Yive <admin@yive.me>
Date: Wed, 26 May 2021 15:09:33 -0700
Subject: [PATCH] Limit item frame cursors on maps
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index 3bdbb31e050444d4052c6cac4b0af8454196ab8c..cc04fe5b0275ef5466fad2ca84f2273d274baadd 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -767,4 +767,9 @@ public class PaperWorldConfig {
private void allowUsingSignsInsideSpawnProtection() {
allowUsingSignsInsideSpawnProtection = getBoolean("allow-using-signs-inside-spawn-protection", allowUsingSignsInsideSpawnProtection);
}
+
+ public int mapItemFrameCursorLimit = 128;
+ private void mapItemFrameCursorLimit() {
+ mapItemFrameCursorLimit = getInt("map-item-frame-cursor-limit", mapItemFrameCursorLimit);
+ }
}
diff --git a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
index 77fde68dae2e64ef54b1cee7ab8b33f4609b3675..77209dfe179f97a5be89bdf812622773b90e6214 100644
--- a/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
+++ b/src/main/java/net/minecraft/world/level/saveddata/maps/MapItemSavedData.java
@@ -295,8 +295,12 @@ public class MapItemSavedData extends SavedData {
MapFrame worldmapframe1 = new MapFrame(blockposition, entityitemframe.getDirection().get2DDataValue() * 90, entityitemframe.getId());
+ // Paper start
+ if (this.decorations.size() < player.level.paperConfig.mapItemFrameCursorLimit) {
this.addDecoration(MapDecoration.Type.FRAME, player.level, "frame-" + entityitemframe.getId(), (double) blockposition.getX(), (double) blockposition.getZ(), (double) (entityitemframe.getDirection().get2DDataValue() * 90), (Component) null);
this.frameMarkers.put(worldmapframe1.getId(), worldmapframe1);
+ }
+ // Paper end
}
CompoundTag nbttagcompound = stack.getTag();

View file

@ -0,0 +1,384 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 15 May 2021 20:30:45 -0700
Subject: [PATCH] Add PlayerKickEvent causes
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
index d93e6d987e013bce37d511ac6c5b2481d86b9235..688d6a2ce9bc21ed24251b59ba0f09508f04e640 100644
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
@@ -2045,7 +2045,7 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
if (!whitelist.isWhiteListed(entityplayer.getGameProfile()) && !this.getPlayerList().isOp(entityplayer.getGameProfile())) { // Paper - Fix kicking ops when whitelist is reloaded (MC-171420)
- entityplayer.connection.disconnect(org.spigotmc.SpigotConfig.whitelistMessage); // Paper - use configurable message
+ entityplayer.connection.disconnect(org.spigotmc.SpigotConfig.whitelistMessage, org.bukkit.event.player.PlayerKickEvent.Cause.WHITELIST); // Paper - use configurable message
}
}
diff --git a/src/main/java/net/minecraft/server/commands/BanIpCommands.java b/src/main/java/net/minecraft/server/commands/BanIpCommands.java
index 144ca9280ce2fb19b4859e2c8299349ffd19f115..9f63d38853657cb01a4be0f1f7b613b2377a33ad 100644
--- a/src/main/java/net/minecraft/server/commands/BanIpCommands.java
+++ b/src/main/java/net/minecraft/server/commands/BanIpCommands.java
@@ -62,7 +62,7 @@ public class BanIpCommands {
}
for(ServerPlayer serverPlayer : list) {
- serverPlayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.ip_banned"));
+ serverPlayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.ip_banned"), org.bukkit.event.player.PlayerKickEvent.Cause.IP_BANNED); // Paper - kick event cause
}
return list.size();
diff --git a/src/main/java/net/minecraft/server/commands/BanPlayerCommands.java b/src/main/java/net/minecraft/server/commands/BanPlayerCommands.java
index c8361cd6c75df09481612eee729e23435229c6bf..b6eb53d5647600963c038cf2ef1301aba66f524d 100644
--- a/src/main/java/net/minecraft/server/commands/BanPlayerCommands.java
+++ b/src/main/java/net/minecraft/server/commands/BanPlayerCommands.java
@@ -43,7 +43,7 @@ public class BanPlayerCommands {
source.sendSuccess(new TranslatableComponent("commands.ban.success", ComponentUtils.getDisplayName(gameProfile), userBanListEntry.getReason()), true);
ServerPlayer serverPlayer = source.getServer().getPlayerList().getPlayer(gameProfile.getId());
if (serverPlayer != null) {
- serverPlayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.banned"));
+ serverPlayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.banned"), org.bukkit.event.player.PlayerKickEvent.Cause.BANNED); // Paper - kick event cause
}
}
}
diff --git a/src/main/java/net/minecraft/server/commands/KickCommand.java b/src/main/java/net/minecraft/server/commands/KickCommand.java
index 708ac03d5a849bf09c49547306e4a8c5a5ef8d91..5a8df368a4a25839cd4ac9be6972da2ee4875d85 100644
--- a/src/main/java/net/minecraft/server/commands/KickCommand.java
+++ b/src/main/java/net/minecraft/server/commands/KickCommand.java
@@ -23,7 +23,7 @@ public class KickCommand {
private static int kickPlayers(CommandSourceStack source, Collection<ServerPlayer> targets, Component reason) {
for(ServerPlayer serverPlayer : targets) {
- serverPlayer.connection.disconnect(reason);
+ serverPlayer.connection.disconnect(reason, org.bukkit.event.player.PlayerKickEvent.Cause.KICK_COMMAND); // Paper - kick event cause
source.sendSuccess(new TranslatableComponent("commands.kick.success", serverPlayer.getDisplayName(), reason), true);
}
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 311df240858d4416306a795d893bdf7da403e90b..85e24920e774e84f9fa63a4fb088c07caf2833da 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -319,7 +319,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (this.clientIsFloating && !this.player.isSleeping()) {
if (++this.aboveGroundTickCount > 80) {
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating too long!", this.player.getName().getString());
- this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage); // Paper - use configurable kick message
+ this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickPlayerMessage, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_PLAYER); // Paper - use configurable kick message & kick event cause
return;
}
} else {
@@ -338,7 +338,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (this.clientVehicleIsFloating && this.player.getRootVehicle().getControllingPassenger() == this.player) {
if (++this.aboveGroundVehicleTickCount > 80) {
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked for floating a vehicle too long!", this.player.getName().getString());
- this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickVehicleMessage); // Paper - use configurable kick message
+ this.disconnect(com.destroystokyo.paper.PaperConfig.flyingKickVehicleMessage, org.bukkit.event.player.PlayerKickEvent.Cause.FLYING_VEHICLE); // Paper - use configurable kick message & kick event cause
return;
}
} else {
@@ -360,7 +360,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (this.keepAlivePending) {
if (!this.processedDisconnect && elapsedTime >= KEEPALIVE_LIMIT) { // check keepalive limit, don't fire if already disconnected
ServerGamePacketListenerImpl.LOGGER.warn("{} was kicked due to keepalive timeout!", this.player.getScoreboardName()); // more info
- this.disconnect(new TranslatableComponent("disconnect.timeout", new Object[0]));
+ this.disconnect(new TranslatableComponent("disconnect.timeout", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
}
} else {
if (elapsedTime >= 15000L) { // 15 seconds
@@ -390,7 +390,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) (this.server.getPlayerIdleTimeout() * 1000 * 60)) {
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
- this.disconnect(new TranslatableComponent("multiplayer.disconnect.idling"));
+ this.disconnect(new TranslatableComponent("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}
}
@@ -415,14 +415,22 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
public void disconnect(String s) {
// Paper start
- this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s));
+ this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
+ }
+
+ public void disconnect(String s, PlayerKickEvent.Cause cause) {
+ this.disconnect(PaperAdventure.LEGACY_SECTION_UXRC.deserialize(s), cause);
}
public void disconnect(final Component reason) {
- this.disconnect(PaperAdventure.asAdventure(reason));
+ this.disconnect(PaperAdventure.asAdventure(reason), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN);
+ }
+
+ public void disconnect(final Component reason, PlayerKickEvent.Cause cause) {
+ this.disconnect(PaperAdventure.asAdventure(reason), cause);
}
- public void disconnect(net.kyori.adventure.text.Component reason) {
+ public void disconnect(net.kyori.adventure.text.Component reason, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
// Paper end
// CraftBukkit start - fire PlayerKickEvent
if (this.processedDisconnect) {
@@ -430,7 +438,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
net.kyori.adventure.text.Component leaveMessage = net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, this.player.getBukkitEntity().displayName()); // Paper - Adventure
- PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), reason, leaveMessage); // Paper - Adventure
+ PlayerKickEvent event = new PlayerKickEvent(this.player.getBukkitEntity(), reason, leaveMessage, cause); // Paper - Adventure & kick event reason
if (this.cserver.getServer().isRunning()) {
this.cserver.getPluginManager().callEvent(event);
@@ -502,7 +510,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
public void handleMoveVehicle(ServerboundMoveVehiclePacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(), packet.getY(), packet.getZ(), packet.getYRot(), packet.getXRot())) {
- this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_vehicle_movement"));
+ this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_vehicle_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_VEHICLE_MOVEMENT); // Paper - kick event cause
} else {
Entity entity = this.player.getRootVehicle();
@@ -743,13 +751,13 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// PlayerConnectionUtils.ensureMainThread(packetplayintabcomplete, this, this.player.getWorldServer()); // Paper - run this async
// CraftBukkit start
if (this.chatSpamTickCount.addAndGet(com.destroystokyo.paper.PaperConfig.tabSpamIncrement) > com.destroystokyo.paper.PaperConfig.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
- server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
+ server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
return;
}
// Paper start
String str = packet.getCommand(); int index = -1;
if (str.length() > 64 && ((index = str.indexOf(' ')) == -1 || index >= 64)) {
- server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
+ server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
return;
}
// Paper end
@@ -901,7 +909,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// Paper start - validate pick item position
if (!(packet.getSlot() >= 0 && packet.getSlot() < this.player.getInventory().items.size())) {
ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
- this.disconnect("Invalid hotbar selection (Hacking?)");
+ this.disconnect("Invalid hotbar selection (Hacking?)", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
return;
}
this.player.getInventory().pickSlot(packet.getSlot()); // Paper - Diff above if changed
@@ -1060,7 +1068,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
int byteLength = testString.getBytes(java.nio.charset.StandardCharsets.UTF_8).length;
if (byteLength > 256 * 4) {
ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send a book with with a page too large!");
- server.scheduleOnMain(() -> this.disconnect("Book too large!"));
+ server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause
return;
}
byteTotal += byteLength;
@@ -1083,14 +1091,14 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
if (byteTotal > byteAllowed) {
ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " tried to send too large of a book. Book Size: " + byteTotal + " - Allowed: "+ byteAllowed + " - Pages: " + pageList.size());
- server.scheduleOnMain(() -> this.disconnect("Book too large!"));
+ server.scheduleOnMain(() -> this.disconnect("Book too large!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause
return;
}
}
// Paper end
// CraftBukkit start
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
- this.disconnect("Book edited too quickly!");
+ this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
return;
}
this.lastBookTick = MinecraftServer.currentTick;
@@ -1214,7 +1222,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
public void handleMovePlayer(ServerboundMovePlayerPacket packet) {
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
if (ServerGamePacketListenerImpl.containsInvalidValues(packet.getX(0.0D), packet.getY(0.0D), packet.getZ(0.0D), packet.getYRot(0.0F), packet.getXRot(0.0F))) {
- this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_player_movement"));
+ this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_player_movement"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PLAYER_MOVEMENT); // Paper - kick event cause
} else {
ServerLevel worldserver = this.player.getLevel();
@@ -1637,7 +1645,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.dropCount++;
if (this.dropCount >= 20) {
ServerGamePacketListenerImpl.LOGGER.warn(this.player.getScoreboardName() + " dropped their items too quickly!");
- this.disconnect("You dropped your items too quickly (Hacking?)");
+ this.disconnect("You dropped your items too quickly (Hacking?)", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
return;
}
}
@@ -1844,7 +1852,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.getLevel());
if (packet.getAction() == ServerboundResourcePackPacket.Action.DECLINED && this.server.isResourcePackRequired()) {
ServerGamePacketListenerImpl.LOGGER.info("Disconnecting {} due to resource pack rejection", this.player.getName());
- this.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"));
+ this.disconnect(new TranslatableComponent("multiplayer.requiredTexturePrompt.disconnect"), org.bukkit.event.player.PlayerKickEvent.Cause.RESOURCE_PACK_REJECTION); // Paper - add cause
}
// Paper start
PlayerResourcePackStatusEvent.Status packStatus = PlayerResourcePackStatusEvent.Status.values()[packet.action.ordinal()];
@@ -1949,7 +1957,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.player.resetLastActionTime();
} else {
ServerGamePacketListenerImpl.LOGGER.warn("{} tried to set an invalid carried item", this.player.getName().getString());
- this.disconnect("Invalid hotbar selection (Hacking?)"); // CraftBukkit
+ this.disconnect("Invalid hotbar selection (Hacking?)", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // CraftBukkit // Paper - kick event cause
}
}
@@ -1965,7 +1973,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
for (int i = 0; i < s.length(); ++i) {
if (!SharedConstants.isAllowedChatCharacter(s.charAt(i))) {
- this.disconnect(new TranslatableComponent("multiplayer.disconnect.illegal_characters"));
+ this.disconnect(new TranslatableComponent("multiplayer.disconnect.illegal_characters"), org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_CHARACTERS); // Paper - add cause
return;
}
}
@@ -2038,7 +2046,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
Waitable waitable = new Waitable() {
@Override
protected Object evaluate() {
- ServerGamePacketListenerImpl.this.disconnect(new TranslatableComponent("disconnect.spam"));
+ ServerGamePacketListenerImpl.this.disconnect(new TranslatableComponent("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause
return null;
}
};
@@ -2053,7 +2061,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
throw new RuntimeException(e);
}
} else {
- this.disconnect(new TranslatableComponent("disconnect.spam"));
+ this.disconnect(new TranslatableComponent("disconnect.spam"), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM); // Paper - kick event cause
}
// CraftBukkit end
}
@@ -2326,7 +2334,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// Spigot Start
if ( entity == this.player && !this.player.isSpectator() )
{
- this.disconnect( "Cannot interact with self!" );
+ this.disconnect( "Cannot interact with self!", org.bukkit.event.player.PlayerKickEvent.Cause.SELF_INTERACTION ); // Paper - add cause
return;
}
// Spigot End
@@ -2421,7 +2429,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
// CraftBukkit end
} else {
- ServerGamePacketListenerImpl.this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_entity_attacked"));
+ ServerGamePacketListenerImpl.this.disconnect(new TranslatableComponent("multiplayer.disconnect.invalid_entity_attacked"), org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_ENTITY_ATTACKED); // Paper - add cause
ServerGamePacketListenerImpl.LOGGER.warn("Player {} tried to attack an invalid entity", ServerGamePacketListenerImpl.this.player.getName().getString());
}
}
@@ -2821,7 +2829,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// Paper start
if (!org.bukkit.Bukkit.isPrimaryThread()) {
if (recipeSpamPackets.addAndGet(com.destroystokyo.paper.PaperConfig.autoRecipeIncrement) > com.destroystokyo.paper.PaperConfig.autoRecipeLimit) {
- server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]))); // Paper
+ server.scheduleOnMain(() -> this.disconnect(new TranslatableComponent("disconnect.spam", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.SPAM)); // Paper - kick event cause
return;
}
}
@@ -3006,7 +3014,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
} else if (!this.isSingleplayerOwner()) {
// Paper start - This needs to be handled on the main thread for plugins
server.submit(() -> {
- this.disconnect(new TranslatableComponent("disconnect.timeout"));
+ this.disconnect(new TranslatableComponent("disconnect.timeout"), org.bukkit.event.player.PlayerKickEvent.Cause.TIMEOUT); // Paper - kick event cause
});
// Paper end
}
@@ -3052,7 +3060,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t register custom payload", ex);
- this.disconnect("Invalid payload REGISTER!");
+ this.disconnect("Invalid payload REGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
}
} else if (packet.identifier.equals(CUSTOM_UNREGISTER)) {
try {
@@ -3062,7 +3070,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t unregister custom payload", ex);
- this.disconnect("Invalid payload UNREGISTER!");
+ this.disconnect("Invalid payload UNREGISTER!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
}
} else {
try {
@@ -3080,7 +3088,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
this.cserver.getMessenger().dispatchIncomingMessage(this.player.getBukkitEntity(), packet.identifier.toString(), data);
} catch (Exception ex) {
ServerGamePacketListenerImpl.LOGGER.error("Couldn\'t dispatch custom payload", ex);
- this.disconnect("Invalid custom payload!");
+ this.disconnect("Invalid custom payload!", org.bukkit.event.player.PlayerKickEvent.Cause.INVALID_PAYLOAD); // Paper - kick event cause
}
}
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index bc2f8dd01039d855a174358825d2fdc8d0f0f526..de8a14e86b337954fd0f730c1096758e1db409aa 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -713,7 +713,7 @@ public abstract class PlayerList {
while (iterator.hasNext()) {
entityplayer = (ServerPlayer) iterator.next();
this.save(entityplayer); // CraftBukkit - Force the player's inventory to be saved
- entityplayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]));
+ entityplayer.connection.disconnect(new TranslatableComponent("multiplayer.disconnect.duplicate_login", new Object[0]), org.bukkit.event.player.PlayerKickEvent.Cause.DUPLICATE_LOGIN); // Paper - kick event cause
}
// Instead of kicking then returning, we need to store the kick reason
@@ -1332,8 +1332,8 @@ public abstract class PlayerList {
// Paper end
// CraftBukkit start - disconnect safely
for (ServerPlayer player : this.players) {
- if (isRestarting) player.connection.disconnect(org.spigotmc.SpigotConfig.restartMessage); else // Paper
- player.connection.disconnect(this.server.server.shutdownMessage()); // CraftBukkit - add custom shutdown message // Paper - Adventure
+ if (isRestarting) player.connection.disconnect(org.spigotmc.SpigotConfig.restartMessage, org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); else // Paper - kick event cause (cause is never used here)
+ player.connection.disconnect(this.server.server.shutdownMessage(), org.bukkit.event.player.PlayerKickEvent.Cause.UNKNOWN); // CraftBukkit - add custom shutdown message // Paper - Adventure & KickEventCause (cause is never used here)
}
// CraftBukkit end
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 4c1430a6499dd44bb07c9d13de511d365a93db58..b5df4beaefe68b13e402b6f71d67ca5ddd47c6f4 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -502,16 +502,21 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
org.spigotmc.AsyncCatcher.catchOp("player kick"); // Spigot
if (this.getHandle().connection == null) return;
- this.getHandle().connection.disconnect(message == null ? "" : message);
+ this.getHandle().connection.disconnect(message == null ? "" : message, org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN); // Paper - kick event cause
}
// Paper start
@Override
public void kick(final net.kyori.adventure.text.Component message) {
+ kick(message, org.bukkit.event.player.PlayerKickEvent.Cause.PLUGIN);
+ }
+
+ @Override
+ public void kick(net.kyori.adventure.text.Component message, org.bukkit.event.player.PlayerKickEvent.Cause cause) {
org.spigotmc.AsyncCatcher.catchOp("player kick");
final ServerGamePacketListenerImpl connection = this.getHandle().connection;
if (connection != null) {
- connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message);
+ connection.disconnect(message == null ? net.kyori.adventure.text.Component.empty() : message, cause);
}
}
diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java
index 92d97a5810a379b427a99b4c63fb9844d823a84f..160115bf8a153ff981ba308599d22c4c08026fb6 100644
--- a/src/main/java/org/spigotmc/RestartCommand.java
+++ b/src/main/java/org/spigotmc/RestartCommand.java
@@ -74,7 +74,7 @@ public class RestartCommand extends Command
// Kick all players
for ( ServerPlayer p : com.google.common.collect.ImmutableList.copyOf( MinecraftServer.getServer().getPlayerList().players ) )
{
- p.connection.disconnect(SpigotConfig.restartMessage);
+ p.connection.disconnect(SpigotConfig.restartMessage, org.bukkit.event.player.PlayerKickEvent.Cause.RESTART_COMMAND); // Paper - kick event reason (cause is never used))
}
// Give the socket a chance to send the packets
try