more patches done

This commit is contained in:
Jake 2021-11-24 15:26:29 -08:00 committed by MiniDigger | Martin
parent c4ef2add48
commit 4664528315
27 changed files with 111 additions and 123 deletions

View file

@ -1,80 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Max Lee <max@themoep.de>
Date: Thu, 27 May 2021 14:52:30 -0700
Subject: [PATCH] Fix invulnerable end crystals
MC-108513
diff --git a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index d8ed734450a14ffeed6d7a42eed238645b0cb380..b1a8c0e6c07bcc3625e834592923da462977af5e 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -868,5 +868,10 @@ public class PaperWorldConfig {
private void fixItemsMergingThroughWalls() {
fixItemsMergingThroughWalls = getBoolean("fix-items-merging-through-walls", fixItemsMergingThroughWalls);
}
+
+ public boolean fixInvulnerableEndCrystalExploit = true;
+ private void fixInvulnerableEndCrystalExploit() {
+ fixInvulnerableEndCrystalExploit = getBoolean("unsupported-settings.fix-invulnerable-end-crystal-exploit", fixInvulnerableEndCrystalExploit);
+ }
}
diff --git a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
index 2c4c1fc2a2afe88864b72d86708a3ddb6a1f50a0..b643a2449e329560c936c0a06fb4cc494d0737a7 100644
--- a/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
+++ b/src/main/java/net/minecraft/world/entity/boss/enderdragon/EndCrystal.java
@@ -31,6 +31,7 @@ public class EndCrystal extends Entity {
private static final EntityDataAccessor<Optional<BlockPos>> DATA_BEAM_TARGET = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.OPTIONAL_BLOCK_POS);
private static final EntityDataAccessor<Boolean> DATA_SHOW_BOTTOM = SynchedEntityData.defineId(EndCrystal.class, EntityDataSerializers.BOOLEAN);
public int time;
+ public boolean generatedByDragonFight = false; // Paper - Fix invulnerable end crystals
public EndCrystal(EntityType<? extends EndCrystal> type, Level world) {
super(type, world);
@@ -67,6 +68,17 @@ public class EndCrystal extends Entity {
}
// CraftBukkit end
}
+ // Paper start - Fix invulnerable end crystals
+ if (this.level.paperConfig.fixInvulnerableEndCrystalExploit && this.generatedByDragonFight && this.isInvulnerable()) {
+ if (!java.util.Objects.equals(((ServerLevel) this.level).uuid, this.getOriginWorld())
+ || ((ServerLevel) this.level).dragonFight() == null
+ || ((ServerLevel) this.level).dragonFight().respawnStage == null
+ || ((ServerLevel) this.level).dragonFight().respawnStage.ordinal() > net.minecraft.world.level.dimension.end.DragonRespawnAnimation.SUMMONING_DRAGON.ordinal()) {
+ this.setInvulnerable(false);
+ this.setBeamTarget(null);
+ }
+ }
+ // Paper end
}
}
@@ -78,6 +90,7 @@ public class EndCrystal extends Entity {
}
nbt.putBoolean("ShowBottom", this.showsBottom());
+ if (this.generatedByDragonFight) nbt.putBoolean("Paper.GeneratedByDragonFight", this.generatedByDragonFight); // Paper - Fix invulnerable end crystals
}
@Override
@@ -89,6 +102,7 @@ public class EndCrystal extends Entity {
if (nbt.contains("ShowBottom", 1)) {
this.setShowBottom(nbt.getBoolean("ShowBottom"));
}
+ if (nbt.contains("Paper.GeneratedByDragonFight", 1)) this.generatedByDragonFight = nbt.getBoolean("Paper.GeneratedByDragonFight"); // Paper - Fix invulnerable end crystals
}
diff --git a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
index 1e53d4bef86349eaa1356444a80ae92d4311ccce..c03bf5bdb67b00c75f9fcfead882c4d944282244 100644
--- a/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
+++ b/src/main/java/net/minecraft/world/level/levelgen/feature/SpikeFeature.java
@@ -99,6 +99,7 @@ public class SpikeFeature extends Feature<SpikeConfiguration> {
endCrystal.setBeamTarget(config.getCrystalBeamTarget());
endCrystal.setInvulnerable(config.isCrystalInvulnerable());
endCrystal.moveTo((double)spike.getCenterX() + 0.5D, (double)(spike.getHeight() + 1), (double)spike.getCenterZ() + 0.5D, random.nextFloat() * 360.0F, 0.0F);
+ endCrystal.generatedByDragonFight = true; // Paper
world.addFreshEntity(endCrystal);
this.setBlock(world, new BlockPos(spike.getCenterX(), spike.getHeight(), spike.getCenterZ()), Blocks.BEDROCK.defaultBlockState());
}

View file

@ -1,23 +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/entity/monster/ElderGuardian.java b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
index 854ef7895f044087ab4d74bc6952d2987cfe2460..ee9194ffb3cc6d660d4f99a3914ede7e4a3643fe 100644
--- a/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
+++ b/src/main/java/net/minecraft/world/entity/monster/ElderGuardian.java
@@ -77,10 +77,12 @@ public class ElderGuardian extends Guardian {
while (iterator.hasNext()) {
ServerPlayer entityplayer = (ServerPlayer) iterator.next();
+ if (new io.papermc.paper.event.entity.ElderGuardianAppearanceEvent(getBukkitEntity(), entityplayer.getBukkitEntity()).callEvent()) { // Paper - Add Guardian Appearance Event
if (!entityplayer.hasEffect(mobeffectlist) || entityplayer.getEffect(mobeffectlist).getAmplifier() < 2 || entityplayer.getEffect(mobeffectlist).getDuration() < 1200) {
entityplayer.connection.send(new ClientboundGameEventPacket(ClientboundGameEventPacket.GUARDIAN_ELDER_EFFECT, this.isSilent() ? 0.0F : 1.0F));
entityplayer.addEffect(new MobEffectInstance(mobeffectlist, 6000, 2), this, org.bukkit.event.entity.EntityPotionEffectEvent.Cause.ATTACK); // CraftBukkit
}
+ } // Paper - Add Guardian Appearance Event
}
}

