From 1e76d09fad502bf33504afe8c10a6f39cb0df239 Mon Sep 17 00:00:00 2001 From: Phoenix616 Date: Fri, 14 Aug 2020 08:26:40 +1000 Subject: [PATCH] #724: Re-implement player portal event search radius and creation API This also fixes that the nether/end portals would be created even if the event was cancelled as well as that the EntityPortalEvent would be called for player portal usage which is not according to its API specification --- nms-patches/BlockPortalShape.patch | 13 +- nms-patches/Entity.patch | 120 +++++++++------- nms-patches/EntityPlayer.patch | 130 ++++++++++-------- nms-patches/ShapeDetectorShape.patch | 13 +- .../craftbukkit/event/CraftEventFactory.java | 16 --- .../craftbukkit/event/CraftPortalEvent.java | 53 +++++++ 6 files changed, 215 insertions(+), 130 deletions(-) create mode 100644 src/main/java/org/bukkit/craftbukkit/event/CraftPortalEvent.java diff --git a/nms-patches/BlockPortalShape.patch b/nms-patches/BlockPortalShape.patch index 392adc9ca1..ed6ae3c035 100644 --- a/nms-patches/BlockPortalShape.patch +++ b/nms-patches/BlockPortalShape.patch @@ -7,7 +7,7 @@ +// CraftBukkit start +import org.bukkit.craftbukkit.block.CraftBlock; +import org.bukkit.craftbukkit.block.CraftBlockState; -+import org.bukkit.event.entity.EntityPortalEnterEvent; ++import org.bukkit.craftbukkit.event.CraftPortalEvent; +import org.bukkit.event.world.PortalCreateEvent; +// CraftBukkit end + @@ -62,11 +62,20 @@ } public boolean c() { +@@ -194,7 +221,7 @@ + return new Vec3D(d2, d3, d4); + } + +- public static ShapeDetectorShape a(WorldServer worldserver, BlockUtil.Rectangle blockutil_rectangle, EnumDirection.EnumAxis enumdirection_enumaxis, Vec3D vec3d, EntitySize entitysize, Vec3D vec3d1, float f, float f1) { ++ public static ShapeDetectorShape a(WorldServer worldserver, BlockUtil.Rectangle blockutil_rectangle, EnumDirection.EnumAxis enumdirection_enumaxis, Vec3D vec3d, EntitySize entitysize, Vec3D vec3d1, float f, float f1, CraftPortalEvent portalEventInfo) { // CraftBukkit // PAIL rename toDetectorShape + BlockPosition blockposition = blockutil_rectangle.origin; + IBlockData iblockdata = worldserver.getType(blockposition); + EnumDirection.EnumAxis enumdirection_enumaxis1 = (EnumDirection.EnumAxis) iblockdata.get(BlockProperties.E); @@ -208,6 +235,6 @@ boolean flag = enumdirection_enumaxis1 == EnumDirection.EnumAxis.X; Vec3D vec3d3 = new Vec3D((double) blockposition.getX() + (flag ? d2 : d4), (double) blockposition.getY() + d3, (double) blockposition.getZ() + (flag ? d4 : d2)); - return new ShapeDetectorShape(vec3d3, vec3d2, f + (float) i, f1); -+ return new ShapeDetectorShape(vec3d3, vec3d2, f + (float) i, f1, worldserver); // CraftBukkit ++ return new ShapeDetectorShape(vec3d3, vec3d2, f + (float) i, f1, worldserver, portalEventInfo); // CraftBukkit } } diff --git a/nms-patches/Entity.patch b/nms-patches/Entity.patch index 3af43eea2e..5e65cebe41 100644 --- a/nms-patches/Entity.patch +++ b/nms-patches/Entity.patch @@ -1,14 +1,16 @@ --- a/net/minecraft/server/Entity.java +++ b/net/minecraft/server/Entity.java -@@ -21,8 +21,56 @@ +@@ -21,8 +21,58 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +// CraftBukkit start +import org.bukkit.Bukkit; ++import org.bukkit.Location; +import org.bukkit.Server; +import org.bukkit.block.BlockFace; +import org.bukkit.command.CommandSender; ++import org.bukkit.craftbukkit.event.CraftPortalEvent; +import org.bukkit.entity.Hanging; +import org.bukkit.entity.LivingEntity; +import org.bukkit.entity.Vehicle; @@ -57,7 +59,7 @@ protected static final Logger LOGGER = LogManager.getLogger(); private static final AtomicInteger entityCount = new AtomicInteger(); private static final List c = Collections.emptyList(); -@@ -106,6 +154,20 @@ +@@ -106,6 +156,20 @@ private long aB; private EntitySize size; private float headHeight; @@ -78,7 +80,7 @@ public Entity(EntityTypes entitytypes, World world) { this.id = Entity.entityCount.incrementAndGet(); -@@ -212,6 +274,12 @@ +@@ -212,6 +276,12 @@ } public void setPose(EntityPose entitypose) { @@ -91,7 +93,7 @@ this.datawatcher.set(Entity.POSE, entitypose); } -@@ -228,6 +296,33 @@ +@@ -228,6 +298,33 @@ } protected void setYawPitch(float f, float f1) { @@ -125,7 +127,7 @@ this.yaw = f % 360.0F; this.pitch = f1 % 360.0F; } -@@ -235,6 +330,7 @@ +@@ -235,6 +332,7 @@ public void setPosition(double d0, double d1, double d2) { this.setPositionRaw(d0, d1, d2); this.a(this.size.a(d0, d1, d2)); @@ -133,7 +135,7 @@ } protected void ae() { -@@ -249,6 +345,15 @@ +@@ -249,6 +347,15 @@ this.entityBaseTick(); } @@ -149,7 +151,7 @@ public void entityBaseTick() { this.world.getMethodProfiler().enter("entityBaseTick"); if (this.isPassenger() && this.getVehicle().dead) { -@@ -262,7 +367,7 @@ +@@ -262,7 +369,7 @@ this.z = this.A; this.lastPitch = this.pitch; this.lastYaw = this.yaw; @@ -158,7 +160,7 @@ if (this.aN()) { this.aO(); } -@@ -325,12 +430,44 @@ +@@ -325,12 +432,44 @@ protected void burnFromLava() { if (!this.isFireProof()) { @@ -204,7 +206,7 @@ int j = i * 20; if (this instanceof EntityLiving) { -@@ -427,6 +564,28 @@ +@@ -427,6 +566,28 @@ block.a((IBlockAccess) this.world, this); } @@ -233,7 +235,7 @@ if (this.onGround && !this.bu()) { block.stepOn(this.world, blockposition, this); } -@@ -700,6 +859,7 @@ +@@ -700,6 +861,7 @@ AxisAlignedBB axisalignedbb = this.getBoundingBox(); this.setPositionRaw((axisalignedbb.minX + axisalignedbb.maxX) / 2.0D, axisalignedbb.minY, (axisalignedbb.minZ + axisalignedbb.maxZ) / 2.0D); @@ -241,7 +243,7 @@ } protected SoundEffect getSoundSwim() { -@@ -1025,6 +1185,13 @@ +@@ -1025,6 +1187,13 @@ } public void spawnIn(World world) { @@ -255,7 +257,7 @@ this.world = world; } -@@ -1044,6 +1211,7 @@ +@@ -1044,6 +1213,7 @@ this.lastY = d1; this.lastZ = d4; this.setPosition(d3, d1, d4); @@ -263,7 +265,7 @@ } public void d(Vec3D vec3d) { -@@ -1218,6 +1386,12 @@ +@@ -1218,6 +1388,12 @@ return false; } @@ -276,7 +278,7 @@ public void a(Entity entity, int i, DamageSource damagesource) { if (entity instanceof EntityPlayer) { CriterionTriggers.c.a((EntityPlayer) entity, this, damagesource); -@@ -1228,7 +1402,7 @@ +@@ -1228,7 +1404,7 @@ public boolean a_(NBTTagCompound nbttagcompound) { String s = this.getSaveID(); @@ -285,7 +287,7 @@ nbttagcompound.setString("id", s); this.save(nbttagcompound); return true; -@@ -1252,6 +1426,18 @@ +@@ -1252,6 +1428,18 @@ Vec3D vec3d = this.getMot(); nbttagcompound.set("Motion", this.a(vec3d.x, vec3d.y, vec3d.z)); @@ -304,7 +306,7 @@ nbttagcompound.set("Rotation", this.a(this.yaw, this.pitch)); nbttagcompound.setFloat("FallDistance", this.fallDistance); nbttagcompound.setShort("Fire", (short) this.fireTicks); -@@ -1260,6 +1446,12 @@ +@@ -1260,6 +1448,12 @@ nbttagcompound.setBoolean("Invulnerable", this.invulnerable); nbttagcompound.setInt("PortalCooldown", this.portalCooldown); nbttagcompound.a("UUID", this.getUniqueID()); @@ -317,7 +319,7 @@ IChatBaseComponent ichatbasecomponent = this.getCustomName(); if (ichatbasecomponent != null) { -@@ -1317,6 +1509,11 @@ +@@ -1317,6 +1511,11 @@ } } @@ -329,7 +331,7 @@ return nbttagcompound; } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Saving entity NBT"); -@@ -1394,6 +1591,43 @@ +@@ -1394,6 +1593,43 @@ } else { throw new IllegalStateException("Entity has invalid position"); } @@ -373,7 +375,7 @@ } catch (Throwable throwable) { CrashReport crashreport = CrashReport.a(throwable, "Loading entity NBT"); CrashReportSystemDetails crashreportsystemdetails = crashreport.a("Entity being loaded"); -@@ -1469,9 +1703,22 @@ +@@ -1469,9 +1705,22 @@ } else if (this.world.isClientSide) { return null; } else { @@ -396,7 +398,7 @@ this.world.addEntity(entityitem); return entityitem; } -@@ -1555,7 +1802,7 @@ +@@ -1555,7 +1804,7 @@ this.setPose(EntityPose.STANDING); this.vehicle = entity; @@ -405,7 +407,7 @@ return true; } } -@@ -1580,7 +1827,7 @@ +@@ -1580,7 +1829,7 @@ Entity entity = this.vehicle; this.vehicle = null; @@ -414,7 +416,7 @@ } } -@@ -1589,10 +1836,31 @@ +@@ -1589,10 +1838,31 @@ this.be(); } @@ -447,7 +449,7 @@ if (!this.world.isClientSide && entity instanceof EntityHuman && !(this.getRidingPassenger() instanceof EntityHuman)) { this.passengers.add(0, entity); } else { -@@ -1600,15 +1868,36 @@ +@@ -1600,15 +1870,36 @@ } } @@ -485,7 +487,7 @@ } protected boolean q(Entity entity) { -@@ -1649,11 +1938,17 @@ +@@ -1649,11 +1940,17 @@ ResourceKey resourcekey = this.world.getDimensionKey() == World.THE_NETHER ? World.OVERWORLD : World.THE_NETHER; WorldServer worldserver1 = minecraftserver.getWorldServer(resourcekey); @@ -505,7 +507,7 @@ this.world.getMethodProfiler().exit(); } -@@ -1753,6 +2048,13 @@ +@@ -1753,6 +2050,13 @@ } public void setSwimming(boolean flag) { @@ -519,7 +521,7 @@ this.setFlag(4, flag); } -@@ -1813,16 +2115,56 @@ +@@ -1813,16 +2117,56 @@ } public void setAirTicks(int i) { @@ -554,9 +556,8 @@ + this.setOnFire(entityCombustEvent.getDuration(), false); + } + // CraftBukkit end - } - -- this.damageEntity(DamageSource.LIGHTNING, 5.0F); ++ } ++ + // CraftBukkit start + if (thisBukkitEntity instanceof Hanging) { + HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity); @@ -565,8 +566,9 @@ + if (hangingEvent.isCancelled()) { + return; + } -+ } -+ + } + +- this.damageEntity(DamageSource.LIGHTNING, 5.0F); + if (this.isFireProof()) { + return; + } @@ -579,7 +581,7 @@ } public void k(boolean flag) { -@@ -1972,15 +2314,32 @@ +@@ -1972,15 +2316,32 @@ @Nullable public Entity b(WorldServer worldserver) { @@ -601,7 +603,7 @@ + // CraftBukkit end this.world.getMethodProfiler().enter("reposition"); - ShapeDetectorShape shapedetectorshape = this.a(worldserver); -+ ShapeDetectorShape shapedetectorshape = (location == null) ? this.a(worldserver) : new ShapeDetectorShape(new Vec3D(location.getX(), location.getY(), location.getZ()), Vec3D.a, this.yaw, this.pitch, worldserver); // CraftBukkit ++ ShapeDetectorShape shapedetectorshape = (location == null) ? this.a(worldserver) : new ShapeDetectorShape(new Vec3D(location.getX(), location.getY(), location.getZ()), Vec3D.a, this.yaw, this.pitch, worldserver, null); // CraftBukkit if (shapedetectorshape == null) { return null; @@ -614,7 +616,7 @@ this.world.getMethodProfiler().exitEnter("reloading"); Entity entity = this.getEntityType().a((World) worldserver); -@@ -1989,9 +2348,17 @@ +@@ -1989,9 +2350,17 @@ entity.setPositionRotation(shapedetectorshape.position.x, shapedetectorshape.position.y, shapedetectorshape.position.z, shapedetectorshape.yaw, entity.pitch); entity.setMot(shapedetectorshape.velocity); worldserver.addEntityTeleport(entity); @@ -622,19 +624,19 @@ - WorldServer.a(worldserver); + if (worldserver.getTypeKey() == DimensionManager.THE_END) { // CraftBukkit + WorldServer.a(worldserver, this); // CraftBukkit - } ++ } + // CraftBukkit start - Forward the CraftEntity to the new entity + this.getBukkitEntity().setHandle(entity); + entity.bukkitEntity = this.getBukkitEntity(); + + if (this instanceof EntityInsentient) { + ((EntityInsentient) this).unleash(true, false); // Unleash to prevent duping of leads. -+ } + } + // CraftBukkit end } this.bM(); -@@ -2012,13 +2379,18 @@ +@@ -2012,13 +2381,18 @@ @Nullable protected ShapeDetectorShape a(WorldServer worldserver) { @@ -644,8 +646,8 @@ + if (worldserver == null) { + return null; + } -+ boolean flag = this.world.getTypeKey() == DimensionManager.THE_END && worldserver.getTypeKey() == DimensionManager.OVERWORLD; -+ boolean flag1 = worldserver.getTypeKey() == DimensionManager.THE_END; ++ boolean flag = this.world.getTypeKey() == DimensionManager.THE_END && worldserver.getTypeKey() == DimensionManager.OVERWORLD; // fromEndToOverworld ++ boolean flag1 = worldserver.getTypeKey() == DimensionManager.THE_END; // targetIsEnd + // CraftBukkit end if (!flag && !flag1) { @@ -657,67 +659,79 @@ return null; } else { WorldBorder worldborder = worldserver.getWorldBorder(); -@@ -2028,8 +2400,17 @@ +@@ -2028,8 +2402,16 @@ double d3 = Math.min(2.9999872E7D, worldborder.h() - 16.0D); double d4 = DimensionManager.a(this.world.getDimensionManager(), worldserver.getDimensionManager()); BlockPosition blockposition = new BlockPosition(MathHelper.a(this.locX() * d4, d0, d2), this.locY(), MathHelper.a(this.locZ() * d4, d1, d3)); + // CraftBukkit start -+ EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, blockposition, 128); ++ CraftPortalEvent event = callPortalEvent(this, worldserver, blockposition, PlayerTeleportEvent.TeleportCause.NETHER_PORTAL, flag2 ? 16 : 128, 16); + if (event == null) { + return null; + } + final WorldServer worldserverFinal = worldserver = ((CraftWorld) event.getTo().getWorld()).getHandle(); + blockposition = new BlockPosition(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); -+ int searchRadius = event.getSearchRadius(); -+ // CraftBukkit end - return (ShapeDetectorShape) this.a(worldserver, blockposition, flag2).map((blockutil_rectangle) -> { -+ return (ShapeDetectorShape) this.a(worldserver, blockposition, flag2, searchRadius).map((blockutil_rectangle) -> { ++ return (ShapeDetectorShape) this.a(worldserver, blockposition, flag2, event.getSearchRadius(), event.getCanCreatePortal(), event.getCreationRadius()).map((blockutil_rectangle) -> { ++ // CraftBukkit end IBlockData iblockdata = this.world.getType(this.ac); EnumDirection.EnumAxis enumdirection_enumaxis; Vec3D vec3d; -@@ -2046,8 +2427,8 @@ +@@ -2046,8 +2428,8 @@ vec3d = new Vec3D(0.5D, 0.0D, 0.0D); } - return BlockPortalShape.a(worldserver, blockutil_rectangle, enumdirection_enumaxis, vec3d, this.a(this.getPose()), this.getMot(), this.yaw, this.pitch); - }).orElse((Object) null); -+ return BlockPortalShape.a(worldserverFinal, blockutil_rectangle, enumdirection_enumaxis, vec3d, this.a(this.getPose()), this.getMot(), this.yaw, this.pitch); // CraftBukkit ++ return BlockPortalShape.a(worldserverFinal, blockutil_rectangle, enumdirection_enumaxis, vec3d, this.a(this.getPose()), this.getMot(), this.yaw, this.pitch, event); // CraftBukkit + }).orElse(null); // CraftBuukkit - decompile error } } else { BlockPosition blockposition1; -@@ -2057,8 +2438,15 @@ +@@ -2057,8 +2439,15 @@ } else { blockposition1 = worldserver.getHighestBlockYAt(HeightMap.Type.MOTION_BLOCKING_NO_LEAVES, worldserver.getSpawn()); } + // CraftBukkit start -+ EntityPortalEvent event = CraftEventFactory.callEntityPortalEvent(this, worldserver, blockposition1, 0); ++ CraftPortalEvent event = callPortalEvent(this, worldserver, blockposition1, PlayerTeleportEvent.TeleportCause.END_PORTAL, 0, 0); + if (event == null) { + return null; + } + blockposition1 = new BlockPosition(event.getTo().getX(), event.getTo().getY(), event.getTo().getZ()); - return new ShapeDetectorShape(new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D), this.getMot(), this.yaw, this.pitch); -+ return new ShapeDetectorShape(new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D), this.getMot(), this.yaw, this.pitch, ((CraftWorld) event.getTo().getWorld()).getHandle()); ++ return new ShapeDetectorShape(new Vec3D((double) blockposition1.getX() + 0.5D, (double) blockposition1.getY(), (double) blockposition1.getZ() + 0.5D), this.getMot(), this.yaw, this.pitch, ((CraftWorld) event.getTo().getWorld()).getHandle(), null); + // CraftBukkit end } } -@@ -2066,8 +2454,10 @@ +@@ -2066,8 +2455,23 @@ return BlockPortalShape.a(blockutil_rectangle, enumdirection_enumaxis, this.getPositionVector(), this.a(this.getPose())); } - protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag) { - return worldserver.getTravelAgent().findPortal(blockposition, flag); + // CraftBukkit start -+ protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag, int radius) { -+ return worldserver.getTravelAgent().findPortal(blockposition, radius); ++ protected CraftPortalEvent callPortalEvent(Entity entity, WorldServer exitWorldServer, BlockPosition exitPosition, PlayerTeleportEvent.TeleportCause cause, int searchRadius, int creationRadius) { ++ org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); ++ Location enter = bukkitEntity.getLocation(); ++ Location exit = new Location(exitWorldServer.getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ()); ++ ++ EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius); ++ event.getEntity().getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) { ++ return null; ++ } ++ return new CraftPortalEvent(event); ++ } ++ ++ protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag, int searchRadius, boolean canCreatePortal, int createRadius) { // PAIL rename findOrCreatePortal ++ return worldserver.getTravelAgent().findPortal(blockposition, searchRadius); + // CraftBukkit end } public boolean canPortal() { -@@ -2253,7 +2643,26 @@ +@@ -2253,7 +2657,26 @@ } public void a(AxisAlignedBB axisalignedbb) { diff --git a/nms-patches/EntityPlayer.patch b/nms-patches/EntityPlayer.patch index 0ad2db146b..18748ffe34 100644 --- a/nms-patches/EntityPlayer.patch +++ b/nms-patches/EntityPlayer.patch @@ -5,7 +5,6 @@ import org.apache.logging.log4j.Logger; +// CraftBukkit start -+import com.google.common.base.Preconditions; +import org.bukkit.Bukkit; +import org.bukkit.GameMode; +import org.bukkit.Location; @@ -13,6 +12,7 @@ +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; +import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.event.CraftPortalEvent; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.event.inventory.InventoryType; +import org.bukkit.event.player.PlayerChangedMainHandEvent; @@ -58,8 +58,8 @@ + this.displayName = this.getName(); + this.canPickUpLoot = true; + this.maxHealthCache = this.getMaxHealth(); - } - ++ } ++ + // Yes, this doesn't match Vanilla, but it's the best we can do for now. + // If this is an issue, PRs are welcome + public final BlockPosition getSpawnPoint(WorldServer worldserver) { @@ -96,9 +96,9 @@ + } + + return blockposition; -+ } + } + // CraftBukkit end -+ + private void c(WorldServer worldserver) { BlockPosition blockposition = worldserver.getSpawn(); @@ -370,7 +370,7 @@ Vec3D vec3d = shapedetectorshape.position.add(0.0D, -1.0D, 0.0D); - return new ShapeDetectorShape(vec3d, Vec3D.a, 90.0F, 0.0F); -+ return new ShapeDetectorShape(vec3d, Vec3D.a, 90.0F, 0.0F, worldserver); // CraftBukkit ++ return new ShapeDetectorShape(vec3d, Vec3D.a, 90.0F, 0.0F, worldserver, shapedetectorshape.portalEventInfo); // CraftBukkit } else { return shapedetectorshape; } @@ -407,7 +407,7 @@ WorldData worlddata = worldserver.getWorldData(); this.playerConnection.sendPacket(new PacketPlayOutRespawn(worldserver.getDimensionManager(), worldserver.getDimensionKey(), BiomeManager.a(worldserver.getSeed()), this.playerInteractManager.getGameMode(), this.playerInteractManager.c(), worldserver.isDebugWorld(), worldserver.isFlatWorld(), true)); -@@ -575,22 +780,65 @@ +@@ -575,22 +780,52 @@ playerlist.d(this); worldserver1.removePlayer(this); this.dead = false; @@ -423,36 +423,21 @@ + if (resourcekey == DimensionManager.OVERWORLD && worldserver.getTypeKey() == DimensionManager.THE_NETHER) { // CraftBukkit this.ci = this.getPositionVector(); - } else if (worldserver.getDimensionKey() == World.THE_END) { -+ } else if (worldserver.getTypeKey() == DimensionManager.THE_END) { // CraftBukkit ++ } else if (worldserver.getTypeKey() == DimensionManager.THE_END && shapedetectorshape.portalEventInfo != null && shapedetectorshape.portalEventInfo.getCanCreatePortal()) { // CraftBukkit this.a(worldserver, new BlockPosition(shapedetectorshape.position)); } + // CraftBukkit start ++ } else { ++ return null; + } + Location enter = this.getBukkitEntity().getLocation(); + Location exit = (worldserver == null) ? null : new Location(worldserver.getWorld(), shapedetectorshape.position.x, shapedetectorshape.position.y, shapedetectorshape.position.z, shapedetectorshape.yaw, shapedetectorshape.pitch); -+ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, resourcekey == DimensionManager.THE_END ? 0 : 16); -+ Bukkit.getServer().getPluginManager().callEvent(event); -+ if (event.isCancelled() || event.getTo() == null) { -+ return null; -+ } - -- worldserver1.getMethodProfiler().exit(); -- worldserver1.getMethodProfiler().enter("placing"); -+ exit = event.getTo(); -+ if (exit == null) { -+ return null; -+ } -+ + PlayerTeleportEvent tpEvent = new PlayerTeleportEvent(this.getBukkitEntity(), enter, exit, cause); + Bukkit.getServer().getPluginManager().callEvent(tpEvent); + if (tpEvent.isCancelled() || tpEvent.getTo() == null) { + return null; + } -+ + exit = tpEvent.getTo(); -+ if (exit == null) { -+ return null; -+ } + worldserver = ((CraftWorld) exit.getWorld()).getHandle(); + // CraftBukkit end + @@ -468,7 +453,9 @@ + playerlist.d(this); + worldserver1.removePlayer(this); + this.dead = false; -+ + +- worldserver1.getMethodProfiler().exit(); +- worldserver1.getMethodProfiler().enter("placing"); + // CraftBukkit end this.spawnIn(worldserver); worldserver.addPlayerPortal(this); @@ -479,7 +466,7 @@ worldserver1.getMethodProfiler().exit(); this.triggerDimensionAdvancements(worldserver1); this.playerInteractManager.a(worldserver); -@@ -609,6 +857,11 @@ +@@ -609,12 +844,31 @@ this.lastSentExp = -1; this.lastHealthSent = -1.0F; this.lastFoodSent = -1; @@ -491,18 +478,46 @@ } return this; -@@ -631,8 +884,8 @@ + } + } + ++ // CraftBukkit start ++ @Override ++ protected CraftPortalEvent callPortalEvent(Entity entity, WorldServer exitWorldServer, BlockPosition exitPosition, TeleportCause cause, int searchRadius, int creationRadius) { ++ Location enter = this.getBukkitEntity().getLocation(); ++ Location exit = new Location(exitWorldServer.getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ(), yaw, pitch); ++ PlayerPortalEvent event = new PlayerPortalEvent(this.getBukkitEntity(), enter, exit, cause, 128, true, creationRadius); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null) { ++ return null; ++ } ++ return new CraftPortalEvent(event); ++ } ++ // CraftBukkit end ++ + private void a(WorldServer worldserver, BlockPosition blockposition) { + BlockPosition.MutableBlockPosition blockposition_mutableblockposition = blockposition.i(); + +@@ -631,14 +885,14 @@ } @Override - protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag) { - Optional optional = super.a(worldserver, blockposition, flag); -+ protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag, int radius) { // CraftBukkit -+ Optional optional = super.a(worldserver, blockposition, flag, radius); // CraftBukkit ++ protected Optional a(WorldServer worldserver, BlockPosition blockposition, boolean flag, int searchRadius, boolean canCreatePortal, int createRadius) { // CraftBukkit // PAIL rename findOrCreatePortal ++ Optional optional = super.a(worldserver, blockposition, flag, searchRadius, canCreatePortal, createRadius); // CraftBukkit - if (optional.isPresent()) { +- if (optional.isPresent()) { ++ if (optional.isPresent() || !canCreatePortal) { // CraftBukkit return optional; -@@ -685,10 +938,8 @@ + } else { + EnumDirection.EnumAxis enumdirection_enumaxis = (EnumDirection.EnumAxis) this.world.getType(this.ac).d(BlockPortal.AXIS).orElse(EnumDirection.EnumAxis.X); +- Optional optional1 = worldserver.getTravelAgent().createPortal(blockposition, enumdirection_enumaxis); ++ Optional optional1 = worldserver.getTravelAgent().createPortal(blockposition, enumdirection_enumaxis, this, createRadius); // CraftBukkit + + if (!optional1.isPresent()) { + EntityPlayer.LOGGER.error("Unable to create a portal, likely target out of worldborder"); +@@ -685,10 +939,8 @@ this.activeContainer.c(); } @@ -515,7 +530,7 @@ if (!this.isSleeping() && this.isAlive()) { if (!this.world.getDimensionManager().isNatural()) { return Either.left(EntityHuman.EnumBedResult.NOT_POSSIBLE_HERE); -@@ -714,7 +965,36 @@ +@@ -714,7 +966,36 @@ } } @@ -553,7 +568,7 @@ this.a(StatisticList.SLEEP_IN_BED); CriterionTriggers.q.a(this); }); -@@ -723,9 +1003,8 @@ +@@ -723,9 +1004,8 @@ return either; } } @@ -564,7 +579,7 @@ } @Override -@@ -752,6 +1031,7 @@ +@@ -752,6 +1032,7 @@ @Override public void wakeup(boolean flag, boolean flag1) { @@ -572,7 +587,7 @@ if (this.isSleeping()) { this.getWorldServer().getChunkProvider().broadcastIncludingSelf(this, new PacketPlayOutAnimation(this, 2)); } -@@ -823,8 +1103,9 @@ +@@ -823,8 +1104,9 @@ this.playerConnection.sendPacket(new PacketPlayOutOpenSignEditor(tileentitysign.getPosition())); } @@ -583,7 +598,7 @@ } @Override -@@ -839,6 +1120,24 @@ +@@ -839,6 +1121,24 @@ this.nextContainerCounter(); Container container = itileinventory.createMenu(this.containerCounter, this.inventory, this); @@ -608,7 +623,7 @@ if (container == null) { if (this.isSpectator()) { this.a((IChatBaseComponent) (new ChatMessage("container.spectatorCantOpen")).a(EnumChatFormat.RED), true); -@@ -846,9 +1145,11 @@ +@@ -846,9 +1146,11 @@ return OptionalInt.empty(); } else { @@ -622,7 +637,7 @@ return OptionalInt.of(this.containerCounter); } } -@@ -861,13 +1162,24 @@ +@@ -861,13 +1163,24 @@ @Override public void openHorseInventory(EntityHorseAbstract entityhorseabstract, IInventory iinventory) { @@ -649,7 +664,7 @@ this.activeContainer.addSlotListener(this); } -@@ -912,6 +1224,11 @@ +@@ -912,6 +1225,11 @@ public void a(Container container, NonNullList nonnulllist) { this.playerConnection.sendPacket(new PacketPlayOutWindowItems(container.windowId, nonnulllist)); this.playerConnection.sendPacket(new PacketPlayOutSetSlot(-1, -1, this.inventory.getCarried())); @@ -661,7 +676,7 @@ } @Override -@@ -921,6 +1238,7 @@ +@@ -921,6 +1239,7 @@ @Override public void closeInventory() { @@ -669,7 +684,7 @@ this.playerConnection.sendPacket(new PacketPlayOutCloseWindow(this.activeContainer.windowId)); this.o(); } -@@ -955,7 +1273,7 @@ +@@ -955,7 +1274,7 @@ @Override public void a(Statistic statistic, int i) { this.serverStatisticManager.b(this, statistic, i); @@ -678,7 +693,7 @@ scoreboardscore.addScore(i); }); } -@@ -963,7 +1281,7 @@ +@@ -963,7 +1282,7 @@ @Override public void a(Statistic statistic) { this.serverStatisticManager.setStatistic(this, statistic, 0); @@ -687,24 +702,25 @@ } @Override -@@ -1012,7 +1330,16 @@ +@@ -1012,8 +1331,17 @@ public void triggerHealthUpdate() { this.lastHealthSent = -1.0E8F; + this.lastSentExp = -1; // CraftBukkit - Added to reset -+ } -+ + } + + // CraftBukkit start - Support multi-line messages + public void sendMessage(IChatBaseComponent[] ichatbasecomponent) { + for (IChatBaseComponent component : ichatbasecomponent) { + this.sendMessage(component, SystemUtils.b); + } - } ++ } + // CraftBukkit end - ++ @Override public void a(IChatBaseComponent ichatbasecomponent, boolean flag) { -@@ -1065,12 +1392,13 @@ + this.playerConnection.sendPacket(new PacketPlayOutChat(ichatbasecomponent, flag ? ChatMessageType.GAME_INFO : ChatMessageType.CHAT, SystemUtils.b)); +@@ -1065,12 +1393,13 @@ this.lastSentExp = -1; this.lastHealthSent = -1.0F; this.lastFoodSent = -1; @@ -719,7 +735,7 @@ } @Override -@@ -1138,6 +1466,18 @@ +@@ -1138,6 +1467,18 @@ @Override public void a(EnumGamemode enumgamemode) { @@ -738,7 +754,7 @@ this.playerInteractManager.setGameMode(enumgamemode); this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(PacketPlayOutGameStateChange.d, (float) enumgamemode.getId())); if (enumgamemode == EnumGamemode.SPECTATOR) { -@@ -1187,7 +1527,20 @@ +@@ -1187,7 +1528,20 @@ return s; } @@ -759,7 +775,7 @@ this.bY = packetplayinsettings.d(); this.bZ = packetplayinsettings.e(); this.getDataWatcher().set(EntityPlayer.bi, (byte) packetplayinsettings.f()); -@@ -1223,13 +1576,13 @@ +@@ -1223,13 +1577,13 @@ if (entity instanceof EntityHuman) { this.playerConnection.sendPacket(new PacketPlayOutEntityDestroy(new int[]{entity.getId()})); } else { @@ -775,7 +791,7 @@ } @Override -@@ -1253,7 +1606,7 @@ +@@ -1253,7 +1607,7 @@ this.spectatedEntity = (Entity) (entity == null ? this : entity); if (entity1 != this.spectatedEntity) { this.playerConnection.sendPacket(new PacketPlayOutCamera(this.spectatedEntity)); @@ -784,7 +800,7 @@ } } -@@ -1282,7 +1635,7 @@ +@@ -1282,7 +1636,7 @@ @Nullable public IChatBaseComponent getPlayerListName() { @@ -793,7 +809,7 @@ } @Override -@@ -1303,9 +1656,16 @@ +@@ -1303,9 +1657,16 @@ return this.advancementDataPlayer; } @@ -810,7 +826,7 @@ if (worldserver == this.world) { this.playerConnection.a(d0, d1, d2, f, f1); } else { -@@ -1326,6 +1686,9 @@ +@@ -1326,6 +1687,9 @@ this.server.getPlayerList().a(this, worldserver); this.server.getPlayerList().updateClient(this); } @@ -820,7 +836,7 @@ } -@@ -1418,4 +1781,144 @@ +@@ -1418,4 +1782,144 @@ return entityitem; } } diff --git a/nms-patches/ShapeDetectorShape.patch b/nms-patches/ShapeDetectorShape.patch index 7d2311667f..a728f1c733 100644 --- a/nms-patches/ShapeDetectorShape.patch +++ b/nms-patches/ShapeDetectorShape.patch @@ -1,15 +1,24 @@ --- a/net/minecraft/server/ShapeDetectorShape.java +++ b/net/minecraft/server/ShapeDetectorShape.java -@@ -6,8 +6,12 @@ +@@ -1,13 +1,21 @@ + package net.minecraft.server; + ++import org.bukkit.craftbukkit.event.CraftPortalEvent; // CraftBukkit ++ + public class ShapeDetectorShape { + + public final Vec3D position; public final Vec3D velocity; public final float yaw; public final float pitch; + // CraftBukkit start + public final WorldServer world; ++ public final CraftPortalEvent portalEventInfo; - public ShapeDetectorShape(Vec3D vec3d, Vec3D vec3d1, float f, float f1) { -+ public ShapeDetectorShape(Vec3D vec3d, Vec3D vec3d1, float f, float f1, WorldServer world) { ++ public ShapeDetectorShape(Vec3D vec3d, Vec3D vec3d1, float f, float f1, WorldServer world, CraftPortalEvent portalEventInfo) { + this.world = world; ++ this.portalEventInfo = portalEventInfo; + // CraftBukkit end this.position = vec3d; this.velocity = vec3d1; diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java index 29294f91b0..cc4e05bb52 100644 --- a/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java @@ -1572,22 +1572,6 @@ public class CraftEventFactory { Bukkit.getPluginManager().callEvent(event); } - /** - * EntityPortalEvent - */ - public static EntityPortalEvent callEntityPortalEvent(Entity entity, World exitWorld, BlockPosition exitPosition, int searchRadius) { - org.bukkit.entity.Entity bukkitEntity = entity.getBukkitEntity(); - Location enter = bukkitEntity.getLocation(); - Location exit = new Location(exitWorld.getWorld(), exitPosition.getX(), exitPosition.getY(), exitPosition.getZ()); - - EntityPortalEvent event = new EntityPortalEvent(bukkitEntity, enter, exit, searchRadius); - event.getEntity().getServer().getPluginManager().callEvent(event); - if (event.isCancelled() || event.getTo() == null || event.getTo().getWorld() == null || !entity.isAlive()) { - return null; - } - return event; - } - public static LootGenerateEvent callLootGenerateEvent(IInventory inventory, LootTable lootTable, LootTableInfo lootInfo, List loot, boolean plugin) { CraftWorld world = lootInfo.getWorld().getWorld(); Entity entity = lootInfo.getContextParameter(LootContextParameters.THIS_ENTITY); diff --git a/src/main/java/org/bukkit/craftbukkit/event/CraftPortalEvent.java b/src/main/java/org/bukkit/craftbukkit/event/CraftPortalEvent.java new file mode 100644 index 0000000000..7732350d43 --- /dev/null +++ b/src/main/java/org/bukkit/craftbukkit/event/CraftPortalEvent.java @@ -0,0 +1,53 @@ +package org.bukkit.craftbukkit.event; + +import org.bukkit.Location; +import org.bukkit.event.entity.EntityPortalEvent; +import org.bukkit.event.player.PlayerPortalEvent; + +/** + * Helper class to hold information from the {@link PlayerPortalEvent} and {@link EntityPortalEvent} + */ +public class CraftPortalEvent { + private final Location to; + private final int searchRadius; + private final int creationRadius; + + private final boolean canCreatePortal; + private final boolean cancelled; + + public CraftPortalEvent(EntityPortalEvent portalEvent) { + to = portalEvent.getTo(); + searchRadius = portalEvent.getSearchRadius(); + cancelled = portalEvent.isCancelled(); + creationRadius = 0; + canCreatePortal = false; + } + + public CraftPortalEvent(PlayerPortalEvent portalEvent) { + to = portalEvent.getTo(); + searchRadius = portalEvent.getSearchRadius(); + creationRadius = portalEvent.getCreationRadius(); + canCreatePortal = portalEvent.getCanCreatePortal(); + cancelled = portalEvent.isCancelled(); + } + + public Location getTo() { + return to; + } + + public int getSearchRadius() { + return searchRadius; + } + + public int getCreationRadius() { + return creationRadius; + } + + public boolean getCanCreatePortal() { + return canCreatePortal; + } + + public boolean isCancelled() { + return cancelled; + } +}