From 73b101005b4849e0c704037264bc4e2829644a95 Mon Sep 17 00:00:00 2001
From: MeFisto94 <MeFisto94@users.noreply.github.com>
Date: Fri, 28 Aug 2020 01:41:26 +0200
Subject: [PATCH] Expose the Entity Counter to allow plugins to use valid and
 non-conflicting Entity Ids

---
 .../minecraft/world/entity/Entity.java.patch  | 75 ++++++++++---------
 .../craftbukkit/util/CraftMagicNumbers.java   |  5 ++
 2 files changed, 46 insertions(+), 34 deletions(-)

diff --git a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
index d7aa4caa5e..d950e667de 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/Entity.java.patch
@@ -61,7 +61,7 @@
 +// CraftBukkit end
  
  public abstract class Entity implements SyncedDataHolder, Nameable, EntityAccess, ScoreHolder {
-+
+ 
 +    // CraftBukkit start
 +    private static final int CURRENT_LEVEL = 2;
 +    public boolean preserveMotion = true; // Paper - Fix Entity Teleportation and cancel velocity if teleported; keep initial motion on first setPositionRotation
@@ -151,7 +151,7 @@
 +        }
 +        return this.bukkitEntity;
 +    }
- 
++
 +    // CraftBukkit - SPIGOT-6907: re-implement LivingEntity#setMaximumAir()
 +    public int getDefaultMaxAirSupply() {
 +        return Entity.TOTAL_AIR_SUPPLY;
@@ -170,7 +170,7 @@
      private static final EntityDataAccessor<Integer> DATA_TICKS_FROZEN = SynchedEntityData.defineId(Entity.class, EntityDataSerializers.INT);
      private EntityInLevelCallback levelCallback;
      private final VecDeltaCodec packetPositionCodec;
-@@ -253,7 +386,65 @@
+@@ -253,6 +386,64 @@
      private final List<Entity.Movement> movementThisTick;
      private final Set<BlockState> blocksInside;
      private final LongSet visitedBlocks;
@@ -203,7 +203,7 @@
 +    private org.bukkit.util.Vector origin;
 +    @javax.annotation.Nullable
 +    private UUID originWorld;
- 
++
 +    public void setOrigin(@javax.annotation.Nonnull Location location) {
 +        this.origin = location.toVector();
 +        this.originWorld = location.getWorld().getUID();
@@ -232,10 +232,9 @@
 +        return this.dimensions.makeBoundingBox(x, y, z);
 +    }
 +    // Paper end
-+
+ 
      public Entity(EntityType<?> type, Level world) {
          this.id = Entity.ENTITY_COUNTER.incrementAndGet();
-         this.passengers = ImmutableList.of();
 @@ -261,7 +452,7 @@
          this.bb = Entity.INITIAL_AABB;
          this.stuckSpeedMultiplier = Vec3.ZERO;
@@ -521,13 +520,10 @@
      }
  
      public boolean isFree(double offsetX, double offsetY, double offsetZ) {
-@@ -747,8 +1050,30 @@
+@@ -750,6 +1053,28 @@
+                     }
+                 }
  
-                     if (movement.y != vec3d1.y) {
-                         block.updateEntityMovementAfterFallOn(this.level(), this);
-+                    }
-+                }
-+
 +                // CraftBukkit start
 +                if (this.horizontalCollision && this.getBukkitEntity() instanceof Vehicle) {
 +                    Vehicle vehicle = (Vehicle) this.getBukkitEntity();
@@ -546,23 +542,22 @@
 +                    if (!bl.getType().isAir()) {
 +                        VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, bl);
 +                        this.level.getCraftServer().getPluginManager().callEvent(event);
-                     }
-                 }
++                    }
++                }
 +                // CraftBukkit end