View file

@ -1,87 +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 5703949d5ffa56602418d40a85f2fa1827690254..4f1a57c24688d1ae537f5fd1c1649e035f20abfd 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -386,6 +386,37 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
// 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() == DimensionType.END_LOCATION ? 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();
this.passengers = ImmutableList.of();
@@ -2537,6 +2568,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, n
}
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 739c9c3a49fd3893ac39962a02a5e3620dc4fe06..62c2f947a77570228dfdf4dae16c64eb97ee2f40 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 4e06bb1fbda33e79044ac54758b559f7436882a7..86528ff031014e788d72a8bf7c1c9443512096bb 100644
--- a/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
+++ b/src/main/java/net/minecraft/world/level/biome/MobSpawnSettings.java
@@ -70,11 +70,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;
private boolean playerCanSpawn;

View file

@ -1,83 +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/com/destroystokyo/paper/PaperConfig.java b/src/main/java/com/destroystokyo/paper/PaperConfig.java
index 247c172c3b722cb1b753fd92839ab427233d7a13..939744ef6850d4e59e5c94bc4781d045041b977d 100644
--- a/src/main/java/com/destroystokyo/paper/PaperConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperConfig.java
@@ -510,4 +510,19 @@ public class PaperConfig {
enableBrigadierConsoleHighlighting = getBoolean("settings.console.enable-brigadier-highlighting", enableBrigadierConsoleHighlighting);
enableBrigadierConsoleCompletions = getBoolean("settings.console.enable-brigadier-completions", enableBrigadierConsoleCompletions);
}
+
+ public static int itemValidationDisplayNameLength = 8192;
+ public static int itemValidationLocNameLength = 8192;
+ public static int itemValidationLoreLineLength = 8192;
+ public static int itemValidationBookTitleLength = 8192;
+ public static int itemValidationBookAuthorLength = 8192;
+ public static int itemValidationBookPageLength = 16384;
+ private static void itemValidationSettings() {
+ itemValidationDisplayNameLength = getInt("settings.item-validation.display-name", itemValidationDisplayNameLength);
+ itemValidationLocNameLength = getInt("settings.item-validation.loc-name", itemValidationLocNameLength);
+ itemValidationLoreLineLength = getInt("settings.item-validation.lore-line", itemValidationLoreLineLength);
+ itemValidationBookTitleLength = getInt("settings.item-validation.book.title", itemValidationBookTitleLength);
+ itemValidationBookAuthorLength = getInt("settings.item-validation.book.author", itemValidationBookAuthorLength);
+ itemValidationBookPageLength = getInt("settings.item-validation.book.page", itemValidationBookPageLength);
+ }
}
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
index 0f753f4868141ecc383877ea3a666a383f2e3339..ebb643fc0477409d1efb4e9af59675045fa6b8bb 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java
@@ -92,11 +92,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), com.destroystokyo.paper.PaperConfig.itemValidationBookTitleLength); // 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), com.destroystokyo.paper.PaperConfig.itemValidationBookAuthorLength ); // Spigot // Paper - make configurable
}
if (tag.contains(RESOLVED.NBT)) {
@@ -124,7 +124,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, com.destroystokyo.paper.PaperConfig.itemValidationBookPageLength ) ); // 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 808eb6b9ec535b1179a1d7b88877c9ce1755c45b..c88ab49f60857d5687facc8523f9edc4d652c81b 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java
@@ -357,18 +357,18 @@ 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), com.destroystokyo.paper.PaperConfig.itemValidationDisplayNameLength ); // Spigot // Paper - make configurable
}
if (display.contains(LOCNAME.NBT)) {
- this.locName = limit( display.getString(LOCNAME.NBT), 8192 ); // Spigot
+ this.locName = limit( display.getString(LOCNAME.NBT), com.destroystokyo.paper.PaperConfig.itemValidationLocNameLength ); // Spigot // Paper - make configurable
}
if (display.contains(LORE.NBT)) {
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), com.destroystokyo.paper.PaperConfig.itemValidationLoreLineLength ); // Spigot // Paper - make configurable
this.lore.add(line);
}
}

View file

