From 15fcde4b3cd170f6f9675fe78532b207b29061a0 Mon Sep 17 00:00:00 2001
From: Jake Potrebic <jake.m.potrebic@gmail.com>
Date: Sat, 9 Dec 2023 19:15:59 -0800
Subject: [PATCH] Fix NPE on null loc for EntityTeleportEvent

EntityTeleportEvent#setTo is marked as nullable and so is the
getTo method. This fixes the handling of a null "to" location
by treating it the same as the event being cancelled. This is
already existing behavior for the EntityPortalEvent (which
extends EntityTeleportEvent).
---
 .../net/minecraft/server/commands/TeleportCommand.java.patch | 5 +++--
 .../net/minecraft/world/entity/LivingEntity.java.patch       | 2 +-
 .../net/minecraft/world/entity/TamableAnimal.java.patch      | 2 +-
 .../net/minecraft/world/entity/monster/Shulker.java.patch    | 2 +-
 4 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/paper-server/patches/sources/net/minecraft/server/commands/TeleportCommand.java.patch b/paper-server/patches/sources/net/minecraft/server/commands/TeleportCommand.java.patch
index dfbc293e60..0126e4d505 100644
--- a/paper-server/patches/sources/net/minecraft/server/commands/TeleportCommand.java.patch
+++ b/paper-server/patches/sources/net/minecraft/server/commands/TeleportCommand.java.patch
@@ -20,7 +20,7 @@
  
  public class TeleportCommand {
  
-@@ -167,7 +173,30 @@
+@@ -167,7 +173,31 @@
              float f4 = Mth.wrapDegrees(f2);
              float f5 = Mth.wrapDegrees(f3);
  
@@ -33,9 +33,10 @@
 +                Location to = new Location(world.getWorld(), d3, d4, d5, f4, f5);
 +                EntityTeleportEvent event = new EntityTeleportEvent(target.getBukkitEntity(), target.getBukkitEntity().getLocation(), to);
 +                world.getCraftServer().getPluginManager().callEvent(event);
-+                if (event.isCancelled()) {
++                if (event.isCancelled() || event.getTo() == null) { // Paper
 +                    return;
 +                }
++                to = event.getTo(); // Paper - actually track new location
 +
 +                d3 = to.getX();
 +                d4 = to.getY();
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
index 10e3db8f32..2ff298a4ec 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/LivingEntity.java.patch
@@ -1856,7 +1856,7 @@
 +                    if (!(this instanceof ServerPlayer)) {
 +                        EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.level().getWorld(), d3, d4, d5), new Location(this.level().getWorld(), d0, d6, d2));
 +                        this.level().getCraftServer().getPluginManager().callEvent(teleport);
-+                        if (!teleport.isCancelled()) {
++                        if (!teleport.isCancelled() && teleport.getTo() != null) { // Paper
 +                            Location to = teleport.getTo();
 +                            this.teleportTo(to.getX(), to.getY(), to.getZ());
 +                        } else {
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch
index bceefeb824..ae8be7d5d0 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/TamableAnimal.java.patch
@@ -74,7 +74,7 @@
 -            this.moveTo((double) x + 0.5D, (double) y, (double) z + 0.5D, this.getYRot(), this.getXRot());
 +            // CraftBukkit start
 +            EntityTeleportEvent event = CraftEventFactory.callEntityTeleportEvent(this, (double) x + 0.5D, (double) y, (double) z + 0.5D);
-+            if (event.isCancelled()) {
++            if (event.isCancelled() || event.getTo() == null) { // Paper - prevent NP on null event to location
 +                return false;
 +            }
 +            Location to = event.getTo();
diff --git a/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch b/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch
index 2d76d4a4aa..9da90964d4 100644
--- a/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch
+++ b/paper-server/patches/sources/net/minecraft/world/entity/monster/Shulker.java.patch
@@ -34,7 +34,7 @@
                      if (enumdirection != null) {
 +                        // CraftBukkit start
 +                        EntityTeleportEvent teleportEvent = CraftEventFactory.callEntityTeleportEvent(this, blockposition1.getX(), blockposition1.getY(), blockposition1.getZ());
-+                        if (teleportEvent.isCancelled()) {
++                        if (teleportEvent.isCancelled() || teleportEvent.getTo() == null) { // Paper
 +                            return false;
 +                        } else {
 +                            blockposition1 = CraftLocation.toBlockPosition(teleportEvent.getTo());