- 
++
                  if (!this.level().isClientSide() || this.isControlledByLocalInstance()) {
                      Entity.MovementEmission entity_movementemission = this.getMovementEmission();
-@@ -1131,8 +1456,22 @@
  
-     protected SoundEvent getSwimHighSpeedSplashSound() {
+@@ -1133,6 +1458,20 @@
          return SoundEvents.GENERIC_SPLASH;
-+    }
-+
+     }
+ 
 +    // CraftBukkit start - Add delegate methods
 +    public SoundEvent getSwimSound0() {
 +        return this.getSwimSound();
-     }
- 
++    }
++
 +    public SoundEvent getSwimSplashSound0() {
 +        return this.getSwimSplashSound();
 +    }
@@ -620,20 +615,19 @@
          this.hasImpulse = true;
      }
  
-@@ -1859,7 +2220,13 @@
- 
-     public boolean isPushable() {
+@@ -1861,6 +2222,12 @@
          return false;
-+    }
-+
+     }
+ 
 +    // CraftBukkit start - collidable API
 +    public boolean canCollideWithBukkit(Entity entity) {
 +        return this.isPushable();
-     }
++    }
 +    // CraftBukkit end
- 
++
      public void awardKillScore(Entity entityKilled, DamageSource damageSource) {
          if (entityKilled instanceof ServerPlayer) {
+             CriteriaTriggers.ENTITY_KILLED_PLAYER.trigger((ServerPlayer) entityKilled, this, damageSource);
 @@ -1889,16 +2256,22 @@
      }
  
@@ -837,10 +831,11 @@
          } catch (Throwable throwable) {
              CrashReport crashreport = CrashReport.forThrowable(throwable, "Saving entity NBT");
              CrashReportCategory crashreportsystemdetails = crashreport.addCategory("Entity being saved");
-@@ -2080,6 +2521,68 @@
+@@ -2079,7 +2520,69 @@
+                 }
              } else {
                  throw new IllegalStateException("Entity has invalid position");
-             }
++            }
 +
 +            // CraftBukkit start
 +            // Spigot start
@@ -863,7 +858,7 @@
 +                boolean bukkitInvisible = nbt.getBoolean("Bukkit.invisible");
 +                this.setInvisible(bukkitInvisible);
 +                this.persistentInvisibility = bukkitInvisible;
-+            }
+             }
 +            // CraftBukkit end
 +
 +            // Paper start
@@ -1478,10 +1473,11 @@
          return new Vec3(this.getX(), this.getBoundingBox().maxY, this.getZ());
      }
  
-@@ -3489,8 +4217,37 @@
+@@ -3488,9 +4216,38 @@
+     public int getFireImmuneTicks() {
          return 1;
      }
- 
++
 +    // CraftBukkit start
 +    private final CommandSource commandSource = new CommandSource() {
 +
@@ -1510,7 +1506,7 @@
 +        }
 +    };
 +    // CraftBukkit end
-+
+ 
      public CommandSourceStack createCommandSourceStackForNameResolution(ServerLevel world) {
 -        return new CommandSourceStack(CommandSource.NULL, this.position(), this.getRotationVector(), world, 0, this.getName().getString(), this.getDisplayName(), world.getServer(), this);
 +        return new CommandSourceStack(this.commandSource, this.position(), this.getRotationVector(), world, 0, this.getName().getString(), this.getDisplayName(), world.getServer(), this); // CraftBukkit
@@ -1619,3 +1615,14 @@
  
          if (entityliving instanceof Player entityhuman) {
              if (this.isAlive()) {
+@@ -3962,4 +4760,10 @@
+ 
+         void accept(Entity entity, double x, double y, double z);
+     }
++
++    // Paper start - Expose entity id counter
++    public static int nextEntityId() {
++        return ENTITY_COUNTER.incrementAndGet();
++    }
++    // Paper end - Expose entity id counter
+ }
diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
index 1e41803952..78bc460fff 100644
--- a/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
+++ b/paper-server/src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java
@@ -527,6 +527,11 @@ public final class CraftMagicNumbers implements UnsafeValues {
         Preconditions.checkArgument(dataVersion <= getDataVersion(), "Newer version! Server downgrades are not supported!");
         return compound;
     }
+
+    @Override
+    public int nextEntityId() {
+        return net.minecraft.world.entity.Entity.nextEntityId();
+    }
     // Paper end
 
     /**