some more stuffs

This commit is contained in:
Jake Potrebic 2023-06-07 19:04:01 -07:00
parent 1eba407610
commit 47c5d82017
No known key found for this signature in database
GPG key ID: ECE0B3C133C016C5
47 changed files with 375 additions and 265 deletions

View file

@ -1,48 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Fri, 19 Mar 2021 23:39:09 -0400
Subject: [PATCH] Add ElderGuardianAppearanceEvent
diff --git a/src/main/java/net/minecraft/world/effect/MobEffectUtil.java b/src/main/java/net/minecraft/world/effect/MobEffectUtil.java
index 4c46a843c5c7e6f735f6b5f0f3c034524a0cf1e1..2baba1ccc1acd50693e05d565784d11df27bba93 100644
--- a/src/main/java/net/minecraft/world/effect/MobEffectUtil.java
+++ b/src/main/java/net/minecraft/world/effect/MobEffectUtil.java
@@ -54,10 +54,23 @@ public final class MobEffectUtil {
}
public static List<ServerPlayer> addEffectToPlayersAround(ServerLevel worldserver, @Nullable Entity entity, Vec3 vec3d, double d0, MobEffectInstance mobeffect, int i, org.bukkit.event.entity.EntityPotionEffectEvent.Cause cause) {
+ // Paper start
+ return addEffectToPlayersAround(worldserver, entity, vec3d, d0, mobeffect, i, cause, null);
+ }
+
+ public static List<ServerPlayer> addEffectToPlayersAround(ServerLevel worldserver, @Nullable Entity entity, Vec3 vec3d, double d0, MobEffectInstance mobeffect, int i, org.bukkit.event.entity.EntityPotionEffectEvent.Cause cause, @Nullable java.util.function.Predicate<ServerPlayer> playerPredicate) {
+ // Paper end
// CraftBukkit end
MobEffect mobeffectlist = mobeffect.getEffect();
List<ServerPlayer> list = worldserver.getPlayers((entityplayer) -> {
- return entityplayer.gameMode.isSurvival() && (entity == null || !entity.isAlliedTo((Entity) entityplayer)) && vec3d.closerThan(entityplayer.position(), d0) && (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < mobeffect.getAmplifier() || entityplayer.getEffect(mobeffectlist).endsWithin(i - 1));
+ // Paper start
+ boolean condition = entityplayer.gameMode.isSurvival() && (entity == null || !entity.isAlliedTo((Entity) entityplayer)) && vec3d.closerThan(entityplayer.position(), d0) && (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < mobeffect.getAmplifier() || entityplayer.getEffect(mobeffectlist).endsWithin(i - 1));
+ if (condition) {
+ return playerPredicate == null || playerPredicate.test(entityplayer); // Only test the player AFTER it is true
+ } else {
+ return false;
+ }
+ // Paper ned
});
list.forEach((entityplayer) -> {
diff --git a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
index 0b6c6740e1411a558d224589b3786f3ba8e0a1bc..d02286d553c600fe7e75f48e278e380d21c5b868 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
@@ -67,7 +67,7 @@ public class ElderGuardian extends Guardian {
super.customServerAiStep();
if ((this.tickCount + this.getId()) % 1200 == 0) {
MobEffectInstance mobeffect = new MobEffectInstance(MobEffects.DIG_SLOWDOWN, 6000, 2);
- List<ServerPlayer> list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level, this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
+ List<ServerPlayer> list = MobEffectUtil.addEffectToPlayersAround((ServerLevel) this.level, this, this.position(), 50.0D, mobeffect, 1200, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK, (player) -> new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent(getBukkitEntity(), player.getBukkitEntity()).callEvent()); // CraftBukkit // Paper
list.forEach((entityplayer) -> {
entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, this.isSilent() ? 0.0F : 1.0F));

View file

@ -1,86 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <spottedleaf@users.noreply.github.com>
Date: Fri, 4 Jun 2021 17:06:52 -0400
Subject: [PATCH] Fix dangerous end portal logic
End portals could teleport entities during move calls. Stupid
logic given the caller will never expect that kind of thing,
and will result in all kinds of dupes.
Move the tick logic into the post tick, where portaling was
designed to happen in the first place.
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 4dc8a8fcffddfc6673d5c161be1224d822ad3dab..f646e2230dbf1dd6bfb1a43545d95a4d9895c3d6 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -511,6 +511,36 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
return chunkMap.playerEntityTrackerTrackMaps[type.ordinal()].getObjectsInRange(MCUtil.getCoordinateKey(this));
}
// Paper end - optimise entity tracking
+ // Paper start - make end portalling safe
+ public BlockPos portalBlock;
+ public ServerLevel portalWorld;
+ public void tickEndPortal() {
+ BlockPos pos = this.portalBlock;
+ ServerLevel world = this.portalWorld;
+ this.portalBlock = null;
+ this.portalWorld = null;
+
+ if (pos == null || world == null || world != this.level) {
+ return;
+ }
+
+ if (this.isPassenger() || this.isVehicle() || !this.canChangeDimensions() || this.isRemoved() || !this.valid || !this.isAlive()) {
+ return;
+ }
+
+ ResourceKey<Level> resourcekey = world.getTypeKey() == LevelStem.END ? Level.OVERWORLD : Level.END; // CraftBukkit - SPIGOT-6152: send back to main overworld in custom ends
+ ServerLevel worldserver = world.getServer().getLevel(resourcekey);
+
+ org.bukkit.event.entity.EntityPortalEnterEvent event = new org.bukkit.event.entity.EntityPortalEnterEvent(this.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
+ event.callEvent();
+
+ if (this instanceof ServerPlayer) {
+ ((ServerPlayer)this).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
+ return;
+ }
+ this.teleportTo(worldserver, null);
+ }
+ // Paper end - make end portalling safe
public Entity(EntityType<?> type, Level world) {
this.id = Entity.ENTITY_COUNTER.incrementAndGet();
@@ -2731,6 +2761,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
this.processPortalCooldown();
+ this.tickEndPortal(); // Paper - make end portalling safe
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
index 45b427f314da778cc13da9ad6e4e1316790bf1b1..41d7cff39fc37955877668337689b4b26cd8c7cf 100644
--- a/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/EndPortalBlock.java
@@ -53,16 +53,10 @@ public class EndPortalBlock extends BaseEntityBlock {
// return; // CraftBukkit - always fire event in case plugins wish to change it
}
- // CraftBukkit start - Entity in portal
- EntityPortalEnterEvent event = new EntityPortalEnterEvent(entity.getBukkitEntity(), new org.bukkit.Location(world.getWorld(), pos.getX(), pos.getY(), pos.getZ()));
- world.getCraftServer().getPluginManager().callEvent(event);
-
- if (entity instanceof ServerPlayer) {
- ((ServerPlayer) entity).changeDimension(worldserver, PlayerTeleportEvent.TeleportCause.END_PORTAL);
- return;
- }
- // CraftBukkit end
- entity.changeDimension(worldserver);
+ // Paper start - move all of this logic into portal tick
+ entity.portalWorld = ((ServerLevel)world);
+ entity.portalBlock = pos.immutable();
+ // Paper end - move all of this logic into portal tick
}
}

View file

@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Wed, 12 Sep 2018 21:47:01 -0400
Subject: [PATCH] Optimize Biome Mob Lookups for Mob Spawning
Uses an EnumMap as well as a Set paired List for O(1) contains calls.
diff --git a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
index 4f4ef3349f512cc6e1588eb58de5b2558c0bd8b9..9e2f7fc64b284efd6388be35f250642c47e7603b 100644
--- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
+++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
@@ -61,11 +61,43 @@ public class MobSpawnSettings {
}
public static class Builder {
- private final Map<MobCategory, List<MobSpawnSettings.SpawnerData>> spawners = Stream.of(MobCategory.values()).collect(ImmutableMap.toImmutableMap((mobCategory) -> {
+ // Paper start - keep track of data in a pair set to give O(1) contains calls - we have to hook removals incase plugins mess with it
+ public static class MobList extends java.util.ArrayList<MobSpawnSettings.SpawnerData> {
+ java.util.Set<MobSpawnSettings.SpawnerData> biomes = new java.util.HashSet<>();
+
+ @Override
+ public boolean contains(Object o) {
+ return biomes.contains(o);
+ }
+
+ @Override
+ public boolean add(MobSpawnSettings.SpawnerData BiomeSettingsMobs) {
+ biomes.add(BiomeSettingsMobs);
+ return super.add(BiomeSettingsMobs);
+ }
+
+ @Override
+ public MobSpawnSettings.SpawnerData remove(int index) {
+ MobSpawnSettings.SpawnerData removed = super.remove(index);
+ if (removed != null) {
+ biomes.remove(removed);
+ }
+ return removed;
+ }
+
+ @Override
+ public void clear() {
+ biomes.clear();
+ super.clear();
+ }
+ }
+ // use toImmutableEnumMap collector
+ private final Map<MobCategory, List<MobSpawnSettings.SpawnerData>> spawners = (Map) Stream.of(MobCategory.values()).collect(Maps.toImmutableEnumMap((mobCategory) -> {
return mobCategory;
}, (mobCategory) -> {
- return Lists.newArrayList();
+ return new MobList(); // Use MobList instead of ArrayList
}));
+ // Paper end
private final Map<EntityType<?>, MobSpawnSettings.MobSpawnCost> mobSpawnCosts = Maps.newLinkedHashMap();
private float creatureGenerationProbability = 0.1F;

View file

@ -1,55 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 4 Jun 2021 12:12:35 -0700
Subject: [PATCH] Make item validations configurable
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
index e8413ad360e9b6c4eef13edf9dd0095e7e64bce2..a5d7fae348b0b262a0a8a5e8e76f1bc75ca52a16 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
@@ -88,11 +88,11 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
super(tag);
if (tag.contains(BOOK_TITLE.NBT)) {
- this.title = limit( tag.getString(BOOK_TITLE.NBT), 8192 ); // Spigot
+ this.title = limit( tag.getString(BOOK_TITLE.NBT), io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.book.title); // Spigot // Paper - make configurable
}
if (tag.contains(BOOK_AUTHOR.NBT)) {
- this.author = limit( tag.getString(BOOK_AUTHOR.NBT), 8192 ); // Spigot
+ this.author = limit( tag.getString(BOOK_AUTHOR.NBT), io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.book.author ); // Spigot // Paper - make configurable
}
if (tag.contains(RESOLVED.NBT)) {
@@ -120,7 +120,7 @@ public class CraftMetaBook extends CraftMetaItem implements BookMeta {
} else {
page = this.validatePage(page);
}
- this.pages.add( limit( page, 16384 ) ); // Spigot
+ this.pages.add( limit( page, io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.book.page ) ); // Spigot // Paper - make configurable
}
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
index ad202473abbe4b302b825d9dd9dd75402190e824..9fc74007bd887ab71dea9dcfdc1e3017036d0bfc 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -360,7 +360,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
CompoundTag display = tag.getCompound(DISPLAY.NBT);
if (display.contains(NAME.NBT)) {
- this.displayName = limit( display.getString(NAME.NBT), 8192 ); // Spigot
+ this.displayName = limit( display.getString(NAME.NBT), io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.displayName ); // Spigot // Paper - make configurable
}
if (display.contains(LOCNAME.NBT)) {
@@ -371,7 +371,7 @@ class CraftMetaItem implements ItemMeta, Damageable, Repairable, BlockDataMeta {
ListTag list = display.getList(LORE.NBT, CraftMagicNumbers.NBT.TAG_STRING);
this.lore = new ArrayList<String>(list.size());
for (int index = 0; index < list.size(); index++) {
- String line = limit( list.getString(index), 8192 ); // Spigot
+ String line = limit( list.getString(index), io.papermc.paper.configuration.GlobalConfiguration.get().itemValidation.loreLine ); // Spigot // Paper - make configurable
this.lore.add(line);
}
}

View file

@ -1,74 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: TwoLeggedCat <80929284+TwoLeggedCat@users.noreply.github.com>
Date: Sat, 29 May 2021 14:33:25 -0500
Subject: [PATCH] Line Of Sight Changes
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index a99130c736ab17442d708e44434bdb426a3fee91..5cbe700d5620164690ea4a596ec996b6906b473b 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3506,7 +3506,8 @@ public abstract class LivingEntity extends Entity implements Attackable {
Vec3 vec3d = new Vec3(this.getX(), this.getEyeY(), this.getZ());
Vec3 vec3d1 = new Vec3(entity.getX(), entity.getEyeY(), entity.getZ());
- return vec3d1.distanceTo(vec3d) > 128.0D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS;
+ // Paper - diff on change - used in CraftLivingEntity#hasLineOfSight(Location) and CraftWorld#lineOfSightExists
+ return vec3d1.distanceToSqr(vec3d) > 128D * 128D ? false : this.level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this)).getType() == HitResult.Type.MISS; // Paper - use distanceToSqr
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
index f01c6f684da1438808f018fe9a814ecaceb49b2f..505ce1ae7df56be0e70faf359ae1e5ebcc06255e 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftRegionAccessor.java
@@ -996,5 +996,16 @@ public abstract class CraftRegionAccessor implements RegionAccessor {
public org.bukkit.NamespacedKey getKey() {
return org.bukkit.craftbukkit.util.CraftNamespacedKey.fromMinecraft(this.getHandle().getLevel().dimension().location());
}
+
+ public boolean lineOfSightExists(Location from, Location to) {
+ Preconditions.checkArgument(from != null, "from parameter in lineOfSightExists cannot be null");
+ Preconditions.checkArgument(to != null, "to parameter in lineOfSightExists cannot be null");
+ if (from.getWorld() != to.getWorld()) return false;
+ net.minecraft.world.phys.Vec3 vec3d = new net.minecraft.world.phys.Vec3(from.getX(), from.getY(), from.getZ());
+ net.minecraft.world.phys.Vec3 vec3d1 = new net.minecraft.world.phys.Vec3(to.getX(), to.getY(), to.getZ());
+ if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+ return this.getHandle().clip(new net.minecraft.world.level.ClipContext(vec3d, vec3d1, net.minecraft.world.level.ClipContext.Block.COLLIDER, net.minecraft.world.level.ClipContext.Fluid.NONE, null)).getType() == net.minecraft.world.phys.HitResult.Type.MISS;
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index b38d72e921c4705cae72eb65113b36c87e4250fd..f217df2d3c7a53b72418fab63cef06dbc107fe0d 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -29,6 +29,9 @@ import net.minecraft.world.entity.projectile.ThrownEgg;
import net.minecraft.world.entity.projectile.ThrownEnderpearl;
import net.minecraft.world.entity.projectile.ThrownExperienceBottle;
import net.minecraft.world.entity.projectile.ThrownTrident;
+import net.minecraft.world.level.ClipContext;
+import net.minecraft.world.phys.HitResult;
+import net.minecraft.world.phys.Vec3;
import org.apache.commons.lang.Validate;
import org.bukkit.FluidCollisionMode;
import org.bukkit.Location;
@@ -576,6 +579,18 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
return this.getHandle().hasLineOfSight(((CraftEntity) other).getHandle());
}
+ // Paper start
+ @Override
+ public boolean hasLineOfSight(Location loc) {
+ if (this.getHandle().level != ((CraftWorld) loc.getWorld()).getHandle()) return false;
+ Vec3 vec3d = new Vec3(this.getHandle().getX(), this.getHandle().getEyeY(), this.getHandle().getZ());
+ Vec3 vec3d1 = new Vec3(loc.getX(), loc.getY(), loc.getZ());
+ if (vec3d1.distanceToSqr(vec3d) > 128D * 128D) return false; //Return early if the distance is greater than 128 blocks
+
+ return this.getHandle().level.clip(new ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, this.getHandle())).getType() == HitResult.Type.MISS;
+ }
+ // Paper end
+
@Override
public boolean getRemoveWhenFarAway() {
return this.getHandle() instanceof Mob && !((Mob) this.getHandle()).isPersistenceRequired();

View file

@ -1,25 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: chase <chasewhip20@gmail.com>
Date: Wed, 2 Dec 2020 22:43:39 -0800
Subject: [PATCH] add per world spawn limits
Taken from #2982. Credit to Chasewhip8
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index d2c7730a63118612eb0a60853b3221fab3b6f37e..0acb97676ad066d474b0290cbbb8555f11d09154 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -213,6 +213,13 @@ public class CraftWorld extends CraftRegionAccessor implements World {
this.biomeProvider = biomeProvider;
this.environment = env;
+ // Paper start - per world spawn limits
+ for (SpawnCategory spawnCategory : SpawnCategory.values()) {
+ if (CraftSpawnCategory.isValidForLimits(spawnCategory)) {
+ setSpawnLimit(spawnCategory, this.world.paperConfig().entities.spawning.spawnLimits.getInt(CraftSpawnCategory.toNMS(spawnCategory)));
+ }
+ }
+ // Paper end
}
@Override

View file

@ -1,155 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 20 May 2021 20:40:53 -0700
Subject: [PATCH] Fix potions splash events
Fix PotionSplashEvent for water splash potions
Fixes SPIGOT-6221: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-6221
Fix splash events cancellation that still show particles/sound
diff --git a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
index 7f895fe93b7002ee271f985abbeaf4cd11e900ee..5f7be427bfc4d954dece4792764004cf0b7757a1 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -104,56 +104,77 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
Potion potionregistry = PotionUtils.getPotion(itemstack);
List<MobEffectInstance> list = PotionUtils.getMobEffects(itemstack);
boolean flag = potionregistry == Potions.WATER && list.isEmpty();
+ boolean showParticles = true; // Paper
if (flag) {
- this.applyWater();
+ showParticles = this.applyWater(); // Paper
} else if (true || !list.isEmpty()) { // CraftBukkit - Call event even if no effects to apply
if (this.isLingering()) {
- this.makeAreaOfEffectCloud(itemstack, potionregistry);
+ showParticles = this.makeAreaOfEffectCloud(itemstack, potionregistry); // Paper
} else {
- this.applySplash(list, hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null);
+ showParticles = this.applySplash(list, hitResult.getType() == HitResult.Type.ENTITY ? ((EntityHitResult) hitResult).getEntity() : null); // Paper
}
}
+ if (showParticles) { // Paper
int i = potionregistry.hasInstantEffects() ? 2007 : 2002;
this.level.levelEvent(i, this.blockPosition(), PotionUtils.getColor(itemstack));
+ } // Paper
this.discard();
}
}
- private void applyWater() {
+ private static final Predicate<net.minecraft.world.entity.LivingEntity> APPLY_WATER_GET_ENTITIES_PREDICATE = ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE.or(Axolotl.class::isInstance); // Paper
+ private boolean applyWater() { // Paper
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
- List<net.minecraft.world.entity.LivingEntity> list = this.level.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.WATER_SENSITIVE_OR_ON_FIRE);
+ // Paper start
+ List<net.minecraft.world.entity.LivingEntity> list = this.level.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb, ThrownPotion.APPLY_WATER_GET_ENTITIES_PREDICATE);
+ Map<LivingEntity, Double> affected = new HashMap<>();
+ java.util.Set<LivingEntity> rehydrate = new java.util.HashSet<>();
+ java.util.Set<LivingEntity> extinguish = new java.util.HashSet<>();
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
net.minecraft.world.entity.LivingEntity entityliving = (net.minecraft.world.entity.LivingEntity) iterator.next();
+ if (entityliving instanceof Axolotl axolotl) {
+ rehydrate.add(((org.bukkit.entity.Axolotl) axolotl.getBukkitEntity()));
+ }
double d0 = this.distanceToSqr((Entity) entityliving);
if (d0 < 16.0D) {
if (entityliving.isSensitiveToWater()) {
- entityliving.hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ affected.put(entityliving.getBukkitLivingEntity(), 1.0);
}
if (entityliving.isOnFire() && entityliving.isAlive()) {
- entityliving.extinguishFire();
+ extinguish.add(entityliving.getBukkitLivingEntity());
}
}
}
- List<Axolotl> list1 = this.level.getEntitiesOfClass(Axolotl.class, axisalignedbb);
- Iterator iterator1 = list1.iterator();
-
- while (iterator1.hasNext()) {
- Axolotl axolotl = (Axolotl) iterator1.next();
-
- axolotl.rehydrate();
+ io.papermc.paper.event.entity.WaterBottleSplashEvent event = new io.papermc.paper.event.entity.WaterBottleSplashEvent(
+ (org.bukkit.entity.ThrownPotion) this.getBukkitEntity(), affected, rehydrate, extinguish
+ );
+ if (event.callEvent()) {
+ for (LivingEntity affectedEntity : event.getToDamage()) {
+ ((CraftLivingEntity) affectedEntity).getHandle().hurt(this.damageSources().indirectMagic(this, this.getOwner()), 1.0F);
+ }
+ for (LivingEntity toExtinguish : event.getToExtinguish()) {
+ ((CraftLivingEntity) toExtinguish).getHandle().extinguishFire();
+ }
+ for (LivingEntity toRehydrate : event.getToRehydrate()) {
+ if (((CraftLivingEntity) toRehydrate).getHandle() instanceof Axolotl axolotl) {
+ axolotl.rehydrate();
+ }
+ }
+ // Paper end
}
+ return !event.isCancelled(); // Paper
}
- private void applySplash(List<MobEffectInstance> statusEffects, @Nullable Entity entity) {
+ private boolean applySplash(List<MobEffectInstance> statusEffects, @Nullable Entity entity) { // Paper
AABB axisalignedbb = this.getBoundingBox().inflate(4.0D, 2.0D, 4.0D);
List<net.minecraft.world.entity.LivingEntity> list1 = this.level.getEntitiesOfClass(net.minecraft.world.entity.LivingEntity.class, axisalignedbb);
Map<LivingEntity, Double> affected = new HashMap<LivingEntity, Double>(); // CraftBukkit
@@ -171,6 +192,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
if (d0 < 16.0D) {
double d1;
+ // Paper - diff on change, used when calling the splash event for water splash potions
if (entityliving == entity) {
d1 = 1.0D;
} else {
@@ -226,10 +248,11 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
}
}
}
+ return !event.isCancelled(); // Paper
}
- private void makeAreaOfEffectCloud(ItemStack stack, Potion potion) {
+ private boolean makeAreaOfEffectCloud(ItemStack stack, Potion potion) { // Paper
AreaEffectCloud entityareaeffectcloud = new AreaEffectCloud(this.level, this.getX(), this.getY(), this.getZ());
Entity entity = this.getOwner();
@@ -244,10 +267,12 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
entityareaeffectcloud.setPotion(potion);
Iterator iterator = PotionUtils.getCustomEffects(stack).iterator();
+ boolean noEffects = potion.getEffects().isEmpty(); // Paper
while (iterator.hasNext()) {
MobEffectInstance mobeffect = (MobEffectInstance) iterator.next();
entityareaeffectcloud.addEffect(new MobEffectInstance(mobeffect));
+ noEffects = false; // Paper
}
CompoundTag nbttagcompound = stack.getTag();
@@ -258,12 +283,13 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
// CraftBukkit start
org.bukkit.event.entity.LingeringPotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callLingeringPotionSplashEvent(this, entityareaeffectcloud);
- if (!(event.isCancelled() || entityareaeffectcloud.isRemoved())) {
+ if (!(event.isCancelled() || entityareaeffectcloud.isRemoved() || (noEffects && entityareaeffectcloud.effects.isEmpty() && entityareaeffectcloud.getPotion().getEffects().isEmpty()))) { // Paper - don't spawn area effect cloud if the effects were empty and not changed during the event handling
this.level.addFreshEntity(entityareaeffectcloud);
} else {
entityareaeffectcloud.discard();
}
// CraftBukkit end
+ return !event.isCancelled(); // Paper
}
public boolean isLingering() {

View file

@ -1,56 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: dfsek <dfsek@protonmail.com>
Date: Sat, 19 Jun 2021 20:15:59 -0700
Subject: [PATCH] Add more LimitedRegion API
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
index 10fb28aabf8c9f764cdd614edbeec4523f8ab431..0ea1586bab74983fca19dcc5415fbc7a044fe186 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
@@ -251,4 +251,45 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
public void addEntityToWorld(net.minecraft.world.entity.Entity entity, CreatureSpawnEvent.SpawnReason reason) {
this.entities.add(entity);
}
+
+ // Paper start
+ @Override
+ public void setBlockState(int x, int y, int z, BlockState state) {
+ BlockPos pos = new BlockPos(x, y, z);
+ if (!state.getBlockData().matches(getHandle().getBlockState(pos).createCraftBlockData())) {
+ throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getHandle().getBlockState(pos).createCraftBlockData().getAsString(false));
+ }
+ getHandle().getBlockEntity(pos).load(((org.bukkit.craftbukkit.block.CraftBlockEntityState<?>) state).getSnapshotNBT());
+ }
+
+ @Override
+ public void scheduleBlockUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getHandle().scheduleTick(position, getHandle().getBlockState(position).getBlock(), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getHandle().scheduleTick(position, getHandle().getFluidState(position).getType(), 0);
+ }
+
+ @Override
+ public World getWorld() {
+ // reading/writing the returned Minecraft world causes a deadlock.
+ // By implementing this, and covering it in warnings, we're assuming people won't be stupid, and
+ // if they are stupid, they'll figure it out pretty fast.
+ return getHandle().getMinecraftWorld().getWorld();
+ }
+
+ @Override
+ public int getCenterChunkX() {
+ return centerChunkX;
+ }
+
+ @Override
+ public int getCenterChunkZ() {
+ return centerChunkZ;
+ }
+ // Paper end
}

View file

@ -1,35 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Sun, 20 Jun 2021 21:55:59 -0700
Subject: [PATCH] Fix PlayerDropItemEvent using wrong item
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 47d2bf15871e50e46c0e5df725f2bbacfe12a869..4b4bb21149a102a8cbf46ee104417dadb49999df 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -2249,7 +2249,7 @@ public class ServerPlayer extends Player {
if (retainOwnership) {
if (!itemstack1.isEmpty()) {
- this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), stack.getCount());
+ this.awardStat(Stats.ITEM_DROPPED.get(itemstack1.getItem()), itemstack1.getCount()); // Paper
}
this.awardStat(Stats.DROP);
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 eb0f9c2e54d75ee80bcc421d1042d1eea7c57a16..997b2458a3e14296437e76737b837d90d4936072 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -722,6 +722,11 @@ public abstract class Player extends LivingEntity {
}
double d0 = this.getEyeY() - 0.30000001192092896D;
+ // Paper start
+ ItemStack tmp = itemstack.copy();
+ itemstack.setCount(0);
+ itemstack = tmp;
+ // Paper end
ItemEntity entityitem = new ItemEntity(this.level, this.getX(), d0, this.getZ(), itemstack);
entityitem.setPickUpDelay(40);

File diff suppressed because it is too large Load diff

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Tue, 22 Jun 2021 19:58:53 +0100
Subject: [PATCH] Ensure disconnect for book edit is called on main
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 2663576ec20dbeda9ca131a57ea3cee02680e4be..caa8455611046ddd33d07cc61891bb632cbfdb5e 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1205,7 +1205,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
// Paper end
// CraftBukkit start
if (this.lastBookTick + 20 > MinecraftServer.currentTick) {
- this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION); // Paper - kick event cause
+ server.scheduleOnMain(() -> this.disconnect("Book edited too quickly!", org.bukkit.event.player.PlayerKickEvent.Cause.ILLEGAL_ACTION)); // Paper - kick event cause // Paper - Also ensure this is called on main
return;
}
this.lastBookTick = MinecraftServer.currentTick;

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Mon, 28 Jun 2021 18:16:52 -0700
Subject: [PATCH] Fix return value of Block#applyBoneMeal always being false
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
index 9a1304103d367e2d7bc552977542b46e9887bcb4..9fa50da214ad9a134008c91e1e07223904a8e6a3 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -585,7 +585,7 @@ public class CraftBlock implements Block {
}
}
- return result == InteractionResult.SUCCESS && (event == null || !event.isCancelled());
+ return result == InteractionResult.CONSUME && (event == null || !event.isCancelled()); // Paper - CONSUME is returned on success server-side (see BoneMealItem.applyBoneMeal and InteractionResult.sidedSuccess(boolean))
}
@Override

View file

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 8 Jul 2019 00:13:36 -0700
Subject: [PATCH] Use getChunkIfLoadedImmediately in places
This prevents us from hitting chunk loads for chunks at or less-than
ticket level 33 (yes getChunkIfLoaded will actually perform a chunk
load in that case).
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index e93a1713505d52d719738b36ea59859c547553b7..16b73f0498936a8413f6adedd7f92bab07a4a108 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -225,7 +225,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
@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);
+ return this.chunkSource.getChunkAtIfLoadedImmediately(x, z); // Paper
}
@Override
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 8a6f01af6d9a210fbd5cf14002c426c2e36fc51b..5f43dbd3b4a50f425b188beb2ed9236ed2db0a06 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -202,6 +202,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return (CraftServer) Bukkit.getServer();
}
+ // Paper start
+ @Override
+ public boolean hasChunk(int chunkX, int chunkZ) {
+ return this.getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+ // Paper end
+
public abstract ResourceKey<LevelStem> getTypeKey();
protected Level(WritableLevelData worlddatamutable, ResourceKey<Level> resourcekey, RegistryAccess iregistrycustom, Holder<DimensionType> holder, Supplier<ProfilerFiller> supplier, boolean flag, boolean flag1, long i, int j, org.bukkit.generator.ChunkGenerator gen, org.bukkit.generator.BiomeProvider biomeProvider, org.bukkit.World.Environment env, java.util.function.Function<org.spigotmc.SpigotWorldConfig, io.papermc.paper.configuration.WorldConfiguration> paperWorldConfigCreator, java.util.concurrent.Executor executor) { // Paper - Async-Anti-Xray - Pass executor
diff --git a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
index cd92aaa1c874d78762bbab529dfcea71b36d2a91..25e4596e64b74ada86f210b06ba837be8efc21d1 100644
--- a/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
+++ b/src/main/java/net/minecraft/world/level/gameevent/GameEventDispatcher.java
@@ -56,7 +56,7 @@ public class GameEventDispatcher {
for (int l1 = j; l1 <= i1; ++l1) {
for (int i2 = l; i2 <= k1; ++i2) {
- LevelChunk chunk = this.level.getChunkSource().getChunkNow(l1, i2);
+ LevelChunk chunk = (LevelChunk) this.level.getChunkIfLoadedImmediately(l1, i2); // Paper
if (chunk != null) {
for (int j2 = k; j2 <= j1; ++j2) {

View file

@ -1,126 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 9 Jul 2021 13:50:48 -0700
Subject: [PATCH] Fix commands from signs not firing command events
This patch changes sign command logic so that `run_command` click events:
- are logged to the console
- fire PlayerCommandPreprocessEvent
- work with double-slash commands like `//wand`
- sends failure messages to the player who clicked the sign
diff --git a/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
new file mode 100644
index 0000000000000000000000000000000000000000..01a2bc1feec808790bb93618ce46adb9bea5a9c8
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/DelegatingCommandSource.java
@@ -0,0 +1,42 @@
+package io.papermc.paper.commands;
+
+import net.minecraft.commands.CommandSource;
+import net.minecraft.commands.CommandSourceStack;
+import net.minecraft.network.chat.Component;
+import org.bukkit.command.CommandSender;
+
+import java.util.UUID;
+
+public class DelegatingCommandSource implements CommandSource {
+
+ private final CommandSource delegate;
+
+ public DelegatingCommandSource(CommandSource delegate) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void sendSystemMessage(Component message) {
+ delegate.sendSystemMessage(message);
+ }
+
+ @Override
+ public boolean acceptsSuccess() {
+ return delegate.acceptsSuccess();
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return delegate.acceptsFailure();
+ }
+
+ @Override
+ public boolean shouldInformAdmins() {
+ return delegate.shouldInformAdmins();
+ }
+
+ @Override
+ public CommandSender getBukkitSender(CommandSourceStack wrapper) {
+ return delegate.getBukkitSender(wrapper);
+ }
+}
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 aca2da47651a76f3e5593d71c500d749d92ccc3b..4da4edae517a0efec6e03a719ec47b700509dab1 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
@@ -43,6 +43,7 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
private boolean renderMessagedFiltered;
private DyeColor color;
private boolean hasGlowingText;
+ private static final org.apache.logging.log4j.Logger LOGGER = org.apache.logging.log4j.LogManager.getLogger();
public SignBlockEntity(BlockPos pos, BlockState state) {
super(BlockEntityType.SIGN, pos, state);
@@ -260,7 +261,17 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
ClickEvent chatclickable = chatmodifier.getClickEvent();
if (chatclickable != null && chatclickable.getAction() == ClickEvent.Action.RUN_COMMAND) {
- player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(player), chatclickable.getValue());
+ // Paper start
+ String command = chatclickable.getValue().startsWith("/") ? chatclickable.getValue() : "/" + chatclickable.getValue();
+ if (org.spigotmc.SpigotConfig.logCommands) {
+ LOGGER.info("{} issued server command: {}", player.getScoreboardName(), command);
+ }
+ io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent event = new io.papermc.paper.event.player.PlayerSignCommandPreprocessEvent(player.getBukkitEntity(), command, new org.bukkit.craftbukkit.util.LazyPlayerSet(player.getServer()), (org.bukkit.block.Sign) io.papermc.paper.util.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState());
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performPrefixedCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
+ // Paper end
}
}
@@ -296,8 +307,21 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
String s = player == null ? "Sign" : player.getName().getString();
Object object = player == null ? Component.literal("Sign") : player.getDisplayName();
+ // Paper start - send messages back to the player
+ CommandSource commandSource = this.level.paperConfig().misc.showSignClickCommandFailureMsgsToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) {
+ @Override
+ public void sendSystemMessage(Component message) {
+ player.sendSystemMessage(message);
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return true;
+ }
+ } : this;
+ // Paper end
// CraftBukkit - this
- return new CommandSourceStack(this, Vec3.atCenterOf(this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player);
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf(this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player); // Paper
}
public DyeColor getColor() {
diff --git a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
index d113e54a30db16e2ad955170df6030d15de530d6..26f3a2799e687731d883e7733591f6934479e88d 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -61,7 +61,7 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
CommandSender sender = context.getSource().getBukkitSender();
try {
- return this.server.dispatchCommand(sender, context.getInput()) ? 1 : 0;
+ return this.server.dispatchCommand(sender, context.getRange().get(context.getInput())) ? 1 : 0; // Paper - actually use the StringRange from context
} catch (CommandException ex) {
sender.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command");
this.server.getLogger().log(Level.SEVERE, null, ex);

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 12 Mar 2021 19:22:21 -0800
Subject: [PATCH] Adds PlayerArmSwingEvent
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index de3aff55fd3d72e350b97a5a59ff7707cade3660..da575295905ba67b6f8c44dc4a27fd16cc550c7b 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2492,7 +2492,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
}
// Arm swing animation
- PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer(), (packet.getHand() == InteractionHand.MAIN_HAND) ? PlayerAnimationType.ARM_SWING : PlayerAnimationType.OFF_ARM_SWING);
+ io.papermc.paper.event.player.PlayerArmSwingEvent event = new io.papermc.paper.event.player.PlayerArmSwingEvent(this.getCraftPlayer(), packet.getHand() == InteractionHand.MAIN_HAND ? org.bukkit.inventory.EquipmentSlot.HAND : org.bukkit.inventory.EquipmentSlot.OFF_HAND); // Paper
this.cserver.getPluginManager().callEvent(event);
if (event.isCancelled()) return;

View file

@ -1,85 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:19:41 -0700
Subject: [PATCH] Fixes kick event leave message not being sent
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 4b4bb21149a102a8cbf46ee104417dadb49999df..44cf1f81ed53f72b87530cee006e54014a2798bf 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -270,7 +270,6 @@ public class ServerPlayer extends Player {
public boolean sentListPacket = false;
public boolean supressTrackerForLogin = false; // Paper
public Integer clientViewDistance;
- public String kickLeaveMessage = null; // SPIGOT-3034: Forward leave message to PlayerQuitEvent
// CraftBukkit end
public boolean isRealPlayer; // Paper
public double lastEntitySpawnRadiusSquared; // Paper - optimise isOutsideRange, this field is in blocks
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index da9efc8be6bcaec4f0144a3c51896ce37b539f11..435006230d4fc81dc72c79e6110e91f33a687a77 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -514,7 +514,6 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
// Do not kick the player
return;
}
- this.player.kickLeaveMessage = event.getLeaveMessage(); // CraftBukkit - SPIGOT-3034: Forward leave message to PlayerQuitEvent
// Send the possibly modified leave message
final Component ichatbasecomponent = PaperAdventure.asVanilla(event.reason()); // Paper - Adventure
// CraftBukkit end
@@ -523,7 +522,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
this.connection.send(new ClientboundDisconnectPacket(ichatbasecomponent), PacketSendListener.thenRun(() -> {
this.connection.disconnect(ichatbasecomponent);
}));
- this.onDisconnect(ichatbasecomponent); // CraftBukkit - fire quit instantly
+ this.onDisconnect(ichatbasecomponent, event.leaveMessage()); // CraftBukkit - fire quit instantly // Paper - use kick event leave message
this.connection.setReadOnly();
MinecraftServer minecraftserver = this.server;
Connection networkmanager = this.connection;
@@ -1984,6 +1983,11 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
@Override
public void onDisconnect(Component reason) {
+ // Paper start
+ this.onDisconnect(reason, null);
+ }
+ public void onDisconnect(Component reason, @Nullable net.kyori.adventure.text.Component quitMessage) {
+ // Paper end
// CraftBukkit start - Rarely it would send a disconnect line twice
if (this.processedDisconnect) {
return;
@@ -2001,7 +2005,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
this.player.disconnect();
// Paper start - Adventure
- net.kyori.adventure.text.Component quitMessage = this.server.getPlayerList().remove(this.player);
+ quitMessage = quitMessage == null ? this.server.getPlayerList().remove(this.player) : this.server.getPlayerList().remove(this.player, quitMessage); // Paper - pass in quitMessage to fix kick message not being used
if ((quitMessage != null) && !quitMessage.equals(net.kyori.adventure.text.Component.empty())) {
this.server.getPlayerList().broadcastSystemMessage(PaperAdventure.asVanilla(quitMessage), false);
// Paper end
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index c3e0fa27c34132a99f6cc9c0eb7d9544a9873eed..0e314e2b85ed17bef7b9cc75573b0dc6c13b46b1 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -557,6 +557,11 @@ public abstract class PlayerList {
}
public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer) { // Paper - return Component
+ // Paper start
+ return this.remove(entityplayer, 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() : PaperAdventure.asAdventure(entityplayer.getDisplayName())));
+ }
+ public net.kyori.adventure.text.Component remove(ServerPlayer entityplayer, net.kyori.adventure.text.Component leaveMessage) {
+ // Paper end
ServerLevel worldserver = entityplayer.getLevel();
entityplayer.awardStat(Stats.LEAVE_GAME);
@@ -567,7 +572,7 @@ public abstract class PlayerList {
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() : PaperAdventure.asAdventure(entityplayer.getDisplayName())), entityplayer.quitReason); // Paper - Adventure & quit reason
+ PlayerQuitEvent playerQuitEvent = new PlayerQuitEvent(entityplayer.getBukkitEntity(), leaveMessage, entityplayer.quitReason); // Paper - Adventure & quit reason
this.cserver.getPluginManager().callEvent(playerQuitEvent);
entityplayer.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage());

View file

@ -1,57 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 2 Dec 2020 21:03:02 -0800
Subject: [PATCH] Add config for mobs immune to default effects
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 2c4d6294e1c5a0baa76d20fa5d6f95a06e73152b..db69a26a019615df9d6b0f3ab8f3069d25445f07 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1146,7 +1146,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (this.getMobType() == MobType.UNDEAD) {
MobEffect mobeffectlist = effect.getEffect();
- if (mobeffectlist == MobEffects.REGENERATION || mobeffectlist == MobEffects.POISON) {
+ if ((mobeffectlist == MobEffects.REGENERATION || mobeffectlist == MobEffects.POISON) && this.level.paperConfig().entities.mobEffects.undeadImmuneToCertainEffects) { // Paper
return false;
}
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
index 1102e0e7d1c4e5b62924545e137cc8a9830de08f..148b351624bd201592332751adc9adf95da02376 100644
--- a/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
+++ b/src/main/java/net/minecraft/world/entity/boss/wither/WitherBoss.java
@@ -605,7 +605,7 @@ public class WitherBoss extends Monster implements PowerableMob, RangedAttackMob
@Override
public boolean canBeAffected(MobEffectInstance effect) {
- return effect.getEffect() == MobEffects.WITHER ? false : super.canBeAffected(effect);
+ return effect.getEffect() == MobEffects.WITHER && this.level.paperConfig().entities.mobEffects.immuneToWitherEffect.wither ? false : super.canBeAffected(effect); // Paper
}
private class WitherDoNothingGoal extends Goal {
diff --git a/src/main/java/net/minecraft/world/entity/monster/Spider.java b/src/main/java/net/minecraft/world/entity/monster/Spider.java
index 9174feeca84d6413663387df9881b4c227165782..61fd27992516e1238195f8e60766428f01719ba7 100644
--- a/src/main/java/net/minecraft/world/entity/monster/Spider.java
+++ b/src/main/java/net/minecraft/world/entity/monster/Spider.java
@@ -133,7 +133,7 @@ public class Spider extends Monster {
@Override
public boolean canBeAffected(MobEffectInstance effect) {
- return effect.getEffect() == MobEffects.POISON ? false : super.canBeAffected(effect);
+ return effect.getEffect() == MobEffects.POISON && this.level.paperConfig().entities.mobEffects.spidersImmuneToPoisonEffect ? false : super.canBeAffected(effect); // Paper
}
public boolean isClimbing() {
diff --git a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
index ea6233cb3ca30864e54d553a5d1071ea9147a868..6449213d717271bcc516e393a78dfe1e5c762d68 100644
--- a/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
+++ b/src/main/java/net/minecraft/world/entity/monster/WitherSkeleton.java
@@ -123,6 +123,6 @@ public class WitherSkeleton extends AbstractSkeleton {
@Override
public boolean canBeAffected(MobEffectInstance effect) {
- return effect.getEffect() == MobEffects.WITHER ? false : super.canBeAffected(effect);
+ return effect.getEffect() == MobEffects.WITHER && this.level.paperConfig().entities.mobEffects.immuneToWitherEffect.witherSkeleton ? false : super.canBeAffected(effect); // Paper
}
}

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: sulu5890 <sulu@sulu.me>
Date: Sun, 11 Jul 2021 19:34:03 -0500
Subject: [PATCH] Fix incorrect message for outdated client
diff --git a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
index de25fde984d17a3228803a8a274372b0fe27da5e..8f52acc03943b18f87b3b2581066496a254b1156 100644
--- a/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerHandshakePacketListenerImpl.java
@@ -82,7 +82,7 @@ public class ServerHandshakePacketListenerImpl implements ServerHandshakePacketL
if (packet.getProtocolVersion() != SharedConstants.getCurrentVersion().getProtocolVersion()) {
Component ichatmutablecomponent; // Paper - Fix hex colors not working in some kick messages
- if (packet.getProtocolVersion() < 754) {
+ if (packet.getProtocolVersion() < SharedConstants.getCurrentVersion().getProtocolVersion()) { // Paper - Fix incorrect message for outdated clients
ichatmutablecomponent = org.bukkit.craftbukkit.util.CraftChatMessage.fromString( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedClientMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) , true )[0]; // Spigot // Paper - Fix hex colors not working in some kick messages
} else {
ichatmutablecomponent = org.bukkit.craftbukkit.util.CraftChatMessage.fromString( java.text.MessageFormat.format( org.spigotmc.SpigotConfig.outdatedServerMessage.replaceAll("'", "''"), SharedConstants.getCurrentVersion().getName() ) , true )[0]; // Spigot // Paper - Fix hex colors not working in some kick messages

View file

@ -1,33 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Sun, 20 Jun 2021 16:35:42 +0100
Subject: [PATCH] Don't apply cramming damage to players
It does not make a lot of sense to damage players if they get crammed,
especially as the usecase of teleporting lots of players to the same
location isn't too uncommon and killing all those players isn't
really what one would expect to happen.
For those who really want it a config option is provided.
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index 44cf1f81ed53f72b87530cee006e54014a2798bf..a649d1baa727dd16cb8e786bdf510021e2d16d26 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -100,6 +100,7 @@ import net.minecraft.util.Mth;
import net.minecraft.util.RandomSource;
import net.minecraft.util.Unit;
import net.minecraft.world.damagesource.DamageSource;
+import net.minecraft.world.damagesource.DamageSources;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.effect.MobEffects;
import net.minecraft.world.entity.Entity;
@@ -1432,7 +1433,7 @@ public class ServerPlayer extends Player {
@Override
public boolean isInvulnerableTo(DamageSource damageSource) {
- return super.isInvulnerableTo(damageSource) || this.isChangingDimension();
+ return super.isInvulnerableTo(damageSource) || this.isChangingDimension() || !level.paperConfig().collisions.allowPlayerCrammingDamage && damageSource == damageSources().cramming(); // Paper - disable player cramming
}
@Override

View file

@ -1,134 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Phoenix616 <max@themoep.de>
Date: Mon, 28 Jun 2021 22:38:29 +0100
Subject: [PATCH] Rate options and timings for sensors and behaviors
This adds config options to specify the tick rate for sensors
and behaviors of different entity types as well as timings
for those in order to be able to have some metrics as to which
ones might need tweaking.
diff --git a/src/main/java/co/aikar/timings/MinecraftTimings.java b/src/main/java/co/aikar/timings/MinecraftTimings.java
index 59affb62cb487d60e8c3e32decf89d6cb7d22f8d..4d861f9a58f8ea238471af22f387854d855b1801 100644
--- a/src/main/java/co/aikar/timings/MinecraftTimings.java
+++ b/src/main/java/co/aikar/timings/MinecraftTimings.java
@@ -115,6 +115,14 @@ public final class MinecraftTimings {
return Timings.ofSafe("Minecraft", "## tickEntity - " + entityType + " - " + type, tickEntityTimer);
}
+ public static Timing getBehaviorTimings(String type) {
+ return Timings.ofSafe("## Behavior - " + type);
+ }
+
+ public static Timing getSensorTimings(String type, int rate) {
+ return Timings.ofSafe("## Sensor - " + type + " (Default rate: " + rate + ")");
+ }
+
/**
* Get a named timer for the specified tile entity type to track type specific timings.
* @param entity
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
index 4ea437253539e3ee533ca9da77a337cbf4d1e807..57ef7fbba3028c28231abf7b7ae78aa019323536 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/Behavior.java
@@ -13,6 +13,10 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
private long endTimestamp;
private final int minDuration;
private final int maxDuration;
+ // Paper start - configurable behavior tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end
public Behavior(Map<MemoryModuleType<?>, MemoryStatus> requiredMemoryState) {
this(requiredMemoryState, 60);
@@ -26,6 +30,15 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
this.minDuration = minRunTime;
this.maxDuration = maxRunTime;
this.entryCondition = requiredMemoryState;
+ // Paper start - configurable behavior tick rate and timings
+ String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getBehaviorTimings(configKey);
+ // Paper end
}
@Override
@@ -35,11 +48,19 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final boolean tryStart(ServerLevel world, E entity, long time) {
+ // Paper start - behavior tick rate
+ int tickRate = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.behavior.get(entity.getType(), this.configKey), -1);
+ if (tickRate > -1 && time < this.endTimestamp + tickRate) {
+ return false;
+ }
+ // Paper end
if (this.hasRequiredMemories(entity) && this.checkExtraStartConditions(world, entity)) {
this.status = Behavior.Status.RUNNING;
int i = this.minDuration + world.getRandom().nextInt(this.maxDuration + 1 - this.minDuration);
this.endTimestamp = time + (long)i;
+ this.timing.startTiming(); // Paper - behavior timings
this.start(world, entity, time);
+ this.timing.stopTiming(); // Paper - behavior timings
return true;
} else {
return false;
@@ -51,11 +72,13 @@ public abstract class Behavior<E extends LivingEntity> implements BehaviorContro
@Override
public final void tickOrStop(ServerLevel world, E entity, long time) {
+ this.timing.startTiming(); // Paper - behavior timings
if (!this.timedOut(time) && this.canStillUse(world, entity, time)) {
this.tick(world, entity, time);
} else {
this.doStop(world, entity, time);
}
+ this.timing.stopTiming(); // Paper - behavior timings
}
diff --git a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
index 7970eebbd6935402223e6bba962bb8ba7d861dfd..fcdb9bde8e1605e30dde3e580491522d4b62cdc0 100644
--- a/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
+++ b/src/main/java/net/minecraft/world/entity/ai/sensing/Sensor.java
@@ -19,8 +19,21 @@ public abstract class Sensor<E extends LivingEntity> {
private static final TargetingConditions ATTACK_TARGET_CONDITIONS_IGNORE_INVISIBILITY_AND_LINE_OF_SIGHT = TargetingConditions.forCombat().range(16.0D).ignoreLineOfSight().ignoreInvisibilityTesting();
private final int scanRate;
private long timeToTick;
+ // Paper start - configurable sensor tick rate and timings
+ private final String configKey;
+ private final co.aikar.timings.Timing timing;
+ // Paper end
public Sensor(int senseInterval) {
+ // Paper start - configurable sensor tick rate and timings
+ String key = io.papermc.paper.util.ObfHelper.INSTANCE.deobfClassName(this.getClass().getName());
+ int lastSeparator = key.lastIndexOf('.');
+ if (lastSeparator != -1) {
+ key = key.substring(lastSeparator + 1);
+ }
+ this.configKey = key.toLowerCase(java.util.Locale.ROOT);
+ this.timing = co.aikar.timings.MinecraftTimings.getSensorTimings(configKey, senseInterval);
+ // Paper end
this.scanRate = senseInterval;
this.timeToTick = (long)RANDOM.nextInt(senseInterval);
}
@@ -31,8 +44,12 @@ public abstract class Sensor<E extends LivingEntity> {
public final void tick(ServerLevel world, E entity) {
if (--this.timeToTick <= 0L) {
- this.timeToTick = (long)this.scanRate;
+ // Paper start - configurable sensor tick rate and timings
+ this.timeToTick = java.util.Objects.requireNonNullElse(world.paperConfig().tickRates.sensor.get(entity.getType(), this.configKey), this.scanRate);
+ this.timing.startTiming();
+ // Paper end
this.doTick(world, entity);
+ this.timing.stopTiming(); // Paper - sensor timings
}
}

View file

@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 20 Jul 2021 21:25:35 -0700
Subject: [PATCH] Add a bunch of missing forceDrop toggles
diff --git a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
index ac0cfdef53ec82665acf362235842de4f17bfdd1..05c1e8c9f013547d4fcdbbd299329166a8ece1b0 100644
--- a/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
+++ b/src/main/java/net/minecraft/world/entity/ai/behavior/WorkAtComposter.java
@@ -87,7 +87,9 @@ public class WorkAtComposter extends WorkAtPoi {
simpleContainer.removeItemType(Items.WHEAT, m);
ItemStack itemStack = simpleContainer.addItem(new ItemStack(Items.BREAD, l));
if (!itemStack.isEmpty()) {
+ entity.forceDrops = true; // Paper
entity.spawnAtLocation(itemStack, 0.5F);
+ entity.forceDrops = false; // Paper
}
}
diff --git a/src/main/java/net/minecraft/world/entity/animal/Panda.java b/src/main/java/net/minecraft/world/entity/animal/Panda.java
index 2db5d8a937c841718e7b568c215109c39775d82c..0a18108fda778af5b600f77533770bd98584d60e 100644
--- a/src/main/java/net/minecraft/world/entity/animal/Panda.java
+++ b/src/main/java/net/minecraft/world/entity/animal/Panda.java
@@ -528,7 +528,9 @@ public class Panda extends Animal {
}
if (!this.level.isClientSide() && this.random.nextInt(700) == 0 && this.level.getGameRules().getBoolean(GameRules.RULE_DOMOBLOOT)) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation((ItemLike) Items.SLIME_BALL);
+ this.forceDrops = false; // Paper
}
}
@@ -652,7 +654,9 @@ public class Panda extends Animal {
ItemStack itemstack1 = this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack1.isEmpty() && !player.getAbilities().instabuild) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation(itemstack1);
+ this.forceDrops = false; // Paper
}
this.setItemSlot(EquipmentSlot.MAINHAND, new ItemStack(itemstack.getItem(), 1));
@@ -929,7 +933,9 @@ public class Panda extends Animal {
ItemStack itemstack = Panda.this.getItemBySlot(EquipmentSlot.MAINHAND);
if (!itemstack.isEmpty()) {
+ Panda.this.forceDrops = true; // Paper
Panda.this.spawnAtLocation(itemstack);
+ Panda.this.forceDrops = false; // Paper
Panda.this.setItemSlot(EquipmentSlot.MAINHAND, ItemStack.EMPTY);
int i = Panda.this.isLazy() ? Panda.this.random.nextInt(50) + 10 : Panda.this.random.nextInt(150) + 10;
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
index 035c0ff01000f3fd57e1fcab13b93cafb133a169..7b42f7bd100808cb2367d0d7c7361e8f2e597502 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/Piglin.java
@@ -325,7 +325,9 @@ public class Piglin extends AbstractPiglin implements CrossbowAttackMob, Invento
@Override
protected void finishConversion(ServerLevel world) {
PiglinAi.cancelAdmiring(this);
+ this.forceDrops = true; // Paper
this.inventory.removeAllItems().forEach(this::spawnAtLocation);
+ this.forceDrops = false; // Paper
super.finishConversion(world);
}
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index e6d398f07564b4027552db9836e6da2c0972cd42..a3c28f327627b340905ba61238ce8454db0ec9ee 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -270,7 +270,9 @@ public class PiglinAi {
private static void holdInOffhand(Piglin piglin, ItemStack stack) {
if (PiglinAi.isHoldingItemInOffHand(piglin)) {
+ piglin.forceDrops = true; // Paper
piglin.spawnAtLocation(piglin.getItemInHand(InteractionHand.OFF_HAND));
+ piglin.forceDrops = false; // Paper
}
piglin.holdInOffHand(stack);
@@ -330,7 +332,9 @@ public class PiglinAi {
protected static void cancelAdmiring(Piglin piglin) {
if (PiglinAi.isAdmiringItem(piglin) && !piglin.getOffhandItem().isEmpty()) {
+ piglin.forceDrops = true; // Paper
piglin.spawnAtLocation(piglin.getOffhandItem());
+ piglin.forceDrops = false; // Paper
piglin.setItemInHand(InteractionHand.OFF_HAND, ItemStack.EMPTY);
}
diff --git a/src/main/java/net/minecraft/world/entity/raid/Raider.java b/src/main/java/net/minecraft/world/entity/raid/Raider.java
index 50010cc6774c351539cf09e517b7967f45822ec8..da37c51ee443c2f1191a32671912a967a13003cf 100644
--- a/src/main/java/net/minecraft/world/entity/raid/Raider.java
+++ b/src/main/java/net/minecraft/world/entity/raid/Raider.java
@@ -250,7 +250,9 @@ public abstract class Raider extends PatrollingMonster {
double d0 = (double) this.getEquipmentDropChance(enumitemslot);
if (!itemstack1.isEmpty() && (double) Math.max(this.random.nextFloat() - 0.1F, 0.0F) < d0) {
+ this.forceDrops = true; // Paper
this.spawnAtLocation(itemstack1);
+ this.forceDrops = false; // Paper
}
this.onItemPickup(item);

View file

@ -1,39 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Tue, 22 Jun 2021 23:15:44 -0400
Subject: [PATCH] Stinger API
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index f217df2d3c7a53b72418fab63cef06dbc107fe0d..cbb6b437358823cd52518682f32dd597c9aeb85a 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
@@ -340,7 +340,28 @@ public class CraftLivingEntity extends CraftEntity implements LivingEntity {
}
// Paper end
}
+ // Paper Start - Bee Stinger API
+ @Override
+ public int getBeeStingerCooldown() {
+ return getHandle().removeStingerTime;
+ }
+
+ @Override
+ public void setBeeStingerCooldown(int ticks) {
+ getHandle().removeStingerTime = ticks;
+ }
+ @Override
+ public int getBeeStingersInBody() {
+ return getHandle().getStingerCount();
+ }
+
+ @Override
+ public void setBeeStingersInBody(int count) {
+ Preconditions.checkArgument(count >= 0, "New bee stinger amount must be >= 0");
+ getHandle().setStingerCount(count);
+ }
+ // Paper End - Bee Stinger API
@Override
public void damage(double amount) {
this.damage(amount, null);

View file

@ -1,31 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Sun, 1 Aug 2021 09:49:06 +0100
Subject: [PATCH] Fix incosistency issue with empty map items in CB
diff --git a/src/main/java/net/minecraft/world/item/MapItem.java b/src/main/java/net/minecraft/world/item/MapItem.java
index f883e1bc4150bc074f1d8363a95b4eae16f3828e..586852e347cfeb6e52d16e51b3f193e814036e81 100644
--- a/src/main/java/net/minecraft/world/item/MapItem.java
+++ b/src/main/java/net/minecraft/world/item/MapItem.java
@@ -73,7 +73,7 @@ public class MapItem extends ComplexItem {
public static Integer getMapId(ItemStack stack) {
CompoundTag nbttagcompound = stack.getTag();
- return nbttagcompound != null && nbttagcompound.contains("map", 99) ? nbttagcompound.getInt("map") : -1; // CraftBukkit - make new maps for no tag
+ return nbttagcompound != null && nbttagcompound.contains("map", 99) ? nbttagcompound.getInt("map") : null; // CraftBukkit - make new maps for no tag // Paper - don't return invalid ID
}
public static int createNewSavedData(Level world, int x, int z, int scale, boolean showIcons, boolean unlimitedTracking, ResourceKey<Level> dimension) {
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
index 70b365afc40f11d4da3aea2b5d6b2467f517deac..a74ea06e3a190916527ab2c85d13f1e34c08d50a 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java
@@ -133,6 +133,7 @@ class CraftMetaMap extends CraftMetaItem implements MapMeta {
@Override
public int getMapId() {
+ Preconditions.checkState(this.hasMapView(), "Item does not have map associated - check hasMapView() first!"); // Paper - more friendly message
return this.mapId;
}

View file

@ -1,118 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: underscore11code <minecrafter11mrt@gmail.com>
Date: Fri, 23 Jul 2021 23:01:42 -0700
Subject: [PATCH] Add System.out/err catcher
diff --git a/src/main/java/io/papermc/paper/logging/SysoutCatcher.java b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
new file mode 100644
index 0000000000000000000000000000000000000000..a8e813ca89b033f061e695288b3383bdcf128531
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/SysoutCatcher.java
@@ -0,0 +1,94 @@
+package io.papermc.paper.logging;
+
+import org.bukkit.Bukkit;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+
+public final class SysoutCatcher {
+ private static final boolean SUPPRESS_NAGS = Boolean.getBoolean("io.papermc.paper.suppress.sout.nags");
+ // Nanoseconds between nag at most; if interval is caught first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_TIMEOUT = TimeUnit.MILLISECONDS.toNanos(
+ Long.getLong("io.papermc.paper.sout.nags.timeout", TimeUnit.MINUTES.toMillis(5L)));
+ // Count since last nag; if timeout is first, this is reset.
+ // <= 0 for disabling.
+ private static final long NAG_INTERVAL = Long.getLong("io.papermc.paper.sout.nags.interval", 200L);
+
+ // We don't particularly care about how correct this is at any given moment; let's do it on a best attempt basis.
+ // The records are also pretty small, so let's just go for a size of 64 to start...
+ //
+ // Content: Plugin name => nag object
+ // Why plugin name?: This doesn't store a reference to the plugin; keeps the reload ability.
+ // Why not clean on reload?: Effort.
+ private final ConcurrentMap<String, PluginNag> nagRecords = new ConcurrentHashMap<>(64);
+
+ public SysoutCatcher() {
+ System.setOut(new WrappedOutStream(System.out, Level.INFO, "[STDOUT] "));
+ System.setErr(new WrappedOutStream(System.err, Level.SEVERE, "[STDERR] "));
+ }
+
+ private final class WrappedOutStream extends PrintStream {
+ private static final StackWalker STACK_WALKER = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+ private final Level level;
+ private final String prefix;
+
+ public WrappedOutStream(@NotNull final OutputStream out, final Level level, final String prefix) {
+ super(out);
+ this.level = level;
+ this.prefix = prefix;
+ }
+
+ @Override
+ public void println(@Nullable final String line) {
+ final Class<?> clazz = STACK_WALKER.getCallerClass();
+ try {
+ final JavaPlugin plugin = JavaPlugin.getProvidingPlugin(clazz);
+
+ // Instead of just printing the message, send it to the plugin's logger
+ plugin.getLogger().log(this.level, this.prefix + line);
+
+ if (SysoutCatcher.SUPPRESS_NAGS) {
+ return;
+ }
+ if (SysoutCatcher.NAG_INTERVAL > 0 || SysoutCatcher.NAG_TIMEOUT > 0) {
+ final PluginNag nagRecord = SysoutCatcher.this.nagRecords.computeIfAbsent(plugin.getName(), k -> new PluginNag());
+ final boolean hasTimePassed = SysoutCatcher.NAG_TIMEOUT > 0
+ && (nagRecord.lastNagTimestamp == Long.MIN_VALUE
+ || nagRecord.lastNagTimestamp + SysoutCatcher.NAG_TIMEOUT <= System.nanoTime());
+ final boolean hasMessagesPassed = SysoutCatcher.NAG_INTERVAL > 0
+ && (nagRecord.messagesSinceNag == Long.MIN_VALUE
+ || ++nagRecord.messagesSinceNag >= SysoutCatcher.NAG_INTERVAL);
+ if (!hasMessagesPassed && !hasTimePassed) {
+ return;
+ }
+ nagRecord.lastNagTimestamp = System.nanoTime();
+ nagRecord.messagesSinceNag = 0;
+ }
+ Bukkit.getLogger().warning(
+ String.format("Nag author(s): '%s' of '%s' about their usage of System.out/err.print. "
+ + "Please use your plugin's logger instead (JavaPlugin#getLogger).",
+ plugin.getPluginMeta().getAuthors(),
+ plugin.getPluginMeta().getDisplayName())
+ );
+ } catch (final IllegalArgumentException | IllegalStateException e) {
+ // If anything happens, the calling class doesn't exist, there is no JavaPlugin that "owns" the calling class, etc
+ // Just print out normally, with some added information
+ Bukkit.getLogger().log(this.level, String.format("%s[%s] %s", this.prefix, clazz.getName(), line));
+ }
+ }
+ }
+
+ private static class PluginNag {
+ private long lastNagTimestamp = Long.MIN_VALUE;
+ private long messagesSinceNag = Long.MIN_VALUE;
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
index dad38e93aba899b250155a5075fc85fc988d6a8a..a77453e8390d6c9f656c7ae0ea413abfc7381070 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java
@@ -300,6 +300,7 @@ public final class CraftServer implements Server {
public int reloadCount;
private final io.papermc.paper.datapack.PaperDatapackManager datapackManager; // Paper
public static Exception excessiveVelEx; // Paper - Velocity warnings
+ private final io.papermc.paper.logging.SysoutCatcher sysoutCatcher = new io.papermc.paper.logging.SysoutCatcher(); // Paper
static {
ConfigurationSerialization.registerClass(CraftOfflinePlayer.class);

View file

@ -1,24 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Mariell Hoversholm <proximyst@proximyst.com>
Date: Mon, 2 Aug 2021 08:52:21 +0200
Subject: [PATCH] Fix test not bootstrapping
Signed-off-by: Mariell Hoversholm <proximyst@proximyst.com>
diff --git a/src/test/java/org/bukkit/enchantments/EnchantmentTargetTest.java b/src/test/java/org/bukkit/enchantments/EnchantmentTargetTest.java
index 439bf35c251ab5dc0d27923e62789a496618de82..5d3b8ba99d0fe966b7329540d61825aa266c7e64 100644
--- a/src/test/java/org/bukkit/enchantments/EnchantmentTargetTest.java
+++ b/src/test/java/org/bukkit/enchantments/EnchantmentTargetTest.java
@@ -5,10 +5,11 @@ import net.minecraft.world.item.Item;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import org.bukkit.Material;
import org.bukkit.craftbukkit.util.CraftMagicNumbers;
+import org.bukkit.support.AbstractTestingBase;
import org.junit.Assert;
import org.junit.Test;
-public class EnchantmentTargetTest {
+public class EnchantmentTargetTest extends AbstractTestingBase { // Paper
@Test
public void test() {

View file

@ -1,246 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: SirYwell <hannesgreule@outlook.de>
Date: Sat, 10 Jul 2021 11:12:30 +0200
Subject: [PATCH] Rewrite LogEvents to contain the source jars in stack traces
diff --git a/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java b/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ffd1befe64c6c3036c22e05ed1c44808d64bd28
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/DelegateLogEvent.java
@@ -0,0 +1,130 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.Marker;
+import org.apache.logging.log4j.ThreadContext;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+import org.apache.logging.log4j.core.time.Instant;
+import org.apache.logging.log4j.message.Message;
+import org.apache.logging.log4j.util.ReadOnlyStringMap;
+
+import java.util.Map;
+
+public class DelegateLogEvent implements LogEvent {
+ private final LogEvent original;
+
+ protected DelegateLogEvent(LogEvent original) {
+ this.original = original;
+ }
+
+ @Override
+ public LogEvent toImmutable() {
+ return this.original.toImmutable();
+ }
+
+ @Override
+ public Map<String, String> getContextMap() {
+ return this.original.getContextMap();
+ }
+
+ @Override
+ public ReadOnlyStringMap getContextData() {
+ return this.original.getContextData();
+ }
+
+ @Override
+ public ThreadContext.ContextStack getContextStack() {
+ return this.original.getContextStack();
+ }
+
+ @Override
+ public String getLoggerFqcn() {
+ return this.original.getLoggerFqcn();
+ }
+
+ @Override
+ public Level getLevel() {
+ return this.original.getLevel();
+ }
+
+ @Override
+ public String getLoggerName() {
+ return this.original.getLoggerName();
+ }
+
+ @Override
+ public Marker getMarker() {
+ return this.original.getMarker();
+ }
+
+ @Override
+ public Message getMessage() {
+ return this.original.getMessage();
+ }
+
+ @Override
+ public long getTimeMillis() {
+ return this.original.getTimeMillis();
+ }
+
+ @Override
+ public Instant getInstant() {
+ return this.original.getInstant();
+ }
+
+ @Override
+ public StackTraceElement getSource() {
+ return this.original.getSource();
+ }
+
+ @Override
+ public String getThreadName() {
+ return this.original.getThreadName();
+ }
+
+ @Override
+ public long getThreadId() {
+ return this.original.getThreadId();
+ }
+
+ @Override
+ public int getThreadPriority() {
+ return this.original.getThreadPriority();
+ }
+
+ @Override
+ public Throwable getThrown() {
+ return this.original.getThrown();
+ }
+
+ @Override
+ public ThrowableProxy getThrownProxy() {
+ return this.original.getThrownProxy();
+ }
+
+ @Override
+ public boolean isEndOfBatch() {
+ return this.original.isEndOfBatch();
+ }
+
+ @Override
+ public boolean isIncludeLocation() {
+ return this.original.isIncludeLocation();
+ }
+
+ @Override
+ public void setEndOfBatch(boolean endOfBatch) {
+ this.original.setEndOfBatch(endOfBatch);
+ }
+
+ @Override
+ public void setIncludeLocation(boolean locationRequired) {
+ this.original.setIncludeLocation(locationRequired);
+ }
+
+ @Override
+ public long getNanoTime() {
+ return this.original.getNanoTime();
+ }
+}
diff --git a/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java b/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
new file mode 100644
index 0000000000000000000000000000000000000000..558427c65b4051923f73d15d85ee519be005060a
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/ExtraClassInfoLogEvent.java
@@ -0,0 +1,48 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.impl.ExtendedClassInfo;
+import org.apache.logging.log4j.core.impl.ExtendedStackTraceElement;
+import org.apache.logging.log4j.core.impl.ThrowableProxy;
+
+public class ExtraClassInfoLogEvent extends DelegateLogEvent {
+
+ private boolean fixed;
+
+ public ExtraClassInfoLogEvent(LogEvent original) {
+ super(original);
+ }
+
+ @Override
+ public ThrowableProxy getThrownProxy() {
+ if (fixed) {
+ return super.getThrownProxy();
+ }
+ rewriteStackTrace(super.getThrownProxy());
+ fixed = true;
+ return super.getThrownProxy();
+ }
+
+ private void rewriteStackTrace(ThrowableProxy throwable) {
+ ExtendedStackTraceElement[] stackTrace = throwable.getExtendedStackTrace();
+ for (int i = 0; i < stackTrace.length; i++) {
+ ExtendedClassInfo classInfo = stackTrace[i].getExtraClassInfo();
+ if (classInfo.getLocation().equals("?")) {
+ StackTraceElement element = stackTrace[i].getStackTraceElement();
+ String classLoaderName = element.getClassLoaderName();
+ if (classLoaderName != null) {
+ stackTrace[i] = new ExtendedStackTraceElement(element,
+ new ExtendedClassInfo(classInfo.getExact(), classLoaderName, "?"));
+ }
+ }
+ }
+ if (throwable.getCauseProxy() != null) {
+ rewriteStackTrace(throwable.getCauseProxy());
+ }
+ if (throwable.getSuppressedProxies() != null) {
+ for (ThrowableProxy proxy : throwable.getSuppressedProxies()) {
+ rewriteStackTrace(proxy);
+ }
+ }
+ }
+}
diff --git a/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java b/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
new file mode 100644
index 0000000000000000000000000000000000000000..34734bb969a1a74c7a4f9c17d40ebf007ad5d701
--- /dev/null
+++ b/src/main/java/io/papermc/paper/logging/ExtraClassInfoRewritePolicy.java
@@ -0,0 +1,29 @@
+package io.papermc.paper.logging;
+
+import org.apache.logging.log4j.core.Core;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.appender.rewrite.RewritePolicy;
+import org.apache.logging.log4j.core.config.plugins.Plugin;
+import org.apache.logging.log4j.core.config.plugins.PluginFactory;
+import org.jetbrains.annotations.NotNull;
+
+@Plugin(
+ name = "ExtraClassInfoRewritePolicy",
+ category = Core.CATEGORY_NAME,
+ elementType = "rewritePolicy",
+ printObject = true
+)
+public final class ExtraClassInfoRewritePolicy implements RewritePolicy {
+ @Override
+ public LogEvent rewrite(LogEvent source) {
+ if (source.getThrown() != null) {
+ return new ExtraClassInfoLogEvent(source);
+ }
+ return source;
+ }
+
+ @PluginFactory
+ public static @NotNull ExtraClassInfoRewritePolicy createPolicy() {
+ return new ExtraClassInfoRewritePolicy();
+ }
+}
diff --git a/src/main/resources/log4j2.xml b/src/main/resources/log4j2.xml
index 2e421eaac80cf251b32e0bb504dd54a73edf4986..74ccc67e3c12dc5182602fb691ef3ddeb5b53280 100644
--- a/src/main/resources/log4j2.xml
+++ b/src/main/resources/log4j2.xml
@@ -34,6 +34,10 @@
</Async>
<Rewrite name="rewrite">
<StacktraceDeobfuscatingRewritePolicy />
+ <AppenderRef ref="rewrite2"/>
+ </Rewrite>
+ <Rewrite name="rewrite2">
+ <ExtraClassInfoRewritePolicy />
<AppenderRef ref="File"/>
<AppenderRef ref="TerminalConsole" level="info"/>
<AppenderRef ref="ServerGuiConsole" level="info"/>

View file

@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 2 Aug 2021 10:10:40 +0200
Subject: [PATCH] Improve boat collision performance
diff --git a/src/main/java/net/minecraft/Util.java b/src/main/java/net/minecraft/Util.java
index d5b37301d4e860c019105445001ed7a9a6f849bd..f4935f7fc3cbd6ba8f079def43bd735364a2ce87 100644
--- a/src/main/java/net/minecraft/Util.java
+++ b/src/main/java/net/minecraft/Util.java
@@ -112,6 +112,7 @@ public class Util {
}).findFirst().orElseThrow(() -> {
return new IllegalStateException("No jar file system provider found");
});
+ public static final double COLLISION_EPSILON = 1.0E-7; // Paper
private static Consumer<String> thePauser = (message) -> {
};
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index 2b40508750c2f70d1988f324f87e599fc62329f3..a7046e42c1935e9a4e529726072d9f88caaa703a 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -1334,7 +1334,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
if (!source.is(DamageTypeTags.IS_PROJECTILE)) {
Entity entity = source.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
LivingEntity entityliving = (LivingEntity) entity;
this.blockUsingShield(entityliving);
@@ -1439,11 +1439,12 @@ public abstract class LivingEntity extends Entity implements Attackable {
}
if (entity1 != null && !source.is(DamageTypeTags.IS_EXPLOSION)) {
- double d0 = entity1.getX() - this.getX();
+ final boolean far = entity1.distanceToSqr(this) > (200.0 * 200.0); // Paper
+ double d0 = far ? (Math.random() - Math.random()) : entity1.getX() - this.getX(); // Paper
double d1;
- for (d1 = entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) {
+ for (d1 = far ? Math.random() - Math.random() : entity1.getZ() - this.getZ(); d0 * d0 + d1 * d1 < 1.0E-4D; d1 = (Math.random() - Math.random()) * 0.01D) { // Paper
d0 = (Math.random() - Math.random()) * 0.01D;
}
@@ -2177,7 +2178,7 @@ public abstract class LivingEntity extends Entity implements Attackable {
this.hurtCurrentlyUsedShield((float) -event.getDamage(DamageModifier.BLOCKING));
Entity entity = damagesource.getDirectEntity();
- if (entity instanceof LivingEntity) {
+ if (entity instanceof LivingEntity && entity.distanceToSqr(this) <= (200.0D * 200.0D)) { // Paper
this.blockUsingShield((LivingEntity) entity);
}
}
diff --git a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
index 8b562ca6cc92c31c764aebf05d511e347cff8a83..12e3209c5246ede89daaf8455fe70b4a517e12f6 100644
--- a/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
+++ b/src/main/java/net/minecraft/world/entity/vehicle/Boat.java
@@ -709,8 +709,8 @@ public class Boat extends Entity implements VariantHolder<Boat.Type> {
this.invFriction = 0.05F;
if (this.oldStatus == Boat.Status.IN_AIR && this.status != Boat.Status.IN_AIR && this.status != Boat.Status.ON_LAND) {
this.waterLevel = this.getY(1.0D);
- this.setPos(this.getX(), (double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D, this.getZ());
- this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D));
+ this.move(MoverType.SELF, new Vec3(0.0, ((double) (this.getWaterLevelAbove() - this.getBbHeight()) + 0.101D) - this.getY(), 0.0)); // Paper
+ this.setDeltaMovement(this.getDeltaMovement().multiply(1.0D, 0.0D, 1.0D)); // Paper
this.lastYd = 0.0D;
this.status = Boat.Status.IN_WATER;
} else {

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Noah van der Aa <ndvdaa@gmail.com>
Date: Sat, 24 Jul 2021 16:54:11 +0200
Subject: [PATCH] Prevent AFK kick while watching end credits.
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index 435006230d4fc81dc72c79e6110e91f33a687a77..adffa10ad47d1c2a9479ca91073a12e61538a608 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -431,7 +431,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Tic
--this.dropSpamTickCount;
}
- if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) (this.server.getPlayerIdleTimeout() * 1000 * 60)) {
+ if (this.player.getLastActionTime() > 0L && this.server.getPlayerIdleTimeout() > 0 && Util.getMillis() - this.player.getLastActionTime() > (long) (this.server.getPlayerIdleTimeout() * 1000 * 60) && !this.player.wonGame) { // Paper - Prevent AFK kick while watching end credits.
this.player.resetLastActionTime(); // CraftBukkit - SPIGOT-854
this.disconnect(Component.translatable("multiplayer.disconnect.idling"), org.bukkit.event.player.PlayerKickEvent.Cause.IDLING); // Paper - kick event cause
}

View file

@ -1,70 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Fri, 23 Jul 2021 02:32:04 +0200
Subject: [PATCH] Allow skipping writing of comments to server.properties
Makes less git noise, as it won't update the date every single time
Use -DPaper.skipServerPropertiesComments=true flag to disable writing it
diff --git a/src/main/java/net/minecraft/server/dedicated/Settings.java b/src/main/java/net/minecraft/server/dedicated/Settings.java
index 26fc8127024d7b81ffe5c1c81b8ef8a68e35cbb6..bafd0f3492a0b8778d28610785129c5eba7fe4a2 100644
--- a/src/main/java/net/minecraft/server/dedicated/Settings.java
+++ b/src/main/java/net/minecraft/server/dedicated/Settings.java
@@ -23,6 +23,7 @@ public abstract class Settings<T extends Settings<T>> {
private static final Logger LOGGER = LogUtils.getLogger();
public final Properties properties;
+ private static final boolean skipComments = Boolean.getBoolean("Paper.skipServerPropertiesComments"); // Paper - allow skipping server.properties comments
// CraftBukkit start
private OptionSet options = null;
@@ -80,9 +81,47 @@ public abstract class Settings<T extends Settings<T>> {
}
// CraftBukkit end
OutputStream outputstream = Files.newOutputStream(path);
+ // Paper start - disable writing comments to properties file
+ java.io.BufferedOutputStream bufferedOutputStream = !skipComments ? new java.io.BufferedOutputStream(outputstream) : new java.io.BufferedOutputStream(outputstream) {
+ private boolean isRightAfterNewline = true; // If last written char was newline
+ private boolean isComment = false; // Are we writing comment currently?
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] b) throws IOException {
+ this.write(b, 0, b.length);
+ }
+
+ @Override
+ public void write(@org.jetbrains.annotations.NotNull byte[] bbuf, int off, int len) throws IOException {
+ int latest_offset = off; // The latest offset, updated when comment ends
+ for (int index = off; index < off + len; ++index ) {
+ byte c = bbuf[index];
+ boolean isNewline = (c == '\n' || c == '\r');
+ if (isNewline && isComment) {
+ // Comment has ended
+ isComment = false;
+ latest_offset = index+1;
+ }
+ if (c == '#' && isRightAfterNewline) {
+ isComment = true;
+ if (index != latest_offset) {
+ // We got some non-comment data earlier
+ super.write(bbuf, latest_offset, index-latest_offset);
+ }
+ }
+ isRightAfterNewline = isNewline; // Store for next iteration
+
+ }
+ if (latest_offset < off+len && !isComment) {
+ // We have some unwritten data, that isn't part of a comment
+ super.write(bbuf, latest_offset, (off + len) - latest_offset);
+ }
+ }
+ };
+ // Paper end
try {
- this.properties.store(outputstream, "Minecraft server properties");
+ this.properties.store(bufferedOutputStream, "Minecraft server properties"); // Paper - use bufferedOutputStream
} catch (Throwable throwable) {
if (outputstream != null) {
try {

View file

@ -1,189 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 19 May 2021 18:59:10 -0700
Subject: [PATCH] Add PlayerSetSpawnEvent
diff --git a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
index 3072f513c22904f8066e0c37f345df4fdb451f8a..aa701e68ed81562861eba559e61e522b934d5851 100644
--- a/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
+++ b/src/main/java/net/minecraft/server/commands/SetSpawnCommand.java
@@ -38,11 +38,23 @@ public class SetSpawnCommand {
ResourceKey<Level> resourcekey = source.getLevel().dimension();
Iterator iterator = targets.iterator();
+ final Collection<ServerPlayer> actualTargets = new java.util.ArrayList<>(); // Paper
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
- entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.COMMAND); // CraftBukkit
+ // Paper start - PlayerSetSpawnEvent
+ if (entityplayer.setRespawnPosition(resourcekey, pos, angle, true, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.COMMAND)) {
+ actualTargets.add(entityplayer);
+ }
+ // Paper end
}
+ // Paper start
+ if (actualTargets.isEmpty()) {
+ return 0;
+ } else {
+ targets = actualTargets;
+ }
+ // Paper end
String s = resourcekey.location().toString();
diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index a649d1baa727dd16cb8e786bdf510021e2d16d26..cdf85898d6ca9f1159b175dbc2760522abd8eb95 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1309,7 +1309,7 @@ public class ServerPlayer extends Player {
} else if (this.bedBlocked(blockposition, enumdirection)) {
return Either.left(Player.BedSleepingProblem.OBSTRUCTED);
} else {
- this.setRespawnPosition(this.level.dimension(), blockposition, this.getYRot(), false, true, PlayerSpawnChangeEvent.Cause.BED); // CraftBukkit
+ this.setRespawnPosition(this.level.dimension(), blockposition, this.getYRot(), false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.BED); // Paper - PlayerSetSpawnEvent
if (this.level.isDay()) {
return Either.left(Player.BedSleepingProblem.NOT_POSSIBLE_NOW);
} else {
@@ -2151,44 +2151,50 @@ public class ServerPlayer extends Player {
return this.respawnForced;
}
+ @Deprecated // Paper
public void setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage) {
- // CraftBukkit start
- this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, PlayerSpawnChangeEvent.Cause.UNKNOWN);
- }
-
- public void setRespawnPosition(ResourceKey<Level> resourcekey, @Nullable BlockPos blockposition, float f, boolean flag, boolean flag1, PlayerSpawnChangeEvent.Cause cause) {
- ServerLevel newWorld = this.server.getLevel(resourcekey);
- Location newSpawn = (blockposition != null) ? CraftLocation.toBukkit(blockposition, newWorld.getWorld(), f, 0) : null;
-
- PlayerSpawnChangeEvent event = new PlayerSpawnChangeEvent(this.getBukkitEntity(), newSpawn, flag, cause);
- Bukkit.getServer().getPluginManager().callEvent(event);
- if (event.isCancelled()) {
- return;
- }
- newSpawn = event.getNewSpawn();
- flag = event.isForced();
-
- if (newSpawn != null) {
- resourcekey = ((CraftWorld) newSpawn.getWorld()).getHandle().dimension();
- blockposition = BlockPos.containing(newSpawn.getX(), newSpawn.getY(), newSpawn.getZ());
- f = newSpawn.getYaw();
- } else {
- resourcekey = Level.OVERWORLD;
- blockposition = null;
- f = 0.0F;
+ // Paper start
+ this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.UNKNOWN);
+ }
+ @Deprecated
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, PlayerSpawnChangeEvent.Cause cause) {
+ return this.setRespawnPosition(dimension, pos, angle, forced, sendMessage, cause == PlayerSpawnChangeEvent.Cause.RESET ?
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN : com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.valueOf(cause.name()));
+ }
+ public boolean setRespawnPosition(ResourceKey<Level> dimension, @Nullable BlockPos pos, float angle, boolean forced, boolean sendMessage, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause cause) {
+ Location spawnLoc = null;
+ boolean willNotify = false;
+ if (pos != null) {
+ boolean flag2 = pos.equals(this.respawnPosition) && dimension.equals(this.respawnDimension);
+ spawnLoc = io.papermc.paper.util.MCUtil.toLocation(this.getServer().getLevel(dimension), pos);
+ spawnLoc.setYaw(angle);
+ willNotify = sendMessage && !flag2;
+ }
+
+ PlayerSpawnChangeEvent dumbEvent = new PlayerSpawnChangeEvent(this.getBukkitEntity(), spawnLoc, forced,
+ cause == com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN ? PlayerSpawnChangeEvent.Cause.RESET : PlayerSpawnChangeEvent.Cause.valueOf(cause.name()));
+ dumbEvent.callEvent();
+
+ com.destroystokyo.paper.event.player.PlayerSetSpawnEvent event = new com.destroystokyo.paper.event.player.PlayerSetSpawnEvent(this.getBukkitEntity(), cause, dumbEvent.getNewSpawn(), dumbEvent.isForced(), willNotify, willNotify ? net.kyori.adventure.text.Component.translatable("block.minecraft.set_spawn") : null);
+ event.setCancelled(dumbEvent.isCancelled());
+ if (!event.callEvent()) {
+ return false;
}
- // CraftBukkit end
- if (blockposition != null) {
- boolean flag2 = blockposition.equals(this.respawnPosition) && resourcekey.equals(this.respawnDimension);
+ if (event.getLocation() != null) {
+ dimension = event.getLocation().getWorld() != null ? ((CraftWorld) event.getLocation().getWorld()).getHandle().dimension() : dimension;
+ pos = io.papermc.paper.util.MCUtil.toBlockPosition(event.getLocation());
+ angle = event.getLocation().getYaw();
+ forced = event.isForced();
+ // Paper end
- if (flag1 && !flag2) {
- this.sendSystemMessage(Component.translatable("block.minecraft.set_spawn"));
+ if (event.willNotifyPlayer() && event.getNotification() != null) { // Paper
+ this.sendSystemMessage(PaperAdventure.asVanilla(event.getNotification())); // Paper
}
- this.respawnPosition = blockposition;
- this.respawnDimension = resourcekey;
- this.respawnAngle = f;
- this.respawnForced = flag;
+ this.respawnPosition = pos;
+ this.respawnDimension = dimension;
+ this.respawnAngle = angle;
+ this.respawnForced = forced;
} else {
this.respawnPosition = null;
this.respawnDimension = Level.OVERWORLD;
@@ -2196,6 +2202,7 @@ public class ServerPlayer extends Player {
this.respawnForced = false;
}
+ return true; // Paper
}
public void trackChunk(ChunkPos chunkPos, Packet<?> chunkDataPacket) {
diff --git a/src/main/java/net/minecraft/server/players/PlayerList.java b/src/main/java/net/minecraft/server/players/PlayerList.java
index 4771829ba2b2b215567b2f4ceca963a7d2a0f559..801cf17505cee999e7ed58081fa908ca693df498 100644
--- a/src/main/java/net/minecraft/server/players/PlayerList.java
+++ b/src/main/java/net/minecraft/server/players/PlayerList.java
@@ -853,7 +853,7 @@ public abstract class PlayerList {
location = CraftLocation.toBukkit(vec3d, worldserver1.getWorld(), f1, 0.0F);
} else if (blockposition != null) {
entityplayer1.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.NO_RESPAWN_BLOCK_AVAILABLE, 0.0F));
- entityplayer1.setRespawnPosition(null, null, 0f, false, false, PlayerSpawnChangeEvent.Cause.RESET); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed
+ entityplayer1.setRespawnPosition(null, null, 0f, false, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLAYER_RESPAWN); // CraftBukkit - SPIGOT-5988: Clear respawn location when obstructed // Paper - PlayerSetSpawnEvent
}
}
diff --git a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
index 1a27b7faa22e6b3dc5fce329ed06425de56c4315..b9903c29bdea8d1e3b6fce0e97be6bd9493cfdf4 100644
--- a/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/RespawnAnchorBlock.java
@@ -80,9 +80,14 @@ public class RespawnAnchorBlock extends Block {
ServerPlayer entityplayer = (ServerPlayer) player;
if (entityplayer.getRespawnDimension() != world.dimension() || !pos.equals(entityplayer.getRespawnPosition())) {
- entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, org.bukkit.event.player.PlayerSpawnChangeEvent.Cause.RESPAWN_ANCHOR); // CraftBukkit
+ if (entityplayer.setRespawnPosition(world.dimension(), pos, 0.0F, false, true, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.RESPAWN_ANCHOR)) { // Paper - PlayerSetSpawnEvent
world.playSound((Player) null, (double) pos.getX() + 0.5D, (double) pos.getY() + 0.5D, (double) pos.getZ() + 0.5D, SoundEvents.RESPAWN_ANCHOR_SET_SPAWN, SoundSource.BLOCKS, 1.0F, 1.0F);
return InteractionResult.SUCCESS;
+ // Paper start - handle failed set spawn
+ } else {
+ return InteractionResult.FAIL;
+ }
+ // Paper end
}
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index fd7d05c097dcb300aab5320b395e7133dc54998f..88ec1bb0bea5aeb4a6e0ee628de58ac9f1f546cf 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1371,9 +1371,9 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public void setBedSpawnLocation(Location location, boolean override) {
if (location == null) {
- this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(null, null, 0.0F, override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
} else {
- this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, PlayerSpawnChangeEvent.Cause.PLUGIN);
+ this.getHandle().setRespawnPosition(((CraftWorld) location.getWorld()).getHandle().dimension(), CraftLocation.toBlockPosition(location), location.getYaw(), override, false, com.destroystokyo.paper.event.player.PlayerSetSpawnEvent.Cause.PLUGIN); // Paper - PlayerSetSpawnEvent
}
}

View file

@ -1,30 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Wed, 7 Jul 2021 16:30:17 -0700
Subject: [PATCH] Make hoppers respect inventory max stack size
diff --git a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
index 6605a7f7c046729850256489c21a1e90f0cca972..789e5458f4a137694563a22612455506807de51b 100644
--- a/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
+++ b/src/main/java/net/minecraft/world/level/block/entity/HopperBlockEntity.java
@@ -436,15 +436,17 @@ public class HopperBlockEntity extends RandomizableContainerBlockEntity implemen
if (itemstack1.isEmpty()) {
// Spigot start - SPIGOT-6693, InventorySubcontainer#setItem
+ ItemStack leftover = ItemStack.EMPTY; // Paper
if (!stack.isEmpty() && stack.getCount() > to.getMaxStackSize()) {
+ leftover = stack; // Paper
stack = stack.split(to.getMaxStackSize());
}
// Spigot end
to.setItem(slot, stack);
- stack = ItemStack.EMPTY;
+ stack = leftover; // Paper
flag = true;
} else if (HopperBlockEntity.canMergeItems(itemstack1, stack)) {
- int j = stack.getMaxStackSize() - itemstack1.getCount();
+ int j = Math.min(stack.getMaxStackSize(), to.getMaxStackSize()) - itemstack1.getCount(); // Paper
int k = Math.min(stack.getCount(), j);
stack.shrink(k);

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Sun, 8 Aug 2021 00:52:54 -0400
Subject: [PATCH] Optimize entity tracker passenger checks
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index d4696783f5adaee5f4350dfe5da8d6b85cf07f7e..dd75d109feacbc146dc49ae1e1b4bba94b51d18b 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -78,7 +78,7 @@ public class ServerEntity {
this.trackedPlayers = trackedPlayers;
// CraftBukkit end
this.ap = Vec3.ZERO;
- this.lastPassengers = Collections.emptyList();
+ this.lastPassengers = com.google.common.collect.ImmutableList.of(); // Paper - optimize passenger checks
this.level = worldserver;
this.broadcast = consumer;
this.entity = entity;

View file

@ -1,18 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jason Penilla <11360596+jpenilla@users.noreply.github.com>
Date: Wed, 2 Dec 2020 03:07:58 -0800
Subject: [PATCH] Config option for Piglins guarding chests
diff --git a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
index a3c28f327627b340905ba61238ce8454db0ec9ee..c3a2b83794c612340edf0bc67f58917f1f96db45 100644
--- a/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
+++ b/src/main/java/net/minecraft/world/entity/monster/piglin/PiglinAi.java
@@ -477,6 +477,7 @@ public class PiglinAi {
}
public static void angerNearbyPiglins(Player player, boolean blockOpen) {
+ if (!player.level.paperConfig().entities.behavior.piglinsGuardChests) return; // Paper
List<Piglin> list = player.level.getEntitiesOfClass(Piglin.class, player.getBoundingBox().inflate(16.0D));
list.stream().filter(PiglinAi::isIdle).filter((entitypiglin) -> {

View file

@ -1,65 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Tue, 22 Dec 2020 13:52:48 -0800
Subject: [PATCH] Added EntityDamageItemEvent
diff --git a/src/main/java/net/minecraft/world/item/ItemStack.java b/src/main/java/net/minecraft/world/item/ItemStack.java
index 36c560ea3b33ef854f2190d07209b7f36c6d7e6b..8b7d4b0bdb18067213462492ce4b8af2477a111b 100644
--- a/src/main/java/net/minecraft/world/item/ItemStack.java
+++ b/src/main/java/net/minecraft/world/item/ItemStack.java
@@ -583,7 +583,7 @@ public final class ItemStack {
return this.getItem().getMaxDamage();
}
- public boolean hurt(int amount, RandomSource random, @Nullable ServerPlayer player) {
+ public boolean hurt(int amount, RandomSource random, @Nullable LivingEntity player) { // Paper - allow any living entity instead of only ServerPlayers
if (!this.isDamageableItem()) {
return false;
} else {
@@ -601,8 +601,8 @@ public final class ItemStack {
amount -= k;
// CraftBukkit start
- if (player != null) {
- PlayerItemDamageEvent event = new PlayerItemDamageEvent(player.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount);
+ if (player instanceof ServerPlayer serverPlayer) { // Paper
+ PlayerItemDamageEvent event = new PlayerItemDamageEvent(serverPlayer.getBukkitEntity(), CraftItemStack.asCraftMirror(this), amount); // Paper
event.getPlayer().getServer().getPluginManager().callEvent(event);
if (amount != event.getDamage() || event.isCancelled()) {
@@ -613,6 +613,14 @@ public final class ItemStack {
}
amount = event.getDamage();
+ // Paper start - EntityDamageItemEvent
+ } else if (player != null) {
+ io.papermc.paper.event.entity.EntityDamageItemEvent event = new io.papermc.paper.event.entity.EntityDamageItemEvent(player.getBukkitLivingEntity(), CraftItemStack.asCraftMirror(this), amount);
+ if (!event.callEvent()) {
+ return false;
+ }
+ amount = event.getDamage();
+ // Paper end
}
// CraftBukkit end
if (amount <= 0) {
@@ -620,8 +628,8 @@ public final class ItemStack {
}
}
- if (player != null && amount != 0) {
- CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(player, this, this.getDamageValue() + amount);
+ if (player instanceof ServerPlayer serverPlayer && amount != 0) { // Paper
+ CriteriaTriggers.ITEM_DURABILITY_CHANGED.trigger(serverPlayer, this, this.getDamageValue() + amount); // Paper
}
j = this.getDamageValue() + amount;
@@ -633,7 +641,7 @@ public final class ItemStack {
public <T extends LivingEntity> void hurtAndBreak(int amount, T entity, Consumer<T> breakCallback) {
if (!entity.level.isClientSide && (!(entity instanceof net.minecraft.world.entity.player.Player) || !((net.minecraft.world.entity.player.Player) entity).getAbilities().instabuild)) {
if (this.isDamageableItem()) {
- if (this.hurt(amount, entity.getRandom(), entity instanceof ServerPlayer ? (ServerPlayer) entity : null)) {
+ if (this.hurt(amount, entity.getRandom(), entity /*instanceof ServerPlayer ? (ServerPlayer) entity : null*/)) { // Paper - pass LivingEntity for EntityItemDamageEvent
breakCallback.accept(entity);
Item item = this.getItem();
// CraftBukkit start - Check for item breaking

View file

@ -1,53 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Andrew Steinborn <git@steinborn.me>
Date: Mon, 9 Aug 2021 00:38:37 -0400
Subject: [PATCH] Optimize indirect passenger iteration
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index f646e2230dbf1dd6bfb1a43545d95a4d9895c3d6..d69352cc86f1a40bf696e30f11a3a84fac3b20c5 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3765,20 +3765,34 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
}
private Stream<Entity> getIndirectPassengersStream() {
+ if (this.passengers.isEmpty()) { return Stream.of(); } // Paper
return this.passengers.stream().flatMap(Entity::getSelfAndPassengers);
}
@Override
public Stream<Entity> getSelfAndPassengers() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
return Stream.concat(Stream.of(this), this.getIndirectPassengersStream());
}
@Override
public Stream<Entity> getPassengersAndSelf() {
+ if (this.passengers.isEmpty()) { return Stream.of(this); } // Paper
return Stream.concat(this.passengers.stream().flatMap(Entity::getPassengersAndSelf), Stream.of(this));
}
public Iterable<Entity> getIndirectPassengers() {
+ // Paper start - rewrite this method
+ if (this.passengers.isEmpty()) { return ImmutableList.of(); }
+ ImmutableList.Builder<Entity> indirectPassengers = ImmutableList.builder();
+ for (Entity passenger : this.passengers) {
+ indirectPassengers.add(passenger);
+ indirectPassengers.addAll(passenger.getIndirectPassengers());
+ }
+ return indirectPassengers.build();
+ }
+ private Iterable<Entity> getIndirectPassengers_old() {
+ // Paper end
return () -> {
return this.getIndirectPassengersStream().iterator();
};
@@ -3795,6 +3809,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
// Paper end - rewrite chunk system
public boolean hasExactlyOnePlayerPassenger() {
+ if (this.passengers.isEmpty()) { return false; } // Paper
return this.getIndirectPassengersStream().filter((entity) -> {
return entity instanceof Player;
}).count() == 1L;

View file

@ -1,19 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Warrior <50800980+Warriorrrr@users.noreply.github.com>
Date: Fri, 13 Aug 2021 01:14:38 +0200
Subject: [PATCH] Configurable item frame map cursor update interval
diff --git a/src/main/java/net/minecraft/server/level/ServerEntity.java b/src/main/java/net/minecraft/server/level/ServerEntity.java
index dd75d109feacbc146dc49ae1e1b4bba94b51d18b..f9fc646811a3952065d1b9fc74ff7a10ae495c32 100644
--- a/src/main/java/net/minecraft/server/level/ServerEntity.java
+++ b/src/main/java/net/minecraft/server/level/ServerEntity.java
@@ -118,7 +118,7 @@ public class ServerEntity {
if (true || this.tickCount % 10 == 0) { // CraftBukkit - Moved below, should always enter this block
ItemStack itemstack = entityitemframe.getItem();
- if (this.tickCount % 10 == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks
+ if (this.level.paperConfig().maps.itemFrameCursorUpdateInterval > 0 && this.tickCount % this.level.paperConfig().maps.itemFrameCursorUpdateInterval == 0 && itemstack.getItem() instanceof MapItem) { // CraftBukkit - Moved this.tickCounter % 10 logic here so item frames do not enter the other blocks // Paper - Make item frame map cursor update interval configurable
Integer integer = MapItem.getMapId(itemstack);
MapItemSavedData worldmap = MapItem.getSavedData(integer, this.level);

View file

@ -1,41 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 3 Jan 2021 21:25:31 -0800
Subject: [PATCH] Make EntityUnleashEvent cancellable
diff --git a/src/main/java/net/minecraft/world/entity/Mob.java b/src/main/java/net/minecraft/world/entity/Mob.java
index 3fbdd1b01bc86696b958ca6b7a3848e72fb51d50..00c6605f06773c52f6f5c5c1f5bcdd6dd67fb5b6 100644
--- a/src/main/java/net/minecraft/world/entity/Mob.java
+++ b/src/main/java/net/minecraft/world/entity/Mob.java
@@ -1541,7 +1541,7 @@ public abstract class Mob extends LivingEntity implements Targeting {
if (flag1 && this.isLeashed()) {
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN, true);
- this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) { return flag1; }
this.dropLeash(true, event.isDropLeash());
// Paper end
}
diff --git a/src/main/java/net/minecraft/world/entity/PathfinderMob.java b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
index e49fb8be7d3975506a6c39c87cace664e45b3c86..a53466a84973f5e83afc71245b317ab4296e0f9e 100644
--- a/src/main/java/net/minecraft/world/entity/PathfinderMob.java
+++ b/src/main/java/net/minecraft/world/entity/PathfinderMob.java
@@ -51,7 +51,7 @@ public abstract class PathfinderMob extends Mob {
if (f > entity.level.paperConfig().misc.maxLeashDistance) { // Paper
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
- this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) { return; }
this.dropLeash(true, event.isDropLeash());
// Paper end
}
@@ -63,7 +63,7 @@ public abstract class PathfinderMob extends Mob {
if (f > entity.level.paperConfig().misc.maxLeashDistance) { // Paper
// Paper start - drop leash variable
EntityUnleashEvent event = new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE, true);
- this.level.getCraftServer().getPluginManager().callEvent(event); // CraftBukkit
+ if (!event.callEvent()) return;
this.dropLeash(true, event.isDropLeash());
// Paper end
this.goalSelector.disableControlFlag(Goal.Flag.MOVE);

View file

@ -1,20 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 13 Aug 2021 15:00:06 -0700
Subject: [PATCH] Clear bucket NBT after dispense
diff --git a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
index abd20f9495c315e73c1eb6572b8fc47db27450d7..9b56f742443ad98994acc34630f1cef75a00ca8a 100644
--- a/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
+++ b/src/main/java/net/minecraft/core/dispenser/DispenseItemBehavior.java
@@ -652,8 +652,7 @@ public interface DispenseItemBehavior {
Item item = Items.BUCKET;
stack.shrink(1);
if (stack.isEmpty()) {
- stack.setItem(Items.BUCKET);
- stack.setCount(1);
+ stack = new ItemStack(item); // Paper - clear tag
} else if (((DispenserBlockEntity) pointer.getEntity()).addItem(new ItemStack(item)) < 0) {
this.defaultDispenseItemBehavior.dispense(pointer, new ItemStack(item));
}

View file

@ -1,54 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 21 Aug 2021 12:13:53 -0700
Subject: [PATCH] Change EnderEye target without changing other things
diff --git a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
index f1582be22ffdd916eaab8998e3f367f2aac29d51..855e85e8d0d1f15304b0a42b46ef845325e103aa 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/EyeOfEnder.java
@@ -73,6 +73,11 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
}
public void signalTo(BlockPos pos) {
+ // Paper start
+ this.signalTo(pos, true);
+ }
+ public void signalTo(BlockPos pos, boolean update) {
+ // Paper end
double d0 = (double) pos.getX();
int i = pos.getY();
double d1 = (double) pos.getZ();
@@ -90,8 +95,10 @@ public class EyeOfEnder extends Entity implements ItemSupplier {
this.tz = d1;
}
+ if (update) { // Paper
this.life = 0;
this.surviveAfterDeath = this.random.nextInt(5) > 0;
+ } // Paper
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
index e45c1bfb1b8e0cd8f7b9ab5b655d33dd4da1b151..e3688e941d9b63b5319faf9370b8f75e0e5828ae 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java
@@ -38,8 +38,15 @@ public class CraftEnderSignal extends CraftEntity implements EnderSignal {
@Override
public void setTargetLocation(Location location) {
+ // Paper start
+ this.setTargetLocation(location, true);
+ }
+
+ @Override
+ public void setTargetLocation(Location location, boolean update) {
+ // Paper end
Preconditions.checkArgument(getWorld().equals(location.getWorld()), "Cannot target EnderSignal across worlds");
- this.getHandle().signalTo(CraftLocation.toBlockPosition(location));
+ this.getHandle().signalTo(CraftLocation.toBlockPosition(location), update); // Paper
}
@Override

View file

@ -1,86 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 3 Jan 2021 17:58:11 -0800
Subject: [PATCH] Add BlockBreakBlockEvent
diff --git a/src/main/java/net/minecraft/world/level/block/Block.java b/src/main/java/net/minecraft/world/level/block/Block.java
index 536a4e9f2bec3f44ca00edaf518c5d6c475d3c8b..4f91e4832a94c3facbc711fcae4cb5ad540a5ca0 100644
--- a/src/main/java/net/minecraft/world/level/block/Block.java
+++ b/src/main/java/net/minecraft/world/level/block/Block.java
@@ -331,6 +331,23 @@ public class Block extends BlockBehaviour implements ItemLike {
}
}
+ // Paper start
+ public static boolean dropResources(BlockState state, LevelAccessor world, BlockPos pos, @Nullable BlockEntity blockEntity, BlockPos source) {
+ if (world instanceof ServerLevel) {
+ List<org.bukkit.inventory.ItemStack> items = com.google.common.collect.Lists.newArrayList();
+ for (net.minecraft.world.item.ItemStack drop : net.minecraft.world.level.block.Block.getDrops(state, world.getMinecraftWorld(), pos, blockEntity)) {
+ items.add(org.bukkit.craftbukkit.inventory.CraftItemStack.asBukkitCopy(drop));
+ }
+ io.papermc.paper.event.block.BlockBreakBlockEvent event = new io.papermc.paper.event.block.BlockBreakBlockEvent(org.bukkit.craftbukkit.block.CraftBlock.at(world, pos), org.bukkit.craftbukkit.block.CraftBlock.at(world, source), items);
+ event.callEvent();
+ for (var drop : event.getDrops()) {
+ popResource(world.getMinecraftWorld(), pos, org.bukkit.craftbukkit.inventory.CraftItemStack.asNMSCopy(drop));
+ }
+ state.spawnAfterBreak(world.getMinecraftWorld(), pos, ItemStack.EMPTY, true);
+ }
+ return true;
+ }
+ // Paper end
public static void dropResources(BlockState state, Level world, BlockPos pos, @Nullable BlockEntity blockEntity, Entity entity, ItemStack tool) {
if (world instanceof ServerLevel) {
diff --git a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
index 8d73893100884c08aa552ff41c2a07a3e714df47..24a822ade17849a083161216c184f02c30b5cb1f 100644
--- a/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
+++ b/src/main/java/net/minecraft/world/level/block/piston/PistonBaseBlock.java
@@ -400,7 +400,7 @@ public class PistonBaseBlock extends DirectionalBlock {
iblockdata1 = world.getBlockState(blockposition3);
BlockEntity tileentity = iblockdata1.hasBlockEntity() ? world.getBlockEntity(blockposition3) : null;
- dropResources(iblockdata1, world, blockposition3, tileentity);
+ dropResources(iblockdata1, world, blockposition3, tileentity, pos); // Paper
world.setBlock(blockposition3, Blocks.AIR.defaultBlockState(), 18);
world.gameEvent(GameEvent.BLOCK_DESTROY, blockposition3, GameEvent.Context.of(iblockdata1));
if (!iblockdata1.is(BlockTags.FIRE)) {
diff --git a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
index 00516a230073391b31795ec5af2aa7aa48db639a..bf4de7b8fd630c596e096a411a8c84c64c13ebf7 100644
--- a/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/FlowingFluid.java
@@ -294,7 +294,7 @@ public abstract class FlowingFluid extends Fluid {
((LiquidBlockContainer) state.getBlock()).placeLiquid(world, pos, state, fluidState);
} else {
if (!state.isAir()) {
- this.beforeDestroyingBlock(world, pos, state);
+ this.beforeDestroyingBlock(world, pos, state, pos.relative(direction.getOpposite())); // Paper
}
world.setBlock(pos, fluidState.createLegacyBlock(), 3);
@@ -302,6 +302,7 @@ public abstract class FlowingFluid extends Fluid {
}
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) { beforeDestroyingBlock(world, pos, state); } // Paper - add source parameter
protected abstract void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state);
private static short getCacheKey(BlockPos blockposition, BlockPos blockposition1) {
diff --git a/src/main/java/net/minecraft/world/level/material/WaterFluid.java b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
index 1897c0012800d5ba9d2fc386f3e2bf57c9d878bb..82e85fbbd45244d02df90fa00c9046e7f51275a2 100644
--- a/src/main/java/net/minecraft/world/level/material/WaterFluid.java
+++ b/src/main/java/net/minecraft/world/level/material/WaterFluid.java
@@ -64,6 +64,13 @@ public abstract class WaterFluid extends FlowingFluid {
return world.getGameRules().getBoolean(GameRules.RULE_WATER_SOURCE_CONVERSION);
}
+ // Paper start
+ @Override
+ protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state, BlockPos source) {
+ BlockEntity tileentity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;
+ Block.dropResources(state, world, pos, tileentity, source);
+ }
+ // Paper end
@Override
protected void beforeDestroyingBlock(LevelAccessor world, BlockPos pos, BlockState state) {
BlockEntity blockEntity = state.hasBlockEntity() ? world.getBlockEntity(pos) : null;

View file

@ -1,84 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 26 Sep 2021 12:57:28 -0700
Subject: [PATCH] Option to prevent NBT copy in smithing recipes
diff --git a/src/main/java/net/minecraft/world/item/crafting/LegacyUpgradeRecipe.java b/src/main/java/net/minecraft/world/item/crafting/LegacyUpgradeRecipe.java
index 9c8ca33327e2e54c1c9d7f5a3a9a6648b5422737..06c7ca77456acc1f206aabc6d4198128ca927c6a 100644
--- a/src/main/java/net/minecraft/world/item/crafting/LegacyUpgradeRecipe.java
+++ b/src/main/java/net/minecraft/world/item/crafting/LegacyUpgradeRecipe.java
@@ -26,8 +26,15 @@ public class LegacyUpgradeRecipe implements SmithingRecipe {
final Ingredient addition;
final ItemStack result;
private final ResourceLocation id;
+ final boolean copyNBT; // Paper
public LegacyUpgradeRecipe(ResourceLocation id, Ingredient base, Ingredient addition, ItemStack result) {
+ // Paper start
+ this(id, base, addition, result, true);
+ }
+ public LegacyUpgradeRecipe(ResourceLocation id, Ingredient base, Ingredient addition, ItemStack result, boolean copyNBT) {
+ this.copyNBT = copyNBT;
+ // Paper end
this.id = id;
this.base = base;
this.addition = addition;
@@ -42,11 +49,13 @@ public class LegacyUpgradeRecipe implements SmithingRecipe {
@Override
public ItemStack assemble(Container inventory, RegistryAccess registryManager) {
ItemStack itemstack = this.result.copy();
+ if (this.copyNBT) { // Paper - copy nbt conditionally
CompoundTag nbttagcompound = inventory.getItem(0).getTag();
if (nbttagcompound != null) {
itemstack.setTag(nbttagcompound.copy());
}
+ } // Paper
return itemstack;
}
@@ -98,7 +107,7 @@ public class LegacyUpgradeRecipe implements SmithingRecipe {
public Recipe toBukkitRecipe() {
CraftItemStack result = CraftItemStack.asCraftMirror(this.result);
- CraftSmithingRecipe recipe = new CraftSmithingRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition));
+ CraftSmithingRecipe recipe = new CraftSmithingRecipe(CraftNamespacedKey.fromMinecraft(this.id), result, CraftRecipe.toBukkit(this.base), CraftRecipe.toBukkit(this.addition), this.copyNBT); // Paper
return recipe;
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingRecipe.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingRecipe.java
index d3e149d9d9b514f0d5b06799cc5dc9b790de5085..1c133200eb9efac6ae6eef553e5a69d3d3a8df83 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingRecipe.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftSmithingRecipe.java
@@ -8,15 +8,21 @@ import org.bukkit.inventory.RecipeChoice;
import org.bukkit.inventory.SmithingRecipe;
public class CraftSmithingRecipe extends SmithingRecipe implements CraftRecipe {
+ @Deprecated // Paper
public CraftSmithingRecipe(NamespacedKey key, ItemStack result, RecipeChoice base, RecipeChoice addition) {
super(key, result, base, addition);
}
+ // Paper start
+ public CraftSmithingRecipe(NamespacedKey key, ItemStack result, RecipeChoice base, RecipeChoice addition, boolean copyNbt) {
+ super(key, result, base, addition, copyNbt);
+ }
+ // Paper end
public static CraftSmithingRecipe fromBukkitRecipe(SmithingRecipe recipe) {
if (recipe instanceof CraftSmithingRecipe) {
return (CraftSmithingRecipe) recipe;
}
- CraftSmithingRecipe ret = new CraftSmithingRecipe(recipe.getKey(), recipe.getResult(), recipe.getBase(), recipe.getAddition());
+ CraftSmithingRecipe ret = new CraftSmithingRecipe(recipe.getKey(), recipe.getResult(), recipe.getBase(), recipe.getAddition(), recipe.willCopyNbt()); // Paper
return ret;
}
@@ -24,6 +30,6 @@ public class CraftSmithingRecipe extends SmithingRecipe implements CraftRecipe {
public void addToCraftingManager() {
ItemStack result = this.getResult();
- MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.LegacyUpgradeRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getBase(), true), toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result)));
+ MinecraftServer.getServer().getRecipeManager().addRecipe(new net.minecraft.world.item.crafting.LegacyUpgradeRecipe(CraftNamespacedKey.toMinecraft(this.getKey()), toNMS(this.getBase(), true), toNMS(this.getAddition(), true), CraftItemStack.asNMSCopy(result), this.willCopyNbt())); // Paper
}
}

View file

@ -1,100 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Thu, 23 Sep 2021 10:40:09 -0700
Subject: [PATCH] More CommandBlock API
diff --git a/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
new file mode 100644
index 0000000000000000000000000000000000000000..0b42306f17bf8850a13a51067c2d19e7583187e5
--- /dev/null
+++ b/src/main/java/io/papermc/paper/commands/PaperCommandBlockHolder.java
@@ -0,0 +1,33 @@
+package io.papermc.paper.commands;
+
+import io.papermc.paper.adventure.PaperAdventure;
+import io.papermc.paper.command.CommandBlockHolder;
+import net.kyori.adventure.text.Component;
+import net.minecraft.world.level.BaseCommandBlock;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public interface PaperCommandBlockHolder extends CommandBlockHolder {
+
+ BaseCommandBlock getCommandBlockHandle();
+
+ @Override
+ default @NotNull Component lastOutput() {
+ return PaperAdventure.asAdventure(getCommandBlockHandle().getLastOutput());
+ }
+
+ @Override
+ default void lastOutput(@Nullable Component lastOutput) {
+ getCommandBlockHandle().setLastOutput(PaperAdventure.asVanilla(lastOutput));
+ }
+
+ @Override
+ default int getSuccessCount() {
+ return getCommandBlockHandle().getSuccessCount();
+ }
+
+ @Override
+ default void setSuccessCount(int successCount) {
+ getCommandBlockHandle().setSuccessCount(successCount);
+ }
+}
diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
index c4ea6760f489e6171f9e6e170160b932597f842f..245a9b062a0033a39fd42f3ff94350192570aec4 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java
@@ -5,7 +5,7 @@ import org.bukkit.World;
import org.bukkit.block.CommandBlock;
import org.bukkit.craftbukkit.util.CraftChatMessage;
-public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock {
+public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity> implements CommandBlock, io.papermc.paper.commands.PaperCommandBlockHolder {
public CraftCommandBlock(World world, CommandBlockEntity tileEntity) {
super(world, tileEntity);
@@ -41,5 +41,10 @@ public class CraftCommandBlock extends CraftBlockEntityState<CommandBlockEntity>
public void name(net.kyori.adventure.text.Component name) {
getSnapshot().getCommandBlock().setName(name == null ? net.minecraft.network.chat.Component.literal("@") : io.papermc.paper.adventure.PaperAdventure.asVanilla(name));
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getSnapshot().getCommandBlock();
+ }
// Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
index f9863e138994f6c7a7975a852f106faa96d52315..b709a1d909c189f60d0c3aa97b4b96623e7c1db0 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java
@@ -14,7 +14,7 @@ import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
-public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart {
+public class CraftMinecartCommand extends CraftMinecart implements CommandMinecart, io.papermc.paper.commands.PaperCommandBlockHolder {
private final PermissibleBase perm = new PermissibleBase(this);
public CraftMinecartCommand(CraftServer server, MinecartCommandBlock entity) {
@@ -70,6 +70,17 @@ public class CraftMinecartCommand extends CraftMinecart implements CommandMineca
public net.kyori.adventure.text.@org.jetbrains.annotations.NotNull Component name() {
return io.papermc.paper.adventure.PaperAdventure.asAdventure(this.getHandle().getCommandBlock().getName());
}
+
+ @Override
+ public net.minecraft.world.level.BaseCommandBlock getCommandBlockHandle() {
+ return getHandle().getCommandBlock();
+ }
+
+ @Override
+ public void lastOutput(net.kyori.adventure.text.Component lastOutput) {
+ io.papermc.paper.commands.PaperCommandBlockHolder.super.lastOutput(lastOutput);
+ getCommandBlockHandle().onUpdated();
+ }
// Paper end
@Override

View file

@ -1,106 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Fri, 1 Oct 2021 08:04:39 -0700
Subject: [PATCH] Add missing team sidebar display slots
== AT ==
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations toBukkitSlot(I)Lorg/bukkit/scoreboard/DisplaySlot;
public org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations fromBukkitSlot(Lorg/bukkit/scoreboard/DisplaySlot;)I
diff --git a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
index e2d3fe9af7d3bd82bee519b20e141cd58f68bbd6..944a4fee237730c0d89567aaa6ddf268467aa0e0 100644
--- a/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
+++ b/src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java
@@ -7,36 +7,23 @@ import org.bukkit.scoreboard.DisplaySlot;
import org.bukkit.scoreboard.RenderType;
public final class CraftScoreboardTranslations {
- static final int MAX_DISPLAY_SLOT = 19;
+ static final int MAX_DISPLAY_SLOT = Scoreboard.getDisplaySlotNames().length; // Paper
+ @Deprecated // Paper
static final ImmutableBiMap<DisplaySlot, String> SLOTS = ImmutableBiMap.<DisplaySlot, String>builder()
.put(DisplaySlot.BELOW_NAME, "belowName")
.put(DisplaySlot.PLAYER_LIST, "list")
.put(DisplaySlot.SIDEBAR, "sidebar")
- .put(DisplaySlot.SIDEBAR_BLACK, "sidebar.team.black")
- .put(DisplaySlot.SIDEBAR_DARK_BLUE, "sidebar.team.dark_blue")
- .put(DisplaySlot.SIDEBAR_DARK_GREEN, "sidebar.team.dark_green")
- .put(DisplaySlot.SIDEBAR_DARK_AQUA, "sidebar.team.dark_aqua")
- .put(DisplaySlot.SIDEBAR_DARK_RED, "sidebar.team.dark_red")
- .put(DisplaySlot.SIDEBAR_DARK_PURPLE, "sidebar.team.dark_purple")
- .put(DisplaySlot.SIDEBAR_GOLD, "sidebar.team.gold")
- .put(DisplaySlot.SIDEBAR_GRAY, "sidebar.team.gray")
- .put(DisplaySlot.SIDEBAR_DARK_GRAY, "sidebar.team.dark_gray")
- .put(DisplaySlot.SIDEBAR_BLUE, "sidebar.team.blue")
- .put(DisplaySlot.SIDEBAR_GREEN, "sidebar.team.green")
- .put(DisplaySlot.SIDEBAR_AQUA, "sidebar.team.aqua")
- .put(DisplaySlot.SIDEBAR_RED, "sidebar.team.red")
- .put(DisplaySlot.SIDEBAR_LIGHT_PURPLE, "sidebar.team.light_purple")
- .put(DisplaySlot.SIDEBAR_YELLOW, "sidebar.team.yellow")
- .put(DisplaySlot.SIDEBAR_WHITE, "sidebar.team.white")
.buildOrThrow();
private CraftScoreboardTranslations() {}
public static DisplaySlot toBukkitSlot(int i) {
+ if (true) return org.bukkit.scoreboard.DisplaySlot.NAMES.value(Scoreboard.getDisplaySlotName(i)); // Paper
return CraftScoreboardTranslations.SLOTS.inverse().get(Scoreboard.getDisplaySlotName(i));
}
public static int fromBukkitSlot(DisplaySlot slot) {
+ if (true) return Scoreboard.getDisplaySlotByName(slot.getId()); // Paper
return Scoreboard.getDisplaySlotByName(CraftScoreboardTranslations.SLOTS.get(slot));
}
diff --git a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
index 2eb62af25076b7160b0159ec382baebe5162b024..0ef20dc6a43dc973183854a638d5f9f770583ec1 100644
--- a/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
+++ b/src/main/java/org/bukkit/craftbukkit/util/Commodore.java
@@ -251,6 +251,14 @@ public class Commodore
desc = getOriginalOrRewrite( desc );
}
// Paper end
+ // Paper start - DisplaySlot
+ if (owner.equals("org/bukkit/scoreboard/DisplaySlot")) {
+ if (name.startsWith("SIDEBAR_") && !name.startsWith("SIDEBAR_TEAM_")) {
+ super.visitFieldInsn(opcode, owner, name.replace("SIDEBAR_", "SIDEBAR_TEAM_"), desc);
+ return;
+ }
+ }
+ // Paper end - DisplaySlot
if ( owner.equals( "org/bukkit/block/Biome" ) )
{
diff --git a/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb41a2f2c0a5e3b4cb3fe1b584e0ceb7a7116afb
--- /dev/null
+++ b/src/test/java/io/papermc/paper/scoreboard/DisplaySlotTest.java
@@ -0,0 +1,26 @@
+package io.papermc.paper.scoreboard;
+
+import net.minecraft.world.scores.Scoreboard;
+import org.bukkit.craftbukkit.scoreboard.CraftScoreboardTranslations;
+import org.bukkit.scoreboard.DisplaySlot;
+import org.junit.Test;
+
+import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class DisplaySlotTest {
+
+ @Test
+ public void testBukkitToMinecraftDisplaySlots() {
+ for (DisplaySlot value : DisplaySlot.values()) {
+ assertNotEquals(-1, CraftScoreboardTranslations.fromBukkitSlot(value));
+ }
+ }
+
+ @Test
+ public void testMinecraftToBukkitDisplaySlots() {
+ for (String name : Scoreboard.getDisplaySlotNames()) {
+ assertNotNull(CraftScoreboardTranslations.toBukkitSlot(Scoreboard.getDisplaySlotByName(name)));
+ }
+ }
+}

View file

@ -1,45 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sun, 16 May 2021 09:39:46 -0700
Subject: [PATCH] Add back EntityPortalExitEvent
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index d69352cc86f1a40bf696e30f11a3a84fac3b20c5..d2f93f6cf5ff5a0ee5de18d4e593c1423e191d14 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -3217,6 +3217,23 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
} else {
// CraftBukkit start
worldserver = shapedetectorshape.world;
+ // Paper start - Call EntityPortalExitEvent
+ CraftEntity bukkitEntity = this.getBukkitEntity();
+ Vec3 position = shapedetectorshape.pos;
+ float yaw = shapedetectorshape.yRot;
+ float pitch = bukkitEntity.getLocation().getPitch(); // Keep entity pitch as per moveTo line below
+ Vec3 velocity = shapedetectorshape.speed;
+ org.bukkit.event.entity.EntityPortalExitEvent event = new org.bukkit.event.entity.EntityPortalExitEvent(bukkitEntity,
+ bukkitEntity.getLocation(), new Location(worldserver.getWorld(), position.x, position.y, position.z, yaw, pitch),
+ bukkitEntity.getVelocity(), org.bukkit.craftbukkit.util.CraftVector.toBukkit(shapedetectorshape.speed));
+ if (event.callEvent() && event.getTo() != null && this.isAlive()) {
+ worldserver = ((CraftWorld) event.getTo().getWorld()).getHandle();
+ position = new Vec3(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ());
+ yaw = event.getTo().getYaw();
+ pitch = event.getTo().getPitch();
+ velocity = org.bukkit.craftbukkit.util.CraftVector.toNMS(event.getAfter());
+ }
+ // Paper end
if (worldserver == this.level) {
// SPIGOT-6782: Just move the entity if a plugin changed the world to the one the entity is already in
this.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, shapedetectorshape.xRot);
@@ -3236,8 +3253,8 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
if (entity != null) {
entity.restoreFrom(this);
- entity.moveTo(shapedetectorshape.pos.x, shapedetectorshape.pos.y, shapedetectorshape.pos.z, shapedetectorshape.yRot, entity.getXRot());
- entity.setDeltaMovement(shapedetectorshape.speed);
+ entity.moveTo(position.x, position.y, position.z, yaw, pitch); // Paper - use EntityPortalExitEvent values
+ entity.setDeltaMovement(velocity); // Paper - use EntityPortalExitEvent values
worldserver.addDuringTeleport(entity);
if (worldserver.getTypeKey() == LevelStem.END) { // CraftBukkit
ServerLevel.makeObsidianPlatform(worldserver, this); // CraftBukkit

View file

@ -1,60 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jakub Zacek <dawon@dawon.eu>
Date: Mon, 4 Oct 2021 10:16:44 +0200
Subject: [PATCH] Add methods to find targets for lightning strikes
== AT ==
public net.minecraft.server.level.ServerLevel findLightningRod(Lnet/minecraft/core/BlockPos;)Ljava/util/Optional;
diff --git a/src/main/java/net/minecraft/server/level/ServerLevel.java b/src/main/java/net/minecraft/server/level/ServerLevel.java
index 16b73f0498936a8413f6adedd7f92bab07a4a108..f12d844d422ca4175d4cb2b8e3112b590a207a16 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -833,6 +833,11 @@ public class ServerLevel extends Level implements WorldGenLevel {
}
protected BlockPos findLightningTargetAround(BlockPos pos) {
+ // Paper start
+ return this.findLightningTargetAround(pos, false);
+ }
+ public BlockPos findLightningTargetAround(BlockPos pos, boolean returnNullWhenNoTarget) {
+ // Paper end
BlockPos blockposition1 = this.getHeightmapPos(Heightmap.Types.MOTION_BLOCKING, pos);
Optional<BlockPos> optional = this.findLightningRod(blockposition1);
@@ -847,6 +852,7 @@ public class ServerLevel extends Level implements WorldGenLevel {
if (!list.isEmpty()) {
return ((LivingEntity) list.get(this.random.nextInt(list.size()))).blockPosition();
} else {
+ if (returnNullWhenNoTarget) return null; // Paper
if (blockposition1.getY() == this.getMinBuildHeight() - 1) {
blockposition1 = blockposition1.above(2);
}
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 0acb97676ad066d474b0290cbbb8555f11d09154..1c0cf2bb708e4333319fd3355d937a3dcc3c1ade 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -693,6 +693,23 @@ public class CraftWorld extends CraftRegionAccessor implements World {
return (LightningStrike) lightning.getBukkitEntity();
}
+ // Paper start
+ @Override
+ public Location findLightningRod(Location location) {
+ return this.world.findLightningRod(io.papermc.paper.util.MCUtil.toBlockPosition(location))
+ .map(blockPos -> io.papermc.paper.util.MCUtil.toLocation(this.world, blockPos)
+ // get the actual rod pos
+ .subtract(0, 1, 0))
+ .orElse(null);
+ }
+
+ @Override
+ public Location findLightningTarget(Location location) {
+ final BlockPos pos = this.world.findLightningTargetAround(io.papermc.paper.util.MCUtil.toBlockPosition(location), true);
+ return pos == null ? null : io.papermc.paper.util.MCUtil.toLocation(this.world, pos);
+ }
+ // Paper end
+
@Override
public boolean generateTree(Location loc, TreeType type) {
return generateTree(loc, CraftWorld.rand, type);