@ -1,76 +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 b84e20cd955fd75582a2c52f0c571d54ead555b2..a60d289f3cf3826ac5368f3de77584fb63bf5e64 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3430,7 +3430,8 @@ public abstract class LivingEntity extends Entity {
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/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 483ca752016c0d5e669b462396e50e83b66d3ef1..6a4c379a2905455b14c3cbd4a46a0f95c5f78aac 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -188,6 +188,18 @@ public class CraftWorld extends CraftRegionAccessor implements World {
public io.papermc.paper.world.MoonPhase getMoonPhase() {
return io.papermc.paper.world.MoonPhase.getPhase(getFullTime() / 24000L);
}
+
+ @Override
+ public boolean lineOfSightExists(Location from, Location to) {
+ Validate.notNull(from, "from parameter in lineOfSightExists cannot be null");
+ Validate.notNull(to, "to parameter in lineOfSightExists cannot be null");
+ if (from.getWorld() != to.getWorld()) return false;
+ Vec3 vec3d = new Vec3(from.getX(), from.getY(), from.getZ());
+ Vec3 vec3d1 = new 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 ClipContext(vec3d, vec3d1, ClipContext.Block.COLLIDER, ClipContext.Fluid.NONE, null)).getType() == HitResult.Type.MISS;
+ }
// Paper end
private static final Random rand = new Random();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java
index 20e619baa4bce6a133ade5e5d6a6f04f49a1b176..1c684244213d04b36589dd50ea66052a9cdad072 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;
@@ -557,6 +560,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,72 +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/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index b1a8c0e6c07bcc3625e834592923da462977af5e..d40d6ead65bd0f6ae64155ee7960245fd0e72b77 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -14,6 +14,7 @@ import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.monster.Vindicator;
import net.minecraft.world.entity.monster.Zombie;
import com.destroystokyo.paper.antixray.ChunkPacketBlockControllerAntiXray.EngineMode;
+import net.minecraft.world.level.NaturalSpawner;
import org.bukkit.Bukkit;
import org.bukkit.configuration.file.YamlConfiguration;
import org.spigotmc.SpigotWorldConfig;
@@ -57,6 +58,11 @@ public class PaperWorldConfig {
set("despawn-ranges.soft", null);
set("despawn-ranges.hard", null);
+
+ set("spawn-limits.monsters", null);
+ set("spawn-limits.animals", null);
+ set("spawn-limits.water-animals", null);
+ set("spawn-limits.water-ambient", null);
}
if (needsSave) {
@@ -721,6 +727,21 @@ public class PaperWorldConfig {
zombieVillagerInfectionChance = getDouble("zombie-villager-infection-chance", zombieVillagerInfectionChance);
}
+ public Reference2IntMap<MobCategory> perWorldSpawnLimits = new Reference2IntOpenHashMap<>(NaturalSpawner.SPAWNING_CATEGORIES.length);
+ private void perWorldSpawnLimits() {
+ perWorldSpawnLimits.defaultReturnValue(-1);
+ if (PaperConfig.version < 24) {
+ // ambient category already had correct name
+ perWorldSpawnLimits.put(MobCategory.MONSTER, getInt("spawn-limits.monsters", -1, false));
+ perWorldSpawnLimits.put(MobCategory.CREATURE, getInt("spawn-limits.animals", -1, false));
+ perWorldSpawnLimits.put(MobCategory.WATER_CREATURE, getInt("spawn-limits.water-animals", -1, false));
+ perWorldSpawnLimits.put(MobCategory.WATER_AMBIENT, getInt("spawn-limits.water-ambient", -1, false));
+ }
+ for (MobCategory value : NaturalSpawner.SPAWNING_CATEGORIES) {
+ perWorldSpawnLimits.put(value, getInt("spawn-limits." + value.getName(), perWorldSpawnLimits.getInt(value)));
+ }
+ }
+
public int lightQueueSize = 20;
private void lightQueueSize() {
lightQueueSize = getInt("light-queue-size", lightQueueSize);
diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
index 6a4c379a2905455b14c3cbd4a46a0f95c5f78aac..4430385a758906239b8573c59b18d19470339ec5 100644
--- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
+++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java
@@ -210,6 +210,14 @@ public class CraftWorld extends CraftRegionAccessor implements World {
this.biomeProvider = biomeProvider;
this.environment = env;
+ // Paper start - per world spawn limits
+ this.monsterSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.MONSTER);
+ this.animalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.CREATURE);
+ this.waterAnimalSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_CREATURE);
+ this.waterAmbientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.WATER_AMBIENT);
+ this.ambientSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.AMBIENT);
+ this.waterUndergroundCreatureSpawn = this.world.paperConfig.perWorldSpawnLimits.getInt(net.minecraft.world.entity.MobCategory.UNDERGROUND_WATER_CREATURE);
+ // Paper end
}
@Override

View file

