some patches
This commit is contained in:
@@ -1,165 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 6 Nov 2017 21:08:22 -0500
|
||||
Subject: [PATCH] API to get a BlockState without a snapshot
|
||||
|
||||
This allows you to get a BlockState without creating a snapshot, operating
|
||||
on the real tile entity.
|
||||
|
||||
This is useful for where performance is needed
|
||||
|
||||
also Avoid NPE during CraftBlockEntityState load if could not get TE
|
||||
|
||||
If Tile Entity was null, correct Sign to return empty lines instead of null
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/BlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockEntity {
|
||||
this.type = type;
|
||||
this.worldPosition = pos.immutable();
|
||||
this.blockState = state;
|
||||
+ this.persistentDataContainer = new CraftPersistentDataContainer(DATA_TYPE_REGISTRY); // Paper - always init
|
||||
}
|
||||
|
||||
public static BlockPos getPosFromTag(CompoundTag nbt) {
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockEntity {
|
||||
|
||||
// CraftBukkit start - read container
|
||||
public void load(CompoundTag nbt) {
|
||||
- this.persistentDataContainer = new CraftPersistentDataContainer(BlockEntity.DATA_TYPE_REGISTRY);
|
||||
+ this.persistentDataContainer.clear(); // Paper - clear instead of init
|
||||
|
||||
net.minecraft.nbt.Tag persistentDataTag = nbt.get("PublicBukkitValues");
|
||||
if (persistentDataTag instanceof CompoundTag) {
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockEntity {
|
||||
|
||||
// CraftBukkit start - add method
|
||||
public InventoryHolder getOwner() {
|
||||
+ // Paper start
|
||||
+ return getOwner(true);
|
||||
+ }
|
||||
+ public InventoryHolder getOwner(boolean useSnapshot) {
|
||||
+ // Paper end
|
||||
if (this.level == null) return null;
|
||||
- org.bukkit.block.BlockState state = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ()).getState();
|
||||
+ org.bukkit.block.Block block = this.level.getWorld().getBlockAt(this.worldPosition.getX(), this.worldPosition.getY(), this.worldPosition.getZ());
|
||||
+ if (block.getType() == org.bukkit.Material.AIR) return null;
|
||||
+ org.bukkit.block.BlockState state = block.getState(useSnapshot); // Paper
|
||||
if (state instanceof InventoryHolder) return (InventoryHolder) state;
|
||||
return null;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlock implements Block {
|
||||
return CraftBlockStates.getBlockState(this);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public BlockState getState(boolean useSnapshot) {
|
||||
+ return CraftBlockStates.getBlockState(this, useSnapshot);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
return this.getWorld().getBiome(this.getX(), this.getY(), this.getZ());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockEntityState.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
|
||||
|
||||
private final T tileEntity;
|
||||
private final T snapshot;
|
||||
+ public boolean snapshotDisabled; // Paper
|
||||
+ public static boolean DISABLE_SNAPSHOT = false; // Paper
|
||||
|
||||
public CraftBlockEntityState(World world, T tileEntity) {
|
||||
super(world, tileEntity.getBlockPos(), tileEntity.getBlockState());
|
||||
|
||||
this.tileEntity = tileEntity;
|
||||
|
||||
+ // Paper start
|
||||
+ this.snapshotDisabled = DISABLE_SNAPSHOT;
|
||||
+ if (DISABLE_SNAPSHOT) {
|
||||
+ this.snapshot = this.tileEntity;
|
||||
+ } else {
|
||||
+ this.snapshot = this.createSnapshot(tileEntity);
|
||||
+ }
|
||||
// copy tile entity data:
|
||||
- this.snapshot = this.createSnapshot(tileEntity);
|
||||
- this.load(this.snapshot);
|
||||
+ if (this.snapshot != null) {
|
||||
+ this.load(this.snapshot);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
protected CraftBlockEntityState(CraftBlockEntityState<T> state) {
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockEntityState<T extends BlockEntity> extends CraftBlockStat
|
||||
public CraftBlockEntityState<T> copy() {
|
||||
return new CraftBlockEntityState<>(this);
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isSnapshot() {
|
||||
+ return !this.snapshotDisabled;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlockStates.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftBlockStates {
|
||||
}
|
||||
|
||||
public static BlockState getBlockState(Block block) {
|
||||
+ // Paper start
|
||||
+ return CraftBlockStates.getBlockState(block, true);
|
||||
+ }
|
||||
+ public static BlockState getBlockState(Block block, boolean useSnapshot) {
|
||||
+ // Paper end
|
||||
Preconditions.checkNotNull(block, "block is null");
|
||||
CraftBlock craftBlock = (CraftBlock) block;
|
||||
CraftWorld world = (CraftWorld) block.getWorld();
|
||||
BlockPos blockPosition = craftBlock.getPosition();
|
||||
net.minecraft.world.level.block.state.BlockState blockData = craftBlock.getNMS();
|
||||
BlockEntity tileEntity = craftBlock.getHandle().getBlockEntity(blockPosition);
|
||||
+ // Paper start - block state snapshots
|
||||
+ boolean prev = CraftBlockEntityState.DISABLE_SNAPSHOT;
|
||||
+ CraftBlockEntityState.DISABLE_SNAPSHOT = !useSnapshot;
|
||||
+ try {
|
||||
+ // Paper end
|
||||
CraftBlockState blockState = CraftBlockStates.getBlockState(world, blockPosition, blockData, tileEntity);
|
||||
blockState.setWorldHandle(craftBlock.getHandle()); // Inject the block's generator access
|
||||
return blockState;
|
||||
+ // Paper start
|
||||
+ } finally {
|
||||
+ CraftBlockEntityState.DISABLE_SNAPSHOT = prev;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public static BlockState getBlockState(Material material, @Nullable CompoundTag blockEntityTag) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/persistence/CraftPersistentDataContainer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPersistentDataContainer implements PersistentDataContainer {
|
||||
public String serialize() {
|
||||
return CraftNBTTagConfigSerializer.serialize(this.toTagCompound());
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ public void clear() {
|
||||
+ this.customDataTags.clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 20 Dec 2017 17:36:49 -0500
|
||||
Subject: [PATCH] Ability to apply mending to XP API
|
||||
|
||||
This allows plugins that give players the ability to apply the experience
|
||||
points to the Item Mending formula, which will repair an item instead
|
||||
of giving the player experience points.
|
||||
|
||||
Both an API To standalone mend, and apply mending logic to .giveExp has been added.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.ExperienceOrb durabilityToXp(I)I
|
||||
public net.minecraft.world.entity.ExperienceOrb xpToDurability(I)I
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public void giveExp(int exp) {
|
||||
+ // Paper start
|
||||
+ public int applyMending(int amount) {
|
||||
+ ServerPlayer handle = this.getHandle();
|
||||
+ // Logic copied from EntityExperienceOrb and remapped to unobfuscated methods/properties
|
||||
+ final var stackEntry = net.minecraft.world.item.enchantment.EnchantmentHelper
|
||||
+ .getRandomItemWith(net.minecraft.world.item.enchantment.Enchantments.MENDING, handle);
|
||||
+ final net.minecraft.world.item.ItemStack itemstack = stackEntry != null ? stackEntry.getValue() : net.minecraft.world.item.ItemStack.EMPTY;
|
||||
+ if (!itemstack.isEmpty() && itemstack.getItem().canBeDepleted()) {
|
||||
+ net.minecraft.world.entity.ExperienceOrb orb = net.minecraft.world.entity.EntityType.EXPERIENCE_ORB.create(handle.level());
|
||||
+ orb.value = amount;
|
||||
+ orb.spawnReason = org.bukkit.entity.ExperienceOrb.SpawnReason.CUSTOM;
|
||||
+ orb.setPosRaw(handle.getX(), handle.getY(), handle.getZ());
|
||||
+
|
||||
+ int i = Math.min(orb.xpToDurability(amount), itemstack.getDamageValue());
|
||||
+ org.bukkit.event.player.PlayerItemMendEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemMendEvent(handle, orb, itemstack, stackEntry.getKey(), i);
|
||||
+ i = event.getRepairAmount();
|
||||
+ orb.discard();
|
||||
+ if (!event.isCancelled()) {
|
||||
+ amount -= orb.durabilityToXp(i);
|
||||
+ itemstack.setDamageValue(itemstack.getDamageValue() - i);
|
||||
+ }
|
||||
+ }
|
||||
+ return amount;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void giveExp(int exp, boolean applyMending) {
|
||||
+ if (applyMending) {
|
||||
+ exp = this.applyMending(exp);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.getHandle().giveExperiencePoints(exp);
|
||||
}
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 18 Mar 2018 11:45:57 -0400
|
||||
Subject: [PATCH] Ability to change PlayerProfile in AsyncPreLoginEvent
|
||||
|
||||
This will allow you to change the players name or skin on login.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
java.util.UUID uniqueId = gameprofile.getId();
|
||||
final org.bukkit.craftbukkit.CraftServer server = ServerLoginPacketListenerImpl.this.server.server;
|
||||
|
||||
- AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile profile = org.bukkit.Bukkit.createProfile(uniqueId, playerName);
|
||||
+ AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile);
|
||||
server.getPluginManager().callEvent(asyncEvent);
|
||||
+ profile = asyncEvent.getPlayerProfile();
|
||||
+ profile.complete();
|
||||
+ gameprofile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile);
|
||||
+ playerName = gameprofile.getName();
|
||||
+ uniqueId = gameprofile.getId();
|
||||
+ // Paper end
|
||||
|
||||
if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) {
|
||||
final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId);
|
||||
@@ -1,55 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 15 Aug 2018 01:16:34 -0400
|
||||
Subject: [PATCH] Ability to get Tile Entities from a chunk without snapshots
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
|
||||
@Override
|
||||
public BlockState[] getTileEntities() {
|
||||
+ // Paper start
|
||||
+ return getTileEntities(true);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public BlockState[] getTileEntities(boolean useSnapshot) {
|
||||
+ // Paper end
|
||||
if (!this.isLoaded()) {
|
||||
this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftChunk implements Chunk {
|
||||
BlockState[] entities = new BlockState[chunk.blockEntities.size()];
|
||||
|
||||
for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
- entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState();
|
||||
+ // Paper start
|
||||
+ entities[index++] = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ()).getState(useSnapshot);
|
||||
+ }
|
||||
+
|
||||
+ return entities;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Collection<BlockState> getTileEntities(Predicate<? super Block> blockPredicate, boolean useSnapshot) {
|
||||
+ Preconditions.checkNotNull(blockPredicate, "blockPredicate");
|
||||
+ if (!this.isLoaded()) {
|
||||
+ this.getWorld().getChunkAt(this.x, this.z); // Transient load for this tick
|
||||
+ }
|
||||
+ ChunkAccess chunk = this.getHandle(ChunkStatus.FULL);
|
||||
+
|
||||
+ java.util.List<BlockState> entities = new java.util.ArrayList<>();
|
||||
+
|
||||
+ for (BlockPos position : chunk.blockEntities.keySet()) {
|
||||
+ Block block = this.worldServer.getWorld().getBlockAt(position.getX(), position.getY(), position.getZ());
|
||||
+ if (blockPredicate.test(block)) {
|
||||
+ entities.add(block.getState(useSnapshot));
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return entities;
|
||||
@@ -1,287 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Sat, 27 Jan 2018 17:04:14 -0500
|
||||
Subject: [PATCH] Add ArmorStand Item Meta
|
||||
|
||||
This is adds basic item meta for armor stands. It does not add all
|
||||
possible metadata however.
|
||||
|
||||
There are armor, hand, and equipment types, as well as position data
|
||||
that can also be added here. This initial addition should serve a
|
||||
starting point for future additions in this area.
|
||||
|
||||
Fixes GH-559
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaArmorStand.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.Material;
|
||||
import org.bukkit.configuration.serialization.DelegateDeserialization;
|
||||
|
||||
@DelegateDeserialization(CraftMetaItem.SerializableMeta.class)
|
||||
-public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
+public class CraftMetaArmorStand extends CraftMetaItem implements com.destroystokyo.paper.inventory.meta.ArmorStandMeta { // Paper
|
||||
|
||||
static final ItemMetaKey ENTITY_TAG = new ItemMetaKey("EntityTag", "entity-tag");
|
||||
+ // Paper start
|
||||
+ static final ItemMetaKey INVISIBLE = new ItemMetaKey("Invisible", "invisible");
|
||||
+ static final ItemMetaKey NO_BASE_PLATE = new ItemMetaKey("NoBasePlate", "no-base-plate");
|
||||
+ static final ItemMetaKey SHOW_ARMS = new ItemMetaKey("ShowArms", "show-arms");
|
||||
+ static final ItemMetaKey SMALL = new ItemMetaKey("Small", "small");
|
||||
+ static final ItemMetaKey MARKER = new ItemMetaKey("Marker", "marker");
|
||||
+
|
||||
+ private Boolean invisible = null;
|
||||
+ private Boolean noBasePlate = null;
|
||||
+ private Boolean showArms = null;
|
||||
+ private Boolean small = null;
|
||||
+ private Boolean marker = null;
|
||||
+ // Paper end
|
||||
CompoundTag entityTag;
|
||||
|
||||
CraftMetaArmorStand(CraftMetaItem meta) {
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
}
|
||||
|
||||
CraftMetaArmorStand armorStand = (CraftMetaArmorStand) meta;
|
||||
+ // Paper start
|
||||
+ this.invisible = armorStand.invisible;
|
||||
+ this.noBasePlate = armorStand.noBasePlate;
|
||||
+ this.showArms = armorStand.showArms;
|
||||
+ this.small = armorStand.small;
|
||||
+ this.marker = armorStand.marker;
|
||||
+ // Paper end
|
||||
this.entityTag = armorStand.entityTag;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
|
||||
if (tag.contains(CraftMetaArmorStand.ENTITY_TAG.NBT)) {
|
||||
this.entityTag = tag.getCompound(CraftMetaArmorStand.ENTITY_TAG.NBT).copy();
|
||||
+ // Paper start
|
||||
+ if (entityTag.contains(INVISIBLE.NBT)) {
|
||||
+ invisible = entityTag.getBoolean(INVISIBLE.NBT);
|
||||
+ }
|
||||
+
|
||||
+ if (entityTag.contains(NO_BASE_PLATE.NBT)) {
|
||||
+ noBasePlate = entityTag.getBoolean(NO_BASE_PLATE.NBT);
|
||||
+ }
|
||||
+
|
||||
+ if (entityTag.contains(SHOW_ARMS.NBT)) {
|
||||
+ showArms = entityTag.getBoolean(SHOW_ARMS.NBT);
|
||||
+ }
|
||||
+
|
||||
+ if (entityTag.contains(SMALL.NBT)) {
|
||||
+ small = entityTag.getBoolean(SMALL.NBT);
|
||||
+ }
|
||||
+
|
||||
+ if (entityTag.contains(MARKER.NBT)) {
|
||||
+ marker = entityTag.getBoolean(MARKER.NBT);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
CraftMetaArmorStand(Map<String, Object> map) {
|
||||
super(map);
|
||||
+ // Paper start
|
||||
+ this.invisible = SerializableMeta.getBoolean(map, INVISIBLE.BUKKIT);
|
||||
+ this.noBasePlate = SerializableMeta.getBoolean(map, NO_BASE_PLATE.BUKKIT);
|
||||
+ this.showArms = SerializableMeta.getBoolean(map, SHOW_ARMS.BUKKIT);
|
||||
+ this.small = SerializableMeta.getBoolean(map, SMALL.BUKKIT);
|
||||
+ this.marker = SerializableMeta.getBoolean(map, MARKER.BUKKIT);
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
void applyToItem(CompoundTag tag) {
|
||||
super.applyToItem(tag);
|
||||
|
||||
+ // Paper start
|
||||
+ if (!isArmorStandEmpty() && this.entityTag == null) {
|
||||
+ this.entityTag = new CompoundTag();
|
||||
+ }
|
||||
+
|
||||
+ if (this.invisible != null) {
|
||||
+ this.entityTag.putBoolean(INVISIBLE.NBT, this.invisible);
|
||||
+ }
|
||||
+
|
||||
+ if (this.noBasePlate != null) {
|
||||
+ this.entityTag.putBoolean(NO_BASE_PLATE.NBT, this.noBasePlate);
|
||||
+ }
|
||||
+
|
||||
+ if (this.showArms != null) {
|
||||
+ this.entityTag.putBoolean(SHOW_ARMS.NBT, this.showArms);
|
||||
+ }
|
||||
+
|
||||
+ if (this.small != null) {
|
||||
+ this.entityTag.putBoolean(SMALL.NBT, this.small);
|
||||
+ }
|
||||
+
|
||||
+ if (this.marker != null) {
|
||||
+ this.entityTag.putBoolean(MARKER.NBT, this.marker);
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (this.entityTag != null) {
|
||||
tag.put(CraftMetaArmorStand.ENTITY_TAG.NBT, this.entityTag);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
}
|
||||
|
||||
boolean isArmorStandEmpty() {
|
||||
- return !(this.entityTag != null);
|
||||
+ return !(this.invisible != null || this.noBasePlate != null || this.showArms != null || this.small != null || this.marker != null || this.entityTag != null); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
if (meta instanceof CraftMetaArmorStand) {
|
||||
CraftMetaArmorStand that = (CraftMetaArmorStand) meta;
|
||||
|
||||
- return this.entityTag != null ? that.entityTag != null && this.entityTag.equals(that.entityTag) : this.entityTag == null;
|
||||
+ // Paper start
|
||||
+ return this.invisible == that.invisible &&
|
||||
+ this.noBasePlate == that.noBasePlate &&
|
||||
+ this.showArms == that.showArms &&
|
||||
+ this.small == that.small &&
|
||||
+ this.marker == that.marker;
|
||||
+ // Paper end
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
final int original;
|
||||
int hash = original = super.applyHash();
|
||||
|
||||
- if (this.entityTag != null) {
|
||||
- hash = 73 * hash + this.entityTag.hashCode();
|
||||
- }
|
||||
+ // Paper start
|
||||
+ hash += this.entityTag != null ? 73 * hash + this.entityTag.hashCode() : 0;
|
||||
+ hash += this.isInvisible() ? 61 * hash + 1231 : 0;
|
||||
+ hash += this.hasNoBasePlate() ? 61 * hash + 1231 : 0;
|
||||
+ hash += this.shouldShowArms() ? 61 * hash + 1231 : 0;
|
||||
+ hash += this.isSmall() ? 61 * hash + 1231 : 0;
|
||||
+ hash += this.isMarker() ? 61 * hash + 1231 : 0;
|
||||
+ // Paper end
|
||||
|
||||
return original != hash ? CraftMetaArmorStand.class.hashCode() ^ hash : hash;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
Builder<String, Object> serialize(Builder<String, Object> builder) {
|
||||
super.serialize(builder);
|
||||
|
||||
+ // Paper start
|
||||
+ if (invisible != null) {
|
||||
+ builder.put(INVISIBLE.BUKKIT, invisible);
|
||||
+ }
|
||||
+
|
||||
+ if (noBasePlate != null) {
|
||||
+ builder.put(NO_BASE_PLATE.BUKKIT, noBasePlate);
|
||||
+ }
|
||||
+
|
||||
+ if (showArms != null) {
|
||||
+ builder.put(SHOW_ARMS.BUKKIT, showArms);
|
||||
+ }
|
||||
+
|
||||
+ if (small != null) {
|
||||
+ builder.put(SMALL.BUKKIT, small);
|
||||
+ }
|
||||
+
|
||||
+ if (marker != null) {
|
||||
+ builder.put(MARKER.BUKKIT, marker);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftMetaArmorStand extends CraftMetaItem {
|
||||
|
||||
return clone;
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean isInvisible() {
|
||||
+ return invisible != null && invisible;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasNoBasePlate() {
|
||||
+ return noBasePlate != null && noBasePlate;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean shouldShowArms() {
|
||||
+ return showArms != null && showArms;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSmall() {
|
||||
+ return small != null && small;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isMarker() {
|
||||
+ return marker != null && marker;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setInvisible(boolean invisible) {
|
||||
+ this.invisible = invisible;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setNoBasePlate(boolean noBasePlate) {
|
||||
+ this.noBasePlate = noBasePlate;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShowArms(boolean showArms) {
|
||||
+ this.showArms = showArms;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setSmall(boolean small) {
|
||||
+ this.small = small;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setMarker(boolean marker) {
|
||||
+ this.marker = marker;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
|
||||
@@ -0,0 +0,0 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
|
||||
CraftMetaCrossbow.CHARGED.NBT,
|
||||
CraftMetaCrossbow.CHARGED_PROJECTILES.NBT,
|
||||
CraftMetaSuspiciousStew.EFFECTS.NBT,
|
||||
+ // Paper start
|
||||
+ CraftMetaArmorStand.ENTITY_TAG.NBT,
|
||||
+ CraftMetaArmorStand.INVISIBLE.NBT,
|
||||
+ CraftMetaArmorStand.NO_BASE_PLATE.NBT,
|
||||
+ CraftMetaArmorStand.SHOW_ARMS.NBT,
|
||||
+ CraftMetaArmorStand.SMALL.NBT,
|
||||
+ CraftMetaArmorStand.MARKER.NBT,
|
||||
+ // Paper end
|
||||
CraftMetaCompass.LODESTONE_DIMENSION.NBT,
|
||||
CraftMetaCompass.LODESTONE_POS.NBT,
|
||||
CraftMetaCompass.LODESTONE_TRACKED.NBT,
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -0,0 +0,0 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
final CraftMetaArmorStand meta = (CraftMetaArmorStand) cleanStack.getItemMeta();
|
||||
meta.entityTag = new CompoundTag();
|
||||
meta.entityTag.putBoolean("Small", true);
|
||||
+ meta.setInvisible(true); // Paper
|
||||
cleanStack.setItemMeta(meta);
|
||||
return cleanStack;
|
||||
}
|
||||
@@ -1,129 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 21 Jul 2018 08:25:40 -0400
|
||||
Subject: [PATCH] Add Debug Entities option to debug dupe uuid issues
|
||||
|
||||
Add -Ddebug.entities=true to your JVM flags to gain more information
|
||||
|
||||
1.17: Needs to be reworked for new entity storage system
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
} else {
|
||||
ChunkMap.TrackedEntity playerchunkmap_entitytracker = new ChunkMap.TrackedEntity(entity, i, j, entitytypes.trackDeltas());
|
||||
|
||||
+ entity.tracker = playerchunkmap_entitytracker; // Paper - Fast access to tracker
|
||||
this.entityMap.put(entity.getId(), playerchunkmap_entitytracker);
|
||||
playerchunkmap_entitytracker.updatePlayers(this.level.players());
|
||||
if (entity instanceof ServerPlayer) {
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
if (playerchunkmap_entitytracker1 != null) {
|
||||
playerchunkmap_entitytracker1.broadcastRemoved();
|
||||
}
|
||||
-
|
||||
+ entity.tracker = null; // Paper - We're no longer tracked
|
||||
}
|
||||
|
||||
protected void tick() {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
public final LevelStorageSource.LevelStorageAccess convertable;
|
||||
public final UUID uuid;
|
||||
public boolean hasPhysicsEvent = true; // Paper
|
||||
+ public static Throwable getAddToWorldStackTrace(Entity entity) {
|
||||
+ return new Throwable(entity + " Added to world at " + new java.util.Date());
|
||||
+ }
|
||||
|
||||
@Override public LevelChunk getChunkIfLoaded(int x, int z) { // Paper - this was added in world too but keeping here for NMS ABI
|
||||
return this.chunkSource.getChunk(x, z, false);
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// CraftBukkit start
|
||||
private boolean addEntity(Entity entity, CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("entity add"); // Spigot
|
||||
+ // Paper start
|
||||
+ if (entity.valid) {
|
||||
+ MinecraftServer.LOGGER.error("Attempted Double World add on " + entity, new Throwable());
|
||||
+
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ Throwable thr = entity.addedToWorldStack;
|
||||
+ if (thr == null) {
|
||||
+ MinecraftServer.LOGGER.error("Double add entity has no add stacktrace");
|
||||
+ } else {
|
||||
+ MinecraftServer.LOGGER.error("Double add stacktrace: ", thr);
|
||||
+ }
|
||||
+ }
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entity.isRemoved()) {
|
||||
+ // Paper start
|
||||
+ if (DEBUG_ENTITIES) {
|
||||
+ new Throwable("Tried to add entity " + entity + " but it was marked as removed already").printStackTrace(); // CraftBukkit
|
||||
+ getAddToWorldStackTrace(entity).printStackTrace();
|
||||
+ }
|
||||
+ // Paper end
|
||||
// WorldServer.LOGGER.warn("Tried to add entity {} but it was marked as removed already", EntityTypes.getKey(entity.getType())); // CraftBukkit
|
||||
return false;
|
||||
} else {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
public com.destroystokyo.paper.loottable.PaperLootableInventoryData lootableData; // Paper
|
||||
private CraftEntity bukkitEntity;
|
||||
|
||||
+ public @org.jetbrains.annotations.Nullable net.minecraft.server.level.ChunkMap.TrackedEntity tracker; // Paper
|
||||
+ public @Nullable Throwable addedToWorldStack; // Paper - entity debug
|
||||
public CraftEntity getBukkitEntity() {
|
||||
if (this.bukkitEntity == null) {
|
||||
this.bukkitEntity = CraftEntity.getEntity(this.level.getCraftServer(), this);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
public boolean pvpMode;
|
||||
public boolean keepSpawnInMemory = true;
|
||||
public org.bukkit.generator.ChunkGenerator generator;
|
||||
+ public static final boolean DEBUG_ENTITIES = Boolean.getBoolean("debug.entities"); // Paper
|
||||
|
||||
public boolean preventPoiUpdated = false; // CraftBukkit - SPIGOT-5710
|
||||
public boolean captureBlockStates = false;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/entity/EntityLookup.java
|
||||
@@ -0,0 +0,0 @@ public class EntityLookup<T extends EntityAccess> {
|
||||
UUID uUID = entity.getUUID();
|
||||
if (this.byUuid.containsKey(uUID)) {
|
||||
LOGGER.warn("Duplicate entity UUID {}: {}", uUID, entity);
|
||||
+ // Paper start - extra debug info
|
||||
+ if (entity instanceof net.minecraft.world.entity.Entity entityCast) {
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ entityCast.addedToWorldStack = net.minecraft.server.level.ServerLevel.getAddToWorldStackTrace(entityCast);
|
||||
+ }
|
||||
+
|
||||
+ T old = this.byUuid.get(entity.getUUID());
|
||||
+ if (old instanceof net.minecraft.world.entity.Entity oldCast && old != null && oldCast.getId() != entity.getId() && oldCast.valid) {
|
||||
+ LOGGER.error("Overwrote an existing entity " + oldCast + " with " + entity);
|
||||
+ if (net.minecraft.server.level.ServerLevel.DEBUG_ENTITIES) {
|
||||
+ if (oldCast.addedToWorldStack != null) {
|
||||
+ oldCast.addedToWorldStack.printStackTrace();
|
||||
+ } else {
|
||||
+ LOGGER.error("Oddly, the old entity was not added to the world in the normal way. Plugins?");
|
||||
+ }
|
||||
+ entityCast.addedToWorldStack.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.byUuid.put(uUID, entity);
|
||||
this.byId.put(entity.getId(), entity);
|
||||
@@ -1,160 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Wed, 8 Aug 2018 15:30:52 -0400
|
||||
Subject: [PATCH] Add Early Warning Feature to WatchDog
|
||||
|
||||
Detect when the server has been hung for a long duration, and start printing
|
||||
thread dumps at an interval until the point of crash.
|
||||
|
||||
This will help diagnose what was going on in that time before the crash.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
this.status = this.buildServerStatus();
|
||||
|
||||
// Spigot start
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper
|
||||
Arrays.fill( this.recentTps, 20 );
|
||||
long start = System.nanoTime(), curTime, tickSection = start; // Paper - Further improve server tick loop
|
||||
lastTick = start - TICK_TIME; // Paper
|
||||
diff --git a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/dedicated/DedicatedServer.java
|
||||
@@ -0,0 +0,0 @@ public class DedicatedServer extends MinecraftServer implements ServerInterface
|
||||
// Paper start
|
||||
paperConfigurations.initializeGlobalConfiguration(this.registryAccess());
|
||||
paperConfigurations.initializeWorldDefaultsConfiguration(this.registryAccess());
|
||||
+ org.spigotmc.WatchdogThread.doStart(org.spigotmc.SpigotConfig.timeoutTime, org.spigotmc.SpigotConfig.restartOnCrash);
|
||||
io.papermc.paper.command.PaperCommands.registerCommands(this);
|
||||
com.destroystokyo.paper.Metrics.PaperMetrics.startMetrics();
|
||||
com.destroystokyo.paper.VersionHistoryManager.INSTANCE.getClass(); // load version history now
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = false; // Paper - Disable watchdog early timeout on reload
|
||||
this.reloadCount++;
|
||||
this.configuration = YamlConfiguration.loadConfiguration(this.getConfigFile());
|
||||
this.commandsConfiguration = YamlConfiguration.loadConfiguration(this.getCommandsConfigFile());
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
this.enablePlugins(PluginLoadOrder.STARTUP);
|
||||
this.enablePlugins(PluginLoadOrder.POSTWORLD);
|
||||
this.getPluginManager().callEvent(new ServerLoadEvent(ServerLoadEvent.LoadType.RELOAD));
|
||||
+ org.spigotmc.WatchdogThread.hasStarted = true; // Paper - Disable watchdog early timeout on reload
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotConfig
|
||||
SpigotConfig.restartScript = SpigotConfig.getString( "settings.restart-script", SpigotConfig.restartScript );
|
||||
SpigotConfig.restartMessage = SpigotConfig.transform( SpigotConfig.getString( "messages.restart", "Server is restarting" ) );
|
||||
SpigotConfig.commands.put( "restart", new RestartCommand( "restart" ) );
|
||||
- WatchdogThread.doStart( SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash );
|
||||
+ // WatchdogThread.doStart( SpigotConfig.timeoutTime, SpigotConfig.restartOnCrash ); // Paper - moved to after paper config initialization
|
||||
}
|
||||
|
||||
public static boolean bungee;
|
||||
diff --git a/src/main/java/org/spigotmc/WatchdogThread.java b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
+++ b/src/main/java/org/spigotmc/WatchdogThread.java
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
private static WatchdogThread instance;
|
||||
private long timeoutTime;
|
||||
private boolean restart;
|
||||
+ private final long earlyWarningEvery; // Paper - Timeout time for just printing a dump but not restarting
|
||||
+ private final long earlyWarningDelay; // Paper
|
||||
+ public static volatile boolean hasStarted; // Paper
|
||||
+ private long lastEarlyWarning; // Paper - Keep track of short dump times to avoid spamming console with short dumps
|
||||
private volatile long lastTick;
|
||||
private volatile boolean stopping;
|
||||
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
super( "Paper Watchdog Thread" );
|
||||
this.timeoutTime = timeoutTime;
|
||||
this.restart = restart;
|
||||
+ earlyWarningEvery = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningEvery, timeoutTime); // Paper
|
||||
+ earlyWarningDelay = Math.min(io.papermc.paper.configuration.GlobalConfiguration.get().watchdog.earlyWarningDelay, timeoutTime); // Paper
|
||||
}
|
||||
|
||||
private static long monotonicMillis()
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
while ( !this.stopping )
|
||||
{
|
||||
//
|
||||
- if ( this.lastTick != 0 && this.timeoutTime > 0 && WatchdogThread.monotonicMillis() > this.lastTick + this.timeoutTime && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
+ // Paper start
|
||||
+ Logger log = Bukkit.getServer().getLogger();
|
||||
+ long currentTime = WatchdogThread.monotonicMillis();
|
||||
+ if ( this.lastTick != 0 && this.timeoutTime > 0 && currentTime > this.lastTick + this.earlyWarningEvery && !Boolean.getBoolean("disable.watchdog")) // Paper - Add property to disable
|
||||
{
|
||||
- Logger log = Bukkit.getServer().getLogger();
|
||||
+ boolean isLongTimeout = currentTime > lastTick + timeoutTime;
|
||||
+ // Don't spam early warning dumps
|
||||
+ if ( !isLongTimeout && (earlyWarningEvery <= 0 || !hasStarted || currentTime < lastEarlyWarning + earlyWarningEvery || currentTime < lastTick + earlyWarningDelay)) continue;
|
||||
+ if ( !isLongTimeout && MinecraftServer.getServer().hasStopped()) continue; // Don't spam early watchdog warnings during shutdown, we'll come back to this...
|
||||
+ lastEarlyWarning = currentTime;
|
||||
+ if (isLongTimeout) {
|
||||
+ // Paper end
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "The server has stopped responding! This is (probably) not a Paper bug." ); // Paper
|
||||
log.log( Level.SEVERE, "If you see a plugin in the Server thread dump below, then please report it to that author" );
|
||||
@@ -0,0 +0,0 @@ public final class WatchdogThread extends io.papermc.paper.util.TickThread // Pa
|
||||
}
|
||||
}
|
||||
// Paper end
|
||||
+ } else
|
||||
+ {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH - " + Bukkit.getServer().getVersion() + " ---");
|
||||
+ log.log(Level.SEVERE, "The server has not responded for " + (currentTime - lastTick) / 1000 + " seconds! Creating thread dump");
|
||||
+ }
|
||||
+ // Paper end - Different message for short timeout
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
log.log( Level.SEVERE, "Server thread dump (Look for plugins here before reporting to Paper!):" ); // Paper
|
||||
io.papermc.paper.chunk.system.scheduling.ChunkTaskScheduler.dumpAllChunkLoadInfo(isLongTimeout); // Paper // Paper - rewrite chunk system
|
||||
WatchdogThread.dumpThread( ManagementFactory.getThreadMXBean().getThreadInfo( MinecraftServer.getServer().serverThread.getId(), Integer.MAX_VALUE ), log );
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
//
|
||||
+ // Paper start - Only print full dump on long timeouts
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
log.log( Level.SEVERE, "Entire Thread Dump:" );
|
||||
ThreadInfo[] threads = ManagementFactory.getThreadMXBean().dumpAllThreads( true, true );
|
||||
for ( ThreadInfo thread : threads )
|
||||
{
|
||||
WatchdogThread.dumpThread( thread, log );
|
||||
}
|
||||
+ } else {
|
||||
+ log.log(Level.SEVERE, "--- DO NOT REPORT THIS TO PAPER - THIS IS NOT A BUG OR A CRASH ---");
|
||||
+ }
|
||||
+
|
||||
log.log( Level.SEVERE, "------------------------------" );
|
||||
|
||||
+ if ( isLongTimeout )
|
||||
+ {
|
||||
if ( this.restart && !MinecraftServer.getServer().hasStopped() )
|
||||
{
|
||||
RestartCommand.restart();
|
||||
}
|
||||
break;
|
||||
+ } // Paper end
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
- sleep( 10000 );
|
||||
+ sleep( 1000 ); // Paper - Reduce check time to every second instead of every ten seconds, more consistent and allows for short timeout
|
||||
} catch ( InterruptedException ex )
|
||||
{
|
||||
this.interrupt();
|
||||
@@ -1,60 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 11:50:26 -0500
|
||||
Subject: [PATCH] Add More Creeper API
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
}
|
||||
|
||||
if (nbt.getBoolean("ignited")) {
|
||||
- this.ignite();
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, true); // Paper - set directly to avoid firing event
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
}
|
||||
|
||||
public void ignite() {
|
||||
- this.entityData.set(Creeper.DATA_IS_IGNITED, true);
|
||||
+ // Paper start
|
||||
+ setIgnited(true);
|
||||
+ }
|
||||
+
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ if (isIgnited() != ignited) {
|
||||
+ com.destroystokyo.paper.event.entity.CreeperIgniteEvent event = new com.destroystokyo.paper.event.entity.CreeperIgniteEvent((org.bukkit.entity.Creeper) getBukkitEntity(), ignited);
|
||||
+ if (event.callEvent()) {
|
||||
+ this.entityData.set(Creeper.DATA_IS_IGNITED, event.isIgnited());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean canDropMobsSkull() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java
|
||||
@@ -0,0 +0,0 @@ public class CraftCreeper extends CraftMonster implements Creeper {
|
||||
public String toString() {
|
||||
return "CraftCreeper";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setIgnited(boolean ignited) {
|
||||
+ getHandle().setIgnited(ignited);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isIgnited() {
|
||||
+ return getHandle().isIgnited();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 25 Aug 2018 19:56:51 -0500
|
||||
Subject: [PATCH] Add PhantomPreSpawnEvent
|
||||
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Phantom.java
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
}
|
||||
|
||||
this.setPhantomSize(nbt.getInt("Size"));
|
||||
+ // Paper start
|
||||
+ if (nbt.hasUUID("Paper.SpawningEntity")) {
|
||||
+ this.spawningEntity = nbt.getUUID("Paper.SpawningEntity");
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
nbt.putInt("AY", this.anchorPoint.getY());
|
||||
nbt.putInt("AZ", this.anchorPoint.getZ());
|
||||
nbt.putInt("Size", this.getPhantomSize());
|
||||
+ // Paper start
|
||||
+ if (this.spawningEntity != null) {
|
||||
+ nbt.putUUID("Paper.SpawningEntity", this.spawningEntity);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Phantom extends FlyingMob implements Enemy {
|
||||
return -0.125F;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ java.util.UUID spawningEntity;
|
||||
+
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return spawningEntity;
|
||||
+ }
|
||||
+ public void setSpawningEntity(java.util.UUID entity) { this.spawningEntity = entity; }
|
||||
+ // Paper end
|
||||
private static enum AttackPhase {
|
||||
|
||||
CIRCLE, SWOOP;
|
||||
diff --git a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/levelgen/PhantomSpawner.java
|
||||
@@ -0,0 +0,0 @@ public class PhantomSpawner implements CustomSpawner {
|
||||
int k = 1 + randomsource.nextInt(difficultydamagescaler.getDifficulty().getId() + 1);
|
||||
|
||||
for (int l = 0; l < k; ++l) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent event = new com.destroystokyo.paper.event.entity.PhantomPreSpawnEvent(io.papermc.paper.util.MCUtil.toLocation(world, blockposition1), entityplayer.getBukkitEntity(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL);
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ // Paper end
|
||||
Phantom entityphantom = (Phantom) EntityType.PHANTOM.create(world);
|
||||
|
||||
if (entityphantom != null) {
|
||||
+ entityphantom.setSpawningEntity(entityplayer.getUUID()); // Paper
|
||||
entityphantom.moveTo(blockposition1, 0.0F, 0.0F);
|
||||
groupdataentity = entityphantom.finalizeSpawn(world, difficultydamagescaler, MobSpawnType.NATURAL, groupdataentity, (CompoundTag) null);
|
||||
world.addFreshEntityWithPassengers(entityphantom, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.NATURAL); // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPhantom.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPhantom extends CraftFlying implements Phantom, CraftEnemy {
|
||||
public String toString() {
|
||||
return "CraftPhantom";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public java.util.UUID getSpawningEntity() {
|
||||
+ return getHandle().getSpawningEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 19 Jan 2018 08:15:29 -0600
|
||||
Subject: [PATCH] Add PlayerAdvancementCriterionGrantEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/PlayerAdvancements.java b/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
||||
+++ b/src/main/java/net/minecraft/server/PlayerAdvancements.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerAdvancements {
|
||||
boolean flag1 = advancementprogress.isDone();
|
||||
|
||||
if (advancementprogress.grantProgress(criterionName)) {
|
||||
+ // Paper start
|
||||
+ if (!new com.destroystokyo.paper.event.player.PlayerAdvancementCriterionGrantEvent(this.player.getBukkitEntity(), advancement.toBukkit(), criterionName).callEvent()) {
|
||||
+ advancementprogress.revokeProgress(criterionName);
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.unregisterListeners(advancement);
|
||||
this.progressChanged.add(advancement);
|
||||
flag = true;
|
||||
@@ -1,111 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: pkt77 <parkerkt77@gmail.com>
|
||||
Date: Fri, 10 Nov 2017 23:46:34 -0500
|
||||
Subject: [PATCH] Add PlayerArmorChangeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.world.entity;
|
||||
|
||||
+import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent; // Paper
|
||||
import com.google.common.base.Objects;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
ItemStack itemstack1 = this.getItemBySlot(enumitemslot);
|
||||
|
||||
if (this.equipmentHasChanged(itemstack, itemstack1)) {
|
||||
+ // Paper start - PlayerArmorChangeEvent
|
||||
+ if (this instanceof ServerPlayer && enumitemslot.getType() == EquipmentSlot.Type.ARMOR) {
|
||||
+ final org.bukkit.inventory.ItemStack oldItem = CraftItemStack.asBukkitCopy(itemstack);
|
||||
+ final org.bukkit.inventory.ItemStack newItem = CraftItemStack.asBukkitCopy(itemstack1);
|
||||
+ new PlayerArmorChangeEvent((Player) this.getBukkitEntity(), PlayerArmorChangeEvent.SlotType.valueOf(enumitemslot.name()), oldItem, newItem).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (map == null) {
|
||||
map = Maps.newEnumMap(EquipmentSlot.class);
|
||||
}
|
||||
diff --git a/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java b/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/test/java/io/papermc/paper/inventory/item/ArmorSlotTypeMaterialTest.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package io.papermc.paper.inventory.item;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.player.PlayerArmorChangeEvent;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+import java.util.stream.Stream;
|
||||
+import net.minecraft.world.entity.EquipmentSlot;
|
||||
+import net.minecraft.world.item.Equipable;
|
||||
+import net.minecraft.world.item.Item;
|
||||
+import net.minecraft.world.item.ItemStack;
|
||||
+import org.bukkit.Material;
|
||||
+import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
+import org.bukkit.support.AbstractTestingBase;
|
||||
+import org.junit.jupiter.params.ParameterizedTest;
|
||||
+import org.junit.jupiter.params.provider.MethodSource;
|
||||
+
|
||||
+import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
+import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
+import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
+
|
||||
+public class ArmorSlotTypeMaterialTest extends AbstractTestingBase {
|
||||
+
|
||||
+ public static Stream<Object[]> slotTypeParams() {
|
||||
+ final List<Object[]> parameters = new ArrayList<>();
|
||||
+ for (final PlayerArmorChangeEvent.SlotType slotType : PlayerArmorChangeEvent.SlotType.values()) {
|
||||
+ for (final Material item : slotType.getTypes()) {
|
||||
+ parameters.add(new Object[]{ slotType, item });
|
||||
+ }
|
||||
+ }
|
||||
+ return parameters.stream();
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest(name = "{argumentsWithNames}")
|
||||
+ @MethodSource("slotTypeParams")
|
||||
+ public void testSlotType(PlayerArmorChangeEvent.SlotType slotType, Material item) {
|
||||
+ final Item nmsItem = CraftMagicNumbers.getItem(item);
|
||||
+ final Equipable equipable = Equipable.get(new ItemStack(nmsItem));
|
||||
+ assertNotNull(equipable, item + " isn't equipable");
|
||||
+ final EquipmentSlot slot = switch (slotType) {
|
||||
+ case HEAD -> EquipmentSlot.HEAD;
|
||||
+ case CHEST -> EquipmentSlot.CHEST;
|
||||
+ case LEGS -> EquipmentSlot.LEGS;
|
||||
+ case FEET -> EquipmentSlot.FEET;
|
||||
+ };
|
||||
+ assertEquals(equipable.getEquipmentSlot(), slot, item + " isn't set to the right slot");
|
||||
+ }
|
||||
+
|
||||
+ public static Stream<Object[]> equipableParams() {
|
||||
+ final List<Object[]> parameters = new ArrayList<>();
|
||||
+ for (final Item item : net.minecraft.core.registries.BuiltInRegistries.ITEM) {
|
||||
+ final Equipable equipable = Equipable.get(new ItemStack(item));
|
||||
+ if (equipable != null) {
|
||||
+ parameters.add(new Object[]{equipable, item});
|
||||
+ }
|
||||
+ }
|
||||
+ return parameters.stream();
|
||||
+ }
|
||||
+
|
||||
+ @ParameterizedTest(name = "{argumentsWithNames}")
|
||||
+ @MethodSource("equipableParams")
|
||||
+ public void testEquipable(Equipable equipable, Item item) {
|
||||
+ final EquipmentSlot equipmentSlot = equipable.getEquipmentSlot();
|
||||
+ PlayerArmorChangeEvent.SlotType slotType = switch (equipmentSlot) {
|
||||
+ case HEAD -> PlayerArmorChangeEvent.SlotType.HEAD;
|
||||
+ case CHEST -> PlayerArmorChangeEvent.SlotType.CHEST;
|
||||
+ case LEGS -> PlayerArmorChangeEvent.SlotType.LEGS;
|
||||
+ case FEET -> PlayerArmorChangeEvent.SlotType.FEET;
|
||||
+ default -> null;
|
||||
+ };
|
||||
+ if (slotType != null) {
|
||||
+ assertTrue(slotType.getTypes().contains(CraftMagicNumbers.getMaterial(item)), "SlotType " + slotType + " doesn't include " + item);
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Thu, 28 Sep 2017 17:21:44 -0400
|
||||
Subject: [PATCH] Add PlayerJumpEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
boolean flag = d7 > 0.0D;
|
||||
|
||||
if (this.player.onGround() && !packet.isOnGround() && flag) {
|
||||
- this.player.jumpFromGround();
|
||||
+ // Paper start - Add player jump event
|
||||
+ Player player = this.getCraftPlayer();
|
||||
+ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location.
|
||||
+ Location to = player.getLocation().clone(); // Start off the To location as the Players current location.
|
||||
+
|
||||
+ // If the packet contains movement information then we update the To location with the correct XYZ.
|
||||
+ if (packet.hasPos) {
|
||||
+ to.setX(packet.x);
|
||||
+ to.setY(packet.y);
|
||||
+ to.setZ(packet.z);
|
||||
+ }
|
||||
+
|
||||
+ // If the packet contains look information then we update the To location with the correct Yaw & Pitch.
|
||||
+ if (packet.hasRot) {
|
||||
+ to.setYaw(packet.yRot);
|
||||
+ to.setPitch(packet.xRot);
|
||||
+ }
|
||||
+
|
||||
+ com.destroystokyo.paper.event.player.PlayerJumpEvent event = new com.destroystokyo.paper.event.player.PlayerJumpEvent(player, from, to);
|
||||
+
|
||||
+ if (event.callEvent()) {
|
||||
+ this.player.jumpFromGround();
|
||||
+ } else {
|
||||
+ from = event.getFrom();
|
||||
+ this.internalTeleport(from.getX(), from.getY(), from.getZ(), from.getYaw(), from.getPitch(), Collections.emptySet());
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
boolean flag1 = this.player.verticalCollisionBelow;
|
||||
@@ -1,117 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Mon, 16 Jul 2018 00:05:05 +0300
|
||||
Subject: [PATCH] Add TNTPrimeEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
});
|
||||
craftBlock.getNMS().spawnAfterBreak((ServerLevel) this.level(), blockposition, ItemStack.EMPTY, false);
|
||||
}
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = this.level().getWorld().getBlockAt(blockposition.getX(), blockposition.getY(), blockposition.getZ());
|
||||
+ if(!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, explosionSource.getIndirectSourceEntity().getBukkitEntity()).callEvent())
|
||||
+ continue;
|
||||
+ // Paper end
|
||||
nmsBlock.wasExploded(this.level(), blockposition, this.explosionSource);
|
||||
|
||||
this.level().removeBlock(blockposition, false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FireBlock.java b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FireBlock.java
|
||||
@@ -0,0 +0,0 @@ public class FireBlock extends BaseFireBlock {
|
||||
|
||||
world.setBlock(blockposition, this.getStateWithAge(world, blockposition, l), 3);
|
||||
} else {
|
||||
- world.removeBlock(blockposition, false);
|
||||
+ if(iblockdata.getBlock() != Blocks.TNT) world.removeBlock(blockposition, false); // Paper - TNTPrimeEvent - We might be cancelling it below, move the setAir down
|
||||
}
|
||||
|
||||
Block block = iblockdata.getBlock();
|
||||
|
||||
if (block instanceof TntBlock) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.FIRE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ world.removeBlock(blockposition, false);
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/TntBlock.java b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/TntBlock.java
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (!oldState.is(state.getBlock())) {
|
||||
if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, null)) { // CraftBukkit - TNTPrimeEvent
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||
if (world.hasNeighborSignal(pos) && CraftEventFactory.callTNTPrimeEvent(world, pos, PrimeCause.REDSTONE, null, sourcePos)) { // CraftBukkit - TNTPrimeEvent
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.REDSTONE, null).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos);
|
||||
world.removeBlock(pos, false);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
@Override
|
||||
public void wasExploded(Level world, BlockPos pos, Explosion explosion) {
|
||||
if (!world.isClientSide) {
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ org.bukkit.entity.Entity source = explosion.source != null ? explosion.source.getBukkitEntity() : null;
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.EXPLOSION, source).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
PrimedTnt entitytntprimed = new PrimedTnt(world, (double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D, explosion.getIndirectSourceEntity());
|
||||
int i = entitytntprimed.getFuse();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
return InteractionResult.CONSUME;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, pos);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.ITEM, player.getBukkitEntity()).callEvent()) {
|
||||
+ return InteractionResult.FAIL;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, pos, player);
|
||||
world.setBlock(pos, Blocks.AIR.defaultBlockState(), 11);
|
||||
Item item = itemstack.getItem();
|
||||
@@ -0,0 +0,0 @@ public class TntBlock extends Block {
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - TNTPrimeEvent
|
||||
+ org.bukkit.block.Block tntBlock = io.papermc.paper.util.MCUtil.toBukkitBlock(world, blockposition);
|
||||
+ if (!new com.destroystokyo.paper.event.block.TNTPrimeEvent(tntBlock, com.destroystokyo.paper.event.block.TNTPrimeEvent.PrimeReason.PROJECTILE, projectile.getBukkitEntity()).callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
TntBlock.explode(world, blockposition, entity instanceof LivingEntity ? (LivingEntity) entity : null);
|
||||
world.removeBlock(blockposition, false);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 22 Jun 2018 10:38:31 -0500
|
||||
Subject: [PATCH] Add config to disable ender dragon legacy check
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/dimension/end/EndDragonFight.java
|
||||
@@ -0,0 +0,0 @@ public class EndDragonFight {
|
||||
this.ticksSinceLastPlayerScan = 21;
|
||||
this.skipArenaLoadedCheck = false;
|
||||
this.needsStateScanning = true;
|
||||
+ // Paper start
|
||||
+ this.needsStateScanning = world.paperConfig().entities.spawning.scanForLegacyEnderDragon;
|
||||
+ if (!this.needsStateScanning) this.dragonKilled = true;
|
||||
+ // Paper end
|
||||
this.level = world;
|
||||
this.origin = origin;
|
||||
this.validPlayer = EntitySelector.ENTITY_STILL_ALIVE.and(EntitySelector.withinDistance((double) origin.getX(), (double) (128 + origin.getY()), (double) origin.getZ(), 192.0D));
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Mark Vainomaa <mikroskeem@mikroskeem.eu>
|
||||
Date: Sun, 1 Apr 2018 02:29:37 +0300
|
||||
Subject: [PATCH] Add openSign method to HumanEntity
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - move open sign method to HumanEntity
|
||||
+ @Override
|
||||
+ public void openSign(final org.bukkit.block.Sign sign, final org.bukkit.block.sign.Side side) {
|
||||
+ org.bukkit.craftbukkit.block.CraftSign.openSign(sign, (CraftPlayer) this, side);
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public boolean dropItem(boolean dropAll) {
|
||||
if (!(this.getHandle() instanceof ServerPlayer)) return false;
|
||||
@@ -1,69 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 3 Sep 2018 18:20:03 -0500
|
||||
Subject: [PATCH] Add ray tracing methods to LivingEntity
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
// Paper start
|
||||
+
|
||||
+ public HitResult getRayTrace(int maxDistance, ClipContext.Fluid fluidCollisionOption) {
|
||||
+ if (maxDistance < 1 || maxDistance > 120) {
|
||||
+ throw new IllegalArgumentException("maxDistance must be between 1-120");
|
||||
+ }
|
||||
+
|
||||
+ Vec3 start = new Vec3(getX(), getY() + getEyeHeight(), getZ());
|
||||
+ org.bukkit.util.Vector dir = getBukkitEntity().getLocation().getDirection().multiply(maxDistance);
|
||||
+ Vec3 end = new Vec3(start.x + dir.getX(), start.y + dir.getY(), start.z + dir.getZ());
|
||||
+ ClipContext raytrace = new ClipContext(start, end, ClipContext.Block.OUTLINE, fluidCollisionOption, this);
|
||||
+
|
||||
+ return this.level().clip(raytrace);
|
||||
+ }
|
||||
+
|
||||
public int shieldBlockingDelay = this.level().paperConfig().misc.shieldBlockingDelay;
|
||||
|
||||
public int getShieldBlockingDelay() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return blocks.get(0);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public Block getTargetBlock(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ return this.getTargetBlockExact(maxDistance, fluidMode.bukkit);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ return this.getTargetBlockFace(maxDistance, fluidMode.bukkit);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.block.BlockFace getTargetBlockFace(int maxDistance, org.bukkit.FluidCollisionMode fluidMode) {
|
||||
+ RayTraceResult result = this.rayTraceBlocks(maxDistance, fluidMode);
|
||||
+ return result != null ? result.getHitBlockFace() : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.block.TargetBlockInfo getTargetBlockInfo(int maxDistance, com.destroystokyo.paper.block.TargetBlockInfo.FluidMode fluidMode) {
|
||||
+ RayTraceResult result = this.rayTraceBlocks(maxDistance, fluidMode.bukkit);
|
||||
+ if (result != null && result.getHitBlock() != null && result.getHitBlockFace() != null) {
|
||||
+ return new com.destroystokyo.paper.block.TargetBlockInfo(result.getHitBlock(), result.getHitBlockFace());
|
||||
+ }
|
||||
+ return null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public List<Block> getLastTwoTargetBlocks(Set<Material> transparent, int maxDistance) {
|
||||
return this.getLineOfSight(transparent, maxDistance, 2);
|
||||
@@ -1,104 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 19 Jan 2018 00:36:25 -0500
|
||||
Subject: [PATCH] Add setPlayerProfile API for Skulls
|
||||
|
||||
This allows you to create already filled textures on Skulls to avoid texture lookups
|
||||
which commonly cause rate limit issues with Mojang API
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSkull extends CraftBlockEntityState<SkullBlockEntity> implemen
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
@Override
|
||||
+ public void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile) {
|
||||
+ Preconditions.checkNotNull(profile, "profile");
|
||||
+ this.profile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile);
|
||||
+ }
|
||||
+
|
||||
+ @javax.annotation.Nullable
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile() {
|
||||
+ return profile != null ? com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitCopy(profile) : null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
+ @Override
|
||||
+ @Deprecated // Paper
|
||||
public PlayerProfile getOwnerProfile() {
|
||||
if (!this.hasOwner()) {
|
||||
return null;
|
||||
@@ -0,0 +0,0 @@ public class CraftSkull extends CraftBlockEntityState<SkullBlockEntity> implemen
|
||||
}
|
||||
|
||||
@Override
|
||||
+ @Deprecated // Paper
|
||||
public void setOwnerProfile(PlayerProfile profile) {
|
||||
if (profile == null) {
|
||||
this.profile = null;
|
||||
} else {
|
||||
- this.profile = CraftPlayerProfile.validateSkullProfile(((CraftPlayerProfile) profile).buildGameProfile());
|
||||
+ this.profile = CraftPlayerProfile.validateSkullProfile(((com.destroystokyo.paper.profile.SharedPlayerProfile) profile).buildGameProfile()); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java
|
||||
@@ -0,0 +0,0 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
||||
return this.hasOwner() ? this.profile.getName() : null;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setPlayerProfile(@org.jetbrains.annotations.Nullable com.destroystokyo.paper.profile.PlayerProfile profile) {
|
||||
+ setProfile((profile == null) ? null : com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile));
|
||||
+ }
|
||||
+
|
||||
+ @org.jetbrains.annotations.Nullable
|
||||
+ @Override
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile() {
|
||||
+ return profile != null ? com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitCopy(profile) : null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public OfflinePlayer getOwningPlayer() {
|
||||
if (this.hasOwner()) {
|
||||
@@ -0,0 +0,0 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
||||
}
|
||||
|
||||
@Override
|
||||
+ @Deprecated // Paper
|
||||
public PlayerProfile getOwnerProfile() {
|
||||
if (!this.hasOwner()) {
|
||||
return null;
|
||||
@@ -0,0 +0,0 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
||||
}
|
||||
|
||||
@Override
|
||||
+ @Deprecated // Paper
|
||||
public void setOwnerProfile(PlayerProfile profile) {
|
||||
if (profile == null) {
|
||||
this.setProfile(null);
|
||||
} else {
|
||||
- this.setProfile(CraftPlayerProfile.validateSkullProfile(((CraftPlayerProfile) profile).buildGameProfile()));
|
||||
+ this.setProfile(CraftPlayerProfile.validateSkullProfile(((com.destroystokyo.paper.profile.SharedPlayerProfile) profile).buildGameProfile())); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta {
|
||||
Builder<String, Object> serialize(Builder<String, Object> builder) {
|
||||
super.serialize(builder);
|
||||
if (this.profile != null) {
|
||||
- return builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new CraftPlayerProfile(this.profile));
|
||||
+ return builder.put(CraftMetaSkull.SKULL_OWNER.BUKKIT, new com.destroystokyo.paper.profile.CraftPlayerProfile(this.profile)); // Paper
|
||||
}
|
||||
NamespacedKey namespacedKeyNB = this.getNoteBlockSound();
|
||||
if (namespacedKeyNB != null) {
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 8 Sep 2018 18:43:31 -0500
|
||||
Subject: [PATCH] Allow chests to be placed with NBT data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack {
|
||||
enuminteractionresult = InteractionResult.FAIL; // cancel placement
|
||||
// PAIL: Remove this when MC-99075 fixed
|
||||
placeEvent.getPlayer().updateInventory();
|
||||
+ world.capturedTileEntities.clear(); // Paper - clear out tile entities as chests and such will pop loot
|
||||
// revert back all captured blocks
|
||||
world.preventPoiUpdated = true; // CraftBukkit - SPIGOT-5710
|
||||
for (BlockState blockstate : blocks) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/ChestBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class ChestBlockEntity extends RandomizableContainerBlockEntity implement
|
||||
// CraftBukkit start
|
||||
@Override
|
||||
public boolean onlyOpCanSetNbt() {
|
||||
- return true;
|
||||
+ return false; // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
@@ -1,145 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Wed, 15 Aug 2018 01:26:09 -0700
|
||||
Subject: [PATCH] Allow disabling armour stand ticking
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
public Rotations leftLegPose;
|
||||
public Rotations rightLegPose;
|
||||
public boolean canMove = true; // Paper
|
||||
+ // Paper start - Allow ArmorStands not to tick
|
||||
+ public boolean canTick = true;
|
||||
+ public boolean canTickSetByAPI = false;
|
||||
+ private boolean noTickPoseDirty = false;
|
||||
+ private boolean noTickEquipmentDirty = false;
|
||||
+ // Paper end
|
||||
|
||||
public ArmorStand(EntityType<? extends ArmorStand> type, Level world) {
|
||||
super(type, world);
|
||||
+ if (world != null) this.canTick = world.paperConfig().entities.armorStands.tick; // Paper - armour stand ticking
|
||||
this.handItems = NonNullList.withSize(2, ItemStack.EMPTY);
|
||||
this.armorItems = NonNullList.withSize(4, ItemStack.EMPTY);
|
||||
this.headPose = ArmorStand.DEFAULT_HEAD_POSE;
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.onEquipItem(enumitemslot, (ItemStack) this.armorItems.set(enumitemslot.getIndex(), itemstack), itemstack, silent); // CraftBukkit
|
||||
}
|
||||
|
||||
+ this.noTickEquipmentDirty = true; // Paper - Allow equipment to be updated even when tick disabled
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
nbt.put("Pose", this.writePose());
|
||||
+ if (this.canTickSetByAPI) nbt.putBoolean("Paper.CanTickOverride", this.canTick); // Paper - persist no tick setting
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.setNoBasePlate(nbt.getBoolean("NoBasePlate"));
|
||||
this.setMarker(nbt.getBoolean("Marker"));
|
||||
this.noPhysics = !this.hasPhysics();
|
||||
+ // Paper start - persist no tick
|
||||
+ if (nbt.contains("Paper.CanTickOverride")) {
|
||||
+ this.canTick = nbt.getBoolean("Paper.CanTickOverride");
|
||||
+ this.canTickSetByAPI = true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
CompoundTag nbttagcompound1 = nbt.getCompound("Pose");
|
||||
|
||||
this.readPose(nbttagcompound1);
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start
|
||||
+ if (!this.canTick) {
|
||||
+ if (this.noTickPoseDirty) {
|
||||
+ this.noTickPoseDirty = false;
|
||||
+ this.updatePose();
|
||||
+ }
|
||||
+
|
||||
+ if (this.noTickEquipmentDirty) {
|
||||
+ this.noTickEquipmentDirty = false;
|
||||
+ this.detectEquipmentUpdatesPublic();
|
||||
+ }
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
super.tick();
|
||||
+ // Paper start - Split into separate method
|
||||
+ updatePose();
|
||||
+ }
|
||||
+
|
||||
+ public void updatePose() {
|
||||
+ // Paper end
|
||||
Rotations vector3f = (Rotations) this.entityData.get(ArmorStand.DATA_HEAD_POSE);
|
||||
|
||||
if (!this.headPose.equals(vector3f)) {
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
public void setHeadPose(Rotations angle) {
|
||||
this.headPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_HEAD_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setBodyPose(Rotations angle) {
|
||||
this.bodyPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_BODY_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftArmPose(Rotations angle) {
|
||||
this.leftArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightArmPose(Rotations angle) {
|
||||
this.rightArmPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_ARM_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setLeftLegPose(Rotations angle) {
|
||||
this.leftLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_LEFT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public void setRightLegPose(Rotations angle) {
|
||||
this.rightLegPose = angle;
|
||||
this.entityData.set(ArmorStand.DATA_RIGHT_LEG_POSE, angle);
|
||||
+ this.noTickPoseDirty = true; // Paper - Allow updates when not ticking
|
||||
}
|
||||
|
||||
public Rotations getHeadPose() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
public void setCanMove(boolean move) {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canTick() {
|
||||
+ return this.getHandle().canTick;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanTick(final boolean tick) {
|
||||
+ this.getHandle().canTick = tick;
|
||||
+ this.getHandle().canTickSetByAPI = true;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 4 Jun 2018 20:39:20 -0400
|
||||
Subject: [PATCH] Allow spawning Item entities with World.spawnEntity
|
||||
|
||||
This API has more capabilities than .dropItem with the Consumer function
|
||||
|
||||
Item can be set inside of the Consumer pre spawn function.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
|
||||
entity = net.minecraft.world.entity.EntityType.BOAT.create(world);
|
||||
}
|
||||
entity.moveTo(x, y, z, yaw, pitch);
|
||||
+ // Paper start
|
||||
+ } else if (org.bukkit.entity.Item.class.isAssignableFrom(clazz)) {
|
||||
+ entity = new net.minecraft.world.entity.item.ItemEntity(world, x, y, z, new net.minecraft.world.item.ItemStack(net.minecraft.world.item.Items.DIRT));
|
||||
+ // Paper end
|
||||
} else if (FallingBlock.class.isAssignableFrom(clazz)) {
|
||||
BlockPos pos = BlockPos.containing(x, y, z);
|
||||
entity = FallingBlockEntity.fall(world, pos, this.getHandle().getBlockState(pos));
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Riley Park <rileysebastianpark@gmail.com>
|
||||
Date: Thu, 17 Aug 2017 16:08:20 -0700
|
||||
Subject: [PATCH] Allow specifying a custom "authentication servers down" kick
|
||||
message
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
ServerLoginPacketListenerImpl.LOGGER.warn("Authentication servers are down but will let them in anyway!");
|
||||
ServerLoginPacketListenerImpl.this.startClientVerification(ServerLoginPacketListenerImpl.this.createOfflineProfile(s1)); // Spigot
|
||||
} else {
|
||||
- ServerLoginPacketListenerImpl.this.disconnect(Component.translatable("multiplayer.disconnect.authservers_down"));
|
||||
+ ServerLoginPacketListenerImpl.this.disconnect(io.papermc.paper.adventure.PaperAdventure.asVanilla(io.papermc.paper.configuration.GlobalConfiguration.get().messages.kick.authenticationServersDown)); // Paper
|
||||
ServerLoginPacketListenerImpl.LOGGER.error("Couldn't verify username because servers are unavailable");
|
||||
}
|
||||
// CraftBukkit start - catch all exceptions
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 20 Jul 2018 23:37:03 -0500
|
||||
Subject: [PATCH] AnvilDamageEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
+++ b/src/main/java/net/minecraft/world/inventory/AnvilMenu.java
|
||||
@@ -0,0 +0,0 @@ public class AnvilMenu extends ItemCombinerMenu {
|
||||
if (!player.getAbilities().instabuild && iblockdata.is(BlockTags.ANVIL) && player.getRandom().nextFloat() < 0.12F) {
|
||||
BlockState iblockdata1 = AnvilBlock.damage(iblockdata);
|
||||
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.block.AnvilDamagedEvent event = new com.destroystokyo.paper.event.block.AnvilDamagedEvent(getBukkitView(), iblockdata1 != null ? org.bukkit.craftbukkit.block.data.CraftBlockData.fromData(iblockdata1) : null);
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ } else if (event.getDamageState() == com.destroystokyo.paper.event.block.AnvilDamagedEvent.DamageState.BROKEN) {
|
||||
+ iblockdata1 = null;
|
||||
+ } else {
|
||||
+ iblockdata1 = ((org.bukkit.craftbukkit.block.data.CraftBlockData) event.getDamageState().getMaterial().createBlockData()).getState().setValue(AnvilBlock.FACING, iblockdata.getValue(AnvilBlock.FACING));
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (iblockdata1 == null) {
|
||||
world.removeBlock(blockposition, false);
|
||||
world.levelEvent(1029, blockposition, 0);
|
||||
@@ -1,187 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
|
||||
Date: Sun, 26 Nov 2017 13:19:58 -0500
|
||||
Subject: [PATCH] AsyncTabCompleteEvent
|
||||
|
||||
Let plugins be able to control tab completion of commands and chat async.
|
||||
|
||||
This will be useful for frameworks like ACF so we can define async safe completion handlers,
|
||||
and avoid going to main for tab completions.
|
||||
|
||||
Especially useful if you need to query a database in order to obtain the results for tab
|
||||
completion, such as offline players.
|
||||
|
||||
Also adds isCommand and getLocation to the sync TabCompleteEvent
|
||||
|
||||
Co-authored-by: Aikar <aikar@aikar.co>
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private static final java.util.concurrent.ExecutorService TAB_COMPLETE_EXECUTOR = java.util.concurrent.Executors.newFixedThreadPool(4,
|
||||
+ new com.google.common.util.concurrent.ThreadFactoryBuilder().setDaemon(true).setNameFormat("Async Tab Complete Thread - #%d").setUncaughtExceptionHandler(new net.minecraft.DefaultUncaughtExceptionHandlerWithName(net.minecraft.server.MinecraftServer.LOGGER)).build());
|
||||
+ // Paper end
|
||||
@Override
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
- PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
+ // PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
|
||||
- this.disconnect(Component.translatable("disconnect.spam"));
|
||||
+ server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
||||
// Paper start
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
// Paper end
|
||||
// CraftBukkit end
|
||||
+ // Paper start - async tab completion
|
||||
+ TAB_COMPLETE_EXECUTOR.execute(() -> {
|
||||
StringReader stringreader = new StringReader(packet.getCommand());
|
||||
|
||||
if (stringreader.canRead() && stringreader.peek() == '/') {
|
||||
stringreader.skip();
|
||||
}
|
||||
-
|
||||
- ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
||||
-
|
||||
- this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
||||
- if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
||||
- this.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions));
|
||||
+ final String command = packet.getCommand();
|
||||
+ final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event = new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(this.getCraftPlayer(), command, true, null);
|
||||
+ event.callEvent();
|
||||
+ final java.util.List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
|
||||
+ // If the event isn't handled, we can assume that we have no completions, and so we'll ask the server
|
||||
+ if (!event.isHandled()) {
|
||||
+ if (!event.isCancelled()) {
|
||||
+
|
||||
+ this.server.scheduleOnMain(() -> { // This needs to be on main
|
||||
+ ParseResults<CommandSourceStack> parseresults = this.server.getCommands().getDispatcher().parse(stringreader, this.player.createCommandSourceStack());
|
||||
+
|
||||
+ this.server.getCommands().getDispatcher().getCompletionSuggestions(parseresults).thenAccept((suggestions) -> {
|
||||
+ if (suggestions.isEmpty()) return; // CraftBukkit - don't send through empty suggestions - prevents [<args>] from showing for plugins with nothing more to offer
|
||||
+ this.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), suggestions));
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+ } else if (!completions.isEmpty()) {
|
||||
+ final com.mojang.brigadier.suggestion.SuggestionsBuilder builder0 = new com.mojang.brigadier.suggestion.SuggestionsBuilder(command, stringreader.getTotalLength());
|
||||
+ final com.mojang.brigadier.suggestion.SuggestionsBuilder builder = builder0.createOffset(builder0.getInput().lastIndexOf(' ') + 1);
|
||||
+ completions.forEach(completion -> {
|
||||
+ final Integer intSuggestion = com.google.common.primitives.Ints.tryParse(completion.suggestion());
|
||||
+ if (intSuggestion != null) {
|
||||
+ builder.suggest(intSuggestion, PaperAdventure.asVanilla(completion.tooltip()));
|
||||
+ } else {
|
||||
+ builder.suggest(completion.suggestion(), PaperAdventure.asVanilla(completion.tooltip()));
|
||||
+ }
|
||||
+ });
|
||||
+ player.connection.send(new ClientboundCommandSuggestionsPacket(packet.getId(), builder.buildFuture().join()));
|
||||
+ }
|
||||
});
|
||||
+ // Paper end - async tab completion
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftServer implements Server {
|
||||
offers = this.tabCompleteChat(player, message);
|
||||
}
|
||||
|
||||
- TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers);
|
||||
+ TabCompleteEvent tabEvent = new TabCompleteEvent(player, message, offers, message.startsWith("/") || forceCommand, pos != null ? io.papermc.paper.util.MCUtil.toLocation(((CraftWorld) player.getWorld()).getHandle(), BlockPos.containing(pos)) : null); // Paper
|
||||
this.getPluginManager().callEvent(tabEvent);
|
||||
|
||||
return tabEvent.isCancelled() ? Collections.EMPTY_LIST : tabEvent.getCompletions();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java
|
||||
@@ -0,0 +0,0 @@ public class ConsoleCommandCompleter implements Completer {
|
||||
public void complete(LineReader reader, ParsedLine line, List<Candidate> candidates) {
|
||||
final CraftServer server = this.server.server;
|
||||
final String buffer = line.line();
|
||||
+ // Async Tab Complete
|
||||
+ final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event =
|
||||
+ new com.destroystokyo.paper.event.server.AsyncTabCompleteEvent(server.getConsoleSender(), buffer, true, null);
|
||||
+ event.callEvent();
|
||||
+ final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions = event.isCancelled() ? com.google.common.collect.ImmutableList.of() : event.completions();
|
||||
+
|
||||
+ if (event.isCancelled() || event.isHandled()) {
|
||||
+ // Still fire sync event with the provided completions, if someone is listening
|
||||
+ if (!event.isCancelled() && TabCompleteEvent.getHandlerList().getRegisteredListeners().length > 0) {
|
||||
+ List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> finalCompletions = new java.util.ArrayList<>(completions);
|
||||
+ Waitable<List<String>> syncCompletions = new Waitable<List<String>>() {
|
||||
+ @Override
|
||||
+ protected List<String> evaluate() {
|
||||
+ org.bukkit.event.server.TabCompleteEvent syncEvent = new org.bukkit.event.server.TabCompleteEvent(server.getConsoleSender(), buffer,
|
||||
+ finalCompletions.stream()
|
||||
+ .map(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion::suggestion)
|
||||
+ .collect(java.util.stream.Collectors.toList()));
|
||||
+ return syncEvent.callEvent() ? syncEvent.getCompletions() : com.google.common.collect.ImmutableList.of();
|
||||
+ }
|
||||
+ };
|
||||
+ server.getServer().processQueue.add(syncCompletions);
|
||||
+ try {
|
||||
+ final List<String> legacyCompletions = syncCompletions.get();
|
||||
+ completions.removeIf(it -> !legacyCompletions.contains(it.suggestion())); // remove any suggestions that were removed
|
||||
+ // add any new suggestions
|
||||
+ for (final String completion : legacyCompletions) {
|
||||
+ if (notNewSuggestion(completions, completion)) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ completions.add(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion.completion(completion));
|
||||
+ }
|
||||
+ } catch (InterruptedException | ExecutionException e1) {
|
||||
+ e1.printStackTrace();
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!completions.isEmpty()) {
|
||||
+ for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion completion : completions) {
|
||||
+ if (completion.suggestion().isEmpty()) {
|
||||
+ continue;
|
||||
+ }
|
||||
+ candidates.add(new Candidate(
|
||||
+ completion.suggestion(),
|
||||
+ completion.suggestion(),
|
||||
+ null,
|
||||
+ io.papermc.paper.adventure.PaperAdventure.PLAIN.serializeOr(completion.tooltip(), null),
|
||||
+ null,
|
||||
+ null,
|
||||
+ false
|
||||
+ ));
|
||||
+ }
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
// Paper end
|
||||
Waitable<List<String>> waitable = new Waitable<List<String>>() {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class ConsoleCommandCompleter implements Completer {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private boolean notNewSuggestion(final List<com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion> completions, final String completion) {
|
||||
+ for (final com.destroystokyo.paper.event.server.AsyncTabCompleteEvent.Completion it : completions) {
|
||||
+ if (it.suggestion().equals(completion)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 17:15:26 -0400
|
||||
Subject: [PATCH] Block Enderpearl Travel Exploit
|
||||
|
||||
Players are able to use alt accounts and enderpearls to travel
|
||||
long distances utilizing the pearls in unloaded chunks and loading
|
||||
the chunk later when convenient.
|
||||
|
||||
This disables that by not saving the thrower when the chunk is unloaded.
|
||||
|
||||
This is mainly useful for survival servers that do not allow freeform teleporting.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.Projectile cachedOwner
|
||||
public net.minecraft.world.entity.projectile.Projectile ownerUUID
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
|
||||
public void onTickingEnd(Entity entity) {
|
||||
ServerLevel.this.entityTickList.remove(entity);
|
||||
+ // Paper start - Reset pearls when they stop being ticked
|
||||
+ if (paperConfig().fixes.disableUnloadedChunkEnderpearlExploit && entity instanceof net.minecraft.world.entity.projectile.ThrownEnderpearl pearl) {
|
||||
+ pearl.cachedOwner = null;
|
||||
+ pearl.ownerUUID = null;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void onTrackingStart(Entity entity) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/Projectile.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Projectile extends Entity implements TraceableEntity {
|
||||
if (nbt.hasUUID("Owner")) {
|
||||
this.ownerUUID = nbt.getUUID("Owner");
|
||||
this.cachedOwner = null;
|
||||
+ if (this instanceof ThrownEnderpearl && this.level() != null && this.level().paperConfig().fixes.disableUnloadedChunkEnderpearlExploit) { this.ownerUUID = null; } // Paper - Don't store shooter name for pearls to block enderpearl travel exploit
|
||||
}
|
||||
|
||||
this.leftOwner = nbt.getBoolean("LeftOwner");
|
||||
@@ -1,23 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Sun, 2 Jul 2017 21:35:56 -0500
|
||||
Subject: [PATCH] Block player logins during server shutdown
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
+ // Paper start - Do not allow logins while the server is shutting down
|
||||
+ if (!MinecraftServer.getServer().isRunning()) {
|
||||
+ this.disconnect(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(org.spigotmc.SpigotConfig.restartMessage)[0]);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
|
||||
this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile));
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 29 Jul 2018 05:02:15 +0100
|
||||
Subject: [PATCH] Break up and make tab spam limits configurable
|
||||
|
||||
Due to the changes in 1.13, clients will send a tab completion request
|
||||
for all bukkit commands in order to factor in the lack of support for
|
||||
brigadier and provide backwards support in the API.
|
||||
|
||||
Craftbukkit, however; has moved the chat spam limiter to also interact
|
||||
with the tab completion request, which while good for avoiding abuse,
|
||||
causes 1.13 clients to easilly be kicked from a server in bukkit due
|
||||
to this. Removing the spam limit could cause issues for servers, however,
|
||||
there is no way for servers to manipulate this without blindly cancelling
|
||||
kick events, which only causes additional complications. This also causes
|
||||
issues in that the tab spam limit and chat share the same field but different
|
||||
limits, meaning that a player having typed a long command may be kicked from
|
||||
the server.
|
||||
|
||||
Splitting the field up and making it configurable allows for server owners
|
||||
to take the burden of this into their own hand without having to rely on
|
||||
plugins doing unsafe things.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
private int ackBlockChangesUpTo = -1;
|
||||
// CraftBukkit start - multithreaded fields
|
||||
private final AtomicInteger chatSpamTickCount = new AtomicInteger();
|
||||
+ private final java.util.concurrent.atomic.AtomicInteger tabSpamLimiter = new java.util.concurrent.atomic.AtomicInteger(); // Paper - configurable tab spam limits
|
||||
// CraftBukkit end
|
||||
private int dropSpamTickCount;
|
||||
private double firstGoodX;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.keepConnectionAlive();
|
||||
// CraftBukkit start
|
||||
for (int spam; (spam = this.chatSpamTickCount.get()) > 0 && !this.chatSpamTickCount.compareAndSet(spam, spam - 1); ) ;
|
||||
+ if (tabSpamLimiter.get() > 0) tabSpamLimiter.getAndDecrement(); // Paper - split to seperate variable
|
||||
/* Use thread-safe field access instead
|
||||
if (this.chatSpamTickCount > 0) {
|
||||
--this.chatSpamTickCount;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
public void handleCustomCommandSuggestions(ServerboundCommandSuggestionPacket packet) {
|
||||
// PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel()); // Paper - run this async
|
||||
// CraftBukkit start
|
||||
- if (this.chatSpamTickCount.addAndGet(1) > 500 && !this.server.getPlayerList().isOp(this.player.getGameProfile())) {
|
||||
+ if (this.chatSpamTickCount.addAndGet(io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamIncrement) > io.papermc.paper.configuration.GlobalConfiguration.get().spamLimiter.tabSpamLimit && !this.server.getPlayerList().isOp(this.player.getGameProfile())) { // Paper start - split and make configurable
|
||||
server.scheduleOnMain(() -> this.disconnect(Component.translatable("disconnect.spam", new Object[0]))); // Paper
|
||||
return;
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 19:30:51 +0200
|
||||
Subject: [PATCH] Call PaperServerListPingEvent for legacy pings
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperLegacyStatusClient.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
+import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
|
||||
+import net.minecraft.ChatFormatting;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.apache.commons.lang3.StringUtils;
|
||||
+
|
||||
+import java.net.InetSocketAddress;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+public final class PaperLegacyStatusClient implements StatusClient {
|
||||
+
|
||||
+ private final InetSocketAddress address;
|
||||
+ private final int protocolVersion;
|
||||
+ @Nullable private final InetSocketAddress virtualHost;
|
||||
+
|
||||
+ private PaperLegacyStatusClient(InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
|
||||
+ this.address = address;
|
||||
+ this.protocolVersion = protocolVersion;
|
||||
+ this.virtualHost = virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getAddress() {
|
||||
+ return this.address;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ return this.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ return this.virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isLegacy() {
|
||||
+ return true;
|
||||
+ }
|
||||
+
|
||||
+ public static PaperServerListPingEvent processRequest(MinecraftServer server,
|
||||
+ InetSocketAddress address, int protocolVersion, @Nullable InetSocketAddress virtualHost) {
|
||||
+
|
||||
+ PaperServerListPingEvent event = new PaperServerListPingEventImpl(server,
|
||||
+ new PaperLegacyStatusClient(address, protocolVersion, virtualHost), Byte.MAX_VALUE, null);
|
||||
+ server.server.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ if (event.isCancelled()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ return event;
|
||||
+ }
|
||||
+
|
||||
+ @SuppressWarnings("deprecation") // Valid as this is the legacy status client
|
||||
+ public static String getMotd(PaperServerListPingEvent event) {
|
||||
+ return getFirstLine(event.getMotd());
|
||||
+ }
|
||||
+
|
||||
+ public static String getUnformattedMotd(PaperServerListPingEvent event) {
|
||||
+ // Strip color codes and all other occurrences of the color char (because it's used as delimiter)
|
||||
+ return getFirstLine(StringUtils.remove(PlainTextComponentSerializer.plainText().serialize(event.motd()), ChatFormatting.PREFIX_CODE));
|
||||
+ }
|
||||
+
|
||||
+ private static String getFirstLine(String s) {
|
||||
+ int pos = s.indexOf('\n');
|
||||
+ return pos >= 0 ? s.substring(0, pos) : s;
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
SocketAddress socketaddress = channelhandlercontext.channel().remoteAddress();
|
||||
int i = bytebuf.readableBytes();
|
||||
String s = null; // Paper
|
||||
- org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(socketaddress, this.server.getMotd(), this.server.getPlayerCount(), this.server.getMaxPlayers()); // CraftBukkit
|
||||
+ // org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(socketaddress, this.server.getMotd(), this.server.getPlayerCount(), this.server.getMaxPlayers()); // CraftBukkit // Paper
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event; // Paper
|
||||
|
||||
if (i == 0) {
|
||||
LegacyQueryHandler.LOGGER.debug("Ping: (<1.3.x) from {}", socketaddress);
|
||||
- s = LegacyQueryHandler.createVersion0Response(this.server, event); // CraftBukkit
|
||||
+
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketaddress, 39, null);
|
||||
+ if (event == null) {
|
||||
+ channelhandlercontext.close();
|
||||
+ bytebuf.release();
|
||||
+ flag = false;
|
||||
+ return;
|
||||
+ }
|
||||
+ s = String.format(Locale.ROOT, "%s\u00a7%d\u00a7%d", com.destroystokyo.paper.network.PaperLegacyStatusClient.getUnformattedMotd(event), event.getNumPlayers(), event.getMaxPlayers());
|
||||
+ // Paper end
|
||||
LegacyQueryHandler.sendFlushAndClose(channelhandlercontext, LegacyQueryHandler.createLegacyDisconnectPacket(channelhandlercontext.alloc(), s));
|
||||
} else {
|
||||
if (bytebuf.readUnsignedByte() != 1) {
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", socketaddress);
|
||||
}
|
||||
|
||||
- if (s == null) s = LegacyQueryHandler.createVersion1Response(this.server, event); // CraftBukkit // Paper
|
||||
+ if (s == null) {
|
||||
+ // Paper start - Call PaperServerListPingEvent and use results
|
||||
+ event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(net.minecraft.server.MinecraftServer.getServer(), (java.net.InetSocketAddress) socketaddress, 127, null); // Paper
|
||||
+ if (event == null) {
|
||||
+ channelhandlercontext.close();
|
||||
+ bytebuf.release();
|
||||
+ flag = false;
|
||||
+ return;
|
||||
+ }
|
||||
+ s = String.format(Locale.ROOT, "\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", new Object[] { event.getProtocolVersion(), this.server.getServerVersion(), event.getMotd(), event.getNumPlayers(), event.getMaxPlayers()}); // CraftBukkit
|
||||
+ // Paper end
|
||||
+ }
|
||||
LegacyQueryHandler.sendFlushAndClose(channelhandlercontext, LegacyQueryHandler.createLegacyDisconnectPacket(channelhandlercontext.alloc(), s));
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
|
||||
- String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
|
||||
- Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
|
||||
+ java.net.InetSocketAddress virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(host, port);
|
||||
+ com.destroystokyo.paper.event.server.PaperServerListPingEvent event = com.destroystokyo.paper.network.PaperLegacyStatusClient.processRequest(
|
||||
+ server, (java.net.InetSocketAddress) ctx.channel().remoteAddress(), protocolVersion, virtualHost);
|
||||
+ if (event == null) {
|
||||
+ ctx.close();
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d", event.getProtocolVersion(), event.getVersion(),
|
||||
+ com.destroystokyo.paper.network.PaperLegacyStatusClient.getMotd(event), event.getNumPlayers(), event.getMaxPlayers());
|
||||
return response;
|
||||
}
|
||||
|
||||
@@ -1,78 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 00:30:32 -0400
|
||||
Subject: [PATCH] Configurable Alternative LootPool Luck Formula
|
||||
|
||||
Rewrites the Vanilla luck application formula so that luck can be
|
||||
applied to items that do not have any quality defined.
|
||||
|
||||
See: https://luckformula.emc.gs for data and details
|
||||
-----------
|
||||
|
||||
The rough summary is:
|
||||
My goal was that in a pool, when luck was applied, the pool
|
||||
rebalances so the percentages for bigger items is
|
||||
lowered and smaller items is boosted.
|
||||
|
||||
Do this by boosting and then reducing the weight value,
|
||||
so that larger numbers are penalized more than smaller numbers.
|
||||
resulting in a larger reduction of entries for more common
|
||||
items than the reduction on small weights,
|
||||
giving smaller weights more of a chance
|
||||
|
||||
-----------
|
||||
|
||||
This work kind of obsoletes quality, but quality would be useful
|
||||
for 2 items with same weight that you want luck to impact
|
||||
in varying directions.
|
||||
|
||||
Fishing still falls into that as the weights are closer, so luck
|
||||
will invalidate junk more.
|
||||
|
||||
This change will result in some major changes to fishing formulas.
|
||||
|
||||
-----------
|
||||
|
||||
I would love to see this change in Vanilla, so Mojang please pull :)
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/loot/entries/LootPoolSingletonContainer.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LootPoolSingletonContainer extends LootPoolEntryContainer
|
||||
protected abstract class EntryBase implements LootPoolEntry {
|
||||
@Override
|
||||
public int getWeight(float luck) {
|
||||
- return Math.max(Mth.floor((float)LootPoolSingletonContainer.this.weight + (float)LootPoolSingletonContainer.this.quality * luck), 0);
|
||||
+ // Paper start - Offer an alternative loot formula to refactor how luck bonus applies
|
||||
+ // SEE: https://luckformula.emc.gs for details and data
|
||||
+ if (LootPoolSingletonContainer.this.lastLuck != null && LootPoolSingletonContainer.this.lastLuck == luck) {
|
||||
+ return lastWeight;
|
||||
+ }
|
||||
+ // This is vanilla
|
||||
+ float qualityModifer = (float) LootPoolSingletonContainer.this.quality * luck;
|
||||
+ double baseWeight = (LootPoolSingletonContainer.this.weight + qualityModifer);
|
||||
+ if (io.papermc.paper.configuration.GlobalConfiguration.get().misc.useAlternativeLuckFormula) {
|
||||
+ // Random boost to avoid losing precision in the final int cast on return
|
||||
+ final int weightBoost = 100;
|
||||
+ baseWeight *= weightBoost;
|
||||
+ // If we have vanilla 1, bump that down to 0 so nothing is is impacted
|
||||
+ // vanilla 3 = 300, 200 basis = impact 2%
|
||||
+ // =($B2*(($B2-100)/100/100))
|
||||
+ double impacted = baseWeight * ((baseWeight - weightBoost) / weightBoost / 100);
|
||||
+ // =($B$7/100)
|
||||
+ float luckModifier = Math.min(100, luck * 10) / 100;
|
||||
+ // =B2 - (C2 *($B$7/100))
|
||||
+ baseWeight = Math.ceil(baseWeight - (impacted * luckModifier));
|
||||
+ }
|
||||
+ LootPoolSingletonContainer.this.lastLuck = luck;
|
||||
+ LootPoolSingletonContainer.this.lastWeight = (int) Math.max(Math.floor(baseWeight), 0);
|
||||
+ return lastWeight;
|
||||
}
|
||||
}
|
||||
+ private Float lastLuck = null;
|
||||
+ private int lastWeight = 0;
|
||||
+ // Paper end
|
||||
|
||||
@FunctionalInterface
|
||||
protected interface EntryConstructor {
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Byteflux <byte@byteflux.net>
|
||||
Date: Wed, 8 Aug 2018 16:33:21 -0600
|
||||
Subject: [PATCH] Configurable speed for water flowing over lava
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/LiquidBlock.java
|
||||
@@ -0,0 +0,0 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void onPlace(BlockState state, Level world, BlockPos pos, BlockState oldState, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - Get flow speed. Throttle if its water and flowing adjacent to lava
|
||||
+ public int getFlowSpeed(Level world, BlockPos blockposition) {
|
||||
+ if (net.minecraft.core.registries.BuiltInRegistries.FLUID.wrapAsHolder(this.fluid).is(FluidTags.WATER)) {
|
||||
+ if (
|
||||
+ isLava(world, blockposition.north(1)) ||
|
||||
+ isLava(world, blockposition.south(1)) ||
|
||||
+ isLava(world, blockposition.west(1)) ||
|
||||
+ isLava(world, blockposition.east(1))
|
||||
+ ) {
|
||||
+ return world.paperConfig().environment.waterOverLavaFlowSpeed;
|
||||
+ }
|
||||
+ }
|
||||
+ return this.fluid.getTickDelay(world);
|
||||
+ }
|
||||
+ private static boolean isLava(Level world, BlockPos blockPos) {
|
||||
+ final FluidState fluidState = world.getFluidIfLoaded(blockPos);
|
||||
+ return fluidState != null && fluidState.is(FluidTags.LAVA);
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public BlockState updateShape(BlockState state, Direction direction, BlockState neighborState, LevelAccessor world, BlockPos pos, BlockPos neighborPos) {
|
||||
if (state.getFluidState().isSource() || neighborState.getFluidState().isSource()) {
|
||||
@@ -0,0 +0,0 @@ public class LiquidBlock extends Block implements BucketPickup {
|
||||
@Override
|
||||
public void neighborChanged(BlockState state, Level world, BlockPos pos, Block sourceBlock, BlockPos sourcePos, boolean notify) {
|
||||
if (this.shouldSpreadLiquid(world, pos, state)) {
|
||||
- world.scheduleTick(pos, state.getFluidState().getType(), this.fluid.getTickDelay(world));
|
||||
+ world.scheduleTick(pos, state.getFluidState().getType(), this.getFlowSpeed(world, pos)); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Sat, 14 Apr 2018 20:20:46 +0200
|
||||
Subject: [PATCH] Configurable sprint interruption on attack
|
||||
|
||||
If the sprint interruption is disabled players continue sprinting when they attack entities.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
- this.setSprinting(false);
|
||||
+ // Paper start - Configuration option to disable automatic sprint interruption
|
||||
+ if (!this.level().paperConfig().misc.disableSprintInterruptionOnAttack) {
|
||||
+ this.setSprinting(false);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
if (flag3) {
|
||||
@@ -1,34 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 11 Mar 2018 14:13:33 -0400
|
||||
Subject: [PATCH] Disable Explicit Network Manager Flushing
|
||||
|
||||
This seems completely pointless, as packet dispatch uses .writeAndFlush.
|
||||
|
||||
Things seem to work fine without explicit flushing, but incase issues arise,
|
||||
provide a System property to re-enable it using improved logic of doing the
|
||||
flushing on the netty event loop, so it won't do the flush on the main thread.
|
||||
|
||||
Renable flushing by passing -Dpaper.explicit-flush=true
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
// Paper start - NetworkClient implementation
|
||||
public int protocolVersion;
|
||||
public java.net.InetSocketAddress virtualHost;
|
||||
+ private static boolean enableExplicitFlush = Boolean.getBoolean("paper.explicit-flush");
|
||||
// Paper end
|
||||
|
||||
// Paper start - add utility methods
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
}
|
||||
|
||||
if (this.channel != null) {
|
||||
- this.channel.flush();
|
||||
+ if (enableExplicitFlush) this.channel.eventLoop().execute(() -> this.channel.flush()); // Paper - we don't need to explicit flush here, but allow opt in incase issues are found to a better version
|
||||
}
|
||||
|
||||
if (this.tickCount++ % 20 == 0) {
|
||||
@@ -1,64 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Thu, 26 Jul 2018 14:10:23 +0200
|
||||
Subject: [PATCH] Don't call getItemMeta on hasItemMeta
|
||||
|
||||
Spigot 1.13 checks if any field (which are manually copied from the ItemStack's "tag" NBT tag) on the ItemMeta class of an ItemStack is set.
|
||||
|
||||
We could just check if the "tag" NBT tag is empty, albeit that would break some plugins. The only general tag added on 1.13 is "Damage", and we can just check if the "tag" NBT tag contains any other tag that's not "Damage" (https://minecraft.wiki/wiki/Player.dat_format#Item_structure) making the `hasItemStack` method behave as before.
|
||||
|
||||
Returns true if getDamage() == 0 or has damage tag or other tag is set.
|
||||
Check the `ItemMetaTest#testTaggedButNotMeta` method to see how this method behaves.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
|
||||
@Override
|
||||
public boolean hasItemMeta() {
|
||||
- return CraftItemStack.hasItemMeta(this.handle) && !CraftItemFactory.instance().equals(this.getItemMeta(), null);
|
||||
+ return CraftItemStack.hasItemMeta(this.handle) && (this.handle.getDamageValue() != 0 || (this.handle.getTag() != null && this.handle.getTag().tags.size() >= (this.handle.getTag().contains(CraftMetaItem.DAMAGE.NBT) ? 2 : 1))); // Paper - keep 1.12 CraftBukkit behavior without calling getItemMeta
|
||||
}
|
||||
|
||||
static boolean hasItemMeta(net.minecraft.world.item.ItemStack item) {
|
||||
diff --git a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
+++ b/src/test/java/org/bukkit/craftbukkit/inventory/ItemMetaTest.java
|
||||
@@ -0,0 +0,0 @@ public class ItemMetaTest extends AbstractTestingBase {
|
||||
assertThat(itemMeta.hasConflictingEnchant(null), is(false));
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private void testItemMeta(ItemStack stack) {
|
||||
+ assertThat(stack.hasItemMeta(), is(false), "Should not have ItemMeta");
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat(stack.hasItemMeta(), is(false), "ItemStack with zero durability should not have ItemMeta");
|
||||
+
|
||||
+ stack.setDurability((short) 2);
|
||||
+ assertThat(stack.hasItemMeta(), is(true), "ItemStack with non-zero durability should have ItemMeta");
|
||||
+
|
||||
+ stack.setLore(java.util.Collections.singletonList("Lore"));
|
||||
+ assertThat(stack.hasItemMeta(), is(true), "ItemStack with lore and durability should have ItemMeta");
|
||||
+
|
||||
+ stack.setDurability((short) 0);
|
||||
+ assertThat(stack.hasItemMeta(), is(true), "ItemStack with lore should have ItemMeta");
|
||||
+
|
||||
+ stack.setLore(null);
|
||||
+ }
|
||||
+
|
||||
+ @Test
|
||||
+ public void testHasItemMeta() {
|
||||
+ ItemStack itemStack = new ItemStack(Material.SHEARS);
|
||||
+
|
||||
+ testItemMeta(itemStack);
|
||||
+ testItemMeta(CraftItemStack.asCraftCopy(itemStack));
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Test
|
||||
public void testConflictingStoredEnchantment() {
|
||||
EnchantmentStorageMeta itemMeta = (EnchantmentStorageMeta) Bukkit.getItemFactory().getItemMeta(Material.ENCHANTED_BOOK);
|
||||
@@ -1,53 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:51:27 -0500
|
||||
Subject: [PATCH] EnderDragon Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonSittingFlamingPhase.java
|
||||
@@ -0,0 +0,0 @@ public class DragonSittingFlamingPhase extends AbstractDragonSittingPhase {
|
||||
this.flame.setDuration(200);
|
||||
this.flame.setParticle(ParticleTypes.DRAGON_BREATH);
|
||||
this.flame.addEffect(new MobEffectInstance(MobEffects.HARM));
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFlameEvent((org.bukkit.entity.EnderDragon) this.dragon.getBukkitEntity(), (org.bukkit.entity.AreaEffectCloud) this.flame.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.dragon.level().addFreshEntity(this.flame);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.end();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/phases/DragonStrafePlayerPhase.java
|
||||
@@ -0,0 +0,0 @@ public class DragonStrafePlayerPhase extends AbstractDragonPhaseInstance {
|
||||
|
||||
DragonFireball dragonFireball = new DragonFireball(this.dragon.level(), this.dragon, r, s, t);
|
||||
dragonFireball.moveTo(o, p, q, 0.0F, 0.0F);
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonShootFireballEvent((org.bukkit.entity.EnderDragon) dragon.getBukkitEntity(), (org.bukkit.entity.DragonFireball) dragonFireball.getBukkitEntity()).callEvent()) // Paper
|
||||
this.dragon.level().addFreshEntity(dragonFireball);
|
||||
+ else dragonFireball.discard(); // Paper
|
||||
this.fireballCharge = 0;
|
||||
if (this.currentPath != null) {
|
||||
while(!this.currentPath.isDone()) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/DragonFireball.java
|
||||
@@ -0,0 +0,0 @@ public class DragonFireball extends AbstractHurtingProjectile {
|
||||
}
|
||||
}
|
||||
|
||||
+ if (new com.destroystokyo.paper.event.entity.EnderDragonFireballHitEvent((org.bukkit.entity.DragonFireball) this.getBukkitEntity(), list.stream().map(LivingEntity::getBukkitLivingEntity).collect(java.util.stream.Collectors.toList()), (org.bukkit.entity.AreaEffectCloud) areaEffectCloud.getBukkitEntity()).callEvent()) { // Paper
|
||||
this.level().levelEvent(2006, this.blockPosition(), this.isSilent() ? -1 : 1);
|
||||
this.level().addFreshEntity(areaEffectCloud);
|
||||
+ } else areaEffectCloud.discard(); // Paper
|
||||
this.discard();
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:29:44 -0400
|
||||
Subject: [PATCH] Enderman.teleportRandomly()
|
||||
|
||||
Ability to trigger the vanilla "teleport randomly" mechanic of an enderman.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEnderman extends CraftMonster implements Enderman {
|
||||
super(server, entity);
|
||||
}
|
||||
|
||||
+ @Override public boolean teleportRandomly() { return getHandle().teleport(); } // Paper
|
||||
@Override
|
||||
public MaterialData getCarriedMaterial() {
|
||||
BlockState blockData = this.getHandle().getCarriedBlock();
|
||||
@@ -1,30 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 1 May 2018 20:18:54 -0400
|
||||
Subject: [PATCH] EndermanAttackPlayerEvent
|
||||
|
||||
Allow control over whether or not an enderman aggros a player.
|
||||
|
||||
This allows you to override/extend the pumpkin/stare logic.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
this.readPersistentAngerSaveData(this.level(), nbt);
|
||||
}
|
||||
|
||||
- boolean isLookingAtMe(Player player) {
|
||||
+ // Paper start - EndermanAttackPlayerEvent
|
||||
+ private boolean isLookingAtMe(Player player) {
|
||||
+ boolean shouldAttack = isLookingAtMe_check(player);
|
||||
+ com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent event = new com.destroystokyo.paper.event.entity.EndermanAttackPlayerEvent((org.bukkit.entity.Enderman) getBukkitEntity(), (org.bukkit.entity.Player) player.getBukkitEntity());
|
||||
+ event.setCancelled(!shouldAttack);
|
||||
+ return event.callEvent();
|
||||
+ }
|
||||
+ private boolean isLookingAtMe_check(Player player) {
|
||||
+ // Paper end
|
||||
ItemStack itemstack = (ItemStack) player.getInventory().armor.get(3);
|
||||
|
||||
if (itemstack.is(Blocks.CARVED_PUMPKIN.asItem())) {
|
||||
@@ -1,58 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 30 Apr 2018 13:15:55 -0400
|
||||
Subject: [PATCH] EndermanEscapeEvent
|
||||
|
||||
Fires an event anytime an enderman intends to teleport away from the player
|
||||
|
||||
You may cancel this, enabling ranged attacks to damage the enderman for example.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/EnderMan.java
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
this.setTarget(target, EntityTargetEvent.TargetReason.UNKNOWN, true);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private boolean tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason reason) {
|
||||
+ return new com.destroystokyo.paper.event.entity.EndermanEscapeEvent((org.bukkit.craftbukkit.entity.CraftEnderman) this.getBukkitEntity(), reason).callEvent();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean setTarget(LivingEntity entityliving, EntityTargetEvent.TargetReason reason, boolean fireEvent) {
|
||||
if (!super.setTarget(entityliving, reason, fireEvent)) {
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
if (this.level().isDay() && this.tickCount >= this.targetChangeTime + 600) {
|
||||
float f = this.getLightLevelDependentMagicValue();
|
||||
|
||||
- if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F) {
|
||||
+ if (f > 0.5F && this.level().canSeeSky(this.blockPosition()) && this.random.nextFloat() * 30.0F < (f - 0.4F) * 2.0F && this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.RUNAWAY)) { // Paper
|
||||
this.setTarget((LivingEntity) null);
|
||||
this.teleport();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
} else {
|
||||
flag1 = flag && this.hurtWithCleanWater(source, (ThrownPotion) source.getDirectEntity(), amount);
|
||||
|
||||
+ if (this.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.INDIRECT)) { // Paper start
|
||||
for (int i = 0; i < 64; ++i) {
|
||||
if (this.teleport()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+ } // Paper end
|
||||
|
||||
return flag1;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class EnderMan extends Monster implements NeutralMob {
|
||||
} else {
|
||||
if (this.target != null && !this.enderman.isPassenger()) {
|
||||
if (this.enderman.isLookingAtMe((Player) this.target)) {
|
||||
- if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D) {
|
||||
+ if (this.target.distanceToSqr((Entity) this.enderman) < 16.0D && this.enderman.tryEscape(com.destroystokyo.paper.event.entity.EndermanEscapeEvent.Reason.STARE)) { // Paper
|
||||
this.enderman.teleport();
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sun, 18 Jun 2017 18:17:05 -0500
|
||||
Subject: [PATCH] Entity#fromMobSpawner()
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
// Spigot end
|
||||
// Paper start
|
||||
protected int numCollisions = 0; // Paper
|
||||
+ public boolean spawnedViaMobSpawner; // Paper - Yes this name is similar to above, upstream took the better one
|
||||
@javax.annotation.Nullable
|
||||
private org.bukkit.util.Vector origin;
|
||||
@javax.annotation.Nullable
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
nbt.put("Paper.Origin", this.newDoubleList(origin.getX(), origin.getY(), origin.getZ()));
|
||||
}
|
||||
+ // Save entity's from mob spawner status
|
||||
+ if (spawnedViaMobSpawner) {
|
||||
+ nbt.putBoolean("Paper.FromMobSpawner", true);
|
||||
+ }
|
||||
// Paper end
|
||||
return nbt;
|
||||
} catch (Throwable throwable) {
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
this.originWorld = originWorld;
|
||||
origin = new org.bukkit.util.Vector(originTag.getDouble(0), originTag.getDouble(1), originTag.getDouble(2));
|
||||
}
|
||||
+
|
||||
+ spawnedViaMobSpawner = nbt.getBoolean("Paper.FromMobSpawner"); // Restore entity's from mob spawner status
|
||||
// Paper end
|
||||
|
||||
} catch (Throwable throwable) {
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
// Spigot End
|
||||
}
|
||||
|
||||
+ entity.spawnedViaMobSpawner = true; // Paper
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
||||
continue;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
//noinspection ConstantConditions
|
||||
return originVector.toLocation(world);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean fromMobSpawner() {
|
||||
+ return getHandle().spawnedViaMobSpawner;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 20 Jun 2018 23:17:24 -0400
|
||||
Subject: [PATCH] Expand Explosions API
|
||||
|
||||
Add Entity as a Source capability, and add more API choices, and on Location.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
public boolean createExplosion(double x, double y, double z, float power, boolean setFire, boolean breakBlocks, Entity source) {
|
||||
return !this.world.explode(source == null ? null : ((CraftEntity) source).getHandle(), x, y, z, power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled;
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean createExplosion(Entity source, Location loc, float power, boolean setFire, boolean breakBlocks) {
|
||||
+ return !world.explode(source != null ? ((org.bukkit.craftbukkit.entity.CraftEntity) source).getHandle() : null, loc.getX(), loc.getY(), loc.getZ(), power, setFire, breakBlocks ? net.minecraft.world.level.Level.ExplosionInteraction.MOB : net.minecraft.world.level.Level.ExplosionInteraction.NONE).wasCanceled;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean createExplosion(Location loc, float power) {
|
||||
@@ -1,61 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 15 Aug 2017 22:29:12 -0400
|
||||
Subject: [PATCH] Expand World.spawnParticle API and add Builder
|
||||
|
||||
Adds ability to control who receives it and who is the source/sender (vanish API)
|
||||
the standard API is to send the packet to everyone in the world, which is ineffecient.
|
||||
Adds an option to control the force mode of the particle.
|
||||
|
||||
This adds a new Builder API which is much friendlier to use.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
}
|
||||
|
||||
public <T extends ParticleOptions> int sendParticles(ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
|
||||
+ // Paper start - Particle API Expansion
|
||||
+ return sendParticles(players, sender, t0, d0, d1, d2, i, d3, d4, d5, d6, force);
|
||||
+ }
|
||||
+ public <T extends ParticleOptions> int sendParticles(List<ServerPlayer> receivers, @Nullable ServerPlayer sender, T t0, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6, boolean force) {
|
||||
+ // Paper end
|
||||
ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(t0, force, d0, d1, d2, (float) d3, (float) d4, (float) d5, (float) d6, i);
|
||||
// CraftBukkit end
|
||||
int j = 0;
|
||||
|
||||
- for (int k = 0; k < this.players.size(); ++k) {
|
||||
- ServerPlayer entityplayer = (ServerPlayer) this.players.get(k);
|
||||
+ for (Player entityhuman : receivers) { // Paper - Particle API Expansion
|
||||
+ ServerPlayer entityplayer = (ServerPlayer) entityhuman; // Paper - Particle API Expansion
|
||||
if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit
|
||||
|
||||
if (this.sendParticles(entityplayer, force, d0, d1, d2, packetplayoutworldparticles)) { // CraftBukkit
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
|
||||
@Override
|
||||
public <T> void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
||||
+ // Paper start - Particle API Expansion
|
||||
+ spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, force);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public <T> void spawnParticle(Particle particle, List<Player> receivers, Player sender, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) {
|
||||
+ // Paper end
|
||||
particle = CraftParticle.convertLegacy(particle);
|
||||
data = CraftParticle.convertLegacy(data);
|
||||
if (data != null) {
|
||||
Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType());
|
||||
}
|
||||
this.getHandle().sendParticles(
|
||||
- null, // Sender
|
||||
+ receivers == null ? getHandle().players() : receivers.stream().map(player -> ((CraftPlayer) player).getHandle()).collect(java.util.stream.Collectors.toList()), // Paper - Particle API Expansion
|
||||
+ sender != null ? ((CraftPlayer) sender).getHandle() : null, // Sender // Paper - Particle API Expansion
|
||||
CraftParticle.createParticleParam(particle, data), // Particle
|
||||
x, y, z, // Position
|
||||
count, // Count
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Tue, 4 Sep 2018 15:02:00 -0500
|
||||
Subject: [PATCH] Expose attack cooldown methods for Player
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
return this.adventure$pointers;
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public float getCooldownPeriod() {
|
||||
+ return getHandle().getCurrentItemAttackStrengthDelay();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public float getCooledAttackStrength(float adjustTicks) {
|
||||
+ return getHandle().getAttackStrengthScale(adjustTicks);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void resetCooldown() {
|
||||
+ getHandle().resetAttackStrengthTicker();
|
||||
+ }
|
||||
// Paper end
|
||||
// Spigot start
|
||||
private final Player.Spigot spigot = new Player.Spigot()
|
||||
@@ -1,116 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Tue, 10 Oct 2017 18:45:20 +0200
|
||||
Subject: [PATCH] Expose client protocol version and virtual host
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java b/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperNetworkClient.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import java.net.InetSocketAddress;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.minecraft.network.Connection;
|
||||
+
|
||||
+public class PaperNetworkClient implements NetworkClient {
|
||||
+
|
||||
+ private final Connection networkManager;
|
||||
+
|
||||
+ PaperNetworkClient(Connection networkManager) {
|
||||
+ this.networkManager = networkManager;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getAddress() {
|
||||
+ return (InetSocketAddress) this.networkManager.getRemoteAddress();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ return this.networkManager.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ return this.networkManager.virtualHost;
|
||||
+ }
|
||||
+
|
||||
+ public static InetSocketAddress prepareVirtualHost(String host, int port) {
|
||||
+ int len = host.length();
|
||||
+
|
||||
+ // FML appends a marker to the host to recognize FML clients (\0FML\0)
|
||||
+ int pos = host.indexOf('\0');
|
||||
+ if (pos >= 0) {
|
||||
+ len = pos;
|
||||
+ }
|
||||
+
|
||||
+ // When clients connect with a SRV record, their host contains a trailing '.'
|
||||
+ if (len > 0 && host.charAt(len - 1) == '.') {
|
||||
+ len--;
|
||||
+ }
|
||||
+
|
||||
+ return InetSocketAddress.createUnresolved(host.substring(0, len), port);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/network/Connection.java b/src/main/java/net/minecraft/network/Connection.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/Connection.java
|
||||
+++ b/src/main/java/net/minecraft/network/Connection.java
|
||||
@@ -0,0 +0,0 @@ public class Connection extends SimpleChannelInboundHandler<Packet<?>> {
|
||||
@Nullable
|
||||
BandwidthDebugMonitor bandwidthDebugMonitor;
|
||||
public String hostname = ""; // CraftBukkit - add field
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ public int protocolVersion;
|
||||
+ public java.net.InetSocketAddress virtualHost;
|
||||
+ // Paper end
|
||||
|
||||
// Paper start - add utility methods
|
||||
public final net.minecraft.server.level.ServerPlayer getPlayer() {
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
|
||||
throw new UnsupportedOperationException("Invalid intention " + packet.intention());
|
||||
}
|
||||
|
||||
+ // Paper start - NetworkClient implementation
|
||||
+ this.connection.protocolVersion = packet.protocolVersion();
|
||||
+ this.connection.virtualHost = com.destroystokyo.paper.network.PaperNetworkClient.prepareVirtualHost(packet.hostName(), packet.port());
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start - Implement NetworkClient
|
||||
+ @Override
|
||||
+ public int getProtocolVersion() {
|
||||
+ if (getHandle().connection == null) return -1;
|
||||
+ return getHandle().connection.connection.protocolVersion;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public InetSocketAddress getVirtualHost() {
|
||||
+ if (getHandle().connection == null) return null;
|
||||
+ return getHandle().connection.connection.virtualHost;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public double getEyeHeight(boolean ignorePose) {
|
||||
if (ignorePose) {
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sun, 11 Feb 2018 10:43:46 +0000
|
||||
Subject: [PATCH] Extend Player Interact cancellation
|
||||
|
||||
GUIs are opened on the client, meaning that the server cannot block them from opening,
|
||||
However, it is possible to close these GUIs from the server.
|
||||
|
||||
Flower pots are also not updated on the client when interaction is cancelled, this patch
|
||||
also resolves this.
|
||||
|
||||
Update adjacent blocks of doors, double plants, pistons and beds
|
||||
when cancelling interaction.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayerGameMode.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayerGameMode {
|
||||
|
||||
// send a correcting update to the client for the block above as well, this because of replaceable blocks (such as grass, sea grass etc)
|
||||
player.connection.send(new ClientboundBlockUpdatePacket(world, blockposition.above()));
|
||||
+ // Paper start - extend Player Interact cancellation // TODO: consider merging this into the extracted method
|
||||
+ } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.StructureBlock) {
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId));
|
||||
+ } else if (iblockdata.getBlock() instanceof net.minecraft.world.level.block.CommandBlock) {
|
||||
+ player.connection.send(new net.minecraft.network.protocol.game.ClientboundContainerClosePacket(this.player.containerMenu.containerId));
|
||||
}
|
||||
+ // Paper end - extend Player Interact cancellation
|
||||
player.getBukkitEntity().updateInventory(); // SPIGOT-2867
|
||||
enuminteractionresult = (event.useItemInHand() != Event.Result.ALLOW) ? InteractionResult.SUCCESS : InteractionResult.PASS;
|
||||
} else if (this.gameModeForPlayer == GameType.SPECTATOR) {
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 2 Jan 2018 00:31:26 -0500
|
||||
Subject: [PATCH] Fill Profile Property Events
|
||||
|
||||
Allows plugins to populate profile properties from local sources to avoid calls out to Mojang API
|
||||
to fill in textures for example.
|
||||
|
||||
If Mojang API does need to be hit, event fire so you can get the results.
|
||||
|
||||
This is useful for implementing a ProfileCache for Player Skulls
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperMinecraftSessionService.java
|
||||
@@ -0,0 +0,0 @@ public class PaperMinecraftSessionService extends YggdrasilMinecraftSessionServi
|
||||
return super.getTextures(profile, requireSecure);
|
||||
}
|
||||
|
||||
- @Override
|
||||
+ public @Nullable ProfileResult fetchProfile(GameProfile profile, final boolean requireSecure) {
|
||||
+ CraftPlayerProfile playerProfile = (CraftPlayerProfile) CraftPlayerProfile.asBukkitMirror(profile);
|
||||
+ new com.destroystokyo.paper.event.profile.PreFillProfileEvent(playerProfile).callEvent();
|
||||
+ profile = playerProfile.getGameProfile();
|
||||
+ if (profile.getProperties().containsKey("textures")) {
|
||||
+ return new ProfileResult(profile, java.util.Collections.emptySet());
|
||||
+ }
|
||||
+ ProfileResult result = super.fetchProfile(profile.getId(), requireSecure);
|
||||
+ if (result != null) {
|
||||
+ new com.destroystokyo.paper.event.profile.FillProfileEvent(CraftPlayerProfile.asBukkitMirror(result.profile())).callEvent();
|
||||
+ }
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ @Override @io.papermc.paper.annotation.DoNotUse @Deprecated
|
||||
public @Nullable ProfileResult fetchProfile(final UUID profileId, final boolean requireSecure) {
|
||||
return super.fetchProfile(profileId, requireSecure);
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SkullBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SkullBlockEntity extends BlockEntity {
|
||||
MinecraftSessionService minecraftsessionservice = SkullBlockEntity.sessionService;
|
||||
|
||||
if (minecraftsessionservice != null) {
|
||||
- ProfileResult profileresult = minecraftsessionservice.fetchProfile(profile.getId(), true);
|
||||
+ ProfileResult profileresult = minecraftsessionservice instanceof com.destroystokyo.paper.profile.PaperMinecraftSessionService paperMinecraftSessionService ? paperMinecraftSessionService.fetchProfile(profile, true) : minecraftsessionservice.fetchProfile(profile.getId(), true); // Paper
|
||||
|
||||
return profileresult == null ? Optional.of(profile) : Optional.of(profileresult.profile());
|
||||
} else {
|
||||
@@ -1,46 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 20:20:15 -0400
|
||||
Subject: [PATCH] Fix CraftEntity hashCode
|
||||
|
||||
hashCodes are not allowed to change, however bukkit used a value
|
||||
that does change, the entityId.
|
||||
|
||||
When an entity is teleported dimensions, the entity reference is
|
||||
replaced with a new one with a new entity ID.
|
||||
|
||||
For hashCode, we can simply use the UUID's hashCode to keep
|
||||
the hashCode from changing.
|
||||
|
||||
equals() is ok to use getEntityId() because equals() should only
|
||||
be true if both the left and right are the same reference.
|
||||
|
||||
Since entity ids can not duplicate during runtime, this
|
||||
check is essentially the same as this.getHandle() == other.getHandle()
|
||||
|
||||
However, replaced it too to make it clearer of intent.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
|
||||
return false;
|
||||
}
|
||||
final CraftEntity other = (CraftEntity) obj;
|
||||
- return (this.getEntityId() == other.getEntityId());
|
||||
+ return (this.getHandle() == other.getHandle()); // Paper - while logically the same, this is clearer
|
||||
}
|
||||
|
||||
+ // Paper - Fix hashCode. entity ID's are not static.
|
||||
+ // A CraftEntity can change reference to a new entity with a new ID, and hash codes should never change
|
||||
@Override
|
||||
public int hashCode() {
|
||||
- int hash = 7;
|
||||
- hash = 29 * hash + this.getEntityId();
|
||||
- return hash;
|
||||
+ return getUniqueId().hashCode();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: mezz <tehgeek@gmail.com>
|
||||
Date: Wed, 9 Aug 2017 17:51:22 -0500
|
||||
Subject: [PATCH] Fix MC-117075: TE Unload Lag Spike
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Spigot start
|
||||
// Iterator iterator = this.blockEntityTickers.iterator();
|
||||
int tilesThisCycle = 0;
|
||||
+ var toRemove = new it.unimi.dsi.fastutil.objects.ObjectOpenCustomHashSet<TickingBlockEntity>(net.minecraft.Util.identityStrategy()); // Paper - use removeAll
|
||||
+ toRemove.add(null);
|
||||
for (tileTickPosition = 0; tileTickPosition < this.blockEntityTickers.size(); tileTickPosition++) { // Paper - Disable tick limiters
|
||||
this.tileTickPosition = (this.tileTickPosition < this.blockEntityTickers.size()) ? this.tileTickPosition : 0;
|
||||
TickingBlockEntity tickingblockentity = (TickingBlockEntity) this.blockEntityTickers.get(this.tileTickPosition);
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
if (tickingblockentity == null) {
|
||||
this.getCraftServer().getLogger().severe("Spigot has detected a null entity and has removed it, preventing a crash");
|
||||
tilesThisCycle--;
|
||||
- this.blockEntityTickers.remove(this.tileTickPosition--);
|
||||
continue;
|
||||
}
|
||||
// Spigot end
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
if (tickingblockentity.isRemoved()) {
|
||||
// Spigot start
|
||||
tilesThisCycle--;
|
||||
- this.blockEntityTickers.remove(this.tileTickPosition--);
|
||||
+ toRemove.add(tickingblockentity); // Paper - use removeAll
|
||||
// Spigot end
|
||||
} else if (this.shouldTickBlocksAt(tickingblockentity.getPos())) {
|
||||
tickingblockentity.tick();
|
||||
}
|
||||
}
|
||||
+ this.blockEntityTickers.removeAll(toRemove);
|
||||
|
||||
this.timings.tileEntityTick.stopTiming(); // Spigot
|
||||
this.tickingBlockEntities = false;
|
||||
@@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 3 Aug 2018 00:04:54 -0400
|
||||
Subject: [PATCH] Fix NBT type issues
|
||||
|
||||
Addresses two issues:
|
||||
- MC-135506: Experience should save as Integers
|
||||
- Allay duplication cooldown is saved and exposed as a long, but loaded as an int
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
nbt.putShort("Health", (short) this.health);
|
||||
nbt.putShort("Age", (short) this.age);
|
||||
- nbt.putShort("Value", (short) this.value);
|
||||
+ nbt.putInt("Value", this.value); // Paper - save as Integer
|
||||
nbt.putInt("Count", this.count);
|
||||
this.savePaperNBT(nbt); // Paper
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.health = nbt.getShort("Health");
|
||||
this.age = nbt.getShort("Age");
|
||||
- this.value = nbt.getShort("Value");
|
||||
+ this.value = nbt.getInt("Value"); // Paper - load as Integer
|
||||
this.count = Math.max(nbt.getInt("Count"), 1);
|
||||
this.loadPaperNBT(nbt); // Paper
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/allay/Allay.java
|
||||
@@ -0,0 +0,0 @@ public class Allay extends PathfinderMob implements InventoryCarrier, VibrationS
|
||||
});
|
||||
}
|
||||
|
||||
- this.duplicationCooldown = (long) nbt.getInt("DuplicationCooldown");
|
||||
+ this.duplicationCooldown = nbt.getLong("DuplicationCooldown"); // Paper - Load as long
|
||||
this.entityData.set(Allay.DATA_CAN_DUPLICATE, nbt.getBoolean("CanDuplicate"));
|
||||
}
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: 0x22 <0x22@futureclient.net>
|
||||
Date: Thu, 26 Apr 2018 04:41:11 -0400
|
||||
Subject: [PATCH] Fix exploit that allowed colored signs to be created
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/SignBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
|
||||
Style chatmodifier = signtext.getMessage(i, entityhuman.isTextFilteringEnabled()).getStyle();
|
||||
|
||||
if (entityhuman.isTextFilteringEnabled()) {
|
||||
- signtext = signtext.setMessage(i, Component.literal(filteredtext.filteredOrEmpty()).setStyle(chatmodifier));
|
||||
+ signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only
|
||||
} else {
|
||||
- signtext = signtext.setMessage(i, Component.literal(filteredtext.raw()).setStyle(chatmodifier), Component.literal(filteredtext.filteredOrEmpty()).setStyle(chatmodifier));
|
||||
+ signtext = signtext.setMessage(i, Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.raw())).setStyle(chatmodifier), Component.literal(net.minecraft.SharedConstants.filterText(filteredtext.filteredOrEmpty())).setStyle(chatmodifier)); // Paper - filter sign text to chat only
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Kyle Wood <kyle@denwav.dev>
|
||||
Date: Sun, 6 Aug 2017 17:17:53 -0500
|
||||
Subject: [PATCH] Fix this stupid bullshit
|
||||
|
||||
Disable the 15 second sleep when the server jar hasn't been rebuilt within a period of time.
|
||||
|
||||
modified in order to prevent merge conflicts when Spigot changes/disables the warning,
|
||||
and to provide some level of hint without being disruptive.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/Bootstrap.java b/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
+++ b/src/main/java/net/minecraft/server/Bootstrap.java
|
||||
@@ -0,0 +0,0 @@ public class Bootstrap {
|
||||
public static void bootStrap() {
|
||||
if (!Bootstrap.isBootstrapped) {
|
||||
// CraftBukkit start
|
||||
- String name = Bootstrap.class.getSimpleName();
|
||||
+ /*String name = Bootstrap.class.getSimpleName(); // Paper
|
||||
switch (name) {
|
||||
case "DispenserRegistry":
|
||||
break;
|
||||
@@ -0,0 +0,0 @@ public class Bootstrap {
|
||||
System.err.println("*** WARNING: This server jar is unsupported, use at your own risk. ***");
|
||||
System.err.println("**********************************************************************");
|
||||
break;
|
||||
- }
|
||||
+ }*/ // Paper
|
||||
// CraftBukkit end
|
||||
Bootstrap.isBootstrapped = true;
|
||||
Instant instant = Instant.now();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/Main.java b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/Main.java
|
||||
@@ -0,0 +0,0 @@ public class Main {
|
||||
Calendar deadline = Calendar.getInstance();
|
||||
deadline.add(Calendar.DAY_OF_YEAR, -21);
|
||||
if (buildDate.before(deadline.getTime())) {
|
||||
- System.err.println("*** Error, this build is outdated ***");
|
||||
+ // Paper start - This is some stupid bullshit
|
||||
+ System.err.println("*** Warning, you've not updated in a while! ***");
|
||||
System.err.println("*** Please download a new build as per instructions from https://papermc.io/downloads/paper ***"); // Paper
|
||||
- System.err.println("*** Server will start in 20 seconds ***");
|
||||
- Thread.sleep(TimeUnit.SECONDS.toMillis(20));
|
||||
+ //System.err.println("*** Server will start in 20 seconds ***");
|
||||
+ //Thread.sleep(TimeUnit.SECONDS.toMillis(20));
|
||||
+ // Paper End
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 31 Mar 2018 17:04:26 +0100
|
||||
Subject: [PATCH] Flag to disable the channel limit
|
||||
|
||||
In some enviroments, the channel limit set by spigot can cause issues,
|
||||
e.g. servers which allow and support the usage of mod packs.
|
||||
|
||||
provide an optional flag to disable this check, at your own risk.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
// Paper start
|
||||
private org.bukkit.event.player.PlayerResourcePackStatusEvent.Status resourcePackStatus;
|
||||
private String resourcePackHash;
|
||||
+ private static final boolean DISABLE_CHANNEL_LIMIT = System.getProperty("paper.disableChannelLimit") != null; // Paper - add a flag to disable the channel limit
|
||||
// Paper end
|
||||
|
||||
public CraftPlayer(CraftServer server, ServerPlayer entity) {
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
// Paper end
|
||||
|
||||
public void addChannel(String channel) {
|
||||
- Preconditions.checkState(this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel);
|
||||
+ Preconditions.checkState(DISABLE_CHANNEL_LIMIT || this.channels.size() < 128, "Cannot register channel '%s'. Too many channels registered!", channel); // Paper - flag to disable channel limit
|
||||
channel = StandardMessenger.validateAndCorrectChannel(channel);
|
||||
if (this.channels.add(channel)) {
|
||||
this.server.getPluginManager().callEvent(new PlayerRegisterChannelEvent(this, channel));
|
||||
@@ -1,71 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Thu, 21 Sep 2017 16:14:55 +0200
|
||||
Subject: [PATCH] Handle plugin prefixes using Log4J configuration
|
||||
|
||||
Display logger name in the console for all loggers except the
|
||||
root logger, Bukkit's logger ("Minecraft") and Minecraft loggers.
|
||||
Since plugins now use the plugin name as logger name this will
|
||||
restore the plugin prefixes without having to prepend them manually
|
||||
to the log messages.
|
||||
|
||||
Logger prefixes are shown by default for all loggers except for
|
||||
the root logger, the Minecraft/Mojang loggers and the Bukkit loggers.
|
||||
This may cause additional prefixes to be disabled for plugins bypassing
|
||||
the plugin logger.
|
||||
|
||||
diff --git a/build.gradle.kts b/build.gradle.kts
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/build.gradle.kts
|
||||
+++ b/build.gradle.kts
|
||||
@@ -0,0 +0,0 @@ dependencies {
|
||||
all its classes to check if they are plugins.
|
||||
Scanning takes about 1-2 seconds so adding this speeds up the server start.
|
||||
*/
|
||||
- runtimeOnly("org.apache.logging.log4j:log4j-core:2.19.0")
|
||||
+ implementation("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - implementation
|
||||
log4jPlugins.annotationProcessorConfigurationName("org.apache.logging.log4j:log4j-core:2.19.0") // Paper - Needed to generate meta for our Log4j plugins
|
||||
runtimeOnly(log4jPlugins.output)
|
||||
alsoShade(log4jPlugins.output)
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotConfig
|
||||
private static void playerSample()
|
||||
{
|
||||
SpigotConfig.playerSample = SpigotConfig.getInt( "settings.sample-count", 12 );
|
||||
- System.out.println( "Server Ping Player Sample Count: " + SpigotConfig.playerSample );
|
||||
+ Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger
|
||||
}
|
||||
|
||||
public static int playerShuffle;
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -0,0 +0,0 @@
|
||||
<PatternLayout pattern="[%d{HH:mm:ss} %level]: %msg%n" />
|
||||
</Queue>
|
||||
<TerminalConsole name="TerminalConsole">
|
||||
- <PatternLayout pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||
+ <PatternLayout>
|
||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx}">
|
||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||
+ </LoggerNamePatternSelector>
|
||||
+ </PatternLayout>
|
||||
</TerminalConsole>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
- <PatternLayout pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||
+ <PatternLayout>
|
||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n">
|
||||
+ <!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||
+ </LoggerNamePatternSelector>
|
||||
+ </PatternLayout>
|
||||
<Policies>
|
||||
<TimeBasedTriggeringPolicy />
|
||||
<OnStartupTriggeringPolicy />
|
||||
@@ -1,200 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Mon, 18 Jun 2018 15:46:23 +0200
|
||||
Subject: [PATCH] Implement EntityKnockbackByEntityEvent and
|
||||
EntityPushedByEntityAttackEvent
|
||||
|
||||
Co-authored-by: aerulion <aerulion@gmail.com>
|
||||
|
||||
This event is called when an entity receives knockback by another entity.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
|
||||
}
|
||||
|
||||
public void push(double deltaX, double deltaY, double deltaZ) {
|
||||
- this.setDeltaMovement(this.getDeltaMovement().add(deltaX, deltaY, deltaZ));
|
||||
- this.hasImpulse = true;
|
||||
+ // Paper start - call EntityPushedByEntityEvent
|
||||
+ this.push(deltaX, deltaY, deltaZ, null);
|
||||
+ }
|
||||
+
|
||||
+ public void push(double deltaX, double deltaY, double deltaZ, @org.jetbrains.annotations.Nullable Entity pushingEntity) {
|
||||
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(deltaX, deltaY, deltaZ);
|
||||
+ if (pushingEntity == null || new io.papermc.paper.event.entity.EntityPushedByEntityAttackEvent(getBukkitEntity(), pushingEntity.getBukkitEntity(), delta).callEvent()) {
|
||||
+ this.setDeltaMovement(this.getDeltaMovement().add(delta.getX(), delta.getY(), delta.getZ()));
|
||||
+ this.hasImpulse = true;
|
||||
+ }
|
||||
+ // Paper end - call EntityPushedByEntityEvent
|
||||
}
|
||||
|
||||
protected void markHurt() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
d0 = (Math.random() - Math.random()) * 0.01D;
|
||||
}
|
||||
|
||||
- this.knockback(0.4000000059604645D, d0, d1);
|
||||
+ this.knockback(0.4000000059604645D, d0, d1, entity1); // Paper
|
||||
if (!flag) {
|
||||
this.indicateDamage(d0, d1);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
protected void blockedByShield(LivingEntity target) {
|
||||
- target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ());
|
||||
+ target.knockback(0.5D, target.getX() - this.getX(), target.getZ() - this.getZ(), this); // Paper
|
||||
}
|
||||
|
||||
private boolean checkTotemDeathProtection(DamageSource source) {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
|
||||
public void knockback(double strength, double x, double z) {
|
||||
+ // Paper start - add knockbacking entity parameter
|
||||
+ this.knockback(strength, x, z, null);
|
||||
+ }
|
||||
+ public void knockback(double strength, double x, double z, Entity knockingBackEntity) {
|
||||
+ // Paper end - add knockbacking entity parameter
|
||||
strength *= 1.0D - this.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE);
|
||||
if (strength > 0.0D) {
|
||||
this.hasImpulse = true;
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
Vec3 vec3d1 = (new Vec3(x, 0.0D, z)).normalize().scale(strength);
|
||||
|
||||
this.setDeltaMovement(vec3d.x / 2.0D - vec3d1.x, this.onGround() ? Math.min(0.4D, vec3d.y / 2.0D + strength) : vec3d.y, vec3d.z / 2.0D - vec3d1.z);
|
||||
+ // Paper start - call EntityKnockbackByEntityEvent
|
||||
+ Vec3 currentMovement = this.getDeltaMovement();
|
||||
+ org.bukkit.util.Vector delta = new org.bukkit.util.Vector(currentMovement.x - vec3d.x, currentMovement.y - vec3d.y, currentMovement.z - vec3d.z);
|
||||
+ // Restore old velocity to be able to access it in the event
|
||||
+ this.setDeltaMovement(vec3d);
|
||||
+ if (knockingBackEntity == null || new com.destroystokyo.paper.event.entity.EntityKnockbackByEntityEvent((org.bukkit.entity.LivingEntity) getBukkitEntity(), knockingBackEntity.getBukkitEntity(), (float) strength, delta).callEvent()) {
|
||||
+ this.setDeltaMovement(vec3d.x + delta.getX(), vec3d.y + delta.getY(), vec3d.z + delta.getZ());
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
|
||||
if (flag) {
|
||||
if (f1 > 0.0F && target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ ((LivingEntity) target).knockback((double) (f1 * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/RamTarget.java
|
||||
@@ -0,0 +0,0 @@ public class RamTarget extends Behavior<Goat> {
|
||||
float f = 0.25F * (float)(i - j);
|
||||
float g = Mth.clamp(entity.getSpeed() * 1.65F, 0.2F, 3.0F) + f;
|
||||
float h = livingEntity.isDamageSourceBlocked(world.damageSources().mobAttack(entity)) ? 0.5F : 1.0F;
|
||||
- livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z());
|
||||
+ livingEntity.knockback((double)(h * g) * this.getKnockbackForce.applyAsDouble(entity), this.ramDirection.x(), this.ramDirection.z(), entity); // Paper
|
||||
this.finishRam(world, entity);
|
||||
world.playSound((Player)null, entity, this.getImpactSound.apply(entity), SoundSource.NEUTRAL, 1.0F, 1.0F);
|
||||
} else if (this.hasRammedHornBreakingBlock(world, entity)) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/warden/SonicBoom.java
|
||||
@@ -0,0 +0,0 @@ public class SonicBoom extends Behavior<Warden> {
|
||||
target.hurt(world.damageSources().sonicBoom(entity), 10.0F);
|
||||
double d = 0.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
|
||||
double e = 2.5D * (1.0D - target.getAttributeValue(Attributes.KNOCKBACK_RESISTANCE));
|
||||
- target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e);
|
||||
+ target.push(vec33.x() * e, vec33.y() * d, vec33.z() * e, entity); // Paper
|
||||
});
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EnderDragon.java
|
||||
@@ -0,0 +0,0 @@ public class EnderDragon extends Mob implements Enemy {
|
||||
double d3 = entity.getZ() - d1;
|
||||
double d4 = Math.max(d2 * d2 + d3 * d3, 0.1D);
|
||||
|
||||
- entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D);
|
||||
+ entity.push(d2 / d4 * 4.0D, 0.20000000298023224D, d3 / d4 * 4.0D, this); // Paper
|
||||
if (!this.phaseManager.getCurrentPhase().isSitting() && ((LivingEntity) entity).getLastHurtByMobTimestamp() < entity.tickCount - 2) {
|
||||
entity.hurt(this.damageSources().mobAttack(this), 5.0F);
|
||||
this.doEnchantDamageEffects(this, entity);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Ravager.java b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Ravager.java
|
||||
@@ -0,0 +0,0 @@ public class Ravager extends Raider {
|
||||
double d1 = entity.getZ() - this.getZ();
|
||||
double d2 = Math.max(d0 * d0 + d1 * d1, 0.001D);
|
||||
|
||||
- entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D);
|
||||
+ entity.push(d0 / d2 * 4.0D, 0.2D, d1 / d2 * 4.0D, this); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/hoglin/HoglinBase.java
|
||||
@@ -0,0 +0,0 @@ public interface HoglinBase {
|
||||
double j = f * (double)(attacker.level().random.nextFloat() * 0.5F + 0.2F);
|
||||
Vec3 vec3 = (new Vec3(g, 0.0D, h)).normalize().scale(j).yRot(i);
|
||||
double k = f * (double)attacker.level().random.nextFloat() * 0.5D;
|
||||
- target.push(vec3.x, k, vec3.z);
|
||||
+ target.push(vec3.x, k, vec3.z, attacker); // Paper
|
||||
target.hurtMarked = true;
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
if (flag5) {
|
||||
if (i > 0) {
|
||||
if (target instanceof LivingEntity) {
|
||||
- ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ ((LivingEntity) target).knockback((double) ((float) i * 0.5F), (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Paper
|
||||
} else {
|
||||
- target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F));
|
||||
+ target.push((double) (-Mth.sin(this.getYRot() * 0.017453292F) * (float) i * 0.5F), 0.1D, (double) (Mth.cos(this.getYRot() * 0.017453292F) * (float) i * 0.5F), this); // Paper
|
||||
}
|
||||
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(0.6D, 1.0D, 0.6D));
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
if (entityliving != this && entityliving != target && !this.isAlliedTo((Entity) entityliving) && (!(entityliving instanceof ArmorStand) || !((ArmorStand) entityliving).isMarker()) && this.distanceToSqr((Entity) entityliving) < 9.0D) {
|
||||
// CraftBukkit start - Only apply knockback if the damage hits
|
||||
if (entityliving.hurt(this.damageSources().playerAttack(this).sweep(), f4)) {
|
||||
- entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)));
|
||||
+ entityliving.knockback(0.4000000059604645D, (double) Mth.sin(this.getYRot() * 0.017453292F), (double) (-Mth.cos(this.getYRot() * 0.017453292F)), this); // Pa
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/projectile/AbstractArrow.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractArrow extends Projectile {
|
||||
Vec3 vec3d = this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D).normalize().scale((double) this.knockback * 0.6D * d0);
|
||||
|
||||
if (vec3d.lengthSqr() > 0.0D) {
|
||||
- entityliving.push(vec3d.x, 0.1D, vec3d.z);
|
||||
+ entityliving.push(vec3d.x, 0.1D, vec3d.z, this); // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shane Freeder <theboyetronic@gmail.com>
|
||||
Date: Sat, 9 Jun 2018 14:08:39 +0200
|
||||
Subject: [PATCH] Implement EntityTeleportEndGatewayEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/entity/TheEndGatewayBlockEntity.java
|
||||
@@ -0,0 +0,0 @@ public class TheEndGatewayBlockEntity extends TheEndPortalBlockEntity {
|
||||
|
||||
}
|
||||
// CraftBukkit end
|
||||
+ // Paper start - EntityTeleportEndGatewayEvent
|
||||
+ org.bukkit.Location location = new org.bukkit.Location(world.getWorld(), blockposition1.getX() + 0.5D, blockposition1.getY(), blockposition1.getZ() + 0.5D);
|
||||
+ location.setPitch(entity1.getXRot());
|
||||
+ location.setYaw(entity1.getBukkitYaw());
|
||||
+
|
||||
+ org.bukkit.entity.Entity bukkitEntity = entity1.getBukkitEntity();
|
||||
+ com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent event = new com.destroystokyo.paper.event.entity.EntityTeleportEndGatewayEvent(bukkitEntity, bukkitEntity.getLocation(), location, new org.bukkit.craftbukkit.block.CraftEndGateway(world.getWorld(), blockEntity));
|
||||
+ if (!event.callEvent()) {
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
entity1.setPortalCooldown();
|
||||
- entity1.teleportToWithTicket((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D); // Paper - diff on change
|
||||
+ entity1.teleportToWithTicket(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); // Paper
|
||||
}
|
||||
|
||||
TheEndGatewayBlockEntity.triggerCooldown(world, pos, state, blockEntity);
|
||||
@@ -1,167 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: willies952002 <admin@domnian.com>
|
||||
Date: Thu, 26 Jul 2018 02:25:46 -0400
|
||||
Subject: [PATCH] Implement Expanded ArmorStand API
|
||||
|
||||
Adds the following:
|
||||
- Add proper methods for getting and setting items in both hands. Deprecates old methods
|
||||
- Enable/Disable slot interactions
|
||||
- Allow using degrees for ArmorStand rotations (via new Rotations class)
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.decoration.ArmorStand isDisabled(Lnet/minecraft/world/entity/EquipmentSlot;)Z
|
||||
|
||||
Co-authored-by: SoSeDiK <mrsosedik@gmail.com>
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class CraftArmorStand extends CraftLivingEntity implements ArmorStand {
|
||||
getHandle().canMove = move;
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public ItemStack getItem(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ return getHandle().getItemBySlot(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot)).asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setItem(org.bukkit.inventory.EquipmentSlot slot, ItemStack item) {
|
||||
+ com.google.common.base.Preconditions.checkNotNull(slot, "slot");
|
||||
+ switch (slot) {
|
||||
+ case HAND:
|
||||
+ getEquipment().setItemInMainHand(item);
|
||||
+ return;
|
||||
+ case OFF_HAND:
|
||||
+ getEquipment().setItemInOffHand(item);
|
||||
+ return;
|
||||
+ case FEET:
|
||||
+ setBoots(item);
|
||||
+ return;
|
||||
+ case LEGS:
|
||||
+ setLeggings(item);
|
||||
+ return;
|
||||
+ case CHEST:
|
||||
+ setChestplate(item);
|
||||
+ return;
|
||||
+ case HEAD:
|
||||
+ setHelmet(item);
|
||||
+ return;
|
||||
+ }
|
||||
+ throw new UnsupportedOperationException(slot.name());
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public java.util.Set<org.bukkit.inventory.EquipmentSlot> getDisabledSlots() {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = new java.util.HashSet<>();
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : org.bukkit.inventory.EquipmentSlot.values()) {
|
||||
+ if (this.isSlotDisabled(slot)) {
|
||||
+ disabled.add(slot);
|
||||
+ }
|
||||
+ }
|
||||
+ return disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ int disabled = 0;
|
||||
+ for (org.bukkit.inventory.EquipmentSlot slot : slots) {
|
||||
+ if (slot == org.bukkit.inventory.EquipmentSlot.OFF_HAND) continue;
|
||||
+ net.minecraft.world.entity.EquipmentSlot nmsSlot = org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot);
|
||||
+ disabled += (1 << nmsSlot.getFilterFlag()) + (1 << (nmsSlot.getFilterFlag() + 8)) + (1 << (nmsSlot.getFilterFlag() + 16));
|
||||
+ }
|
||||
+ getHandle().disabledSlots = disabled;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void addDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ java.util.Collections.addAll(disabled, slots);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void removeDisabledSlots(org.bukkit.inventory.EquipmentSlot... slots) {
|
||||
+ java.util.Set<org.bukkit.inventory.EquipmentSlot> disabled = getDisabledSlots();
|
||||
+ for (final org.bukkit.inventory.EquipmentSlot slot : slots) disabled.remove(slot);
|
||||
+ setDisabledSlots(disabled.toArray(new org.bukkit.inventory.EquipmentSlot[0]));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isSlotDisabled(org.bukkit.inventory.EquipmentSlot slot) {
|
||||
+ return getHandle().isDisabled(org.bukkit.craftbukkit.CraftEquipmentSlot.getNMS(slot));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getBodyRotations() {
|
||||
+ return fromNMSRotations(getHandle().bodyPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setBodyRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setBodyPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getLeftArmRotations() {
|
||||
+ return fromNMSRotations(getHandle().leftArmPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLeftArmRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setLeftArmPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getRightArmRotations() {
|
||||
+ return fromNMSRotations(getHandle().rightArmPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRightArmRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setRightArmPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getLeftLegRotations() {
|
||||
+ return fromNMSRotations(getHandle().leftLegPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setLeftLegRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setLeftLegPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getRightLegRotations() {
|
||||
+ return fromNMSRotations(getHandle().rightLegPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setRightLegRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setRightLegPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public io.papermc.paper.math.Rotations getHeadRotations() {
|
||||
+ return fromNMSRotations(getHandle().headPose);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setHeadRotations(io.papermc.paper.math.Rotations rotations) {
|
||||
+ getHandle().setHeadPose(toNMSRotations(rotations));
|
||||
+ }
|
||||
+
|
||||
+ private static io.papermc.paper.math.Rotations fromNMSRotations(Rotations old) {
|
||||
+ return io.papermc.paper.math.Rotations.ofDegrees(old.getX(), old.getY(), old.getZ());
|
||||
+ }
|
||||
+
|
||||
+ private static Rotations toNMSRotations(io.papermc.paper.math.Rotations old) {
|
||||
+ return new Rotations((float) old.x(), (float) old.y(), (float) old.z());
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public boolean canTick() {
|
||||
return this.getHandle().canTick;
|
||||
@@ -1,26 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 3 Jul 2018 16:08:14 +0200
|
||||
Subject: [PATCH] Implement World.getEntity(UUID) API
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
return list;
|
||||
}
|
||||
|
||||
+ // Paper start - getEntity by UUID API
|
||||
+ @Override
|
||||
+ public Entity getEntity(UUID uuid) {
|
||||
+ Preconditions.checkArgument(uuid != null, "UUID cannot be null");
|
||||
+ net.minecraft.world.entity.Entity entity = world.getEntity(uuid);
|
||||
+ return entity == null ? null : entity.getBukkitEntity();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void save() {
|
||||
org.spigotmc.AsyncCatcher.catchOp("world save"); // Spigot
|
||||
@@ -1,37 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 22:43:12 -0400
|
||||
Subject: [PATCH] Implement ensureServerConversions API
|
||||
|
||||
This will take a Bukkit ItemStack and run it through any conversions a server process would perform on it,
|
||||
to ensure it meets latest minecraft expectations.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class ItemStack {
|
||||
|
||||
// Called to run this stack through the data converter to handle older storage methods and serialized items
|
||||
public void convertStack(int version) {
|
||||
- if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion()) {
|
||||
+ if (0 < version && version < CraftMagicNumbers.INSTANCE.getDataVersion() && MinecraftServer.getServer() != null) { // Paper - skip conversion if the server doesn't exist (for tests)
|
||||
CompoundTag savedStack = new CompoundTag();
|
||||
this.save(savedStack);
|
||||
savedStack = (CompoundTag) MinecraftServer.getServer().fixerUpper.update(References.ITEM_STACK, new Dynamic(NbtOps.INSTANCE, savedStack), version, CraftMagicNumbers.INSTANCE.getDataVersion()).getValue();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
return io.papermc.paper.adventure.PaperAdventure.asAdventure(CraftItemStack.asNMSCopy(itemStack).getDisplayName());
|
||||
}
|
||||
// Paper end - Adventure
|
||||
+
|
||||
+ // Paper start - ensure server conversions API
|
||||
+ @Override
|
||||
+ public ItemStack ensureServerConversions(ItemStack item) {
|
||||
+ return CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(item));
|
||||
+ }
|
||||
+ // Paper end - ensure server conversions API
|
||||
}
|
||||
@@ -1,241 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 15:56:26 +0200
|
||||
Subject: [PATCH] Implement extended PaperServerListPingEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperServerListPingEventImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import net.minecraft.server.level.ServerPlayer;
|
||||
+import org.bukkit.entity.Player;
|
||||
+import org.bukkit.util.CachedServerIcon;
|
||||
+
|
||||
+import javax.annotation.Nullable;
|
||||
+
|
||||
+class PaperServerListPingEventImpl extends PaperServerListPingEvent {
|
||||
+
|
||||
+ private final MinecraftServer server;
|
||||
+
|
||||
+ PaperServerListPingEventImpl(MinecraftServer server, StatusClient client, int protocolVersion, @Nullable CachedServerIcon icon) {
|
||||
+ super(client, server.server.motd(), server.getPlayerCount(), server.getMaxPlayers(),
|
||||
+ server.getServerModName() + ' ' + server.getServerVersion(), protocolVersion, icon);
|
||||
+ this.server = server;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected final Object[] getOnlinePlayers() {
|
||||
+ return this.server.getPlayerList().players.toArray();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ protected final Player getBukkitPlayer(Object player) {
|
||||
+ return ((ServerPlayer) player).getBukkitEntity();
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java b/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/PaperStatusClient.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import net.minecraft.network.Connection;
|
||||
+
|
||||
+class PaperStatusClient extends PaperNetworkClient implements StatusClient {
|
||||
+
|
||||
+ PaperStatusClient(Connection networkManager) {
|
||||
+ super(networkManager);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/network/StandardPaperServerListPingEventImpl.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.network;
|
||||
+
|
||||
+import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
||||
+import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
+import com.google.common.base.MoreObjects;
|
||||
+import com.google.common.base.Strings;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
+import io.papermc.paper.adventure.AdventureComponent;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Collections;
|
||||
+import java.util.List;
|
||||
+import java.util.Optional;
|
||||
+import java.util.UUID;
|
||||
+import javax.annotation.Nonnull;
|
||||
+import net.minecraft.network.Connection;
|
||||
+import net.minecraft.network.chat.Component;
|
||||
+import net.minecraft.network.protocol.status.ClientboundStatusResponsePacket;
|
||||
+import net.minecraft.network.protocol.status.ServerStatus;
|
||||
+import net.minecraft.server.MinecraftServer;
|
||||
+import org.bukkit.craftbukkit.util.CraftIconCache;
|
||||
+
|
||||
+public final class StandardPaperServerListPingEventImpl extends PaperServerListPingEventImpl {
|
||||
+
|
||||
+ // private static final GameProfile[] EMPTY_PROFILES = new GameProfile[0];
|
||||
+ private static final UUID FAKE_UUID = new UUID(0, 0);
|
||||
+
|
||||
+ private List<GameProfile> originalSample;
|
||||
+
|
||||
+ private StandardPaperServerListPingEventImpl(MinecraftServer server, Connection networkManager, ServerStatus ping) {
|
||||
+ super(server, new PaperStatusClient(networkManager), ping.version().map(ServerStatus.Version::protocol).orElse(-1), server.server.getServerIcon());
|
||||
+ this.originalSample = ping.players().map(ServerStatus.Players::sample).orElse(null); // GH-1473 - pre-tick race condition NPE
|
||||
+ }
|
||||
+
|
||||
+ @Nonnull
|
||||
+ @Override
|
||||
+ public List<PlayerProfile> getPlayerSample() {
|
||||
+ List<PlayerProfile> sample = super.getPlayerSample();
|
||||
+
|
||||
+ if (this.originalSample != null) {
|
||||
+ for (GameProfile profile : this.originalSample) {
|
||||
+ sample.add(CraftPlayerProfile.asBukkitCopy(profile));
|
||||
+ }
|
||||
+ this.originalSample = null;
|
||||
+ }
|
||||
+
|
||||
+ return sample;
|
||||
+ }
|
||||
+
|
||||
+ private List<GameProfile> getPlayerSampleHandle() {
|
||||
+ if (this.originalSample != null) {
|
||||
+ return this.originalSample;
|
||||
+ }
|
||||
+
|
||||
+ List<PlayerProfile> entries = super.getPlayerSample();
|
||||
+ if (entries.isEmpty()) {
|
||||
+ return Collections.emptyList();
|
||||
+ }
|
||||
+
|
||||
+ final List<GameProfile> profiles = new ArrayList<>();
|
||||
+ for (PlayerProfile profile : entries) {
|
||||
+ /*
|
||||
+ * Avoid null UUIDs/names since that will make the response invalid
|
||||
+ * on the client.
|
||||
+ * Instead, fall back to a fake/empty UUID and an empty string as name.
|
||||
+ * This can be used to create custom lines in the player list that do not
|
||||
+ * refer to a specific player.
|
||||
+ */
|
||||
+ if (profile.getId() != null && profile.getName() != null) {
|
||||
+ profiles.add(CraftPlayerProfile.asAuthlib(profile));
|
||||
+ } else {
|
||||
+ profiles.add(new GameProfile(MoreObjects.firstNonNull(profile.getId(), FAKE_UUID), Strings.nullToEmpty(profile.getName())));
|
||||
+ }
|
||||
+ }
|
||||
+ return profiles;
|
||||
+ }
|
||||
+
|
||||
+ public static void processRequest(MinecraftServer server, Connection networkManager) {
|
||||
+ StandardPaperServerListPingEventImpl event = new StandardPaperServerListPingEventImpl(server, networkManager, server.getStatus());
|
||||
+ server.server.getPluginManager().callEvent(event);
|
||||
+
|
||||
+ // Close connection immediately if event is cancelled
|
||||
+ if (event.isCancelled()) {
|
||||
+ networkManager.disconnect(null);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ // Setup response
|
||||
+
|
||||
+ // Description
|
||||
+ final Component description = new AdventureComponent(event.motd());
|
||||
+
|
||||
+ // Players
|
||||
+ final Optional<ServerStatus.Players> players;
|
||||
+ if (!event.shouldHidePlayers()) {
|
||||
+ players = Optional.of(new ServerStatus.Players(event.getMaxPlayers(), event.getNumPlayers(), event.getPlayerSampleHandle()));
|
||||
+ } else {
|
||||
+ players = Optional.empty();
|
||||
+ }
|
||||
+
|
||||
+ // Version
|
||||
+ final ServerStatus.Version version = new ServerStatus.Version(event.getVersion(), event.getProtocolVersion());
|
||||
+
|
||||
+ // Favicon
|
||||
+ final Optional<ServerStatus.Favicon> favicon;
|
||||
+ if (event.getServerIcon() != null) {
|
||||
+ favicon = Optional.of(new ServerStatus.Favicon(((CraftIconCache) event.getServerIcon()).value));
|
||||
+ } else {
|
||||
+ favicon = Optional.empty();
|
||||
+ }
|
||||
+ final ServerStatus ping = new ServerStatus(description, players, Optional.of(version), favicon, server.enforceSecureProfile());
|
||||
+
|
||||
+ // Send response
|
||||
+ networkManager.send(new ClientboundStatusResponsePacket(ping));
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/server/MinecraftServer.java b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
+++ b/src/main/java/net/minecraft/server/MinecraftServer.java
|
||||
@@ -0,0 +0,0 @@ package net.minecraft.server;
|
||||
import com.google.common.base.Preconditions;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
+import co.aikar.timings.Timings;
|
||||
+import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
+import com.google.common.base.Stopwatch;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
@@ -0,0 +0,0 @@ public abstract class MinecraftServer extends ReentrantBlockableEventLoop<TickTa
|
||||
if (this.hidesOnlinePlayers()) {
|
||||
return new ServerStatus.Players(i, list.size(), List.of());
|
||||
} else {
|
||||
- int j = Math.min(list.size(), 12);
|
||||
+ int j = Math.min(list.size(), org.spigotmc.SpigotConfig.playerSample); // Paper
|
||||
ObjectArrayList<GameProfile> objectarraylist = new ObjectArrayList(j);
|
||||
int k = Mth.nextInt(this.random, 0, list.size() - j);
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerStatusPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene
|
||||
this.connection.disconnect(ServerStatusPacketListenerImpl.DISCONNECT_REASON);
|
||||
} else {
|
||||
this.hasRequestedStatus = true;
|
||||
+ // Paper start - Replace everything
|
||||
+ /*
|
||||
// CraftBukkit start
|
||||
// this.connection.send(new PacketStatusOutServerInfo(this.status));
|
||||
MinecraftServer server = MinecraftServer.getServer();
|
||||
@@ -0,0 +0,0 @@ public class ServerStatusPacketListenerImpl implements ServerStatusPacketListene
|
||||
|
||||
this.connection.send(new ClientboundStatusResponsePacket(ping));
|
||||
// CraftBukkit end
|
||||
+ */
|
||||
+ com.destroystokyo.paper.network.StandardPaperServerListPingEventImpl.processRequest(MinecraftServer.getServer(), this.connection);
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotConfig
|
||||
public static int playerSample;
|
||||
private static void playerSample()
|
||||
{
|
||||
- SpigotConfig.playerSample = SpigotConfig.getInt( "settings.sample-count", 12 );
|
||||
+ SpigotConfig.playerSample = Math.max( SpigotConfig.getInt( "settings.sample-count", 12 ), 0 ); // Paper - Avoid negative counts
|
||||
Bukkit.getLogger().log( Level.INFO, "Server Ping Player Sample Count: {0}", playerSample ); // Paper - Use logger
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Wed, 4 May 2016 23:59:38 -0400
|
||||
Subject: [PATCH] Implement getI18NDisplayName
|
||||
|
||||
Gets the Display name as seen in the Client.
|
||||
Currently the server only supports the English language. To override this,
|
||||
You must replace the language file embedded in the server jar.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemFactory implements ItemFactory {
|
||||
return CraftItemStack.asCraftMirror(CraftItemStack.asNMSCopy(item));
|
||||
}
|
||||
// Paper end - ensure server conversions API
|
||||
+
|
||||
+ // Paper start - add getI18NDisplayName
|
||||
+ @Override
|
||||
+ public String getI18NDisplayName(ItemStack item) {
|
||||
+ net.minecraft.world.item.ItemStack nms = null;
|
||||
+ if (item instanceof CraftItemStack) {
|
||||
+ nms = ((CraftItemStack) item).handle;
|
||||
+ }
|
||||
+ if (nms == null) {
|
||||
+ nms = CraftItemStack.asNMSCopy(item);
|
||||
+ }
|
||||
+
|
||||
+ return nms != null ? net.minecraft.locale.Language.getInstance().getOrDefault(nms.getItem().getDescriptionId(nms)) : null;
|
||||
+ }
|
||||
+ // Paper end - add getI18NDisplayName
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Techcable <Techcable@outlook.com>
|
||||
Date: Wed, 30 Nov 2016 20:56:58 -0600
|
||||
Subject: [PATCH] Improve BlockPosition inlining
|
||||
|
||||
Normally the JVM can inline virtual getters by having two sets of code, one is the 'optimized' code and the other is the 'deoptimized' code.
|
||||
If a single type is used 99% of the time, then its worth it to inline, and to revert to 'deoptimized' the 1% of the time we encounter other types.
|
||||
But if two types are encountered commonly, then the JVM can't inline them both, and the call overhead remains.
|
||||
|
||||
This scenario also occurs with BlockPos and MutableBlockPos.
|
||||
The variables in BlockPos are final, so MutableBlockPos can't modify them.
|
||||
MutableBlockPos fixes this by adding custom mutable variables, and overriding the getters to access them.
|
||||
|
||||
This approach with utility methods that operate on MutableBlockPos and BlockPos.
|
||||
Specific examples are BlockPosition.up(), and World.isValidLocation().
|
||||
It makes these simple methods much slower than they need to be.
|
||||
|
||||
This should result in an across the board speedup in anything that accesses blocks or does logic with positions.
|
||||
|
||||
This is based upon conclusions drawn from inspecting the assenmbly generated bythe JIT compiler on my microbenchmarks.
|
||||
They had 'callq' (invoke) instead of 'mov' (get from memory) instructions.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/Vec3i.java b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/Vec3i.java
|
||||
+++ b/src/main/java/net/minecraft/core/Vec3i.java
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public boolean equals(Object object) {
|
||||
+ public final boolean equals(Object object) { // Paper
|
||||
if (this == object) {
|
||||
return true;
|
||||
} else if (!(object instanceof Vec3i)) {
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- public int hashCode() {
|
||||
+ public final int hashCode() { // Paper
|
||||
return (this.getY() + this.getZ() * 31) * 31 + this.getX();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Vec3i implements Comparable<Vec3i> {
|
||||
}
|
||||
}
|
||||
|
||||
- public int getX() {
|
||||
+ public final int getX() { // Paper
|
||||
return this.x;
|
||||
}
|
||||
|
||||
- public int getY() {
|
||||
+ public final int getY() { // Paper
|
||||
return this.y;
|
||||
}
|
||||
|
||||
- public int getZ() {
|
||||
+ public final int getZ() { // Paper
|
||||
return this.z;
|
||||
}
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 15 Jun 2013 19:51:17 -0400
|
||||
Subject: [PATCH] Improve EntityShootBowEvent
|
||||
|
||||
Adds missing call to Illagers and also adds Arrow ItemStack to skeletons
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.projectile.AbstractArrow getPickupItem()Lnet.minecraft.world.item.ItemStack;
|
||||
|
||||
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 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/AbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractSkeleton extends Monster implements RangedAttackMo
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4));
|
||||
// CraftBukkit start
|
||||
- org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), null, entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true);
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, net.minecraft.world.InteractionHand.MAIN_HAND, 0.8F, true); // Paper
|
||||
if (event.isCancelled()) {
|
||||
event.getProjectile().remove();
|
||||
return;
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Illusioner.java
|
||||
@@ -0,0 +0,0 @@ public class Illusioner extends SpellcasterIllager implements RangedAttackMob {
|
||||
double d3 = Math.sqrt(d0 * d0 + d2 * d2);
|
||||
|
||||
entityarrow.shoot(d0, d1 + d3 * 0.20000000298023224D, d2, 1.6F, (float) (14 - this.level().getDifficulty().getId() * 4));
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getMainHandItem(), entityarrow.getPickupItem(), entityarrow, target.getUsedItemHand(), 0.8F, true);
|
||||
+ if (event.isCancelled()) {
|
||||
+ event.getProjectile().remove();
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (event.getProjectile() == entityarrow.getBukkitEntity()) {
|
||||
+ this.level().addFreshEntity(entityarrow);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.playSound(SoundEvents.SKELETON_SHOOT, 1.0F, 1.0F / (this.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- this.level().addFreshEntity(entityarrow);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,47 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Sat, 23 Sep 2017 21:07:20 +0200
|
||||
Subject: [PATCH] Improve Log4J Configuration / Plugin Loggers
|
||||
|
||||
Add full exceptions to log4j to not truncate stack traces
|
||||
|
||||
Disable logger prefix for various plugins bypassing the plugin logger
|
||||
|
||||
Some plugins bypass the plugin logger and add the plugin prefix
|
||||
manually to the log message. Since they use other logger names
|
||||
(e.g. qualified class names) these would now also appear in the
|
||||
log. Disable the logger prefix for these plugins so the messages
|
||||
show up correctly.
|
||||
|
||||
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/resources/log4j2.xml
|
||||
+++ b/src/main/resources/log4j2.xml
|
||||
@@ -0,0 +0,0 @@
|
||||
</Queue>
|
||||
<TerminalConsole name="TerminalConsole">
|
||||
<PatternLayout>
|
||||
- <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx}">
|
||||
+ <LoggerNamePatternSelector defaultPattern="%highlightError{[%d{HH:mm:ss} %level]: [%logger] %msg%n%xEx{full}}">
|
||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
- pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx}" />
|
||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||
+ pattern="%highlightError{[%d{HH:mm:ss} %level]: %msg%n%xEx{full}}" />
|
||||
</LoggerNamePatternSelector>
|
||||
</PatternLayout>
|
||||
</TerminalConsole>
|
||||
<RollingRandomAccessFile name="File" fileName="logs/latest.log" filePattern="logs/%d{yyyy-MM-dd}-%i.log.gz">
|
||||
<PatternLayout>
|
||||
- <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n">
|
||||
+ <LoggerNamePatternSelector defaultPattern="[%d{HH:mm:ss}] [%t/%level]: [%logger] %stripAnsi{%msg}%n%xEx{full}">
|
||||
<!-- Log root, Minecraft, Mojang and Bukkit loggers without prefix -->
|
||||
- <PatternMatch key=",net.minecraft.,Minecraft,com.mojang."
|
||||
- pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n" />
|
||||
+ <!-- Disable prefix for various plugins that bypass the plugin logger -->
|
||||
+ <PatternMatch key=",net.minecraft.,Minecraft,com.mojang.,com.sk89q.,ru.tehkode.,Minecraft.AWE"
|
||||
+ pattern="[%d{HH:mm:ss}] [%t/%level]: %stripAnsi{%msg}%n%xEx{full}" />
|
||||
</LoggerNamePatternSelector>
|
||||
</PatternLayout>
|
||||
<Policies>
|
||||
@@ -1,482 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Phoenix616 <mail@moep.tv>
|
||||
Date: Tue, 21 Aug 2018 01:39:35 +0100
|
||||
Subject: [PATCH] Improve death events
|
||||
|
||||
This adds the ability to cancel the death events and to modify the sound
|
||||
an entity makes when dying. (In cases were no sound should it will be
|
||||
called with shouldPlaySound set to false allowing unsilencing of silent
|
||||
entities)
|
||||
|
||||
It makes handling of entity deaths a lot nicer as you no longer need
|
||||
to listen on the damage event and calculate if the entity dies yourself
|
||||
to cancel the death which has the benefit of also receiving the dropped
|
||||
items and experience which is otherwise only properly possible by using
|
||||
internal code.
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LivingEntity getDeathSound()Lnet/minecraft/sounds/SoundEvent;
|
||||
public net.minecraft.world.entity.LivingEntity getSoundVolume()F
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
private int containerCounter;
|
||||
public boolean wonGame;
|
||||
private int containerUpdateDelay; // Paper
|
||||
+ // Paper start - cancellable death event
|
||||
+ public boolean queueHealthUpdatePacket = false;
|
||||
+ public net.minecraft.network.protocol.game.ClientboundSetHealthPacket queuedHealthUpdatePacket;
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start
|
||||
public String displayName;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
String deathmessage = defaultMessage.getString();
|
||||
this.keepLevel = keepInventory; // SPIGOT-2222: pre-set keepLevel
|
||||
org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, PaperAdventure.asAdventure(defaultMessage), defaultMessage.getString(), keepInventory); // Paper - Adventure
|
||||
+ // Paper start - cancellable death event
|
||||
+ if (event.isCancelled()) {
|
||||
+ // make compatible with plugins that might have already set the health in an event listener
|
||||
+ if (this.getHealth() <= 0) {
|
||||
+ this.setHealth((float) event.getReviveHealth());
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// SPIGOT-943 - only call if they have an inventory open
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
}
|
||||
}
|
||||
-
|
||||
- return super.hurt(source, amount);
|
||||
+ // Paper start - cancellable death events
|
||||
+ //return super.hurt(source, amount);
|
||||
+ this.queueHealthUpdatePacket = true;
|
||||
+ boolean damaged = super.hurt(source, amount);
|
||||
+ this.queueHealthUpdatePacket = false;
|
||||
+ if (this.queuedHealthUpdatePacket != null) {
|
||||
+ this.connection.send(this.queuedHealthUpdatePacket);
|
||||
+ this.queuedHealthUpdatePacket = null;
|
||||
+ }
|
||||
+ return damaged;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
public Set<UUID> collidableExemptions = new HashSet<>();
|
||||
public boolean bukkitPickUpLoot;
|
||||
public org.bukkit.craftbukkit.entity.CraftLivingEntity getBukkitLivingEntity() { return (org.bukkit.craftbukkit.entity.CraftLivingEntity) super.getBukkitEntity(); } // Paper
|
||||
+ public boolean silentDeath = false; // Paper - mark entity as dying silently for cancellable death event
|
||||
|
||||
@Override
|
||||
public float getBukkitYaw() {
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
|
||||
if (this.isDeadOrDying()) {
|
||||
if (!this.checkTotemDeathProtection(source)) {
|
||||
- SoundEvent soundeffect = this.getDeathSound();
|
||||
-
|
||||
- if (flag1 && soundeffect != null) {
|
||||
- this.playSound(soundeffect, this.getSoundVolume(), this.getVoicePitch());
|
||||
- }
|
||||
+ // Paper start - moved into CraftEventFactory event caller for cancellable death event
|
||||
+ this.silentDeath = !flag1; // mark entity as dying silently
|
||||
+ // Paper end
|
||||
|
||||
this.die(source);
|
||||
+ this.silentDeath = false; // Paper - cancellable death event - reset to default
|
||||
}
|
||||
} else if (flag1) {
|
||||
this.playHurtSound(source);
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.isRemoved() && !this.dead) {
|
||||
Entity entity = damageSource.getEntity();
|
||||
LivingEntity entityliving = this.getKillCredit();
|
||||
-
|
||||
+ /* // Paper - move down to make death event cancellable - this is the awardKillScore below
|
||||
if (this.deathScore >= 0 && entityliving != null) {
|
||||
entityliving.awardKillScore(this, this.deathScore, damageSource);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.level().isClientSide && this.hasCustomName()) {
|
||||
if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot
|
||||
}
|
||||
+ */ // Paper - move down to make death event cancellable - this is the awardKillScore below
|
||||
|
||||
this.dead = true;
|
||||
- this.getCombatTracker().recheckStatus();
|
||||
+ // Paper - moved into if below
|
||||
Level world = this.level();
|
||||
|
||||
if (world instanceof ServerLevel) {
|
||||
ServerLevel worldserver = (ServerLevel) world;
|
||||
+ // Paper - move below into if for onKill
|
||||
+
|
||||
+ // Paper start
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = this.dropAllDeathLoot(damageSource);
|
||||
+ if (deathEvent == null || !deathEvent.isCancelled()) {
|
||||
+ if (this.deathScore >= 0 && entityliving != null) {
|
||||
+ entityliving.awardKillScore(this, this.deathScore, damageSource);
|
||||
+ }
|
||||
+ // Paper start - clear equipment if event is not cancelled
|
||||
+ if (this instanceof Mob) {
|
||||
+ for (EquipmentSlot slot : this.clearedEquipmentSlots) {
|
||||
+ this.setItemSlot(slot, ItemStack.EMPTY);
|
||||
+ }
|
||||
+ this.clearedEquipmentSlots.clear();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
- if (entity == null || entity.killedEntity(worldserver, this)) {
|
||||
+ if (this.isSleeping()) {
|
||||
+ this.stopSleeping();
|
||||
+ }
|
||||
+
|
||||
+ if (!this.level().isClientSide && this.hasCustomName()) {
|
||||
+ if (org.spigotmc.SpigotConfig.logNamedDeaths) LivingEntity.LOGGER.info("Named entity {} died: {}", this, this.getCombatTracker().getDeathMessage().getString()); // Spigot
|
||||
+ }
|
||||
+
|
||||
+ this.getCombatTracker().recheckStatus();
|
||||
+ if (entity != null) {
|
||||
+ entity.killedEntity((ServerLevel) this.level(), this);
|
||||
+ }
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
- this.dropAllDeathLoot(damageSource);
|
||||
- this.createWitherRose(entityliving);
|
||||
+ } else {
|
||||
+ this.dead = false;
|
||||
+ this.setHealth((float) deathEvent.getReviveHealth());
|
||||
}
|
||||
|
||||
- this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
+ // Paper end
|
||||
+ this.createWitherRose(entityliving);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ if (this.dead) { // Paper
|
||||
+ this.level().broadcastEntityEvent(this, (byte) 3);
|
||||
this.setPose(Pose.DYING);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (!this.level().isClientSide) {
|
||||
boolean flag = false;
|
||||
|
||||
- if (adversary instanceof WitherBoss) {
|
||||
+ if (this.dead && adversary instanceof WitherBoss) { // Paper
|
||||
if (this.level().getGameRules().getBoolean(GameRules.RULE_MOBGRIEFING)) {
|
||||
BlockPos blockposition = this.blockPosition();
|
||||
BlockState iblockdata = Blocks.WITHER_ROSE.defaultBlockState();
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
}
|
||||
}
|
||||
|
||||
- protected void dropAllDeathLoot(DamageSource source) {
|
||||
+ // Paper start
|
||||
+ protected boolean clearEquipmentSlots = true;
|
||||
+ protected Set<EquipmentSlot> clearedEquipmentSlots = new java.util.HashSet<>();
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
|
||||
+ // Paper end
|
||||
Entity entity = source.getEntity();
|
||||
int i;
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
this.dropEquipment(); // CraftBukkit - from below
|
||||
if (this.shouldDropLoot() && this.level().getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
|
||||
this.dropFromLootTable(source, flag);
|
||||
+ // Paper start
|
||||
+ final boolean prev = this.clearEquipmentSlots;
|
||||
+ this.clearEquipmentSlots = false;
|
||||
+ this.clearedEquipmentSlots.clear();
|
||||
+ // Paper end
|
||||
this.dropCustomDeathLoot(source, i, flag);
|
||||
+ this.clearEquipmentSlots = prev; // Paper
|
||||
}
|
||||
// CraftBukkit start - Call death event
|
||||
- CraftEventFactory.callEntityDeathEvent(this, this.drops);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = CraftEventFactory.callEntityDeathEvent(this, this.drops); // Paper
|
||||
+ this.postDeathDropItems(deathEvent); // Paper
|
||||
this.drops = new ArrayList<>();
|
||||
// CraftBukkit end
|
||||
|
||||
// this.dropInventory();// CraftBukkit - moved up
|
||||
this.dropExperience();
|
||||
+ return deathEvent; // Paper
|
||||
}
|
||||
|
||||
protected void dropEquipment() {}
|
||||
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {} // Paper - method for post death logic that cannot be ran before the event is potentially cancelled
|
||||
|
||||
// CraftBukkit start
|
||||
public int getExpReward() {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Mob extends LivingEntity implements Targeting {
|
||||
}
|
||||
|
||||
this.spawnAtLocation(itemstack);
|
||||
+ if (this.clearEquipmentSlots) { // Paper
|
||||
this.setItemSlot(enumitemslot, ItemStack.EMPTY);
|
||||
+ // Paper start
|
||||
+ } else {
|
||||
+ this.clearedEquipmentSlots.add(enumitemslot);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Fox.java b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Fox.java
|
||||
@@ -0,0 +0,0 @@ public class Fox extends Animal implements VariantHolder<Fox.Type> {
|
||||
}
|
||||
|
||||
@Override
|
||||
- protected void dropAllDeathLoot(DamageSource source) {
|
||||
- ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND);
|
||||
+ // Paper start - Cancellable death event
|
||||
+ protected org.bukkit.event.entity.EntityDeathEvent dropAllDeathLoot(DamageSource source) {
|
||||
+ ItemStack itemstack = this.getItemBySlot(EquipmentSlot.MAINHAND).copy(); // Paper - modified by supercall
|
||||
+
|
||||
+ org.bukkit.event.entity.EntityDeathEvent deathEvent = super.dropAllDeathLoot(source);
|
||||
+
|
||||
+ // Below is code to drop
|
||||
+
|
||||
+ if (deathEvent == null || deathEvent.isCancelled()) {
|
||||
+ return deathEvent;
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
if (!itemstack.isEmpty()) {
|
||||
this.spawnAtLocation(itemstack);
|
||||
this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
|
||||
}
|
||||
|
||||
- super.dropAllDeathLoot(source);
|
||||
+ return deathEvent; // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractChestedHorse.java
|
||||
@@ -0,0 +0,0 @@ public abstract class AbstractChestedHorse extends AbstractHorse {
|
||||
this.spawnAtLocation(Blocks.CHEST);
|
||||
}
|
||||
|
||||
- this.setChest(false);
|
||||
+ //this.setCarryingChest(false); // Paper - moved to post death logic
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ protected void postDeathDropItems(org.bukkit.event.entity.EntityDeathEvent event) {
|
||||
+ if (this.hasChest() && (event == null || !event.isCancelled())) {
|
||||
+ this.setChest(false);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (source.is(DamageTypeTags.IS_EXPLOSION)) {
|
||||
- this.brokenByAnything(source);
|
||||
- this.kill();
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(source);
|
||||
+ if (!event.isCancelled()) this.kill(false);
|
||||
+ // Paper end
|
||||
return false;
|
||||
} else if (source.is(DamageTypeTags.IGNITES_ARMOR_STANDS)) {
|
||||
if (this.isOnFire()) {
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, source.getEntity());
|
||||
this.lastHit = i;
|
||||
} else {
|
||||
- this.brokenByPlayer(source);
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByPlayer(source); // Paper
|
||||
this.showBreakingParticles();
|
||||
- this.discard(); // CraftBukkit - SPIGOT-4890: remain as this.discard() since above damagesource method will call death event
|
||||
+ if (!event.isCancelled()) this.kill(false); // Paper - we still need to kill to follow vanilla logic (emit the game event etc...)
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
f1 -= amount;
|
||||
if (f1 <= 0.5F) {
|
||||
- this.brokenByAnything(damageSource);
|
||||
- this.kill();
|
||||
+ // Paper start - avoid duplicate event call
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = this.brokenByAnything(damageSource);
|
||||
+ if (!event.isCancelled()) this.kill(false);
|
||||
+ // Paper end
|
||||
} else {
|
||||
this.setHealth(f1);
|
||||
this.gameEvent(GameEvent.ENTITY_DAMAGE, damageSource.getEntity());
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
- private void brokenByPlayer(DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByPlayer(DamageSource damageSource) { // Paper
|
||||
ItemStack itemstack = new ItemStack(Items.ARMOR_STAND);
|
||||
|
||||
if (this.hasCustomName()) {
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
}
|
||||
|
||||
this.drops.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(itemstack)); // CraftBukkit - add to drops
|
||||
- this.brokenByAnything(damageSource);
|
||||
+ return this.brokenByAnything(damageSource); // Paper
|
||||
}
|
||||
|
||||
- private void brokenByAnything(DamageSource damageSource) {
|
||||
+ private org.bukkit.event.entity.EntityDeathEvent brokenByAnything(DamageSource damageSource) { // Paper
|
||||
this.playBrokenSound();
|
||||
// this.dropAllDeathLoot(damagesource); // CraftBukkit - moved down
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
this.armorItems.set(i, ItemStack.EMPTY);
|
||||
}
|
||||
}
|
||||
- this.dropAllDeathLoot(damageSource); // CraftBukkit - moved from above
|
||||
+ return this.dropAllDeathLoot(damageSource); // CraftBukkit - moved from above // Paper
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
public void kill() {
|
||||
- org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.drops); // CraftBukkit - call event
|
||||
+ // Paper start
|
||||
+ kill(true);
|
||||
+ }
|
||||
+
|
||||
+ public void kill(boolean callEvent) {
|
||||
+ if (callEvent) {
|
||||
+ // Paper end
|
||||
+ org.bukkit.event.entity.EntityDeathEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityDeathEvent(this, this.drops); // CraftBukkit - call event // Paper - make cancellable
|
||||
+ if (event.isCancelled()) return; // Paper - make cancellable
|
||||
+ } // Paper
|
||||
this.remove(Entity.RemovalReason.KILLED);
|
||||
this.gameEvent(GameEvent.ENTITY_DIE);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
@Override
|
||||
public void sendHealthUpdate() {
|
||||
FoodData foodData = this.getHandle().getFoodData();
|
||||
- this.sendHealthUpdate(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
|
||||
+ // Paper start - cancellable death event
|
||||
+ ClientboundSetHealthPacket packet = new ClientboundSetHealthPacket(this.getScaledHealth(), foodData.getFoodLevel(), foodData.getSaturationLevel());
|
||||
+ if (this.getHandle().queueHealthUpdatePacket) {
|
||||
+ this.getHandle().queuedHealthUpdatePacket = packet;
|
||||
+ } else {
|
||||
+ this.getHandle().connection.send(packet);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public void injectScaledMaxHealth(Collection<AttributeInstance> collection, boolean force) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
public static EntityDeathEvent callEntityDeathEvent(net.minecraft.world.entity.LivingEntity victim, List<org.bukkit.inventory.ItemStack> drops) {
|
||||
CraftLivingEntity entity = (CraftLivingEntity) victim.getBukkitEntity();
|
||||
EntityDeathEvent event = new EntityDeathEvent(entity, drops, victim.getExpReward());
|
||||
+ populateFields(victim, event); // Paper - make cancellable
|
||||
CraftWorld world = (CraftWorld) entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
+ // Paper start - make cancellable
|
||||
+ if (event.isCancelled()) {
|
||||
+ return event;
|
||||
+ }
|
||||
+ playDeathSound(victim, event);
|
||||
+ // Paper end
|
||||
victim.expToDrop = event.getDroppedExp();
|
||||
|
||||
for (org.bukkit.inventory.ItemStack stack : event.getDrops()) {
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
PlayerDeathEvent event = new PlayerDeathEvent(entity, drops, victim.getExpReward(), 0, deathMessage, stringDeathMessage); // Paper - Adventure
|
||||
event.setKeepInventory(keepInventory);
|
||||
event.setKeepLevel(victim.keepLevel); // SPIGOT-2222: pre-set keepLevel
|
||||
+ populateFields(victim, event); // Paper - make cancellable
|
||||
org.bukkit.World world = entity.getWorld();
|
||||
Bukkit.getServer().getPluginManager().callEvent(event);
|
||||
+ // Paper start - make cancellable
|
||||
+ if (event.isCancelled()) {
|
||||
+ return event;
|
||||
+ }
|
||||
+ playDeathSound(victim, event);
|
||||
+ // Paper end
|
||||
|
||||
victim.keepLevel = event.getKeepLevel();
|
||||
victim.newLevel = event.getNewLevel();
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start - helper methods for making death event cancellable
|
||||
+ // Add information to death event
|
||||
+ private static void populateFields(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
+ event.setReviveHealth(event.getEntity().getAttribute(org.bukkit.attribute.Attribute.GENERIC_MAX_HEALTH).getValue());
|
||||
+ event.setShouldPlayDeathSound(!victim.silentDeath && !victim.isSilent());
|
||||
+ net.minecraft.sounds.SoundEvent soundEffect = victim.getDeathSound();
|
||||
+ event.setDeathSound(soundEffect != null ? org.bukkit.craftbukkit.CraftSound.minecraftToBukkit(soundEffect) : null);
|
||||
+ event.setDeathSoundCategory(org.bukkit.SoundCategory.valueOf(victim.getSoundSource().name()));
|
||||
+ event.setDeathSoundVolume(victim.getSoundVolume());
|
||||
+ event.setDeathSoundPitch(victim.getVoicePitch());
|
||||
+ }
|
||||
+
|
||||
+ // Play death sound manually
|
||||
+ private static void playDeathSound(net.minecraft.world.entity.LivingEntity victim, EntityDeathEvent event) {
|
||||
+ if (event.shouldPlayDeathSound() && event.getDeathSound() != null && event.getDeathSoundCategory() != null) {
|
||||
+ net.minecraft.world.entity.player.Player source = victim instanceof net.minecraft.world.entity.player.Player ? (net.minecraft.world.entity.player.Player) victim : null;
|
||||
+ double x = event.getEntity().getLocation().getX();
|
||||
+ double y = event.getEntity().getLocation().getY();
|
||||
+ double z = event.getEntity().getLocation().getZ();
|
||||
+ net.minecraft.sounds.SoundEvent soundEffect = org.bukkit.craftbukkit.CraftSound.bukkitToMinecraft(event.getDeathSound());
|
||||
+ net.minecraft.sounds.SoundSource soundCategory = net.minecraft.sounds.SoundSource.valueOf(event.getDeathSoundCategory().name());
|
||||
+ victim.level().playSound(source, x, y, z, soundEffect, soundCategory, event.getDeathSoundVolume(), event.getDeathSoundPitch());
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
/**
|
||||
* Server methods
|
||||
*/
|
||||
@@ -1,59 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Dec 2016 16:24:06 -0500
|
||||
Subject: [PATCH] Improve the Saddle API for Horses
|
||||
|
||||
Not all horses with Saddles have armor. This lets us break up the horses with saddles
|
||||
and access their saddle state separately from an interface shared with Armor.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
@@ -0,0 +0,0 @@ import java.util.UUID;
|
||||
import net.minecraft.world.entity.ai.attributes.Attributes;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.craftbukkit.inventory.CraftInventoryAbstractHorse;
|
||||
+import org.bukkit.craftbukkit.inventory.CraftSaddledInventory;
|
||||
import org.bukkit.entity.AbstractHorse;
|
||||
import org.bukkit.entity.AnimalTamer;
|
||||
import org.bukkit.entity.Horse;
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
|
||||
|
||||
@Override
|
||||
public AbstractHorseInventory getInventory() {
|
||||
- return new CraftInventoryAbstractHorse(this.getHandle().inventory);
|
||||
+ return new CraftSaddledInventory(getHandle().inventory);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.Container;
|
||||
import org.bukkit.inventory.HorseInventory;
|
||||
import org.bukkit.inventory.ItemStack;
|
||||
|
||||
-public class CraftInventoryHorse extends CraftInventoryAbstractHorse implements HorseInventory {
|
||||
+public class CraftInventoryHorse extends CraftSaddledInventory implements HorseInventory {
|
||||
|
||||
public CraftInventoryHorse(Container inventory) {
|
||||
super(inventory);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSaddledInventory.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package org.bukkit.craftbukkit.inventory;
|
||||
+
|
||||
+import net.minecraft.world.Container;
|
||||
+import org.bukkit.inventory.SaddledHorseInventory;
|
||||
+
|
||||
+public class CraftSaddledInventory extends CraftInventoryAbstractHorse implements SaddledHorseInventory {
|
||||
+
|
||||
+ public CraftSaddledInventory(Container inventory) {
|
||||
+ super(inventory);
|
||||
+ }
|
||||
+
|
||||
+}
|
||||
@@ -1,370 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 16 Mar 2018 22:59:43 -0400
|
||||
Subject: [PATCH] Improved Async Task Scheduler
|
||||
|
||||
The Craft Scheduler still uses the primary thread for task scheduling.
|
||||
This results in the main thread still having to do work as part of the
|
||||
dispatching of async tasks.
|
||||
|
||||
If plugins make use of lots of async tasks, such as particle emitters
|
||||
that want to keep the logic off the main thread, the main thread still
|
||||
receives quite a bit of load from processing all of these queued tasks.
|
||||
|
||||
Additionally, resizing and managing the pending entries for all of
|
||||
these asynchronous tasks takes up time on the main thread too.
|
||||
|
||||
This commit replaces the implementation of the scheduler when working
|
||||
with asynchronous tasks, by forwarding calls to the new scheduler.
|
||||
|
||||
The Async Scheduler uses a single thread executor for "management" tasks.
|
||||
The Management Thread is responsible for all adding and dispatching of
|
||||
scheduled tasks.
|
||||
|
||||
The mainThreadHeartbeat will send a heartbeat task to the management thread
|
||||
with the currentTick value, so that it can find which tasks to execute.
|
||||
|
||||
Scheduling of an async tasks also dispatches a management task, ensuring
|
||||
that any Queue resizing operation occurs off of the main thread.
|
||||
|
||||
The async queue uses a complete separate PriorityQueue, ensuring that resize
|
||||
operations are decoupled from the sync tasks queue.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncScheduler.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+/*
|
||||
+ * Copyright (c) 2018 Daniel Ennis (Aikar) MIT License
|
||||
+ *
|
||||
+ * Permission is hereby granted, free of charge, to any person obtaining
|
||||
+ * a copy of this software and associated documentation files (the
|
||||
+ * "Software"), to deal in the Software without restriction, including
|
||||
+ * without limitation the rights to use, copy, modify, merge, publish,
|
||||
+ * distribute, sublicense, and/or sell copies of the Software, and to
|
||||
+ * permit persons to whom the Software is furnished to do so, subject to
|
||||
+ * the following conditions:
|
||||
+ *
|
||||
+ * The above copyright notice and this permission notice shall be
|
||||
+ * included in all copies or substantial portions of the Software.
|
||||
+ *
|
||||
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
+ */
|
||||
+
|
||||
+package org.bukkit.craftbukkit.scheduler;
|
||||
+
|
||||
+import com.destroystokyo.paper.ServerSchedulerReportingWrapper;
|
||||
+import com.google.common.util.concurrent.ThreadFactoryBuilder;
|
||||
+import org.bukkit.plugin.Plugin;
|
||||
+
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.Iterator;
|
||||
+import java.util.List;
|
||||
+import java.util.concurrent.Executor;
|
||||
+import java.util.concurrent.Executors;
|
||||
+import java.util.concurrent.SynchronousQueue;
|
||||
+import java.util.concurrent.ThreadPoolExecutor;
|
||||
+import java.util.concurrent.TimeUnit;
|
||||
+
|
||||
+public class CraftAsyncScheduler extends CraftScheduler {
|
||||
+
|
||||
+ private final ThreadPoolExecutor executor = new ThreadPoolExecutor(
|
||||
+ 4, Integer.MAX_VALUE,30L, TimeUnit.SECONDS, new SynchronousQueue<>(),
|
||||
+ new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %1$d").build());
|
||||
+ private final Executor management = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
|
||||
+ .setNameFormat("Craft Async Scheduler Management Thread").build());
|
||||
+ private final List<CraftTask> temp = new ArrayList<>();
|
||||
+
|
||||
+ CraftAsyncScheduler() {
|
||||
+ super(true);
|
||||
+ executor.allowCoreThreadTimeOut(true);
|
||||
+ executor.prestartAllCoreThreads();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void cancelTask(int taskId) {
|
||||
+ this.management.execute(() -> this.removeTask(taskId));
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void removeTask(int taskId) {
|
||||
+ parsePending();
|
||||
+ this.pending.removeIf((task) -> {
|
||||
+ if (task.getTaskId() == taskId) {
|
||||
+ task.cancel0();
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ });
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void mainThreadHeartbeat(int currentTick) {
|
||||
+ this.currentTick = currentTick;
|
||||
+ this.management.execute(() -> this.runTasks(currentTick));
|
||||
+ }
|
||||
+
|
||||
+ private synchronized void runTasks(int currentTick) {
|
||||
+ parsePending();
|
||||
+ while (!this.pending.isEmpty() && this.pending.peek().getNextRun() <= currentTick) {
|
||||
+ CraftTask task = this.pending.remove();
|
||||
+ if (executeTask(task)) {
|
||||
+ final long period = task.getPeriod();
|
||||
+ if (period > 0) {
|
||||
+ task.setNextRun(currentTick + period);
|
||||
+ temp.add(task);
|
||||
+ }
|
||||
+ }
|
||||
+ parsePending();
|
||||
+ }
|
||||
+ this.pending.addAll(temp);
|
||||
+ temp.clear();
|
||||
+ }
|
||||
+
|
||||
+ private boolean executeTask(CraftTask task) {
|
||||
+ if (isValid(task)) {
|
||||
+ this.runners.put(task.getTaskId(), task);
|
||||
+ this.executor.execute(new ServerSchedulerReportingWrapper(task));
|
||||
+ return true;
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public synchronized void cancelTasks(Plugin plugin) {
|
||||
+ parsePending();
|
||||
+ for (Iterator<CraftTask> iterator = this.pending.iterator(); iterator.hasNext(); ) {
|
||||
+ CraftTask task = iterator.next();
|
||||
+ if (task.getTaskId() != -1 && (plugin == null || task.getOwner().equals(plugin))) {
|
||||
+ task.cancel0();
|
||||
+ iterator.remove();
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ /**
|
||||
+ * Task is not cancelled
|
||||
+ * @param runningTask
|
||||
+ * @return
|
||||
+ */
|
||||
+ static boolean isValid(CraftTask runningTask) {
|
||||
+ return runningTask.getPeriod() >= CraftTask.NO_REPEATING;
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
/**
|
||||
* Main thread logic only
|
||||
*/
|
||||
- private final PriorityQueue<CraftTask> pending = new PriorityQueue<CraftTask>(10,
|
||||
+ final PriorityQueue<CraftTask> pending = new PriorityQueue<CraftTask>(10, // Paper
|
||||
new Comparator<CraftTask>() {
|
||||
@Override
|
||||
public int compare(final CraftTask o1, final CraftTask o2) {
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
/**
|
||||
* These are tasks that are currently active. It's provided for 'viewing' the current state.
|
||||
*/
|
||||
- private final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>();
|
||||
+ final ConcurrentHashMap<Integer, CraftTask> runners = new ConcurrentHashMap<Integer, CraftTask>(); // Paper
|
||||
/**
|
||||
* The sync task that is currently running on the main thread.
|
||||
*/
|
||||
private volatile CraftTask currentTask = null;
|
||||
- private volatile int currentTick = -1;
|
||||
+ // Paper start - Improved Async Task Scheduler
|
||||
+ volatile int currentTick = -1;/*
|
||||
private final Executor executor = Executors.newCachedThreadPool(new ThreadFactoryBuilder().setNameFormat("Craft Scheduler Thread - %d").build());
|
||||
private CraftAsyncDebugger debugHead = new CraftAsyncDebugger(-1, null, null) {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
}
|
||||
};
|
||||
private CraftAsyncDebugger debugTail = this.debugHead;
|
||||
+
|
||||
+ */ // Paper end
|
||||
private static final int RECENT_TICKS;
|
||||
|
||||
static {
|
||||
RECENT_TICKS = 30;
|
||||
}
|
||||
|
||||
+
|
||||
+ // Paper start
|
||||
+ private final CraftScheduler asyncScheduler;
|
||||
+ private final boolean isAsyncScheduler;
|
||||
+ public CraftScheduler() {
|
||||
+ this(false);
|
||||
+ }
|
||||
+
|
||||
+ public CraftScheduler(boolean isAsync) {
|
||||
+ this.isAsyncScheduler = isAsync;
|
||||
+ if (isAsync) {
|
||||
+ this.asyncScheduler = this;
|
||||
+ } else {
|
||||
+ this.asyncScheduler = new CraftAsyncScheduler();
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
@Override
|
||||
public int scheduleSyncDelayedTask(final Plugin plugin, final Runnable task) {
|
||||
return this.scheduleSyncDelayedTask(plugin, task, 0L);
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
} else if (period < CraftTask.NO_REPEATING) {
|
||||
period = CraftTask.NO_REPEATING;
|
||||
}
|
||||
- return this.handle(new CraftAsyncTask(this.runners, plugin, runnable, this.nextId(), period), delay);
|
||||
+ return this.handle(new CraftAsyncTask(this.asyncScheduler.runners, plugin, runnable, this.nextId(), period), delay); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
if (taskId <= 0) {
|
||||
return;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.cancelTask(taskId);
|
||||
+ }
|
||||
+ // Paper end
|
||||
CraftTask task = this.runners.get(taskId);
|
||||
if (task != null) {
|
||||
task.cancel0();
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
@Override
|
||||
public void cancelTasks(final Plugin plugin) {
|
||||
Preconditions.checkArgument(plugin != null, "Cannot cancel tasks of null plugin");
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.cancelTasks(plugin);
|
||||
+ }
|
||||
+ // Paper end
|
||||
final CraftTask task = new CraftTask(
|
||||
new Runnable() {
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
@Override
|
||||
public boolean isCurrentlyRunning(final int taskId) {
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ if (this.asyncScheduler.isCurrentlyRunning(taskId)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
final CraftTask task = this.runners.get(taskId);
|
||||
if (task == null) {
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
if (taskId <= 0) {
|
||||
return false;
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler && this.asyncScheduler.isQueued(taskId)) {
|
||||
+ return true;
|
||||
+ }
|
||||
+ // Paper end
|
||||
for (CraftTask task = this.head.getNext(); task != null; task = task.getNext()) {
|
||||
if (task.getTaskId() == taskId) {
|
||||
return task.getPeriod() >= CraftTask.NO_REPEATING; // The task will run
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
|
||||
@Override
|
||||
public List<BukkitWorker> getActiveWorkers() {
|
||||
+ // Paper start
|
||||
+ if (!isAsyncScheduler) {
|
||||
+ //noinspection TailRecursion
|
||||
+ return this.asyncScheduler.getActiveWorkers();
|
||||
+ }
|
||||
+ // Paper end
|
||||
final ArrayList<BukkitWorker> workers = new ArrayList<BukkitWorker>();
|
||||
for (final CraftTask taskObj : this.runners.values()) {
|
||||
// Iterator will be a best-effort (may fail to grab very new values) if called from an async thread
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
pending.add(task);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ pending.addAll(this.asyncScheduler.getPendingTasks());
|
||||
+ }
|
||||
+ // Paper end
|
||||
return pending;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
* This method is designed to never block or wait for locks; an immediate execution of all current tasks.
|
||||
*/
|
||||
public void mainThreadHeartbeat(final int currentTick) {
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler) {
|
||||
+ this.asyncScheduler.mainThreadHeartbeat(currentTick);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.currentTick = currentTick;
|
||||
final List<CraftTask> temp = this.temp;
|
||||
this.parsePending();
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
this.parsePending();
|
||||
} else {
|
||||
// this.debugTail = this.debugTail.setNext(new CraftAsyncDebugger(currentTick + CraftScheduler.RECENT_TICKS, task.getOwner(), task.getTaskClass())); // Paper
|
||||
- this.executor.execute(new com.destroystokyo.paper.ServerSchedulerReportingWrapper(task)); // Paper
|
||||
+ task.getOwner().getLogger().log(Level.SEVERE, "Unexpected Async Task in the Sync Scheduler. Report this to Paper"); // Paper
|
||||
// We don't need to parse pending
|
||||
// (async tasks must live with race-conditions if they attempt to cancel between these few lines of code)
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
//this.debugHead = this.debugHead.getNextHead(currentTick); // Paper
|
||||
}
|
||||
|
||||
- private void addTask(final CraftTask task) {
|
||||
+ protected void addTask(final CraftTask task) {
|
||||
final AtomicReference<CraftTask> tail = this.tail;
|
||||
CraftTask tailTask = tail.get();
|
||||
while (!tail.compareAndSet(tailTask, task)) {
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
tailTask.setNext(task);
|
||||
}
|
||||
|
||||
- private CraftTask handle(final CraftTask task, final long delay) {
|
||||
+ protected CraftTask handle(final CraftTask task, final long delay) { // Paper
|
||||
+ // Paper start
|
||||
+ if (!this.isAsyncScheduler && !task.isSync()) {
|
||||
+ this.asyncScheduler.handle(task, delay);
|
||||
+ return task;
|
||||
+ }
|
||||
+ // Paper end
|
||||
task.setNextRun(this.currentTick + delay);
|
||||
this.addTask(task);
|
||||
return task;
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
return id;
|
||||
}
|
||||
|
||||
- private void parsePending() {
|
||||
- MinecraftTimings.bukkitSchedulerPendingTimer.startTiming();
|
||||
+ void parsePending() { // Paper
|
||||
+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.startTiming(); // Paper
|
||||
CraftTask head = this.head;
|
||||
CraftTask task = head.getNext();
|
||||
CraftTask lastTask = head;
|
||||
@@ -0,0 +0,0 @@ public class CraftScheduler implements BukkitScheduler {
|
||||
task.setNext(null);
|
||||
}
|
||||
this.head = lastTask;
|
||||
- MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming();
|
||||
+ if (!this.isAsyncScheduler) MinecraftTimings.bukkitSchedulerPendingTimer.stopTiming(); // Paper
|
||||
}
|
||||
|
||||
private boolean isReady(final int currentTick) {
|
||||
@@ -1,58 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Zach Brown <1254957+zachbr@users.noreply.github.com>
|
||||
Date: Tue, 28 Aug 2018 23:04:15 -0400
|
||||
Subject: [PATCH] Inventory#removeItemAnySlot
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
}
|
||||
|
||||
private int first(ItemStack item, boolean withAmount) {
|
||||
+ // Paper start
|
||||
+ return first(item, withAmount, getStorageContents());
|
||||
+ }
|
||||
+
|
||||
+ private int first(ItemStack item, boolean withAmount, ItemStack[] inventory) {
|
||||
+ // Paper end
|
||||
if (item == null) {
|
||||
return -1;
|
||||
}
|
||||
- ItemStack[] inventory = this.getStorageContents();
|
||||
+ // ItemStack[] inventory = this.getStorageContents(); // Paper - let param deal
|
||||
for (int i = 0; i < inventory.length; i++) {
|
||||
if (inventory[i] == null) continue;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
|
||||
@Override
|
||||
public HashMap<Integer, ItemStack> removeItem(ItemStack... items) {
|
||||
+ // Paper start
|
||||
+ return removeItem(false, items);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public HashMap<Integer, ItemStack> removeItemAnySlot(ItemStack... items) {
|
||||
+ return removeItem(true, items);
|
||||
+ }
|
||||
+
|
||||
+ private HashMap<Integer, ItemStack> removeItem(boolean searchEntire, ItemStack... items) {
|
||||
+ // Paper end
|
||||
Preconditions.checkArgument(items != null, "items cannot be null");
|
||||
HashMap<Integer, ItemStack> leftover = new HashMap<Integer, ItemStack>();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class CraftInventory implements Inventory {
|
||||
int toDelete = item.getAmount();
|
||||
|
||||
while (true) {
|
||||
- int first = this.first(item, false);
|
||||
+ // Paper start - Allow searching entire contents
|
||||
+ ItemStack[] toSearch = searchEntire ? getContents() : getStorageContents();
|
||||
+ int first = this.first(item, false, toSearch);
|
||||
+ // Paper end
|
||||
|
||||
// Drat! we don't have this type in the inventory
|
||||
if (first == -1) {
|
||||
@@ -1,220 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 3 Jul 2018 21:56:23 -0400
|
||||
Subject: [PATCH] InventoryCloseEvent Reason API
|
||||
|
||||
Allows you to determine why an inventory was closed, enabling plugin developers
|
||||
to "confirm" things based on if it was player triggered close or not.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
for (net.minecraft.world.level.block.entity.BlockEntity tileentity : chunk.getBlockEntities().values()) {
|
||||
if (tileentity instanceof net.minecraft.world.Container) {
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((net.minecraft.world.Container) tileentity).getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class ServerLevel extends Level implements WorldGenLevel {
|
||||
// Spigot Start
|
||||
if (entity.getBukkitEntity() instanceof org.bukkit.inventory.InventoryHolder && (!(entity instanceof ServerPlayer) || entity.getRemovalReason() != Entity.RemovalReason.KILLED)) { // SPIGOT-6876: closeInventory clears death message
|
||||
for (org.bukkit.entity.HumanEntity h : Lists.newArrayList(((org.bukkit.inventory.InventoryHolder) entity.getBukkitEntity()).getInventory().getViewers())) {
|
||||
- h.closeInventory();
|
||||
+ h.closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNLOADED); // Paper
|
||||
}
|
||||
}
|
||||
// Spigot End
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// Paper end
|
||||
if (!this.level().isClientSide && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
|
||||
// SPIGOT-943 - only call if they have an inventory open
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DEATH); // Paper
|
||||
}
|
||||
|
||||
net.kyori.adventure.text.Component deathMessage = event.deathMessage() != null ? event.deathMessage() : net.kyori.adventure.text.Component.empty(); // Paper - Adventure
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
}
|
||||
// CraftBukkit end
|
||||
if (this.containerMenu != this.inventoryMenu) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
|
||||
// this.nextContainerCounter(); // CraftBukkit - moved up
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
|
||||
@Override
|
||||
public void closeContainer() {
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit
|
||||
+ // Paper start
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ @Override
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this, reason); // CraftBukkit
|
||||
+ // Paper end
|
||||
this.connection.send(new ClientboundContainerClosePacket(this.containerMenu.containerId));
|
||||
this.doCloseContainer();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.event.inventory.ClickType;
|
||||
import org.bukkit.event.inventory.CraftItemEvent;
|
||||
import org.bukkit.event.inventory.InventoryAction;
|
||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
||||
+import org.bukkit.event.inventory.InventoryCloseEvent; // Paper
|
||||
import org.bukkit.event.inventory.InventoryCreativeEvent;
|
||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
||||
import org.bukkit.event.inventory.SmithItemEvent;
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
|
||||
@Override
|
||||
public void handleContainerClose(ServerboundContainerClosePacket packet) {
|
||||
+ // Paper start
|
||||
+ this.handleContainerClose(packet, InventoryCloseEvent.Reason.PLAYER);
|
||||
+ }
|
||||
+ public void handleContainerClose(ServerboundContainerClosePacket packet, InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end
|
||||
PacketUtils.ensureRunningOnSameThread(packet, this, this.player.serverLevel());
|
||||
|
||||
if (this.player.isImmobile()) return; // CraftBukkit
|
||||
- CraftEventFactory.handleInventoryCloseEvent(this.player); // CraftBukkit
|
||||
+ CraftEventFactory.handleInventoryCloseEvent(this.player, reason); // CraftBukkit // Paper
|
||||
|
||||
this.player.doCloseContainer();
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
// CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it
|
||||
// See SPIGOT-5799, SPIGOT-6145
|
||||
if (entityplayer.containerMenu != entityplayer.inventoryMenu) {
|
||||
- entityplayer.closeContainer();
|
||||
+ entityplayer.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.DISCONNECT); // Paper
|
||||
}
|
||||
|
||||
PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), net.kyori.adventure.text.Component.translatable("multiplayer.player.left", net.kyori.adventure.text.format.NamedTextColor.YELLOW, io.papermc.paper.configuration.GlobalConfiguration.get().messages.useDisplayNameInQuitMessage ? entityplayer.getBukkitEntity().displayName() : io.papermc.paper.adventure.PaperAdventure.asAdventure(entityplayer.getDisplayName()))); // Paper - Adventure
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
this.updateIsUnderwater();
|
||||
super.tick();
|
||||
if (!this.level().isClientSide && this.containerMenu != null && !this.containerMenu.stillValid(this)) {
|
||||
- this.closeContainer();
|
||||
+ this.closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.CANT_USE); // Paper
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
}
|
||||
|
||||
+ // Paper start - unused code, but to keep signatures aligned
|
||||
+ public void closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ closeContainer();
|
||||
+ this.containerMenu = this.inventoryMenu;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public void closeContainer() {
|
||||
this.containerMenu = this.inventoryMenu;
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
if (((ServerPlayer) this.getHandle()).connection == null) return;
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
// fire INVENTORY_CLOSE if one already open
|
||||
- ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId));
|
||||
+ ((ServerPlayer) this.getHandle()).connection.handleContainerClose(new ServerboundContainerClosePacket(this.getHandle().containerMenu.containerId), org.bukkit.event.inventory.InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
ServerPlayer player = (ServerPlayer) this.getHandle();
|
||||
AbstractContainerMenu container;
|
||||
@@ -0,0 +0,0 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity {
|
||||
|
||||
@Override
|
||||
public void closeInventory() {
|
||||
- this.getHandle().closeContainer();
|
||||
+ // Paper start
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.PLUGIN);
|
||||
}
|
||||
+ @Override
|
||||
+ public void closeInventory(org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ getHandle().closeContainer(reason);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
@Override
|
||||
public boolean isBlocking() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
// Close any foreign inventory
|
||||
if (this.getHandle().containerMenu != this.getHandle().inventoryMenu) {
|
||||
- this.getHandle().closeContainer();
|
||||
+ this.getHandle().closeContainer(org.bukkit.event.inventory.InventoryCloseEvent.Reason.TELEPORT); // Paper
|
||||
}
|
||||
|
||||
// Check if the fromWorld and toWorld are the same.
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
|
||||
public static AbstractContainerMenu callInventoryOpenEvent(ServerPlayer player, AbstractContainerMenu container, boolean cancelled) {
|
||||
if (player.containerMenu != player.inventoryMenu) { // fire INVENTORY_CLOSE if one already open
|
||||
- player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId));
|
||||
+ player.connection.handleContainerClose(new ServerboundContainerClosePacket(player.containerMenu.containerId), InventoryCloseEvent.Reason.OPEN_NEW); // Paper
|
||||
}
|
||||
|
||||
CraftServer server = player.level().getCraftServer();
|
||||
@@ -0,0 +0,0 @@ public class CraftEventFactory {
|
||||
return event;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ /**
|
||||
+ * Incase plugins hooked into this or Spigot adds a new inventory close event. Prefer to pass a reason
|
||||
+ * @param human
|
||||
+ */
|
||||
+ @Deprecated
|
||||
public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human) {
|
||||
- InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView());
|
||||
+ handleInventoryCloseEvent(human, org.bukkit.event.inventory.InventoryCloseEvent.Reason.UNKNOWN);
|
||||
+ }
|
||||
+ public static void handleInventoryCloseEvent(net.minecraft.world.entity.player.Player human, org.bukkit.event.inventory.InventoryCloseEvent.Reason reason) {
|
||||
+ // Paper end
|
||||
+ InventoryCloseEvent event = new InventoryCloseEvent(human.containerMenu.getBukkitView(), reason); // Paper
|
||||
human.level().getCraftServer().getPluginManager().callEvent(event);
|
||||
human.containerMenu.transferTo(human.inventoryMenu, human.getBukkitEntity());
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 5 Jun 2018 23:00:29 -0400
|
||||
Subject: [PATCH] ItemStack#getMaxItemUseDuration
|
||||
|
||||
Allows you to determine how long it takes to use a usable/consumable item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java
|
||||
@@ -0,0 +0,0 @@ public final class CraftItemStack extends ItemStack {
|
||||
return (this.handle == null) ? Material.AIR.getMaxStackSize() : this.handle.getItem().getMaxStackSize();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public int getMaxItemUseDuration() {
|
||||
+ return handle == null ? 0 : handle.getUseDuration();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public void addUnsafeEnchantment(Enchantment ench, int level) {
|
||||
Preconditions.checkArgument(ench != null, "Enchantment cannot be null");
|
||||
@@ -1,42 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 29 Jun 2018 00:21:28 -0400
|
||||
Subject: [PATCH] LivingEntity Hand Raised/Item Use API
|
||||
|
||||
How long an entity has raised hands to charge an attack or use an item
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void setShieldBlockingDelay(int delay) {
|
||||
getHandle().setShieldBlockingDelay(delay);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public ItemStack getActiveItem() {
|
||||
+ return getHandle().getUseItem().asBukkitMirror();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getItemUseRemainingTime() {
|
||||
+ return getHandle().getUseItemRemainingTicks();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getHandRaisedTime() {
|
||||
+ return getHandle().getTicksUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean isHandRaised() {
|
||||
+ return getHandle().isUsingItem();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public org.bukkit.inventory.EquipmentSlot getHandRaised() {
|
||||
+ return getHandle().getUsedItemHand() == net.minecraft.world.InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND;
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:49:48 -0500
|
||||
Subject: [PATCH] LivingEntity#setKiller
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.LivingEntity lastHurtByPlayerTime
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
return this.getHandle().lastHurtByPlayer == null ? null : (Player) this.getHandle().lastHurtByPlayer.getBukkitEntity();
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setKiller(Player killer) {
|
||||
+ net.minecraft.server.level.ServerPlayer entityPlayer = killer == null ? null : ((CraftPlayer) killer).getHandle();
|
||||
+ getHandle().lastHurtByPlayer = entityPlayer;
|
||||
+ getHandle().lastHurtByMob = entityPlayer;
|
||||
+ getHandle().lastHurtByPlayerTime = entityPlayer == null ? 0 : 100; // 100 value taken from EntityLiving#damageEntity
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public boolean addPotionEffect(PotionEffect effect) {
|
||||
return this.addPotionEffect(effect, false);
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Sun, 2 Sep 2018 19:34:33 -0700
|
||||
Subject: [PATCH] Make CraftWorld#loadChunk(int, int, false) load unconverted
|
||||
chunks
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
|
||||
@@ -0,0 +0,0 @@ public class CraftWorld extends CraftRegionAccessor implements World {
|
||||
@Override
|
||||
public boolean loadChunk(int x, int z, boolean generate) {
|
||||
org.spigotmc.AsyncCatcher.catchOp("chunk load"); // Spigot
|
||||
- ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate ? ChunkStatus.FULL : ChunkStatus.EMPTY, true);
|
||||
+ ChunkAccess chunk = this.world.getChunkSource().getChunk(x, z, generate || isChunkGenerated(x, z) ? ChunkStatus.FULL : ChunkStatus.EMPTY, true); // Paper
|
||||
|
||||
// If generate = false, but the chunk already exists, we will get this back.
|
||||
if (chunk instanceof ImposterProtoChunk) {
|
||||
@@ -1,188 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Wed, 11 Oct 2017 18:22:50 +0200
|
||||
Subject: [PATCH] Make legacy ping handler more reliable
|
||||
|
||||
The Minecraft server often fails to respond to old ("legacy") pings
|
||||
from old Minecraft versions using the protocol used before the switch
|
||||
to Netty in Minecraft 1.7.
|
||||
|
||||
Due to packet fragmentation[1], we might not have all needed bytes
|
||||
available when the LegacyPingHandler is called. In this case, it will
|
||||
run into an error, remove the handler and continue using the modern
|
||||
protocol.
|
||||
|
||||
This is unlikely to happen for the first two revisions of the legacy
|
||||
ping protocol (used in Minecraft 1.5.x and older) since the request
|
||||
consists of only one or two bytes, but happens frequently for the
|
||||
last/third revision introduced in Minecraft 1.6.
|
||||
|
||||
It has much larger, variable packet sizes due to the inclusion of
|
||||
the virtual host (the hostname/port used to connect to the server).
|
||||
|
||||
The solution[2] is simple: If we find more than two matching bytes,
|
||||
we buffer the remaining bytes until we have enough to fully read and
|
||||
respond to the request.
|
||||
|
||||
[1]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h3-11
|
||||
[2]: https://netty.io/wiki/user-guide-for-4.x.html#wiki-h4-13
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/LegacyQueryHandler.java
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
private final ServerInfo server;
|
||||
+ private ByteBuf buf; // Paper
|
||||
|
||||
public LegacyQueryHandler(ServerInfo server) {
|
||||
this.server = server;
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
public void channelRead(ChannelHandlerContext channelhandlercontext, Object object) {
|
||||
ByteBuf bytebuf = (ByteBuf) object;
|
||||
|
||||
+ // Paper start - Make legacy ping handler more reliable
|
||||
+ if (this.buf != null) {
|
||||
+ try {
|
||||
+ readLegacy1_6(channelhandlercontext, bytebuf);
|
||||
+ } finally {
|
||||
+ bytebuf.release();
|
||||
+ }
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
bytebuf.markReaderIndex();
|
||||
boolean flag = true;
|
||||
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
|
||||
SocketAddress socketaddress = channelhandlercontext.channel().remoteAddress();
|
||||
int i = bytebuf.readableBytes();
|
||||
- String s;
|
||||
+ String s = null; // Paper
|
||||
org.bukkit.event.server.ServerListPingEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callServerListPingEvent(socketaddress, this.server.getMotd(), this.server.getPlayerCount(), this.server.getMaxPlayers()); // CraftBukkit
|
||||
|
||||
if (i == 0) {
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
|
||||
if (bytebuf.isReadable()) {
|
||||
- if (!LegacyQueryHandler.readCustomPayloadPacket(bytebuf)) {
|
||||
- return;
|
||||
+ // Paper start - Replace with improved version below
|
||||
+ if (bytebuf.readUnsignedByte() != 250) {
|
||||
+ s = this.readLegacy1_6(channelhandlercontext, bytebuf);
|
||||
+ if (s == null) {
|
||||
+ return;
|
||||
+ }
|
||||
}
|
||||
-
|
||||
- LegacyQueryHandler.LOGGER.debug("Ping: (1.6) from {}", socketaddress);
|
||||
+ // if (!LegacyQueryHandler.readCustomPayloadPacket(bytebuf)) {
|
||||
+ // return;
|
||||
+ // }
|
||||
+ //
|
||||
+ // LegacyQueryHandler.LOGGER.debug("Ping: (1.6) from {}", socketaddress);
|
||||
+ // Paper end
|
||||
} else {
|
||||
LegacyQueryHandler.LOGGER.debug("Ping: (1.4-1.5.x) from {}", socketaddress);
|
||||
}
|
||||
|
||||
- s = LegacyQueryHandler.createVersion1Response(this.server, event); // CraftBukkit
|
||||
+ if (s == null) s = LegacyQueryHandler.createVersion1Response(this.server, event); // CraftBukkit // Paper
|
||||
LegacyQueryHandler.sendFlushAndClose(channelhandlercontext, LegacyQueryHandler.createLegacyDisconnectPacket(channelhandlercontext.alloc(), s));
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class LegacyQueryHandler extends ChannelInboundHandlerAdapter {
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ private static String readLegacyString(ByteBuf buf) {
|
||||
+ int size = buf.readShort() * Character.BYTES;
|
||||
+ if (!buf.isReadable(size)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ String result = buf.toString(buf.readerIndex(), size, java.nio.charset.StandardCharsets.UTF_16BE);
|
||||
+ buf.skipBytes(size); // toString doesn't increase readerIndex automatically
|
||||
+ return result;
|
||||
+ }
|
||||
+
|
||||
+ private String readLegacy1_6(ChannelHandlerContext ctx, ByteBuf part) {
|
||||
+ ByteBuf buf = this.buf;
|
||||
+
|
||||
+ if (buf == null) {
|
||||
+ this.buf = buf = ctx.alloc().buffer();
|
||||
+ buf.markReaderIndex();
|
||||
+ } else {
|
||||
+ buf.resetReaderIndex();
|
||||
+ }
|
||||
+
|
||||
+ buf.writeBytes(part);
|
||||
+
|
||||
+ if (!buf.isReadable(Short.BYTES + Short.BYTES + Byte.BYTES + Short.BYTES + Integer.BYTES)) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ String s = readLegacyString(buf);
|
||||
+ if (s == null) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ if (!s.equals("MC|PingHost")) {
|
||||
+ removeHandler(ctx);
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ if (!buf.isReadable(Short.BYTES) || !buf.isReadable(buf.readShort())) {
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ net.minecraft.server.MinecraftServer server = net.minecraft.server.MinecraftServer.getServer();
|
||||
+ int protocolVersion = buf.readByte();
|
||||
+ String host = readLegacyString(buf);
|
||||
+ if (host == null) {
|
||||
+ removeHandler(ctx);
|
||||
+ return null;
|
||||
+ }
|
||||
+ int port = buf.readInt();
|
||||
+
|
||||
+ if (buf.isReadable()) {
|
||||
+ removeHandler(ctx);
|
||||
+ return null;
|
||||
+ }
|
||||
+
|
||||
+ buf.release();
|
||||
+ this.buf = null;
|
||||
+
|
||||
+ LOGGER.debug("Ping: (1.6) from {}", ctx.channel().remoteAddress());
|
||||
+
|
||||
+ String response = String.format("\u00a71\u0000%d\u0000%s\u0000%s\u0000%d\u0000%d",
|
||||
+ Byte.MAX_VALUE, server.getServerVersion(), server.getMotd(), server.getPlayerCount(), server.getMaxPlayers());
|
||||
+ return response;
|
||||
+ }
|
||||
+
|
||||
+ private void removeHandler(ChannelHandlerContext ctx) {
|
||||
+ ByteBuf buf = this.buf;
|
||||
+ this.buf = null;
|
||||
+
|
||||
+ buf.resetReaderIndex();
|
||||
+ ctx.pipeline().remove(this);
|
||||
+ ctx.fireChannelRead(buf);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void handlerRemoved(ChannelHandlerContext ctx) {
|
||||
+ if (this.buf != null) {
|
||||
+ this.buf.release();
|
||||
+ this.buf = null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
// CraftBukkit start
|
||||
private static String createVersion0Response(ServerInfo serverinfo, org.bukkit.event.server.ServerListPingEvent event) {
|
||||
return String.format(Locale.ROOT, "%s\u00a7%d\u00a7%d", event.getMotd(), event.getNumPlayers(), event.getMaxPlayers());
|
||||
@@ -1,56 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 16 Jun 2018 01:18:16 -0500
|
||||
Subject: [PATCH] Make shield blocking delay configurable
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public abstract class LivingEntity extends Entity implements Attackable {
|
||||
if (this.isUsingItem() && !this.useItem.isEmpty()) {
|
||||
Item item = this.useItem.getItem();
|
||||
|
||||
- return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= 5;
|
||||
+ return item.getUseAnimation(this.useItem) != UseAnim.BLOCK ? false : item.getUseDuration(this.useItem) - this.useItemRemaining >= getShieldBlockingDelay(); // Paper - shieldBlockingDelay
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ public int shieldBlockingDelay = this.level().paperConfig().misc.shieldBlockingDelay;
|
||||
+
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return shieldBlockingDelay;
|
||||
+ }
|
||||
+
|
||||
+ public void setShieldBlockingDelay(int shieldBlockingDelay) {
|
||||
+ this.shieldBlockingDelay = shieldBlockingDelay;
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
public boolean isSuppressingSlidingDownLadder() {
|
||||
return this.isShiftKeyDown();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
|
||||
@@ -0,0 +0,0 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
|
||||
public void setArrowsStuck(final int arrows) {
|
||||
this.getHandle().setArrowCount(arrows);
|
||||
}
|
||||
+
|
||||
+ @Override
|
||||
+ public int getShieldBlockingDelay() {
|
||||
+ return getHandle().getShieldBlockingDelay();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setShieldBlockingDelay(int delay) {
|
||||
+ getHandle().setShieldBlockingDelay(delay);
|
||||
+ }
|
||||
// Paper end
|
||||
}
|
||||
@@ -1,204 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 9 Sep 2018 13:30:00 -0400
|
||||
Subject: [PATCH] Mob Pathfinding API
|
||||
|
||||
Implements Pathfinding API for mobs
|
||||
|
||||
== AT ==
|
||||
public net.minecraft.world.entity.ai.navigation.PathNavigation pathFinder
|
||||
public net.minecraft.world.level.pathfinder.PathFinder nodeEvaluator
|
||||
public net.minecraft.world.level.pathfinder.Path nodes
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/PaperPathfinder.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import org.apache.commons.lang.Validate;
|
||||
+import org.bukkit.Location;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+import org.bukkit.entity.Mob;
|
||||
+import javax.annotation.Nonnull;
|
||||
+import javax.annotation.Nullable;
|
||||
+import net.minecraft.world.level.pathfinder.Node;
|
||||
+import net.minecraft.world.level.pathfinder.Path;
|
||||
+import java.util.ArrayList;
|
||||
+import java.util.List;
|
||||
+
|
||||
+public class PaperPathfinder implements com.destroystokyo.paper.entity.Pathfinder {
|
||||
+
|
||||
+ private net.minecraft.world.entity.Mob entity;
|
||||
+
|
||||
+ public PaperPathfinder(net.minecraft.world.entity.Mob entity) {
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public Mob getEntity() {
|
||||
+ return entity.getBukkitMob();
|
||||
+ }
|
||||
+
|
||||
+ public void setHandle(net.minecraft.world.entity.Mob entity) {
|
||||
+ this.entity = entity;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void stopPathfinding() {
|
||||
+ entity.getNavigation().stop();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean hasPath() {
|
||||
+ return entity.getNavigation().getPath() != null && !entity.getNavigation().getPath().isDone();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult getCurrentPath() {
|
||||
+ Path path = entity.getNavigation().getPath();
|
||||
+ return path != null && !path.isDone() ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult findPath(Location loc) {
|
||||
+ Validate.notNull(loc, "Location can not be null");
|
||||
+ Path path = entity.getNavigation().createPath(loc.getX(), loc.getY(), loc.getZ(), 0);
|
||||
+ return path != null ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public PathResult findPath(LivingEntity target) {
|
||||
+ Validate.notNull(target, "Target can not be null");
|
||||
+ Path path = entity.getNavigation().createPath(((CraftLivingEntity) target).getHandle(), 0);
|
||||
+ return path != null ? new PaperPathResult(path) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean moveTo(@Nonnull PathResult path, double speed) {
|
||||
+ Validate.notNull(path, "PathResult can not be null");
|
||||
+ Path pathEntity = ((PaperPathResult) path).path;
|
||||
+ return entity.getNavigation().moveTo(pathEntity, speed);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canOpenDoors() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canOpenDoors();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanOpenDoors(boolean canOpenDoors) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanOpenDoors(canOpenDoors);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canPassDoors() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canPassDoors();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanPassDoors(boolean canPassDoors) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanPassDoors(canPassDoors);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public boolean canFloat() {
|
||||
+ return entity.getNavigation().pathFinder.nodeEvaluator.canFloat();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setCanFloat(boolean canFloat) {
|
||||
+ entity.getNavigation().pathFinder.nodeEvaluator.setCanFloat(canFloat);
|
||||
+ }
|
||||
+
|
||||
+ public class PaperPathResult implements com.destroystokyo.paper.entity.PaperPathfinder.PathResult {
|
||||
+
|
||||
+ private final Path path;
|
||||
+ PaperPathResult(Path path) {
|
||||
+ this.path = path;
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getFinalPoint() {
|
||||
+ Node point = path.getEndNode();
|
||||
+ return point != null ? toLoc(point) : null;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public List<Location> getPoints() {
|
||||
+ List<Location> points = new ArrayList<>();
|
||||
+ for (Node point : path.nodes) {
|
||||
+ points.add(toLoc(point));
|
||||
+ }
|
||||
+ return points;
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public int getNextPointIndex() {
|
||||
+ return path.getNextNodeIndex();
|
||||
+ }
|
||||
+
|
||||
+ @Nullable
|
||||
+ @Override
|
||||
+ public Location getNextPoint() {
|
||||
+ if (!path.hasNext()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ return toLoc(path.nodes.get(path.getNextNodeIndex()));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private Location toLoc(Node point) {
|
||||
+ return new Location(entity.level().getWorld(), point.x, point.y, point.z);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/pathfinder/Path.java b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/pathfinder/Path.java
|
||||
@@ -0,0 +0,0 @@ public class Path {
|
||||
private final BlockPos target;
|
||||
private final float distToTarget;
|
||||
private final boolean reached;
|
||||
+ public boolean hasNext() { return getNextNodeIndex() < this.nodes.size(); } // Paper
|
||||
|
||||
public Path(List<Node> nodes, BlockPos target, boolean reachesTarget) {
|
||||
this.nodes = nodes;
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMob.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.loot.LootTable;
|
||||
public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
public CraftMob(CraftServer server, net.minecraft.world.entity.Mob entity) {
|
||||
super(server, entity);
|
||||
+ paperPathfinder = new com.destroystokyo.paper.entity.PaperPathfinder(entity); // Paper
|
||||
}
|
||||
|
||||
+ private final com.destroystokyo.paper.entity.PaperPathfinder paperPathfinder; // Paper
|
||||
+ @Override public com.destroystokyo.paper.entity.Pathfinder getPathfinder() { return paperPathfinder; } // Paper
|
||||
@Override
|
||||
public void setTarget(LivingEntity target) {
|
||||
Preconditions.checkState(!this.getHandle().generation, "Cannot set target during world generation");
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftMob extends CraftLivingEntity implements Mob {
|
||||
return (net.minecraft.world.entity.Mob) this.entity;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setHandle(net.minecraft.world.entity.Entity entity) {
|
||||
+ super.setHandle(entity);
|
||||
+ paperPathfinder.setHandle(getHandle());
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Override
|
||||
public String toString() {
|
||||
return "CraftMob";
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:54:40 -0500
|
||||
Subject: [PATCH] Ocelot despawns should honor nametags and leash
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/Ocelot.java
|
||||
@@ -0,0 +0,0 @@ public class Ocelot extends Animal {
|
||||
|
||||
@Override
|
||||
public boolean removeWhenFarAway(double distanceSquared) {
|
||||
- return !this.isTrusting() && this.tickCount > 2400;
|
||||
+ return !this.isTrusting() && this.tickCount > 2400 && !this.hasCustomName() && !this.isLeashed(); // Paper - honor name and leash
|
||||
}
|
||||
|
||||
public static AttributeSupplier.Builder createAttributes() {
|
||||
@@ -1,108 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
|
||||
Date: Wed, 15 Aug 2018 12:05:12 -0700
|
||||
Subject: [PATCH] Optimize BlockPosition helper methods
|
||||
|
||||
Resolves #1338
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/BlockPos.java b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/BlockPos.java
|
||||
+++ b/src/main/java/net/minecraft/core/BlockPos.java
|
||||
@@ -0,0 +0,0 @@ public class BlockPos extends Vec3i {
|
||||
|
||||
@Override
|
||||
public BlockPos above() {
|
||||
- return this.relative(Direction.UP);
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos above(int distance) {
|
||||
- return this.relative(Direction.UP, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY() + distance, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below() {
|
||||
- return this.relative(Direction.DOWN);
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos below(int i) {
|
||||
- return this.relative(Direction.DOWN, i);
|
||||
+ return i == 0 ? this : new BlockPos(this.getX(), this.getY() - i, this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north() {
|
||||
- return this.relative(Direction.NORTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos north(int distance) {
|
||||
- return this.relative(Direction.NORTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() - distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south() {
|
||||
- return this.relative(Direction.SOUTH);
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos south(int distance) {
|
||||
- return this.relative(Direction.SOUTH, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX(), this.getY(), this.getZ() + distance); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west() {
|
||||
- return this.relative(Direction.WEST);
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos west(int distance) {
|
||||
- return this.relative(Direction.WEST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() - distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east() {
|
||||
- return this.relative(Direction.EAST);
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos east(int distance) {
|
||||
- return this.relative(Direction.EAST, distance);
|
||||
+ return distance == 0 ? this : new BlockPos(this.getX() + distance, this.getY(), this.getZ()); // Paper - Optimize BlockPosition
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlockPos relative(Direction direction) {
|
||||
+ // Paper Start - Optimize BlockPosition
|
||||
+ switch(direction) {
|
||||
+ case UP:
|
||||
+ return new BlockPos(this.getX(), this.getY() + 1, this.getZ());
|
||||
+ case DOWN:
|
||||
+ return new BlockPos(this.getX(), this.getY() - 1, this.getZ());
|
||||
+ case NORTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() - 1);
|
||||
+ case SOUTH:
|
||||
+ return new BlockPos(this.getX(), this.getY(), this.getZ() + 1);
|
||||
+ case WEST:
|
||||
+ return new BlockPos(this.getX() - 1, this.getY(), this.getZ());
|
||||
+ case EAST:
|
||||
+ return new BlockPos(this.getX() + 1, this.getY(), this.getZ());
|
||||
+ default:
|
||||
return new BlockPos(this.getX() + direction.getStepX(), this.getY() + direction.getStepY(), this.getZ() + direction.getStepZ());
|
||||
+ }
|
||||
+ // Paper End
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1,49 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: miclebrick <miclebrick@outlook.com>
|
||||
Date: Thu, 23 Aug 2018 11:45:32 -0400
|
||||
Subject: [PATCH] Optimize CraftBlockData Creation
|
||||
|
||||
Avoids a hashmap lookup by cacheing a reference to the CraftBlockData
|
||||
and cloning it when one is needed.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/state/BlockBehaviour.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BlockBehaviour implements FeatureElement {
|
||||
this.replaceable = blockbase_info.replaceable;
|
||||
this.conditionallyFullOpaque = this.isOpaque() & this.isTransparentOnSomeFaces(); // Paper
|
||||
}
|
||||
+ // Paper start - impl cached craft block data, lazy load to fix issue with loading at the wrong time
|
||||
+ private org.bukkit.craftbukkit.block.data.CraftBlockData cachedCraftBlockData;
|
||||
+
|
||||
+ public org.bukkit.craftbukkit.block.data.CraftBlockData createCraftBlockData() {
|
||||
+ if (cachedCraftBlockData == null) cachedCraftBlockData = org.bukkit.craftbukkit.block.data.CraftBlockData.createData(asState());
|
||||
+ return (org.bukkit.craftbukkit.block.data.CraftBlockData) cachedCraftBlockData.clone();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
private boolean calculateSolid() {
|
||||
if (((Block) this.owner).properties.forceSolidOn) {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/block/data/CraftBlockData.java
|
||||
@@ -0,0 +0,0 @@ public class CraftBlockData implements BlockData {
|
||||
return craft;
|
||||
}
|
||||
|
||||
+ // Paper start - optimize creating BlockData to not need a map lookup
|
||||
+ static {
|
||||
+ // Initialize cached data for all IBlockData instances after registration
|
||||
+ Block.BLOCK_STATE_REGISTRY.iterator().forEachRemaining(net.minecraft.world.level.block.state.BlockState::createCraftBlockData);
|
||||
+ }
|
||||
public static CraftBlockData fromData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
+ return data.createCraftBlockData();
|
||||
+ }
|
||||
+
|
||||
+ public static CraftBlockData createData(net.minecraft.world.level.block.state.BlockState data) {
|
||||
+ // Paper end
|
||||
return CraftBlockData.MAP.getOrDefault(data.getBlock().getClass(), CraftBlockData::new).apply(data);
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 26 Aug 2018 20:49:50 -0400
|
||||
Subject: [PATCH] Optimize MappedRegistry
|
||||
|
||||
Use larger initial sizes to increase bucket capacity on the BiMap
|
||||
|
||||
BiMap.get was seen to be using a good bit of CPU time.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/core/MappedRegistry.java b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
+++ b/src/main/java/net/minecraft/core/MappedRegistry.java
|
||||
@@ -0,0 +0,0 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
private static final Logger LOGGER = LogUtils.getLogger();
|
||||
final ResourceKey<? extends Registry<T>> key;
|
||||
private final ObjectList<Holder.Reference<T>> byId = new ObjectArrayList<>(256);
|
||||
- private final Object2IntMap<T> toId = Util.make(new Object2IntOpenCustomHashMap<>(Util.identityStrategy()), (map) -> {
|
||||
- map.defaultReturnValue(-1);
|
||||
- });
|
||||
- private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>();
|
||||
- private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>();
|
||||
- private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>();
|
||||
- private final Map<T, Lifecycle> lifecycles = new IdentityHashMap<>();
|
||||
+ private final it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T> toId = new it.unimi.dsi.fastutil.objects.Reference2IntOpenHashMap<T>(2048);// Paper - use bigger expected size to reduce collisions and direct intent for FastUtil to be identity map
|
||||
+ private final Map<ResourceLocation, Holder.Reference<T>> byLocation = new HashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<ResourceKey<T>, Holder.Reference<T>> byKey = new HashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Holder.Reference<T>> byValue = new IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
+ private final Map<T, Lifecycle> lifecycles = new IdentityHashMap<>(2048); // Paper - use bigger expected size to reduce collisions
|
||||
private Lifecycle registryLifecycle;
|
||||
private volatile Map<TagKey<T>, HolderSet.Named<T>> tags = new IdentityHashMap<>();
|
||||
private boolean frozen;
|
||||
@@ -0,0 +0,0 @@ public class MappedRegistry<T> implements WritableRegistry<T> {
|
||||
}
|
||||
|
||||
public MappedRegistry(ResourceKey<? extends Registry<T>> key, Lifecycle lifecycle, boolean intrusive) {
|
||||
+ this.toId.defaultReturnValue(-1); // Paper
|
||||
Bootstrap.checkBootstrapCalled(() -> {
|
||||
return "registry " + key;
|
||||
});
|
||||
@@ -1,36 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Hugo Manrique <hugmanrique@gmail.com>
|
||||
Date: Mon, 23 Jul 2018 12:57:39 +0200
|
||||
Subject: [PATCH] Option to prevent armor stands from doing entity lookups
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/decoration/ArmorStand.java
|
||||
@@ -0,0 +0,0 @@ public class ArmorStand extends LivingEntity {
|
||||
|
||||
@Override
|
||||
protected void pushEntities() {
|
||||
+ if (!this.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return; // Paper
|
||||
List<Entity> list = this.level().getEntities((Entity) this, this.getBoundingBox(), ArmorStand.RIDABLE_MINECARTS);
|
||||
Iterator iterator = list.iterator();
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/Level.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/Level.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
|
||||
// Paper end
|
||||
}
|
||||
}
|
||||
+ // Paper start - Prevent armor stands from doing entity lookups
|
||||
+ @Override
|
||||
+ public boolean noCollision(@Nullable Entity entity, AABB box) {
|
||||
+ if (entity instanceof net.minecraft.world.entity.decoration.ArmorStand && !entity.level().paperConfig().entities.armorStands.doCollisionEntityLookups) return false;
|
||||
+ return LevelAccessor.super.noCollision(entity, box);
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public boolean shouldTickDeath(Entity entity) {
|
||||
return true;
|
||||
@@ -1,218 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 18 Mar 2018 12:29:48 -0400
|
||||
Subject: [PATCH] Player.setPlayerProfile API
|
||||
|
||||
This can be useful for changing name or skins after a player has logged in.
|
||||
|
||||
== AT ==
|
||||
public-f net.minecraft.world.entity.player.Player gameProfile
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
this.internalTeleport(dest.getX(), dest.getY(), dest.getZ(), dest.getYaw(), dest.getPitch(), Collections.emptySet());
|
||||
}
|
||||
|
||||
- private void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<RelativeMovement> set) {
|
||||
+ public void internalTeleport(double d0, double d1, double d2, float f, float f1, Set<RelativeMovement> set) { // Paper
|
||||
// CraftBukkit start
|
||||
if (Float.isNaN(f)) {
|
||||
f = 0;
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
final org.bukkit.craftbukkit.CraftServer server = ServerLoginPacketListenerImpl.this.server.server;
|
||||
|
||||
// Paper start
|
||||
- com.destroystokyo.paper.profile.PlayerProfile profile = org.bukkit.Bukkit.createProfile(uniqueId, playerName);
|
||||
+ com.destroystokyo.paper.profile.PlayerProfile profile = com.destroystokyo.paper.profile.CraftPlayerProfile.asBukkitMirror(gameprofile);
|
||||
AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId, profile);
|
||||
server.getPluginManager().callEvent(asyncEvent);
|
||||
profile = asyncEvent.getPlayerProfile();
|
||||
- profile.complete();
|
||||
+ profile.complete(true); // Paper - setPlayerProfileAPI
|
||||
gameprofile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile);
|
||||
playerName = gameprofile.getName();
|
||||
uniqueId = gameprofile.getId();
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftOfflinePlayer implements OfflinePlayer, ConfigurationSerializa
|
||||
}
|
||||
|
||||
@Override
|
||||
- public PlayerProfile getPlayerProfile() {
|
||||
- return new CraftPlayerProfile(this.profile);
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile() { // Paper
|
||||
+ return new com.destroystokyo.paper.profile.CraftPlayerProfile(this.profile); // Paper
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
return this.server.getPlayer(this.getUniqueId()) != null;
|
||||
}
|
||||
|
||||
- @Override
|
||||
- public PlayerProfile getPlayerProfile() {
|
||||
- return new CraftPlayerProfile(this.getProfile());
|
||||
- }
|
||||
-
|
||||
@Override
|
||||
public InetSocketAddress getAddress() {
|
||||
if (this.getHandle().connection == null) return null;
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
private void untrackAndHideEntity(org.bukkit.entity.Entity entity) {
|
||||
// Remove this entity from the hidden player's EntityTrackerEntry
|
||||
- ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap;
|
||||
+ // Paper start
|
||||
Entity other = ((CraftEntity) entity).getHandle();
|
||||
+ unregisterEntity(other);
|
||||
+
|
||||
+ server.getPluginManager().callEvent(new PlayerHideEntityEvent(this, entity));
|
||||
+ }
|
||||
+ private void unregisterEntity(Entity other) {
|
||||
+ // Paper end
|
||||
+ ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap;
|
||||
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
|
||||
if (entry != null) {
|
||||
entry.removePlayer(this.getHandle());
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.getHandle().connection.send(new ClientboundPlayerInfoRemovePacket(List.of(otherPlayer.getUUID())));
|
||||
}
|
||||
}
|
||||
-
|
||||
- this.server.getPluginManager().callEvent(new PlayerHideEntityEvent(this, entity));
|
||||
}
|
||||
|
||||
void resetAndHideEntity(org.bukkit.entity.Entity entity) {
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
}
|
||||
|
||||
private void trackAndShowEntity(org.bukkit.entity.Entity entity) {
|
||||
+ // Paper start - uuid override
|
||||
+ this.trackAndShowEntity(entity, null);
|
||||
+ }
|
||||
+ private void trackAndShowEntity(org.bukkit.entity.Entity entity, final @Nullable UUID uuidOverride) {
|
||||
+ // Paper end
|
||||
ChunkMap tracker = ((ServerLevel) this.getHandle().level()).getChunkSource().chunkMap;
|
||||
Entity other = ((CraftEntity) entity).getHandle();
|
||||
|
||||
if (other instanceof ServerPlayer) {
|
||||
ServerPlayer otherPlayer = (ServerPlayer) other;
|
||||
+ // Paper start - uuid override
|
||||
+ UUID original = null;
|
||||
+ if (uuidOverride != null) {
|
||||
+ original = otherPlayer.getUUID();
|
||||
+ otherPlayer.setUUID(uuidOverride);
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.getHandle().connection.send(ClientboundPlayerInfoUpdatePacket.createPlayerInitializing(List.of(otherPlayer)));
|
||||
+ if (original != null) otherPlayer.setUUID(original); // Paper - uuid override
|
||||
}
|
||||
|
||||
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
|
||||
this.server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity));
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public void setPlayerProfile(com.destroystokyo.paper.profile.PlayerProfile profile) {
|
||||
+ ServerPlayer self = this.getHandle();
|
||||
+ GameProfile gameProfile = com.destroystokyo.paper.profile.CraftPlayerProfile.asAuthlibCopy(profile);
|
||||
+ if (!self.sentListPacket) {
|
||||
+ self.gameProfile = gameProfile;
|
||||
+ return;
|
||||
+ }
|
||||
+ List<ServerPlayer> players = this.server.getServer().getPlayerList().players;
|
||||
+ // First unregister the player for all players with the OLD game profile
|
||||
+ for (ServerPlayer player : players) {
|
||||
+ CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+ if (bukkitPlayer.canSee(this)) {
|
||||
+ bukkitPlayer.unregisterEntity(self);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Set the game profile here, we should have unregistered the entity via iterating all player entities above.
|
||||
+ self.gameProfile = gameProfile;
|
||||
+
|
||||
+ // Re-register the game profile for all players
|
||||
+ for (ServerPlayer player : players) {
|
||||
+ CraftPlayer bukkitPlayer = player.getBukkitEntity();
|
||||
+ if (bukkitPlayer.canSee(this)) {
|
||||
+ bukkitPlayer.trackAndShowEntity(self.getBukkitEntity(), gameProfile.getId());
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Refresh misc player things AFTER sending game profile
|
||||
+ this.refreshPlayer();
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
void resetAndShowEntity(org.bukkit.entity.Entity entity) {
|
||||
// SPIGOT-7312: Can't show/hide self
|
||||
@@ -0,0 +0,0 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
|
||||
this.trackAndShowEntity(entity);
|
||||
}
|
||||
}
|
||||
+ // Paper start
|
||||
+ public com.destroystokyo.paper.profile.PlayerProfile getPlayerProfile() {
|
||||
+ return new com.destroystokyo.paper.profile.CraftPlayerProfile(this).clone();
|
||||
+ }
|
||||
+
|
||||
+ private void refreshPlayer() {
|
||||
+ ServerPlayer handle = this.getHandle();
|
||||
+ Location loc = this.getLocation();
|
||||
+
|
||||
+ ServerGamePacketListenerImpl connection = handle.connection;
|
||||
+
|
||||
+ //Respawn the player then update their position and selected slot
|
||||
+ ServerLevel worldserver = handle.serverLevel();
|
||||
+ connection.send(new net.minecraft.network.protocol.game.ClientboundRespawnPacket(new net.minecraft.network.protocol.game.CommonPlayerSpawnInfo(worldserver.dimensionTypeId(), worldserver.dimension(), net.minecraft.world.level.biome.BiomeManager.obfuscateSeed(worldserver.getSeed()), handle.gameMode.getGameModeForPlayer(), handle.gameMode.getPreviousGameModeForPlayer(), worldserver.isDebug(), worldserver.isFlat(), handle.getLastDeathLocation(), handle.getPortalCooldown()), net.minecraft.network.protocol.game.ClientboundRespawnPacket.KEEP_ALL_DATA));
|
||||
+ handle.onUpdateAbilities();
|
||||
+ connection.internalTeleport(loc.getX(), loc.getY(), loc.getZ(), loc.getYaw(), loc.getPitch(), java.util.Collections.emptySet());
|
||||
+ net.minecraft.server.MinecraftServer.getServer().getPlayerList().sendAllPlayerInfo(handle);
|
||||
+
|
||||
+ // Resend their XP and effects because the respawn packet resets it
|
||||
+ connection.send(new net.minecraft.network.protocol.game.ClientboundSetExperiencePacket(handle.experienceProgress, handle.totalExperience, handle.experienceLevel));
|
||||
+ for (net.minecraft.world.effect.MobEffectInstance mobEffect : handle.getActiveEffects()) {
|
||||
+ connection.send(new net.minecraft.network.protocol.game.ClientboundUpdateMobEffectPacket(handle.getId(), mobEffect));
|
||||
+ }
|
||||
+
|
||||
+ if (this.isOp()) {
|
||||
+ this.setOp(false);
|
||||
+ this.setOp(true);
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
public void onEntityRemove(Entity entity) {
|
||||
this.invertedVisibilityEntities.remove(entity.getUUID());
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
|
||||
@@ -0,0 +0,0 @@ public class Commodore
|
||||
return;
|
||||
}
|
||||
|
||||
+ // Paper start - Rewrite plugins
|
||||
+ if ((owner.equals("org/bukkit/OfflinePlayer") || owner.equals("org/bukkit/entity/Player")) && name.equals("getPlayerProfile") && desc.equals("()Lorg/bukkit/profile/PlayerProfile;")) {
|
||||
+ super.visitMethodInsn(opcode, owner, name, "()Lcom/destroystokyo/paper/profile/PlayerProfile;", itf);
|
||||
+ return;
|
||||
+ }
|
||||
+ // Paper end
|
||||
if ( modern )
|
||||
{
|
||||
if ( owner.equals( "org/bukkit/Material" ) )
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 01:59:59 -0500
|
||||
Subject: [PATCH] PlayerElytraBoostEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
|
||||
if (!world.isClientSide) {
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(world, itemStack, user);
|
||||
fireworkRocketEntity.spawningEntity = user.getUUID(); // Paper
|
||||
- world.addFreshEntity(fireworkRocketEntity);
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerElytraBoostEvent event = new com.destroystokyo.paper.event.player.PlayerElytraBoostEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(fireworkRocketEntity)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
+ } else ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
- user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ // user.awardStat(Stats.ITEM_USED.get(this)); // Paper - move up
|
||||
}
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(user.getItemInHand(hand), world.isClientSide());
|
||||
@@ -1,301 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Sat, 21 Jul 2018 03:11:03 -0500
|
||||
Subject: [PATCH] PlayerLaunchProjectileEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EggItem.java b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EggItem.java
|
||||
@@ -0,0 +0,0 @@ public class EggItem extends Item {
|
||||
|
||||
entityegg.setItem(itemstack);
|
||||
entityegg.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- // CraftBukkit start
|
||||
- if (!world.addFreshEntity(entityegg)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityegg.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityegg)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), net.minecraft.sounds.SoundEvents.EGG_THROW, net.minecraft.sounds.SoundSource.PLAYERS, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return InteractionResultHolder.fail(itemstack);
|
||||
}
|
||||
- // CraftBukkit end
|
||||
+ // Paper end
|
||||
}
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EGG_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/EnderpearlItem.java b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/EnderpearlItem.java
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
|
||||
entityenderpearl.setItem(itemstack);
|
||||
entityenderpearl.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (!world.addFreshEntity(entityenderpearl)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entityenderpearl.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entityenderpearl)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ user.getCooldowns().addCooldown(this, 20);
|
||||
+ } else {
|
||||
+ // Paper end
|
||||
if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
}
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.ENDER_PEARL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
user.getCooldowns().addCooldown(this, 20);
|
||||
// CraftBukkit end
|
||||
@@ -0,0 +0,0 @@ public class EnderpearlItem extends Item {
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end - moved up
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ExperienceBottleItem.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceBottleItem extends Item {
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
ItemStack itemStack = user.getItemInHand(hand);
|
||||
- world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
+ // world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F)); // Paper - moved down
|
||||
if (!world.isClientSide) {
|
||||
ThrownExperienceBottle thrownExperienceBottle = new ThrownExperienceBottle(world, user);
|
||||
thrownExperienceBottle.setItem(itemStack);
|
||||
thrownExperienceBottle.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.7F, 1.0F);
|
||||
- world.addFreshEntity(thrownExperienceBottle);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownExperienceBottle.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownExperienceBottle)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.EXPERIENCE_BOTTLE_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (net.minecraft.world.entity.Entity.SHARED_RANDOM.nextFloat() * 0.4F + 0.8F));
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/FireworkRocketItem.java
|
||||
@@ -0,0 +0,0 @@ public class FireworkRocketItem extends Item {
|
||||
Direction direction = context.getClickedFace();
|
||||
FireworkRocketEntity fireworkRocketEntity = new FireworkRocketEntity(level, context.getPlayer(), vec3.x + (double)direction.getStepX() * 0.15D, vec3.y + (double)direction.getStepY() * 0.15D, vec3.z + (double)direction.getStepZ() * 0.15D, itemStack);
|
||||
fireworkRocketEntity.spawningEntity = context.getPlayer() == null ? null : context.getPlayer().getUUID(); // Paper
|
||||
- level.addFreshEntity(fireworkRocketEntity);
|
||||
- itemStack.shrink(1);
|
||||
+ // Paper start - PlayerLaunchProjectileEvent
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) context.getPlayer().getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Firework) fireworkRocketEntity.getBukkitEntity());
|
||||
+ if (!event.callEvent() || !level.addFreshEntity(fireworkRocketEntity)) return InteractionResult.PASS;
|
||||
+ if (event.shouldConsume() && !context.getPlayer().getAbilities().instabuild) itemStack.shrink(1);
|
||||
+ else if (context.getPlayer() instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) context.getPlayer()).getBukkitEntity().updateInventory();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
return InteractionResult.sidedSuccess(level.isClientSide);
|
||||
diff --git a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/LingeringPotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class LingeringPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.LINGERING_POTION_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SnowballItem.java b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SnowballItem.java
|
||||
@@ -0,0 +0,0 @@ public class SnowballItem extends Item {
|
||||
|
||||
entitysnowball.setItem(itemstack);
|
||||
entitysnowball.shootFromRotation(user, user.getXRot(), user.getYRot(), 0.0F, 1.5F, 1.0F);
|
||||
- if (world.addFreshEntity(entitysnowball)) {
|
||||
- if (!user.getAbilities().instabuild) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack), (org.bukkit.entity.Projectile) entitysnowball.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(entitysnowball)) {
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ // Paper end
|
||||
itemstack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) { // Paper
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
}
|
||||
|
||||
world.playSound((Player) null, user.getX(), user.getY(), user.getZ(), SoundEvents.SNOWBALL_THROW, SoundSource.NEUTRAL, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
- ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ } else { // Paper
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory(); // Paper
|
||||
+ return InteractionResultHolder.fail(itemstack); // Paper
|
||||
}
|
||||
}
|
||||
// CraftBukkit end
|
||||
|
||||
+ /* // Paper tart - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
// CraftBukkit start - moved up
|
||||
/*
|
||||
@@ -0,0 +0,0 @@ public class SnowballItem extends Item {
|
||||
itemstack.shrink(1);
|
||||
}
|
||||
*/
|
||||
+ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemstack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/SplashPotionItem.java b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/SplashPotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class SplashPotionItem extends ThrowablePotionItem {
|
||||
|
||||
@Override
|
||||
public InteractionResultHolder<ItemStack> use(Level world, Player user, InteractionHand hand) {
|
||||
+ // Paper start
|
||||
+ InteractionResultHolder<ItemStack> wrapper = super.use(world, user, hand);
|
||||
+ if (wrapper.getResult() != net.minecraft.world.InteractionResult.FAIL) {
|
||||
world.playSound((Player)null, user.getX(), user.getY(), user.getZ(), SoundEvents.SPLASH_POTION_THROW, SoundSource.PLAYERS, 0.5F, 0.4F / (world.getRandom().nextFloat() * 0.4F + 0.8F));
|
||||
- return super.use(world, user, hand);
|
||||
+ }
|
||||
+ return wrapper;
|
||||
+ // Paper end
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/ThrowablePotionItem.java
|
||||
@@ -0,0 +0,0 @@ public class ThrowablePotionItem extends PotionItem {
|
||||
ThrownPotion thrownPotion = new ThrownPotion(world, user);
|
||||
thrownPotion.setItem(itemStack);
|
||||
thrownPotion.shootFromRotation(user, user.getXRot(), user.getYRot(), -20.0F, 0.5F, 1.0F);
|
||||
- world.addFreshEntity(thrownPotion);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) user.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemStack), (org.bukkit.entity.Projectile) thrownPotion.getBukkitEntity());
|
||||
+ if (event.callEvent() && world.addFreshEntity(thrownPotion)) {
|
||||
+ if (event.shouldConsume() && !user.getAbilities().instabuild) {
|
||||
+ itemStack.shrink(1);
|
||||
+ } else if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+
|
||||
+ user.awardStat(Stats.ITEM_USED.get(this));
|
||||
+ } else {
|
||||
+ if (user instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
+ ((net.minecraft.server.level.ServerPlayer) user).getBukkitEntity().updateInventory();
|
||||
+ }
|
||||
+ return InteractionResultHolder.fail(itemStack);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
+ /* // Paper start - moved up
|
||||
user.awardStat(Stats.ITEM_USED.get(this));
|
||||
if (!user.getAbilities().instabuild) {
|
||||
itemStack.shrink(1);
|
||||
}
|
||||
+ */ // Paper end
|
||||
|
||||
return InteractionResultHolder.sidedSuccess(itemStack, world.isClientSide());
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/item/TridentItem.java b/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
+++ b/src/main/java/net/minecraft/world/item/TridentItem.java
|
||||
@@ -0,0 +0,0 @@ public class TridentItem extends Item implements Vanishable {
|
||||
}
|
||||
|
||||
// CraftBukkit start
|
||||
- if (!world.addFreshEntity(entitythrowntrident)) {
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent event = new com.destroystokyo.paper.event.player.PlayerLaunchProjectileEvent((org.bukkit.entity.Player) entityhuman.getBukkitEntity(), org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(stack), (org.bukkit.entity.Projectile) entitythrowntrident.getBukkitEntity());
|
||||
+ if (!event.callEvent() || !world.addFreshEntity(entitythrowntrident)) {
|
||||
+ // Paper end
|
||||
if (entityhuman instanceof net.minecraft.server.level.ServerPlayer) {
|
||||
((net.minecraft.server.level.ServerPlayer) entityhuman).getBukkitEntity().updateInventory();
|
||||
}
|
||||
return;
|
||||
}
|
||||
-
|
||||
+ if (event.shouldConsume()) { // Paper
|
||||
stack.hurtAndBreak(1, entityhuman, (entityhuman1) -> {
|
||||
entityhuman1.broadcastBreakEvent(user.getUsedItemHand());
|
||||
});
|
||||
+ } // Paper
|
||||
entitythrowntrident.tridentItem = stack.copy(); // SPIGOT-4511 update since damage call moved
|
||||
// CraftBukkit end
|
||||
|
||||
world.playSound((Player) null, (Entity) entitythrowntrident, SoundEvents.TRIDENT_THROW, SoundSource.PLAYERS, 1.0F, 1.0F);
|
||||
- if (!entityhuman.getAbilities().instabuild) {
|
||||
+ if (event.shouldConsume() && !entityhuman.getAbilities().instabuild) { // Paper
|
||||
entityhuman.getInventory().removeItem(stack);
|
||||
}
|
||||
// CraftBukkit start - SPIGOT-5458 also need in this branch :(
|
||||
@@ -1,80 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 14 Jan 2018 17:36:02 -0500
|
||||
Subject: [PATCH] PlayerNaturallySpawnCreaturesEvent
|
||||
|
||||
This event can be used for when you want to exclude a certain player
|
||||
from triggering monster spawns on a server.
|
||||
|
||||
Also a highly more effecient way to blanket block spawns in a world
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
chunkRange = (chunkRange > this.level.spigotConfig.viewDistance) ? (byte) this.level.spigotConfig.viewDistance : chunkRange;
|
||||
chunkRange = (chunkRange > 8) ? 8 : chunkRange;
|
||||
|
||||
- double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D;
|
||||
+ final int finalChunkRange = chunkRange; // Paper for lambda below
|
||||
+ //double blockRange = (reducedRange) ? Math.pow(chunkRange << 4, 2) : 16384.0D; // Paper - use from event
|
||||
+ double blockRange = 16384.0D; // Paper
|
||||
// Spigot end
|
||||
if (!this.distanceManager.hasPlayersNearby(chunkcoordintpair.toLong())) {
|
||||
return false;
|
||||
@@ -0,0 +0,0 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
|
||||
}
|
||||
|
||||
entityplayer = (ServerPlayer) iterator.next();
|
||||
+ // Paper start - add PlayerNaturallySpawnCreaturesEvent
|
||||
+ com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent event;
|
||||
+ blockRange = 16384.0D;
|
||||
+ if (reducedRange) {
|
||||
+ event = entityplayer.playerNaturallySpawnedEvent;
|
||||
+ if (event == null || event.isCancelled()) return false;
|
||||
+ blockRange = (double) ((event.getSpawnRadius() << 4) * (event.getSpawnRadius() << 4));
|
||||
+ }
|
||||
+ // Paper end
|
||||
} while (!this.playerIsCloseEnoughForSpawning(entityplayer, chunkcoordintpair, blockRange)); // Spigot
|
||||
|
||||
return true;
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerChunkCache.java b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerChunkCache.java
|
||||
@@ -0,0 +0,0 @@ public class ServerChunkCache extends ChunkSource {
|
||||
boolean flag2 = this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBSPAWNING) && !this.level.players().isEmpty(); // CraftBukkit
|
||||
|
||||
Collections.shuffle(list);
|
||||
+ // Paper start - call player naturally spawn event
|
||||
+ int chunkRange = level.spigotConfig.mobSpawnRange;
|
||||
+ chunkRange = (chunkRange > level.spigotConfig.viewDistance) ? (byte) level.spigotConfig.viewDistance : chunkRange;
|
||||
+ chunkRange = Math.min(chunkRange, 8);
|
||||
+ for (ServerPlayer entityPlayer : this.level.players()) {
|
||||
+ entityPlayer.playerNaturallySpawnedEvent = new com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent(entityPlayer.getBukkitEntity(), (byte) chunkRange);
|
||||
+ entityPlayer.playerNaturallySpawnedEvent.callEvent();
|
||||
+ };
|
||||
+ // Paper end
|
||||
Iterator iterator1 = list.iterator();
|
||||
|
||||
while (iterator1.hasNext()) {
|
||||
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package net.minecraft.server.level;
|
||||
|
||||
+import com.destroystokyo.paper.event.entity.PlayerNaturallySpawnCreaturesEvent;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.net.InetAddresses;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@@ -0,0 +0,0 @@ public class ServerPlayer extends Player {
|
||||
// CraftBukkit end
|
||||
public boolean isRealPlayer; // Paper
|
||||
public final com.destroystokyo.paper.util.misc.PooledLinkedHashSets.PooledObjectLinkedOpenHashSet<ServerPlayer> cachedSingleHashSet; // Paper
|
||||
+ public PlayerNaturallySpawnCreaturesEvent playerNaturallySpawnedEvent; // Paper
|
||||
|
||||
// Paper start - replace player chunk loader
|
||||
private final java.util.concurrent.atomic.AtomicReference<io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances> viewDistances = new java.util.concurrent.atomic.AtomicReference<>(new io.papermc.paper.chunk.system.RegionizedPlayerChunkLoader.ViewDistances(-1, -1, -1));
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 19 Dec 2017 22:02:53 -0500
|
||||
Subject: [PATCH] PlayerPickupExperienceEvent
|
||||
|
||||
Allows plugins to cancel a player picking up an experience orb
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/ExperienceOrb.java
|
||||
@@ -0,0 +0,0 @@ public class ExperienceOrb extends Entity {
|
||||
@Override
|
||||
public void playerTouch(Player player) {
|
||||
if (!this.level().isClientSide) {
|
||||
- if (player.takeXpDelay == 0) {
|
||||
+ if (player.takeXpDelay == 0 && new com.destroystokyo.paper.event.player.PlayerPickupExperienceEvent(((net.minecraft.server.level.ServerPlayer) player).getBukkitEntity(), (org.bukkit.entity.ExperienceOrb) this.getBukkitEntity()).callEvent()) { // Paper
|
||||
player.takeXpDelay = CraftEventFactory.callPlayerXpCooldownEvent(player, 2, PlayerExpCooldownChangeEvent.ChangeReason.PICKUP_ORB).getNewCooldown(); // CraftBukkit - entityhuman.takeXpDelay = 2;
|
||||
player.take(this, 1);
|
||||
int i = this.repairPlayerItems(player, this.value);
|
||||
@@ -1,44 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 18 Jun 2018 01:12:53 -0400
|
||||
Subject: [PATCH] PlayerReadyArrowEvent
|
||||
|
||||
Called when a player is firing a bow and the server is choosing an arrow to use.
|
||||
Plugins can skip selection of certain arrows and control which is used.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
return ImmutableList.of(Pose.STANDING, Pose.CROUCHING, Pose.SWIMMING);
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ protected boolean tryReadyArrow(ItemStack bow, ItemStack itemstack) {
|
||||
+ return !(this instanceof ServerPlayer) ||
|
||||
+ new com.destroystokyo.paper.event.player.PlayerReadyArrowEvent(
|
||||
+ ((ServerPlayer) this).getBukkitEntity(),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(bow),
|
||||
+ org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(itemstack)
|
||||
+ ).callEvent();
|
||||
+ // Paper end
|
||||
+ }
|
||||
+
|
||||
@Override
|
||||
public ItemStack getProjectile(ItemStack stack) {
|
||||
if (!(stack.getItem() instanceof ProjectileWeaponItem)) {
|
||||
return ItemStack.EMPTY;
|
||||
} else {
|
||||
- Predicate<ItemStack> predicate = ((ProjectileWeaponItem) stack.getItem()).getSupportedHeldProjectiles();
|
||||
+ Predicate<ItemStack> predicate = ((ProjectileWeaponItem) stack.getItem()).getSupportedHeldProjectiles().and(item -> tryReadyArrow(stack, item)); // Paper
|
||||
ItemStack itemstack1 = ProjectileWeaponItem.getHeldProjectile(this, predicate);
|
||||
|
||||
if (!itemstack1.isEmpty()) {
|
||||
return itemstack1;
|
||||
} else {
|
||||
- predicate = ((ProjectileWeaponItem) stack.getItem()).getAllSupportedProjectiles();
|
||||
+ predicate = ((ProjectileWeaponItem) stack.getItem()).getAllSupportedProjectiles().and(item -> tryReadyArrow(stack, item)); // Paper
|
||||
|
||||
for (int i = 0; i < this.inventory.getContainerSize(); ++i) {
|
||||
ItemStack itemstack2 = this.inventory.getItem(i);
|
||||
@@ -1,199 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 14 Jan 2018 17:01:31 -0500
|
||||
Subject: [PATCH] PreCreatureSpawnEvent
|
||||
|
||||
Adds an event to fire before an Entity is created, so that plugins that need to cancel
|
||||
CreatureSpawnEvent can do so from this event instead.
|
||||
|
||||
Cancelling CreatureSpawnEvent rapidly causes a lot of garbage collection and CPU waste
|
||||
as it's done after the Entity object has been fully created.
|
||||
|
||||
Mob Limiting plugins and blanket "ban this type of monster" plugins should use this event
|
||||
instead and save a lot of server resources.
|
||||
|
||||
See: https://github.com/PaperMC/Paper/issues/917
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/util/SpawnUtil.java b/src/main/java/net/minecraft/util/SpawnUtil.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/util/SpawnUtil.java
|
||||
+++ b/src/main/java/net/minecraft/util/SpawnUtil.java
|
||||
@@ -0,0 +0,0 @@ public class SpawnUtil {
|
||||
|
||||
public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entityType, MobSpawnType reason, ServerLevel world, BlockPos pos, int tries, int horizontalRange, int verticalRange, SpawnUtil.Strategy requirements) {
|
||||
// CraftBukkit start
|
||||
- return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT);
|
||||
+ return SpawnUtil.trySpawnMob(entityType, reason, world, pos, tries, horizontalRange, verticalRange, requirements, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.DEFAULT, null); // Paper
|
||||
}
|
||||
|
||||
- public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason) {
|
||||
+ public static <T extends Mob> Optional<T> trySpawnMob(EntityType<T> entitytypes, MobSpawnType enummobspawn, ServerLevel worldserver, BlockPos blockposition, int i, int j, int k, SpawnUtil.Strategy spawnutil_a, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason reason, @javax.annotation.Nullable Runnable onAbort) { // Paper
|
||||
// CraftBukkit end
|
||||
BlockPos.MutableBlockPos blockposition_mutableblockposition = blockposition.mutable();
|
||||
|
||||
@@ -0,0 +0,0 @@ public class SpawnUtil {
|
||||
|
||||
blockposition_mutableblockposition.setWithOffset(blockposition, i1, k, j1);
|
||||
if (worldserver.getWorldBorder().isWithinBounds((BlockPos) blockposition_mutableblockposition) && SpawnUtil.moveToPossibleSpawnPosition(worldserver, k, blockposition_mutableblockposition, spawnutil_a)) {
|
||||
+ // Paper start
|
||||
+ String key = EntityType.getKey(entitytypes).getPath();
|
||||
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
|
||||
+
|
||||
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||||
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition),
|
||||
+ type,
|
||||
+ reason
|
||||
+ );
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ if (onAbort != null) {
|
||||
+ onAbort.run();
|
||||
+ }
|
||||
+ return Optional.empty();
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ // Paper end
|
||||
T t0 = entitytypes.create(worldserver, (CompoundTag) null, null, blockposition_mutableblockposition, enummobspawn, false, false); // CraftBukkit - decompile error
|
||||
|
||||
if (t0 != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/EntityType.java b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/EntityType.java
|
||||
@@ -0,0 +0,0 @@ public class EntityType<T extends Entity> implements FeatureElement, EntityTypeT
|
||||
@Nullable
|
||||
public T spawn(ServerLevel worldserver, @Nullable CompoundTag nbttagcompound, @Nullable Consumer<T> consumer, BlockPos blockposition, MobSpawnType enummobspawn, boolean flag, boolean flag1, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {
|
||||
// CraftBukkit end
|
||||
+ // Paper start - Call PreCreatureSpawnEvent
|
||||
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(this).getPath());
|
||||
+ if (type != null) {
|
||||
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||||
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(worldserver, blockposition),
|
||||
+ type,
|
||||
+ spawnReason
|
||||
+ );
|
||||
+ if (!event.callEvent()) {
|
||||
+ return null;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
T t0 = this.create(worldserver, nbttagcompound, consumer, blockposition, enummobspawn, flag, flag1);
|
||||
|
||||
if (t0 != null) {
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/npc/Villager.java b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/npc/Villager.java
|
||||
@@ -0,0 +0,0 @@ public class Villager extends AbstractVillager implements ReputationEventHandler
|
||||
}).limit(5L).collect(Collectors.toList());
|
||||
|
||||
if (list1.size() >= requiredCount) {
|
||||
- if (!SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE).isEmpty()) { // CraftBukkit
|
||||
+ if (SpawnUtil.trySpawnMob(EntityType.IRON_GOLEM, MobSpawnType.MOB_SUMMONED, world, this.blockPosition(), 10, 8, 6, SpawnUtil.Strategy.LEGACY_IRON_GOLEM, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE, () -> {GolemSensor.golemDetected(this);}).isPresent()) { // CraftBukkit // Paper - Set Golem Last Seen to stop it from spawning another one
|
||||
list.forEach(GolemSensor::golemDetected);
|
||||
}
|
||||
}
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
} else if (!SpawnPlacements.checkSpawnRules((EntityType) optional.get(), world, MobSpawnType.SPAWNER, blockposition1, world.getRandom())) {
|
||||
continue;
|
||||
}
|
||||
+ // Paper start
|
||||
+ EntityType<?> entityType = optional.get();
|
||||
+ String key = EntityType.getKey(entityType).getPath();
|
||||
+
|
||||
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
|
||||
+ if (type != null) {
|
||||
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||||
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(world, d0, d1, d2),
|
||||
+ type,
|
||||
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
|
||||
+ );
|
||||
+ if (!event.callEvent()) {
|
||||
+ flag = true;
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ break;
|
||||
+ }
|
||||
+ continue;
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
Entity entity = EntityType.loadEntityRecursive(nbttagcompound, world, (entity1) -> {
|
||||
entity1.moveTo(d0, d1, d2, entity1.getYRot(), entity1.getXRot());
|
||||
diff --git a/src/main/java/net/minecraft/world/level/NaturalSpawner.java b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/NaturalSpawner.java
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
j1 = biomesettingsmobs_c.minCount + world.random.nextInt(1 + biomesettingsmobs_c.maxCount - biomesettingsmobs_c.minCount);
|
||||
}
|
||||
|
||||
- if (NaturalSpawner.isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2) && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
|
||||
+ // Paper start
|
||||
+ PreSpawnStatus doSpawning = isValidSpawnPostitionForType(world, group, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
|
||||
+ if (doSpawning == PreSpawnStatus.ABORT) {
|
||||
+ return;
|
||||
+ }
|
||||
+ if (doSpawning == PreSpawnStatus.SUCCESS && checker.test(biomesettingsmobs_c.type, blockposition_mutableblockposition, chunk)) {
|
||||
+ // Paper end
|
||||
Mob entityinsentient = NaturalSpawner.getMobForSpawn(world, biomesettingsmobs_c.type);
|
||||
|
||||
if (entityinsentient == null) {
|
||||
@@ -0,0 +0,0 @@ public final class NaturalSpawner {
|
||||
return squaredDistance <= 576.0D ? false : (world.getSharedSpawnPos().closerToCenterThan(new Vec3((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D), 24.0D) ? false : Objects.equals(new ChunkPos(pos), chunk.getPos()) || world.isNaturalSpawningAllowed((BlockPos) pos));
|
||||
}
|
||||
|
||||
- private static boolean isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) {
|
||||
+ // Paper start
|
||||
+ private enum PreSpawnStatus {
|
||||
+ FAIL,
|
||||
+ SUCCESS,
|
||||
+ CANCELLED,
|
||||
+ ABORT
|
||||
+ }
|
||||
+ private static PreSpawnStatus isValidSpawnPostitionForType(ServerLevel world, MobCategory group, StructureManager structureAccessor, ChunkGenerator chunkGenerator, MobSpawnSettings.SpawnerData spawnEntry, BlockPos.MutableBlockPos pos, double squaredDistance) {
|
||||
+ // Paper end
|
||||
EntityType<?> entitytypes = spawnEntry.type;
|
||||
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
|
||||
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityType.getKey(entitytypes).getPath());
|
||||
+ if (type != null) {
|
||||
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
|
||||
+ io.papermc.paper.util.MCUtil.toLocation(world, pos),
|
||||
+ type, SpawnReason.NATURAL
|
||||
+ );
|
||||
+ if (!event.callEvent()) {
|
||||
+ if (event.shouldAbortSpawn()) {
|
||||
+ return PreSpawnStatus.ABORT; // Paper
|
||||
+ }
|
||||
+ return PreSpawnStatus.CANCELLED; // Paper
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
if (entitytypes.getCategory() == MobCategory.MISC) {
|
||||
- return false;
|
||||
+ return PreSpawnStatus.FAIL; // Paper
|
||||
} else if (!entitytypes.canSpawnFarFromPlayer() && squaredDistance > (double) (entitytypes.getCategory().getDespawnDistance() * entitytypes.getCategory().getDespawnDistance())) {
|
||||
- return false;
|
||||
+ return PreSpawnStatus.FAIL; // Paper
|
||||
} else if (entitytypes.canSummon() && NaturalSpawner.canSpawnMobAt(world, structureAccessor, chunkGenerator, group, spawnEntry, pos)) {
|
||||
SpawnPlacements.Type entitypositiontypes_surface = SpawnPlacements.getPlacementType(entitytypes);
|
||||
|
||||
- return !NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D)));
|
||||
+ boolean isValid = !NaturalSpawner.isSpawnPositionOk(entitypositiontypes_surface, world, pos, entitytypes) ? false : (!SpawnPlacements.checkSpawnRules(entitytypes, world, MobSpawnType.NATURAL, pos, world.random) ? false : world.noCollision(entitytypes.getAABB((double) pos.getX() + 0.5D, (double) pos.getY(), (double) pos.getZ() + 0.5D))); // Paper
|
||||
+ return isValid ? PreSpawnStatus.SUCCESS : PreSpawnStatus.FAIL; // Paper
|
||||
} else {
|
||||
- return false;
|
||||
+ return PreSpawnStatus.FAIL; // Paper
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 10 Mar 2018 16:33:15 -0500
|
||||
Subject: [PATCH] Prevent Frosted Ice from loading/holding chunks
|
||||
|
||||
1.17: Shouldn't be needed as blocks no longer tick without at least 1 radius chunk loaded.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/block/FrostedIceBlock.java
|
||||
@@ -0,0 +0,0 @@ public class FrostedIceBlock extends IceBlock {
|
||||
|
||||
for(Direction direction : Direction.values()) {
|
||||
mutableBlockPos.setWithOffset(pos, direction);
|
||||
- BlockState blockState = world.getBlockState(mutableBlockPos);
|
||||
+ BlockState blockState = world.getBlockStateIfLoaded(mutableBlockPos); // Paper
|
||||
+ if (blockState == null) { continue; } // Paper
|
||||
if (blockState.is(this) && !this.slightlyMelt(blockState, world, mutableBlockPos)) {
|
||||
world.scheduleTick(mutableBlockPos, this, Mth.nextInt(random, world.paperConfig().environment.frostedIce.delay.min, world.paperConfig().environment.frostedIce.delay.max)); // Paper - use configurable min/max delay
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class FrostedIceBlock extends IceBlock {
|
||||
|
||||
for(Direction direction : Direction.values()) {
|
||||
mutableBlockPos.setWithOffset(pos, direction);
|
||||
- if (world.getBlockState(mutableBlockPos).is(this)) {
|
||||
+ // Paper start
|
||||
+ BlockState blockState = world.getBlockStateIfLoaded(mutableBlockPos);
|
||||
+ if (blockState != null && blockState.is(this)) {
|
||||
+ // Paper end
|
||||
++i;
|
||||
if (i >= maxNeighbors) {
|
||||
return false;
|
||||
@@ -1,21 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: killme <killme-git@ibts.me>
|
||||
Date: Sun, 12 Nov 2017 19:40:01 +0100
|
||||
Subject: [PATCH] Prevent logins from being processed when the player has
|
||||
disconnected
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerLoginPacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerLoginPacketListenerImpl implements ServerLoginPacketListener,
|
||||
}
|
||||
// Paper end
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.VERIFYING) {
|
||||
+ if (this.connection.isConnected()) { // Paper - prevent logins to be processed even though disconnect was called
|
||||
this.verifyLoginAndFinishConnectionSetup((GameProfile) Objects.requireNonNull(this.authenticatedProfile));
|
||||
+ } // Paper
|
||||
}
|
||||
|
||||
if (this.state == ServerLoginPacketListenerImpl.State.WAITING_FOR_DUPE_DISCONNECT && !this.isPlayerAlreadyInWorld((GameProfile) Objects.requireNonNull(this.authenticatedProfile))) {
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Fri, 15 Jun 2018 20:37:03 -0400
|
||||
Subject: [PATCH] Print Error details when failing to save player data
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/storage/PlayerDataStorage.java
|
||||
@@ -0,0 +0,0 @@ public class PlayerDataStorage {
|
||||
|
||||
Util.safeReplaceFile(file1, file, file2);
|
||||
} catch (Exception exception) {
|
||||
- PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getName().getString());
|
||||
+ PlayerDataStorage.LOGGER.warn("Failed to save player data for {}", player.getScoreboardName(), exception); // Paper
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 17 Jun 2017 17:00:32 -0400
|
||||
Subject: [PATCH] Profile Lookup Events
|
||||
|
||||
Adds a Pre Lookup Event and a Post Lookup Event so that plugins may prefill in profile data, and cache the responses from
|
||||
profiles that had to be looked up.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
+++ b/src/main/java/com/destroystokyo/paper/profile/PaperGameProfileRepository.java
|
||||
@@ -0,0 +0,0 @@
|
||||
package com.destroystokyo.paper.profile;
|
||||
|
||||
+import com.destroystokyo.paper.event.profile.LookupProfileEvent;
|
||||
+import com.destroystokyo.paper.event.profile.PreLookupProfileEvent;
|
||||
+import com.google.common.collect.Sets;
|
||||
import com.mojang.authlib.Environment;
|
||||
+import com.mojang.authlib.GameProfile;
|
||||
import com.mojang.authlib.ProfileLookupCallback;
|
||||
import com.mojang.authlib.yggdrasil.YggdrasilGameProfileRepository;
|
||||
import java.net.Proxy;
|
||||
+import java.util.Set;
|
||||
|
||||
public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
|
||||
public PaperGameProfileRepository(Proxy proxy, Environment environment) {
|
||||
@@ -0,0 +0,0 @@ public class PaperGameProfileRepository extends YggdrasilGameProfileRepository {
|
||||
|
||||
@Override
|
||||
public void findProfilesByNames(String[] names, ProfileLookupCallback callback) {
|
||||
- super.findProfilesByNames(names, callback);
|
||||
+ Set<String> unfoundNames = Sets.newHashSet();
|
||||
+ for (String name : names) {
|
||||
+ PreLookupProfileEvent event = new PreLookupProfileEvent(name);
|
||||
+ event.callEvent();
|
||||
+ if (event.getUUID() != null) {
|
||||
+ // Plugin provided UUI, we can skip network call.
|
||||
+ GameProfile gameprofile = new GameProfile(event.getUUID(), name);
|
||||
+ // We might even have properties!
|
||||
+ Set<ProfileProperty> profileProperties = event.getProfileProperties();
|
||||
+ if (!profileProperties.isEmpty()) {
|
||||
+ for (ProfileProperty property : profileProperties) {
|
||||
+ gameprofile.getProperties().put(property.getName(), CraftPlayerProfile.asAuthlib(property));
|
||||
+ }
|
||||
+ }
|
||||
+ callback.onProfileLookupSucceeded(gameprofile);
|
||||
+ } else {
|
||||
+ unfoundNames.add(name);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ // Some things were not found.... Proceed to look up.
|
||||
+ if (!unfoundNames.isEmpty()) {
|
||||
+ String[] namesArr = unfoundNames.toArray(new String[unfoundNames.size()]);
|
||||
+ super.findProfilesByNames(namesArr, new PreProfileLookupCallback(callback));
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ private record PreProfileLookupCallback(ProfileLookupCallback callback) implements ProfileLookupCallback {
|
||||
+ @Override
|
||||
+ public void onProfileLookupSucceeded(GameProfile gameProfile) {
|
||||
+ PlayerProfile from = CraftPlayerProfile.asBukkitMirror(gameProfile);
|
||||
+ new LookupProfileEvent(from).callEvent();
|
||||
+ this.callback.onProfileLookupSucceeded(gameProfile);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void onProfileLookupFailed(final String profileName, final Exception exception) {
|
||||
+ this.callback.onProfileLookupFailed(profileName, exception);
|
||||
+ }
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Mon, 3 Jul 2017 18:11:10 -0500
|
||||
Subject: [PATCH] ProfileWhitelistVerifyEvent
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
|
||||
// return chatmessage;
|
||||
event.disallow(PlayerLoginEvent.Result.KICK_BANNED, io.papermc.paper.adventure.PaperAdventure.asAdventure(ichatmutablecomponent)); // Paper - Adventure
|
||||
- } else if (!this.isWhiteListed(gameprofile)) {
|
||||
- ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted");
|
||||
- event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure
|
||||
+ } else if (!this.isWhiteListed(gameprofile, event)) { // Paper
|
||||
+ //ichatmutablecomponent = Component.translatable("multiplayer.disconnect.not_whitelisted"); // Paper
|
||||
+ //event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(org.spigotmc.SpigotConfig.whitelistMessage)); // Spigot // Paper - Adventure - moved to isWhitelisted
|
||||
} else if (this.getIpBans().isBanned(socketaddress) && !this.getIpBans().get(socketaddress).hasExpired()) {
|
||||
IpBanListEntry ipbanentry = this.ipBans.get(socketaddress);
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class PlayerList {
|
||||
}
|
||||
|
||||
public boolean isWhiteListed(GameProfile profile) {
|
||||
- return !this.doWhiteList || this.ops.contains(profile) || this.whitelist.contains(profile);
|
||||
+ // Paper start
|
||||
+ return isWhiteListed(profile, null);
|
||||
+ }
|
||||
+ public boolean isWhiteListed(GameProfile gameprofile, org.bukkit.event.player.PlayerLoginEvent loginEvent) {
|
||||
+ boolean isOp = this.ops.contains(gameprofile);
|
||||
+ boolean isWhitelisted = !this.doWhiteList || isOp || this.whitelist.contains(gameprofile);
|
||||
+ final com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent event;
|
||||
+ event = new com.destroystokyo.paper.event.profile.ProfileWhitelistVerifyEvent(io.papermc.paper.util.MCUtil.toBukkit(gameprofile), this.doWhiteList, isWhitelisted, isOp, org.spigotmc.SpigotConfig.whitelistMessage);
|
||||
+ event.callEvent();
|
||||
+ if (!event.isWhitelisted()) {
|
||||
+ if (loginEvent != null) {
|
||||
+ loginEvent.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer.legacySection().deserialize(event.getKickMessage() == null ? org.spigotmc.SpigotConfig.whitelistMessage : event.getKickMessage()));
|
||||
+ }
|
||||
+ return false;
|
||||
+ }
|
||||
+ return true;
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
public boolean isOp(GameProfile profile) {
|
||||
@@ -1,162 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 26 Jun 2018 22:00:49 -0400
|
||||
Subject: [PATCH] RangedEntity API
|
||||
|
||||
Allows you to determine if an entity is capable of ranged attacks,
|
||||
and to perform an attack.
|
||||
|
||||
diff --git a/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
new file mode 100644
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000
|
||||
--- /dev/null
|
||||
+++ b/src/main/java/com/destroystokyo/paper/entity/CraftRangedEntity.java
|
||||
@@ -0,0 +0,0 @@
|
||||
+package com.destroystokyo.paper.entity;
|
||||
+
|
||||
+import net.minecraft.world.entity.Mob;
|
||||
+import net.minecraft.world.entity.monster.RangedAttackMob;
|
||||
+import org.bukkit.craftbukkit.entity.CraftLivingEntity;
|
||||
+import org.bukkit.entity.LivingEntity;
|
||||
+
|
||||
+public interface CraftRangedEntity<T extends Mob & RangedAttackMob> extends RangedEntity {
|
||||
+ T getHandle();
|
||||
+
|
||||
+ @Override
|
||||
+ default void rangedAttack(LivingEntity target, float charge) {
|
||||
+ getHandle().performRangedAttack(((CraftLivingEntity) target).getHandle(), charge);
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ default void setChargingAttack(boolean raiseHands) {
|
||||
+ getHandle().setAggressive(raiseHands);
|
||||
+ }
|
||||
+}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractSkeleton.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.AbstractSkeleton;
|
||||
import org.bukkit.entity.Skeleton;
|
||||
|
||||
-public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton {
|
||||
+public abstract class CraftAbstractSkeleton extends CraftMonster implements AbstractSkeleton, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.AbstractSkeleton> { // Paper
|
||||
|
||||
public CraftAbstractSkeleton(CraftServer server, net.minecraft.world.entity.monster.AbstractSkeleton entity) {
|
||||
super(server, entity);
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftAbstractSkeleton extends CraftMonster implements Abst
|
||||
public void setSkeletonType(Skeleton.SkeletonType type) {
|
||||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public net.minecraft.world.entity.monster.AbstractSkeleton getHandle() {
|
||||
+ return (net.minecraft.world.entity.monster.AbstractSkeleton) super.getHandle();
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftDrowned.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Drowned;
|
||||
|
||||
-public class CraftDrowned extends CraftZombie implements Drowned {
|
||||
+public class CraftDrowned extends CraftZombie implements Drowned, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Drowned> { // Paper
|
||||
|
||||
public CraftDrowned(CraftServer server, net.minecraft.world.entity.monster.Drowned entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftIllusioner.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Illusioner;
|
||||
|
||||
-public class CraftIllusioner extends CraftSpellcaster implements Illusioner {
|
||||
+public class CraftIllusioner extends CraftSpellcaster implements Illusioner, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Illusioner> { // Paper
|
||||
|
||||
public CraftIllusioner(CraftServer server, net.minecraft.world.entity.monster.Illusioner entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLlama.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.entity.Llama;
|
||||
import org.bukkit.entity.Llama.Color;
|
||||
import org.bukkit.inventory.LlamaInventory;
|
||||
|
||||
-public class CraftLlama extends CraftChestedHorse implements Llama {
|
||||
+public class CraftLlama extends CraftChestedHorse implements Llama, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.animal.horse.Llama> { // Paper
|
||||
|
||||
public CraftLlama(CraftServer server, net.minecraft.world.entity.animal.horse.Llama entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPiglin.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.util.CraftMagicNumbers;
|
||||
import org.bukkit.entity.Piglin;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPiglin extends CraftPiglinAbstract implements Piglin {
|
||||
+public class CraftPiglin extends CraftPiglinAbstract implements Piglin, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.piglin.Piglin> { // Paper
|
||||
|
||||
public CraftPiglin(CraftServer server, net.minecraft.world.entity.monster.piglin.Piglin entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPillager.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.inventory.CraftInventory;
|
||||
import org.bukkit.entity.Pillager;
|
||||
import org.bukkit.inventory.Inventory;
|
||||
|
||||
-public class CraftPillager extends CraftIllager implements Pillager {
|
||||
+public class CraftPillager extends CraftIllager implements Pillager, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Pillager> { // Paper
|
||||
|
||||
public CraftPillager(CraftServer server, net.minecraft.world.entity.monster.Pillager entity) {
|
||||
super(server, entity);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.entity.animal.SnowGolem;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Snowman;
|
||||
|
||||
-public class CraftSnowman extends CraftGolem implements Snowman {
|
||||
+public class CraftSnowman extends CraftGolem implements Snowman, com.destroystokyo.paper.entity.CraftRangedEntity<SnowGolem> { // Paper
|
||||
public CraftSnowman(CraftServer server, SnowGolem entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java
|
||||
@@ -0,0 +0,0 @@ package org.bukkit.craftbukkit.entity;
|
||||
import org.bukkit.craftbukkit.CraftServer;
|
||||
import org.bukkit.entity.Witch;
|
||||
|
||||
-public class CraftWitch extends CraftRaider implements Witch {
|
||||
+public class CraftWitch extends CraftRaider implements Witch, com.destroystokyo.paper.entity.CraftRangedEntity<net.minecraft.world.entity.monster.Witch> { // Paper
|
||||
public CraftWitch(CraftServer server, net.minecraft.world.entity.monster.Witch entity) {
|
||||
super(server, entity);
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java
|
||||
@@ -0,0 +0,0 @@ import org.bukkit.craftbukkit.boss.CraftBossBar;
|
||||
import org.bukkit.entity.LivingEntity;
|
||||
import org.bukkit.entity.Wither;
|
||||
|
||||
-public class CraftWither extends CraftMonster implements Wither {
|
||||
+public class CraftWither extends CraftMonster implements Wither, com.destroystokyo.paper.entity.CraftRangedEntity<WitherBoss> { // Paper
|
||||
|
||||
private BossBar bossBar;
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Minecrell <minecrell@minecrell.net>
|
||||
Date: Fri, 13 Jul 2018 14:54:43 +0200
|
||||
Subject: [PATCH] Refresh player inventory when cancelling
|
||||
PlayerInteractEntityEvent
|
||||
|
||||
When interacting with entities with an item, the client will assume
|
||||
the interaction is successful, and update the held item on the
|
||||
client. However, if the interaction is cancelled on the server side,
|
||||
the client will still mistakenly remove/replace the item in hand.
|
||||
|
||||
Examples for this are milking cows with a bucket or dyeing sheep.
|
||||
The bucket is replaced with milk and the dye removed from inventory.
|
||||
|
||||
Refresh the player inventory when PlayerInteractEntityEvent is
|
||||
cancelled to avoid this problem.
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
|
||||
@@ -0,0 +0,0 @@ public class ServerGamePacketListenerImpl extends ServerCommonPacketListenerImpl
|
||||
}
|
||||
|
||||
if (event.isCancelled()) {
|
||||
+ ServerGamePacketListenerImpl.this.player.containerMenu.sendAllDataToRemote(); // Paper - Refresh player inventory
|
||||
return;
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -1,28 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Tue, 22 Nov 2016 00:40:42 -0500
|
||||
Subject: [PATCH] Remove unnecessary itemmeta handling
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/network/FriendlyByteBuf.java b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
+++ b/src/main/java/net/minecraft/network/FriendlyByteBuf.java
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
if (item.canBeDepleted() || item.shouldOverrideMultiplayerNbt()) {
|
||||
// Spigot start - filter
|
||||
stack = stack.copy();
|
||||
- CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack));
|
||||
+ // CraftItemStack.setItemMeta(stack, CraftItemStack.getItemMeta(stack)); // Paper - This is no longer with raw NBT being handled in metadata
|
||||
// Spigot end
|
||||
nbttagcompound = stack.getTag();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class FriendlyByteBuf extends ByteBuf {
|
||||
|
||||
itemstack.setTag(this.readNbt());
|
||||
// CraftBukkit start
|
||||
- if (itemstack.getTag() != null) {
|
||||
+ if (false && itemstack.getTag() != null) { // Paper - This is no longer needed with raw NBT being handled in metadata
|
||||
CraftItemStack.setItemMeta(itemstack, CraftItemStack.getItemMeta(itemstack));
|
||||
}
|
||||
// CraftBukkit end
|
||||
@@ -1,27 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Mon, 31 Jul 2017 01:45:19 -0500
|
||||
Subject: [PATCH] Reset spawner timer when spawner event is cancelled
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/level/BaseSpawner.java b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/BaseSpawner.java
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
}
|
||||
|
||||
entity.spawnedViaMobSpawner = true; // Paper
|
||||
+ flag = true; // Paper
|
||||
// CraftBukkit start
|
||||
if (org.bukkit.craftbukkit.event.CraftEventFactory.callSpawnerSpawnEvent(entity, pos).isCancelled()) {
|
||||
continue;
|
||||
@@ -0,0 +0,0 @@ public abstract class BaseSpawner {
|
||||
((Mob) entity).spawnAnim();
|
||||
}
|
||||
|
||||
- flag = true;
|
||||
+ //flag = true; // Paper - moved up above cancellable event
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 18 Aug 2018 12:43:16 -0400
|
||||
Subject: [PATCH] Restore vanilla default mob-spawn-range and water animals
|
||||
limit
|
||||
|
||||
|
||||
diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
+++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java
|
||||
@@ -0,0 +0,0 @@ public class SpigotWorldConfig
|
||||
public byte mobSpawnRange;
|
||||
private void mobSpawnRange()
|
||||
{
|
||||
- this.mobSpawnRange = (byte) this.getInt( "mob-spawn-range", 6 );
|
||||
+ this.mobSpawnRange = (byte) getInt( "mob-spawn-range", 8 ); // Paper - Vanilla
|
||||
this.log( "Mob Spawn Range: " + this.mobSpawnRange );
|
||||
}
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Brokkonaut <hannos17@gmx.de>
|
||||
Date: Tue, 31 Oct 2017 03:26:18 +0100
|
||||
Subject: [PATCH] Send attack SoundEffects only to players who can see the
|
||||
attacker
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
int i = b0 + EnchantmentHelper.getKnockbackBonus(this);
|
||||
|
||||
if (this.isSprinting() && flag) {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_KNOCKBACK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_KNOCKBACK, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
++i;
|
||||
flag1 = true;
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
}
|
||||
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_SWEEP, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
this.sweepAttack();
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
}
|
||||
|
||||
if (flag2) {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_CRIT, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_CRIT, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
this.crit(target);
|
||||
}
|
||||
|
||||
if (!flag2 && !flag3) {
|
||||
if (flag) {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_STRONG, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_STRONG, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
} else {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_WEAK, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_WEAK, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
this.causeFoodExhaustion(this.level().spigotConfig.combatExhaustion, EntityExhaustionEvent.ExhaustionReason.ATTACK); // CraftBukkit - EntityExhaustionEvent // Spigot - Change to use configurable value
|
||||
} else {
|
||||
- this.level().playSound((Player) null, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F);
|
||||
+ sendSoundEffect(this, this.getX(), this.getY(), this.getZ(), SoundEvents.PLAYER_ATTACK_NODAMAGE, this.getSoundSource(), 1.0F, 1.0F); // Paper - send while respecting visibility
|
||||
if (flag4) {
|
||||
target.clearFire();
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
public int getXpNeededForNextLevel() {
|
||||
return this.experienceLevel >= 30 ? 112 + (this.experienceLevel - 30) * 9 : (this.experienceLevel >= 15 ? 37 + (this.experienceLevel - 15) * 5 : 7 + this.experienceLevel * 2);
|
||||
}
|
||||
+ // Paper start - send SoundEffect to everyone who can see fromEntity
|
||||
+ private static void sendSoundEffect(Player fromEntity, double x, double y, double z, SoundEvent soundEffect, SoundSource soundCategory, float volume, float pitch) {
|
||||
+ fromEntity.level().playSound(fromEntity, x, y, z, soundEffect, soundCategory, volume, pitch); // This will not send the effect to the entity himself
|
||||
+ if (fromEntity instanceof ServerPlayer) {
|
||||
+ ((ServerPlayer) fromEntity).connection.send(new net.minecraft.network.protocol.game.ClientboundSoundPacket(net.minecraft.core.registries.BuiltInRegistries.SOUND_EVENT.wrapAsHolder(soundEffect), soundCategory, x, y, z, volume, pitch, fromEntity.random.nextLong()));
|
||||
+ }
|
||||
+ }
|
||||
+ // Paper end
|
||||
|
||||
// CraftBukkit start
|
||||
public void causeFoodExhaustion(float exhaustion) {
|
||||
@@ -1,87 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 27 Jul 2018 22:36:31 -0500
|
||||
Subject: [PATCH] SkeletonHorse Additions
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/SkeletonTrapGoal.java
|
||||
@@ -0,0 +0,0 @@ import net.minecraft.world.item.enchantment.EnchantmentHelper;
|
||||
public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
private final SkeletonHorse horse;
|
||||
+ private java.util.List<org.bukkit.entity.HumanEntity> eligiblePlayers; // Paper
|
||||
|
||||
public SkeletonTrapGoal(SkeletonHorse skeletonHorse) {
|
||||
this.horse = skeletonHorse;
|
||||
@@ -0,0 +0,0 @@ public class SkeletonTrapGoal extends Goal {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.horse.level().hasNearbyAlivePlayerThatAffectsSpawning(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D); // Paper - Affects Spawning API
|
||||
+ return !(eligiblePlayers = this.horse.level().findNearbyBukkitPlayers(this.horse.getX(), this.horse.getY(), this.horse.getZ(), 10.0D, net.minecraft.world.entity.EntitySelector.PLAYER_AFFECTS_SPAWNING)).isEmpty(); // Paper - Affects Spawning API & SkeletonHorseTrapEvent
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
ServerLevel worldserver = (ServerLevel) this.horse.level();
|
||||
+ if (!new com.destroystokyo.paper.event.entity.SkeletonHorseTrapEvent((org.bukkit.entity.SkeletonHorse) this.horse.getBukkitEntity(), eligiblePlayers).callEvent()) return; // Paper
|
||||
DifficultyInstance difficultydamagescaler = worldserver.getCurrentDifficultyAt(this.horse.blockPosition());
|
||||
|
||||
this.horse.setTrap(false);
|
||||
diff --git a/src/main/java/net/minecraft/world/level/EntityGetter.java b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
+++ b/src/main/java/net/minecraft/world/level/EntityGetter.java
|
||||
@@ -0,0 +0,0 @@ public interface EntityGetter {
|
||||
return player;
|
||||
}
|
||||
|
||||
+ // Paper start
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, boolean notSpectator) {
|
||||
+ return findNearbyBukkitPlayers(x, y, z, radius, notSpectator ? EntitySelector.NO_SPECTATORS : net.minecraft.world.entity.EntitySelector.NO_CREATIVE_OR_SPECTATOR);
|
||||
+ }
|
||||
+
|
||||
+ default List<org.bukkit.entity.HumanEntity> findNearbyBukkitPlayers(double x, double y, double z, double radius, @Nullable Predicate<Entity> predicate) {
|
||||
+ com.google.common.collect.ImmutableList.Builder<org.bukkit.entity.HumanEntity> builder = com.google.common.collect.ImmutableList.builder();
|
||||
+
|
||||
+ for (Player human : this.players()) {
|
||||
+ if (predicate == null || predicate.test(human)) {
|
||||
+ double distanceSquared = human.distanceToSqr(x, y, z);
|
||||
+
|
||||
+ if (radius < 0.0D || distanceSquared < radius * radius) {
|
||||
+ builder.add(human.getBukkitEntity());
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return builder.build();
|
||||
+ }
|
||||
+ // Paper end
|
||||
+
|
||||
@Nullable
|
||||
default Player getNearestPlayer(Entity entity, double maxDistance) {
|
||||
return this.getNearestPlayer(entity.getX(), entity.getY(), entity.getZ(), maxDistance, false);
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSkeletonHorse.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSkeletonHorse extends CraftAbstractHorse implements SkeletonHo
|
||||
public void setTrapTime(int trapTime) {
|
||||
this.getHandle().trapTime = trapTime;
|
||||
}
|
||||
+
|
||||
+ // Paper start - replaced by above methods
|
||||
+ @Override
|
||||
+ public boolean isTrap() {
|
||||
+ return getHandle().isTrap();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setTrap(boolean trap) {
|
||||
+ getHandle().setTrap(trap);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: BillyGalbreath <Blake.Galbreath@GMail.com>
|
||||
Date: Fri, 24 Aug 2018 08:18:42 -0500
|
||||
Subject: [PATCH] Slime Pathfinder Events
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Slime.java b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Slime.java
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag nbt) {
|
||||
super.addAdditionalSaveData(nbt);
|
||||
+ nbt.putBoolean("Paper.canWander", this.canWander); // Paper
|
||||
nbt.putInt("Size", this.getSize() - 1);
|
||||
nbt.putBoolean("wasOnGround", this.wasOnGround);
|
||||
}
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public void readAdditionalSaveData(CompoundTag nbt) {
|
||||
this.setSize(nbt.getInt("Size") + 1, false);
|
||||
super.readAdditionalSaveData(nbt);
|
||||
+ // Paper start - check exists before loading or this will be loaded as false
|
||||
+ if (nbt.contains("Paper.canWander")) {
|
||||
+ this.canWander = nbt.getBoolean("Paper.canWander");
|
||||
+ }
|
||||
+ // Paper end
|
||||
this.wasOnGround = nbt.getBoolean("wasOnGround");
|
||||
}
|
||||
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return (this.slime.isInWater() || this.slime.isInLava()) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new com.destroystokyo.paper.event.entity.SlimeSwimEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : this.slime.getMoveControl() instanceof Slime.SlimeMoveControl);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander && new com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
public boolean canContinueToUse() {
|
||||
LivingEntity entityliving = this.slime.getTarget();
|
||||
|
||||
- return entityliving == null ? false : (!this.slime.canAttack(entityliving) ? false : --this.growTiredTimer > 0);
|
||||
+ // Paper start
|
||||
+ if (entityliving == null || !entityliving.isAlive()) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ if (!this.slime.canAttack(entityliving)) {
|
||||
+ return false;
|
||||
+ }
|
||||
+ return --this.growTiredTimer > 0 && this.slime.canWander && new com.destroystokyo.paper.event.entity.SlimeTargetLivingEntityEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), (org.bukkit.entity.LivingEntity) entityliving.getBukkitEntity()).callEvent();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
}
|
||||
|
||||
}
|
||||
+
|
||||
+ // Paper start - clear timer and target when goal resets
|
||||
+ public void stop() {
|
||||
+ this.growTiredTimer = 0;
|
||||
+ this.slime.setTarget(null);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
private static class SlimeRandomDirectionGoal extends Goal {
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return this.slime.getTarget() == null && (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl;
|
||||
+ return this.slime.getTarget() == null && (this.slime.onGround() || this.slime.isInWater() || this.slime.isInLava() || this.slime.hasEffect(MobEffects.LEVITATION)) && this.slime.getMoveControl() instanceof Slime.SlimeMoveControl && this.slime.canWander; // Paper - add canWander
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
if (--this.nextRandomizeTime <= 0) {
|
||||
this.nextRandomizeTime = this.adjustedTickDelay(40 + this.slime.getRandom().nextInt(60));
|
||||
this.chosenDegrees = (float) this.slime.getRandom().nextInt(360);
|
||||
+ // Paper start
|
||||
+ com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent event = new com.destroystokyo.paper.event.entity.SlimeChangeDirectionEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity(), this.chosenDegrees);
|
||||
+ if (!this.slime.canWander || !event.callEvent()) return;
|
||||
+ this.chosenDegrees = event.getNewYaw();
|
||||
+ // Paper end
|
||||
}
|
||||
|
||||
MoveControl controllermove = this.slime.getMoveControl();
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
@Override
|
||||
public boolean canUse() {
|
||||
- return !this.slime.isPassenger();
|
||||
+ return !this.slime.isPassenger() && this.slime.canWander && new com.destroystokyo.paper.event.entity.SlimeWanderEvent((org.bukkit.entity.Slime) this.slime.getBukkitEntity()).callEvent(); // Paper
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -0,0 +0,0 @@ public class Slime extends Mob implements Enemy {
|
||||
|
||||
}
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ private boolean canWander = true;
|
||||
+ public boolean canWander() {
|
||||
+ return canWander;
|
||||
+ }
|
||||
+
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ this.canWander = canWander;
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java
|
||||
@@ -0,0 +0,0 @@ public class CraftSlime extends CraftMob implements Slime, CraftEnemy {
|
||||
public String toString() {
|
||||
return "CraftSlime";
|
||||
}
|
||||
+
|
||||
+ // Paper start
|
||||
+ @Override
|
||||
+ public boolean canWander() {
|
||||
+ return getHandle().canWander();
|
||||
+ }
|
||||
+
|
||||
+ @Override
|
||||
+ public void setWander(boolean canWander) {
|
||||
+ getHandle().setWander(canWander);
|
||||
+ }
|
||||
+ // Paper end
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sat, 24 Feb 2018 01:14:55 -0500
|
||||
Subject: [PATCH] Tameable#getOwnerUniqueId API
|
||||
|
||||
This is faster if all you need is the UUID, as .getOwner() will cause
|
||||
an OfflinePlayer to be loaded from disk.
|
||||
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
|
||||
@@ -0,0 +0,0 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
|
||||
}
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public UUID getOwnerUniqueId() {
|
||||
+ return getOwnerUUID();
|
||||
+ }
|
||||
public UUID getOwnerUUID() {
|
||||
return this.getHandle().getOwnerUUID();
|
||||
}
|
||||
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java
|
||||
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java
|
||||
@@ -0,0 +0,0 @@ public class CraftTameableAnimal extends CraftAnimals implements Tameable, Creat
|
||||
return (TamableAnimal) super.getHandle();
|
||||
}
|
||||
|
||||
+ @Override
|
||||
+ public UUID getOwnerUniqueId() {
|
||||
+ return getOwnerUUID();
|
||||
+ }
|
||||
public UUID getOwnerUUID() {
|
||||
try {
|
||||
return this.getHandle().getOwnerUUID();
|
||||
@@ -1,18 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: MiniDigger | Martin <admin@minidigger.dev>
|
||||
Date: Sat, 10 Mar 2018 00:50:24 +0100
|
||||
Subject: [PATCH] Toggleable player crits, helps mitigate hacked clients.
|
||||
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/player/Player.java b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
|
||||
@@ -0,0 +0,0 @@ public abstract class Player extends LivingEntity {
|
||||
|
||||
boolean flag2 = flag && this.fallDistance > 0.0F && !this.onGround() && !this.onClimbable() && !this.isInWater() && !this.hasEffect(MobEffects.BLINDNESS) && !this.isPassenger() && target instanceof LivingEntity;
|
||||
|
||||
+ flag2 = flag2 && !this.level().paperConfig().entities.behavior.disablePlayerCrits; // Paper
|
||||
flag2 = flag2 && !this.isSprinting();
|
||||
if (flag2) {
|
||||
f *= 1.5F;
|
||||
@@ -1,19 +0,0 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Aikar <aikar@aikar.co>
|
||||
Date: Sun, 10 Jun 2018 01:18:49 -0400
|
||||
Subject: [PATCH] Unset Ignited flag on cancel of Explosion Event
|
||||
|
||||
Otherwise the creeper infinite explodes
|
||||
|
||||
diff --git a/src/main/java/net/minecraft/world/entity/monster/Creeper.java b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 100644
|
||||
--- a/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
+++ b/src/main/java/net/minecraft/world/entity/monster/Creeper.java
|
||||
@@ -0,0 +0,0 @@ public class Creeper extends Monster implements PowerableMob {
|
||||
// CraftBukkit start
|
||||
} else {
|
||||
this.swell = 0;
|
||||
+ this.entityData.set(DATA_IS_IGNITED, Boolean.valueOf(false)); // Paper
|
||||
}
|
||||
// CraftBukkit end
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user