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; + } +}