@ -1,52 +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 PotionSplashEvent for water splash potions
Fixes SPIGOT-6221: https://hub.spigotmc.org/jira/projects/SPIGOT/issues/SPIGOT-6221
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 4dc6ab94a50a1dca8603129b28405578d381a06e..8676796ff65cd0bd3f215dc7edcf3a5b2291ca27 100644
--- a/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
+++ b/src/main/java/net/minecraft/world/entity/projectile/ThrownPotion.java
@@ -126,6 +126,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
private void applyWater() {
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);
+ Map<LivingEntity, Double> affected = new HashMap<>(); // Paper
if (!list.isEmpty()) {
Iterator iterator = list.iterator();
@@ -135,11 +136,23 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
double d0 = this.distanceToSqr(entityliving);
if (d0 < 16.0D && entityliving.isSensitiveToWater()) {
- entityliving.hurt(DamageSource.indirectMagic(entityliving, this.getOwner()), 1.0F);
+ // Paper start
+ double intensity = 1.0D - Math.sqrt(d0) / 4.0D;
+ affected.put(entityliving.getBukkitLivingEntity(), intensity);
+ // entityliving.damageEntity(DamageSource.c(entityliving, this.getShooter()), 1.0F); // Paper - moved down
}
}
}
+ org.bukkit.event.entity.PotionSplashEvent event = CraftEventFactory.callPotionSplashEvent(this, affected);
+ if (!event.isCancelled()) {
+ for (LivingEntity affectedEntity : event.getAffectedEntities()) {
+ net.minecraft.world.entity.LivingEntity entityliving = ((CraftLivingEntity) affectedEntity).getHandle();
+ entityliving.hurt(DamageSource.indirectMagic(entityliving, this.getOwner()), 1.0F);
+ }
+ }
+ // Paper end
+
List<Axolotl> list1 = this.level.getEntitiesOfClass(Axolotl.class, axisalignedbb);
Iterator iterator1 = list1.iterator();
@@ -167,6 +180,7 @@ public class ThrownPotion extends ThrowableItemProjectile implements ItemSupplie
double d0 = this.distanceToSqr(entityliving);
if (d0 < 16.0D) {
+ // Paper - diff on change, used when calling the splash event for water splash potions
double d1 = 1.0D - Math.sqrt(d0) / 4.0D;
if (entityliving == entity) {

View file

@ -1,72 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Spottedleaf <Spottedleaf@users.noreply.github.com>
Date: Mon, 10 May 2021 15:46:57 -0700
Subject: [PATCH] Fix incorrect status dataconverter for pre 1.13 chunks
Vanilla was setting non-populated OR non-lit chunks to empty, but
really this is just completely wrong. It should be set to "carved"
at minmum, because pre 1.13 chunks went through 3 distinct stages
of generation: carving, population, and lighting - in this order.
There is no "empty" status, because a chunk was simply carved
or it didn't exist. So mapping any chunk data to empty is simply
invalid.
If the chunk is terrain populated, then obviously it must be at
minmum "decorated." If the chunk is lit and populated, then it is marked
"mobs_spawned" (which is what Vanilla is doing, and this is the last
stage before moving to full so it looks correct).
So now here is a table representing the new status conversion:
Chunk is lit Chunk is populated Vanilla
F F empty
T F empty
F T empty
T T mobs_spawned
Chunk is lit Chunk is populated Paper
F F carved
T F carved
F T decorated
T T mobs_spawned
This should fix some problems converting old data, as the
changes here are going to prevent the chunk from being regenerated
incorrectly.
diff --git a/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java b/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
index 081bcae48ae34d8354635ea57952f09f14f7fa7a..a4305f58f793e1577de5e13132381ce81304cae4 100644
--- a/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
+++ b/src/main/java/net/minecraft/util/datafix/fixes/ChunkToProtochunkFix.java
@@ -36,17 +36,26 @@ public class ChunkToProtochunkFix extends DataFix {
OpticFinder<?> opticFinder2 = DSL.fieldFinder("TileTicks", type5);
return TypeRewriteRule.seq(this.fixTypeEverywhereTyped("ChunkToProtoChunkFix", type, this.getOutputSchema().getType(References.CHUNK), (typed) -> {
return typed.updateTyped(opticFinder, type4, (typedx) -> {
- Optional<? extends Stream<? extends Dynamic<?>>> optional = typedx.getOptionalTyped(opticFinder2).flatMap((typed) -> {
- return typed.write().result();
+ Optional<? extends Stream<? extends Dynamic<?>>> optional = typedx.getOptionalTyped(opticFinder2).flatMap((it) -> { // Paper - remap fix
+ return it.write().result(); // Paper - remap fix
}).flatMap((dynamicx) -> {
return dynamicx.asStreamOpt().result();
});
Dynamic<?> dynamic = typedx.get(DSL.remainderFinder());
- boolean bl = dynamic.get("TerrainPopulated").asBoolean(false) && (!dynamic.get("LightPopulated").asNumber().result().isPresent() || dynamic.get("LightPopulated").asBoolean(false));
- dynamic = dynamic.set("Status", dynamic.createString(bl ? "mobs_spawned" : "empty"));
+ // Paper start - fix incorrect status conversion
+ // Vanilla is setting chunks to incorrect status here, they should be using at minimum carved.
+ // for populated chunks, it should be at minimum decorated
+ // and for lit and populated, mobs_spawned is correct (technically mobs_spawned should be for populated,
+ // but if it's not lit then it can't be set above lit)
+ final boolean terrainPopulated = dynamic.get("TerrainPopulated").asBoolean(false);
+ final boolean lightPopulated = dynamic.get("LightPopulated").asBoolean(false) || dynamic.get("LightPopulated").asNumber().result().isPresent();
+ final String newStatus = !terrainPopulated ? "carved" : (lightPopulated ? "mobs_spawned" : "decorated");
+
+ dynamic = dynamic.set("Status", dynamic.createString(newStatus));
+ // Paper end - fix incorrect status conversion
dynamic = dynamic.set("hasLegacyStructureData", dynamic.createBoolean(true));
Dynamic<?> dynamic3;
- if (bl) {
+ if (true) { // Paper - fix incorrect status conversion
Optional<ByteBuffer> optional2 = dynamic.get("Biomes").asByteBufferOpt().result();
if (optional2.isPresent()) {
ByteBuffer byteBuffer = optional2.get();

View file

@ -1,255 +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/io/papermc/paper/world/generation/CraftProtoWorld.java b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c6668c2b5e1816db7e0ebabc99af3586849e606
--- /dev/null
+++ b/src/main/java/io/papermc/paper/world/generation/CraftProtoWorld.java
@@ -0,0 +1,116 @@
+package io.papermc.paper.world.generation;
+
+import net.minecraft.core.BlockPos;
+import net.minecraft.nbt.CompoundTag;
+import net.minecraft.server.level.WorldGenRegion;
+import net.minecraft.world.entity.Mob;
+import net.minecraft.world.entity.MobSpawnType;
+import net.minecraft.world.entity.SpawnGroupData;
+import net.minecraft.world.level.block.entity.BlockEntity;
+import org.bukkit.World;
+import org.bukkit.block.BlockState;
+import org.bukkit.block.data.BlockData;
+import org.bukkit.craftbukkit.block.CraftBlockEntityState;
+import org.bukkit.craftbukkit.block.CraftBlockState;
+import org.bukkit.craftbukkit.block.data.CraftBlockData;
+import org.bukkit.craftbukkit.inventory.CraftMetaBlockState;
+import org.bukkit.entity.Entity;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+import org.bukkit.util.Vector;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Objects;
+import java.util.function.Consumer;
+
+@Deprecated
+public class CraftProtoWorld implements ProtoWorld {
+ private WorldGenRegion region;
+
+ public CraftProtoWorld(WorldGenRegion region) {
+ this.region = region;
+ }
+
+ public void clearReference() {
+ region = null;
+ }
+
+ @Override
+ public void setBlockData(int x, int y, int z, @NotNull BlockData data) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().setBlock(position, ((CraftBlockData) data).getState(), 3);
+ }
+
+ @Override
+ public void setBlockState(int x, int y, int z, @NotNull BlockState state) {
+ BlockPos pos = new BlockPos(x, y, z);
+ if(!state.getBlockData().matches(getDelegate().getBlockState(pos).createCraftBlockData())) {
+ throw new IllegalArgumentException("BlockData does not match! Expected " + state.getBlockData().getAsString(false) + ", got " + getDelegate().getBlockState(pos).createCraftBlockData().getAsString(false));
+ }
+ getDelegate().getBlockEntity(pos).load(((CraftBlockEntityState<?>) state).getSnapshotNBT());
+ }
+
+ @Override
+ public @NotNull BlockState getBlockState(int x, int y, int z) {
+ BlockEntity entity = getDelegate().getBlockEntity(new BlockPos(x, y, z));
+ return CraftMetaBlockState.createBlockState(entity.getBlockState().getBukkitMaterial(), entity.save(new CompoundTag()));
+ }
+
+ @Override
+ public void scheduleBlockUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getBlockTicks().scheduleTick(position, getDelegate().getBlockIfLoaded(position), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getDelegate().getLiquidTicks().scheduleTick(position, getDelegate().getFluidState(position).getType(), 0);
+ }
+
+ @Override
+ public @NotNull 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 getDelegate().getMinecraftWorld().getWorld();
+ }
+
+ @Override
+ public @NotNull BlockData getBlockData(int x, int y, int z) {
+ return CraftBlockData.fromData(getDelegate().getBlockState(new BlockPos(x, y, z)));
+ }
+
+ @Override
+ public int getCenterChunkX() {
+ return getDelegate().getCenter().x;
+ }
+
+ @Override
+ public int getCenterChunkZ() {
+ return getDelegate().getCenter().z;
+ }
+
+ @SuppressWarnings({"unchecked", "deprecation"})
+ @Override
+ public <T extends Entity> @NotNull T spawn(@NotNull Vector location, @NotNull Class<T> clazz, @Nullable Consumer<T> function, CreatureSpawnEvent.@NotNull SpawnReason reason) throws IllegalArgumentException {
+ net.minecraft.world.entity.Entity entity = getDelegate().getMinecraftWorld().getWorld().createEntity(location.toLocation(getWorld()), clazz);
+ Objects.requireNonNull(entity, "Cannot spawn null entity");
+ if (entity instanceof Mob mob) {
+ mob.finalizeSpawn(getDelegate(), getDelegate().getCurrentDifficultyAt(entity.blockPosition()), MobSpawnType.COMMAND, (SpawnGroupData) null, null);
+ }
+
+ if (function != null) {
+ function.accept((T) entity.getBukkitEntity());
+ }
+
+ getDelegate().addEntity(entity, reason);
+ return (T) entity.getBukkitEntity();
+ }
+
+ @NotNull
+ private WorldGenRegion getDelegate() {
+ return Objects.requireNonNull(region, "Cannot access ProtoWorld after generation!");
+ }
+}
+
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
index d91c88d7bdfd954fa81fbf1c9ad92161d70993a6..f5ef7e026061351590f1ce77694e2d8fb8521048 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CraftLimitedRegion.java
@@ -151,7 +151,10 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
@Override
public BlockState getBlockState(int x, int y, int z) {
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
- return super.getBlockState(x, y, z);
+ // Paper start
+ net.minecraft.world.level.block.entity.BlockEntity entity = getHandle().getBlockEntity(new BlockPos(x, y, z));
+ return org.bukkit.craftbukkit.inventory.CraftMetaBlockState.createBlockState(entity.getBlockState().getBukkitMaterial(), entity.save(new CompoundTag()));
+ // Paper end
}
@Override
@@ -169,7 +172,7 @@ public class CraftLimitedRegion extends CraftRegionAccessor implements LimitedRe
@Override
public void setBlockData(int x, int y, int z, BlockData blockData) {
Preconditions.checkArgument(this.isInRegion(x, y, z), "Coordinates %s, %s, %s are not in the region", x, y, z);
- super.setBlockData(x, y, z, blockData);
+ getHandle().setBlock(new BlockPos(x, y, z), ((org.bukkit.craftbukkit.block.data.CraftBlockData) blockData).getState(), 3); // Paper
}
@Override
@@ -199,4 +202,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().getBlockTicks().scheduleTick(position, getHandle().getBlockIfLoaded(position), 0);
+ }
+
+ @Override
+ public void scheduleFluidUpdate(int x, int y, int z) {
+ BlockPos position = new BlockPos(x, y, z);
+ getHandle().getLiquidTicks().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
}
diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
index eb82aaf9dcbc912d780a90842601da85497fa443..1b05bb78eaee548806df8ebfff1a1401e30d52e0 100644
--- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
+++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java
@@ -196,6 +196,12 @@ public class CustomChunkGenerator extends InternalChunkGenerator {
for (BlockPos lightPosition : craftData.getLights()) {
((ProtoChunk) chunk).addLight(new BlockPos((x << 4) + lightPosition.getX(), lightPosition.getY(), (z << 4) + lightPosition.getZ())); // PAIL rename addLightBlock
}
+
+ // Paper start
+ io.papermc.paper.world.generation.CraftProtoWorld protoWorld = new io.papermc.paper.world.generation.CraftProtoWorld(region);
+ generator.generateDecorations(protoWorld);
+ protoWorld.clearReference(); // make sure people dont try to use the ProtoWorld after we're done with it.
+ // Paper end
}
@Override
diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
index 55dd618d8421271063843c6e65dbcaceba9a33de..56f65b49e0ce55ee5aa9d929a98ea055ce27a8a1 100644
--- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
+++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBlockState.java
@@ -214,11 +214,16 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
@Override
public BlockState getBlockState() {
- Material stateMaterial = (this.material != Material.SHIELD) ? this.material : CraftMetaBlockState.shieldToBannerHack(this.blockEntityTag); // Only actually used for jigsaws
- if (this.blockEntityTag != null) {
- switch (this.material) {
+ // Paper start
+ return createBlockState(this.material, this.blockEntityTag);
+ }
+ public static BlockState createBlockState(Material material, CompoundTag blockEntityTag) {
+ Material stateMaterial = (material != Material.SHIELD) ? material : CraftMetaBlockState.shieldToBannerHack(blockEntityTag); // Only actually used for jigsaws
+ if (blockEntityTag != null) {
+ switch (material) {
+ // Paper end
case SHIELD:
- this.blockEntityTag.putString("id", "banner");
+ blockEntityTag.putString("id", "banner"); // Paper
break;
case SHULKER_BOX:
case WHITE_SHULKER_BOX:
@@ -237,11 +242,11 @@ public class CraftMetaBlockState extends CraftMetaItem implements BlockStateMeta
case GREEN_SHULKER_BOX:
case RED_SHULKER_BOX:
case BLACK_SHULKER_BOX:
- this.blockEntityTag.putString("id", "shulker_box");
+ blockEntityTag.putString("id", "shulker_box"); // Paper
break;
case BEE_NEST:
case BEEHIVE:
- this.blockEntityTag.putString("id", "beehive");
+ blockEntityTag.putString("id", "beehive"); // Paper
break;
}
}

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 d309e2c460654c2fa7a6668e9f31d330e8e35967..3833c0c863c49c2ff5552030e7a0799cf2ec0614 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -2161,7 +2161,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 3e462d68ce5fa37735c5328997767fa1ef3b869d..fb66da46d2b3a46fe4b8d43f99a1a60f768f5f19 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -705,6 +705,11 @@ public abstract class Player extends LivingEntity {
}
double d0 = this.getEyeY() - 0.30000001192092896D;
+ // Paper start
+ ItemStack tmp = stack.copy();
+ stack.setCount(0);
+ stack = tmp;
+ // Paper end
ItemEntity entityitem = new ItemEntity(this.level, this.getX(), d0, this.getZ(), stack);
entityitem.setPickUpDelay(40);

View file

@ -1,158 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Owen1212055 <23108066+Owen1212055@users.noreply.github.com>
Date: Mon, 21 Jun 2021 23:56:07 -0400
Subject: [PATCH] Missing Entity Behavior API
diff --git a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
index 630b6491ee186e1e3f17489311a91681e52b7ff5..bf610ede1232d18239f210d32db88466350c5aca 100644
--- a/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
+++ b/src/main/java/net/minecraft/world/entity/animal/horse/AbstractHorse.java
@@ -658,6 +658,14 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
}
+ // Paper Start - Horse API
+ public void setMouthOpen(boolean open) {
+ this.setFlag(FLAG_OPEN_MOUTH, open);
+ }
+ public boolean isMouthOpen() {
+ return this.getFlag(FLAG_OPEN_MOUTH);
+ }
+ // Paper End - Horse API
private void openMouth() {
if (!this.level.isClientSide) {
this.mouthCounter = 1;
@@ -670,6 +678,11 @@ public abstract class AbstractHorse extends Animal implements ContainerListener,
this.setFlag(16, eatingGrass);
}
+ // Paper Start - Horse API
+ public void setForceStanding(boolean standing) {
+ this.setFlag(FLAG_STANDING, standing);
+ }
+ // Paper End - Horse API
public void setStanding(boolean angry) {
if (angry) {
this.setEating(false);
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
index 69c95644b2531c1fe1c4a6cf7fee12e997dd67f4..ff2bbdfd01b8fbcae6630184d5bc5954f13a8f2e 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftAbstractHorse.java
@@ -105,4 +105,36 @@ public abstract class CraftAbstractHorse extends CraftAnimals implements Abstrac
public AbstractHorseInventory getInventory() {
return new CraftSaddledInventory(getHandle().inventory);
}
+
+ // Paper start - Horse API
+ @Override
+ public boolean isEatingGrass() {
+ return this.getHandle().isEating();
+ }
+
+ @Override
+ public void setEatingGrass(boolean eating) {
+ this.getHandle().setEating(eating);
+ }
+
+ @Override
+ public boolean isRearing() {
+ return this.getHandle().isStanding();
+ }
+
+ @Override
+ public void setRearing(boolean rearing) {
+ this.getHandle().setForceStanding(rearing);
+ }
+
+ @Override
+ public boolean isEating() {
+ return this.getHandle().isMouthOpen();
+ }
+
+ @Override
+ public void setEating(boolean eating) {
+ this.getHandle().setMouthOpen(eating);
+ }
+ // Paper end - Horse API
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
index a4f909123de26d911aea7cd767d2315ed1f697c9..0eee53c068bca070a86645d0ba54fb1ad49a6a5b 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftCat.java
@@ -49,4 +49,25 @@ public class CraftCat extends CraftTameableAnimal implements Cat {
public void setCollarColor(DyeColor color) {
this.getHandle().setCollarColor(net.minecraft.world.item.DyeColor.byId(color.getWoolData()));
}
+ // Paper Start - More cat api
+ @Override
+ public void setLyingDown(boolean lyingDown) {
+ this.getHandle().setLying(lyingDown);
+ }
+
+ @Override
+ public boolean isLyingDown() {
+ return this.getHandle().isLying();
+ }
+
+ @Override
+ public void setHeadUp(boolean headUp) {
+ this.getHandle().setRelaxStateOne(headUp);
+ }
+
+ @Override
+ public boolean isHeadUp() {
+ return this.getHandle().isRelaxStateOne();
+ }
+ // Paper End - More cat api
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
index b647a5b9fdc1da61c4035d6f2cef7814033dc608..9795341efa748c2d94567e882cd5f26adf0f1591 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftFox.java
@@ -114,4 +114,45 @@ public class CraftFox extends CraftAnimals implements Fox {
this.getHandle().getEntityData().set(net.minecraft.world.entity.animal.Fox.DATA_TRUSTED_ID_1, player == null ? Optional.empty() : Optional.of(player.getUniqueId()));
}
+ // Paper start - Add more fox behavior API
+ @Override
+ public void setInterested(boolean interested) {
+ this.getHandle().setIsInterested(interested);
+ }
+
+ @Override
+ public boolean isInterested() {
+ return this.getHandle().isInterested();
+ }
+
+ @Override
+ public void setLeaping(boolean leaping) {
+ this.getHandle().setIsPouncing(leaping);
+ }
+
+ @Override
+ public boolean isLeaping() {
+ return this.getHandle().isPouncing();
+ }
+
+ @Override
+ public void setDefending(boolean defending) {
+ this.getHandle().setDefending(defending);
+ }
+
+ @Override
+ public boolean isDefending() {
+ return this.getHandle().isDefending();
+ }
+
+ @Override
+ public void setFaceplanted(boolean faceplanted) {
+ this.getHandle().setFaceplanted(faceplanted);
+ }
+
+ @Override
+ public boolean isFaceplanted() {
+ return this.getHandle().isFaceplanted();
+ }
+ // Paper end - Add more fox behavior API
}

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 b9f1384d742d612dd4d40929dfe812e5ebba4371..373280eed4acd146a3c71d944030382bc3c5067e 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1099,7 +1099,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
// 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,27 +0,0 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Professor Bloodstone <git@bloodstone.dev>
Date: Sun, 20 Jun 2021 01:14:41 +0200
Subject: [PATCH] Add git branch and commit to manifest
diff --git a/build.gradle.kts b/build.gradle.kts
index 1e4e3c6fbac820fa03e2a6f5d76c008d5879d2e6..c7ebad49e04c36c27341cabc4a024f170d762f3f 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -69,6 +69,7 @@ tasks.jar {
val gitHash = git("rev-parse", "--short=7", "HEAD").getText().trim()
val implementationVersion = System.getenv("BUILD_NUMBER") ?: "\"$gitHash\""
val date = git("show", "-s", "--format=%ci", gitHash).getText().trim() // Paper
+ val gitBranch = git("rev-parse", "--abbrev-ref", "HEAD").getText().trim() // Paper
attributes(
"Main-Class" to "org.bukkit.craftbukkit.Main",
"Implementation-Title" to "CraftBukkit",
@@ -78,6 +79,8 @@ tasks.jar {
"Specification-Version" to project.version,
"Specification-Vendor" to "Bukkit Team",
"Multi-Release" to "true", // Paper
+ "Git-Branch" to gitBranch, // Paper
+ "Git-Commit" to gitHash, // Paper
)
for (tld in setOf("net", "com", "org")) {
attributes("$tld/bukkit", "Sealed" to true)

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 ea1fa9758fcaa87de11b84d5a2e1d36b0e8930ee..e3944d0f4fd18ef6c545dc4a131c0b120dff753a 100644
--- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
+++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java
@@ -517,7 +517,7 @@ public class CraftBlock implements Block {
Direction direction = CraftBlock.blockFaceToNotch(face);
UseOnContext context = new UseOnContext(this.getCraftWorld().getHandle(), null, InteractionHand.MAIN_HAND, Items.BONE_MEAL.getDefaultInstance(), new BlockHitResult(Vec3.ZERO, direction, this.getPosition(), false));
- return BoneMealItem.applyBonemeal(context) == InteractionResult.SUCCESS;
+ return BoneMealItem.applyBonemeal(context) == InteractionResult.CONSUME; // Paper - CONSUME is returned on success server-side (see BoneMealItem.applyBoneMeal and InteractionResult.sidedSuccess(boolean))
}
@Override

View file

@ -1,62 +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 5f28cca2793cc9b9c795033e112043d89642c858..43a740eb644629bf88d60d7ab559793a1965f9d8 100644
--- a/src/main/java/net/minecraft/server/level/ServerLevel.java
+++ b/src/main/java/net/minecraft/server/level/ServerLevel.java
@@ -203,7 +203,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
}
// Paper start
diff --git a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
index d4f0fcff776012841798a0962207e2cb951ac28e..d40c4c491c4ce19b59cb095cdb5f5e83373356f1 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -1310,7 +1310,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
speed = this.player.getAbilities().walkingSpeed * 10f;
}
// Paper start - Prevent moving into unloaded chunks
- if (player.level.paperConfig.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && !worldserver.hasChunk((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4)) {
+ if (player.level.paperConfig.preventMovingIntoUnloadedChunks && (this.player.getX() != toX || this.player.getZ() != toZ) && worldserver.getChunkIfLoadedImmediately((int) Math.floor(toX) >> 4, (int) Math.floor(toZ) >> 4) == null) { // Paper - use getIfLoadedImmediately
this.internalTeleport(this.player.getX(), this.player.getY(), this.player.getZ(), this.player.getYRot(), this.player.getXRot(), Collections.emptySet(), true);
return;
}
diff --git a/src/main/java/net/minecraft/world/level/Level.java b/src/main/java/net/minecraft/world/level/Level.java
index 4dae0525be49bedadd75276c2668209b602ff967..d0cfa782498eca8a13ce7d7f28d5e55ae4e402fa 100644
--- a/src/main/java/net/minecraft/world/level/Level.java
+++ b/src/main/java/net/minecraft/world/level/Level.java
@@ -193,6 +193,13 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
return (CraftServer) Bukkit.getServer();
}
+ // Paper start
+ @Override
+ public boolean hasChunk(int chunkX, int chunkZ) {
+ return ((ServerLevel) this).getChunkIfLoaded(chunkX, chunkZ) != null;
+ }
+ // Paper end
+
public ResourceKey<DimensionType> getTypeKey() {
return this.typeKey;
}
@@ -1362,7 +1369,7 @@ public abstract class Level implements LevelAccessor, AutoCloseable {
for (int l1 = j; l1 <= l; ++l1) {
for (int i2 = k; i2 <= i1; ++i2) {
- LevelChunk chunk = this.getChunkSource().getChunkNow(l1, i2);
+ LevelChunk chunk = (LevelChunk) this.getChunkIfLoadedImmediately(l1, i2); // Paper
if (chunk != null) {
for (int j2 = j1; j2 <= k1; ++j2) {

View file

@ -1,141 +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/com/destroystokyo/paper/PaperWorldConfig.java b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
index d40d6ead65bd0f6ae64155ee7960245fd0e72b77..37cb74b27763db6f4a6a68030f88c37fc731affc 100644
--- a/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
+++ b/src/main/java/com/destroystokyo/paper/PaperWorldConfig.java
@@ -894,5 +894,10 @@ public class PaperWorldConfig {
private void fixInvulnerableEndCrystalExploit() {
fixInvulnerableEndCrystalExploit = getBoolean("unsupported-settings.fix-invulnerable-end-crystal-exploit", fixInvulnerableEndCrystalExploit);
}
+
+ public boolean showSignClickCommandFailureMessagesToPlayer = false;
+ private void showSignClickCommandFailureMessagesToPlayer() {
+ showSignClickCommandFailureMessagesToPlayer = getBoolean("show-sign-click-command-failure-msgs-to-player", showSignClickCommandFailureMessagesToPlayer);
+ }
}
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..1f6747d7a4c33f0ee7b0dc2120081bb87a855d35
--- /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 sendMessage(Component message, UUID sender) {
+ delegate.sendMessage(message, sender);
+ }
+
+ @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 9b5d11ece006d7aa893360a84ba652c666517ac1..344d3a8c1162f1a4ab5fc2b7676680ddace46649 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
@@ -41,6 +41,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);
@@ -227,7 +228,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().performCommand(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) net.minecraft.server.MCUtil.toBukkitBlock(this.level, this.worldPosition).getState());
+ if (!event.callEvent()) {
+ return false;
+ }
+ player.getServer().getCommands().performCommand(this.createCommandSourceStack(((org.bukkit.craftbukkit.entity.CraftPlayer) event.getPlayer()).getHandle()), event.getMessage());
+ // Paper end
}
}
@@ -263,8 +274,21 @@ public class SignBlockEntity extends BlockEntity implements CommandSource { // C
String s = player == null ? "Sign" : player.getName().getString();
Object object = player == null ? new TextComponent("Sign") : player.getDisplayName();
+ // Paper start - send messages back to the player
+ CommandSource commandSource = this.level.paperConfig.showSignClickCommandFailureMessagesToPlayer ? new io.papermc.paper.commands.DelegatingCommandSource(this) {
+ @Override
+ public void sendMessage(net.minecraft.network.chat.Component message, java.util.UUID sender) {
+ player.sendMessage(message, sender);
+ }
+
+ @Override
+ public boolean acceptsFailure() {
+ return true;
+ }
+ } : this;
+ // Paper end
// CraftBukkit - this
- return new CommandSourceStack(this, Vec3.atCenterOf((Vec3i) this.worldPosition), Vec2.ZERO, (ServerLevel) this.level, 2, s, (Component) object, this.level.getServer(), player);
+ return new CommandSourceStack(commandSource, Vec3.atCenterOf((Vec3i) 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 0bba36d18d56a4dc2d6c6fb7969e5e6f0e1da404..a246a0bd9e57fb0703ba756e8aa1109f1674c0e8 100644
--- a/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
+++ b/src/main/java/org/bukkit/craftbukkit/command/BukkitCommandWrapper.java
@@ -50,7 +50,7 @@ public class BukkitCommandWrapper implements com.mojang.brigadier.Command<Comman
@Override
public int run(CommandContext<CommandSourceStack> context) throws CommandSyntaxException {
- return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getInput()) ? 1 : 0;
+ return this.server.dispatchCommand(context.getSource().getBukkitSender(), context.getRange().get(context.getInput())) ? 1 : 0; // Paper - actually use the StringRange from context
}
@Override

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 e639cbdf9cf070e749da4c90ff475b250ab8e2c9..cdfdad5932f0e03a41cddd8cb7acb0ede43a6a3d 100644
--- a/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
+++ b/src/main/java/net/minecraft/server/network/ServerGamePacketListenerImpl.java
@@ -2225,7 +2225,7 @@ public class ServerGamePacketListenerImpl implements ServerPlayerConnection, Ser
}
// Arm swing animation
- PlayerAnimationEvent event = new PlayerAnimationEvent(this.getCraftPlayer());
+ 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;