From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Shane Freeder <theboyetronic@gmail.com>
Date: Thu, 15 Nov 2018 13:38:37 +0000
Subject: [PATCH] force entity dismount during teleportation

Entities must be dismounted before teleportation in order to avoid
multiple issues in the server with regards to teleportation, shamefully,
too many plugins rely on the events firing, which means that not firing
these events caues more issues than it solves;

In order to counteract this, Entity dismount/exit vehicle events have
been modified to supress cancellation (and has a method to allow plugins
to check if this has been set), noting that cancellation will be silently
surpressed given that plugins are not expecting this event to not be cancellable.

This is a far from ideal scenario, however: given the current state of this
event and other alternatives causing issues elsewhere, I believe that
this is going to be the best soultion all around.

Improvements/suggestions welcome!

diff --git a/src/main/java/net/minecraft/server/level/ServerPlayer.java b/src/main/java/net/minecraft/server/level/ServerPlayer.java
index db7f2715534ed71a2b285de095238586fe6a35b0..f51c416e7938b7905f7efb154ab14cad643962e9 100644
--- a/src/main/java/net/minecraft/server/level/ServerPlayer.java
+++ b/src/main/java/net/minecraft/server/level/ServerPlayer.java
@@ -1323,11 +1323,13 @@ public class ServerPlayer extends Player {
         }
     }
 
-    @Override
-    public void stopRiding() {
+    // Paper start
+    @Override public void stopRiding() { stopRiding(false); }
+    @Override public void stopRiding(boolean suppressCancellation) {
+        // Paper end
         Entity entity = this.getVehicle();
 
-        super.stopRiding();
+        super.stopRiding(suppressCancellation); // Paper
         Entity entity1 = this.getVehicle();
 
         if (entity1 != entity && this.connection != null) {
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index 2981a29b011cb1a08a776abc5ec6a94228061f98..7ec6561722644bfd9dd81d12732eab67c8dd57ae 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -2238,11 +2238,16 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
     }
 
     public void removeVehicle() {
+        // Paper start
+        stopRiding(false);
+    }
+    public void stopRiding(boolean suppressCancellation) {
+        // Paper end
         if (this.vehicle != null) {
             Entity entity = this.vehicle;
 
             this.vehicle = null;
-            if (!entity.removePassenger(this)) this.vehicle = entity; // CraftBukkit
+            if (!entity.removePassenger(this, suppressCancellation)) this.vehicle = entity; // CraftBukkit // Paper
         }
 
     }
@@ -2305,7 +2310,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
         return true; // CraftBukkit
     }
 
-    protected boolean removePassenger(Entity entity) { // CraftBukkit
+    // Paper start
+    protected boolean removePassenger(Entity entity) { return removePassenger(entity, false);}
+    protected boolean removePassenger(Entity entity, boolean suppressCancellation) { // CraftBukkit
+        // Paper end
         if (entity.getVehicle() == this) {
             throw new IllegalStateException("Use x.stopRiding(y), not y.removePassenger(x)");
         } else {
@@ -2315,7 +2323,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
             if (this.getBukkitEntity() instanceof Vehicle && entity.getBukkitEntity() instanceof LivingEntity) {
                 VehicleExitEvent event = new VehicleExitEvent(
                         (Vehicle) this.getBukkitEntity(),
-                        (LivingEntity) entity.getBukkitEntity()
+                        (LivingEntity) entity.getBukkitEntity(), !suppressCancellation // Paper
                 );
                 // Suppress during worldgen
                 if (this.valid) {
@@ -2329,7 +2337,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource, i
             }
             // CraftBukkit end
             // Spigot start
-            org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity());
+            org.spigotmc.event.entity.EntityDismountEvent event = new org.spigotmc.event.entity.EntityDismountEvent(entity.getBukkitEntity(), this.getBukkitEntity(), !suppressCancellation); // Paper
             // Suppress during worldgen
             if (this.valid) {
                 Bukkit.getPluginManager().callEvent(event);
diff --git a/src/main/java/net/minecraft/world/entity/LivingEntity.java b/src/main/java/net/minecraft/world/entity/LivingEntity.java
index ea3d289a859e5f093600ae40baa043599ba2d704..8bdaf925580480a9467b5611e77580bb205c0a4a 100644
--- a/src/main/java/net/minecraft/world/entity/LivingEntity.java
+++ b/src/main/java/net/minecraft/world/entity/LivingEntity.java
@@ -3336,9 +3336,15 @@ public abstract class LivingEntity extends Entity {
 
     @Override
     public void stopRiding() {
+        // Paper start
+        stopRiding(false);
+    }
+    @Override
+    public void stopRiding(boolean suppressCancellation) {
+        // Paper end
         Entity entity = this.getVehicle();
 
-        super.stopRiding();
+        super.stopRiding(suppressCancellation); // Paper - suppress
         if (entity != null && entity != this.getVehicle() && !this.level.isClientSide) {
             this.dismountVehicle(entity);
         }
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 0cd00d0b1017b2995f565ed6a871653a2644ffa1..09bb891fb1274027ea0696a0319816d05d4dc5bc 100644
--- a/src/main/java/net/minecraft/world/entity/player/Player.java
+++ b/src/main/java/net/minecraft/world/entity/player/Player.java
@@ -1094,7 +1094,13 @@ public abstract class Player extends LivingEntity {
 
     @Override
     public void removeVehicle() {
-        super.removeVehicle();
+        // Paper start
+        stopRiding(false);
+    }
+    @Override
+    public void stopRiding(boolean suppressCancellation) {
+        // Paper end
+        super.stopRiding(suppressCancellation); // Paper - suppress
         this.boardingCooldown = 0;
     }
 
