Paper/Spigot-Server-Patches/0186-PreCreatureSpawnEvent.patch
Jake Potrebic 899bc53b79
Updated Upstream (Bukkit/CraftBukkit) (#4779)
Upstream has released updates that appears to apply and compile correctly.
This update has not been tested by PaperMC and as with ANY update, please do your own testing

Bukkit Changes:
f47abd88 SPIGOT-6242: Fix some file line endings
de96535b SPIGOT-6234: enum classes don't serialize properly when implementing ConfigurationSerializable

CraftBukkit Changes:
4475707d SPIGOT-6244: /spawnpoint ignores angle
8b3b096d SPIGOT-6242: Fix some file line endings
4b33c749 SPIGOT-6186: Canceling a CreatureSpawnEvent​ results in a "Unable to summon entity due to duplicate UUIDs" error
2b3ca726 SPIGOT-6236: Vehicle passenger portal cooldown does not change
2020-11-17 22:45:18 -05:00

97 lines
5.9 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Aikar <aikar@aikar.co>
Date: Sun, 14 Jan 2018 17:01:31 -0500
Subject: [PATCH] PreCreatureSpawnEvent
Adds an event to fire before an Entity is created, so that plugins that need to cancel
CreatureSpawnEvent can do so from this event instead.
Cancelling CreatureSpawnEvent rapidly causes a lot of garbage collection and CPU waste
as it's done after the Entity object has been fully created.
Mob Limiting plugins and blanket "ban this type of monster" plugins should use this event
instead and save a lot of server resources.
See: https://github.com/PaperMC/Paper/issues/917
diff --git a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
index 34ab03fce7ab5c7702234590ffc9ca7fec72a86a..2827026ba4bdd857f231028393726d6c95610072 100644
--- a/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
+++ b/src/main/java/net/minecraft/server/MobSpawnerAbstract.java
@@ -108,6 +108,27 @@ public abstract class MobSpawnerAbstract {
WorldServer worldserver = (WorldServer) world;
if (EntityPositionTypes.a((EntityTypes) optional.get(), worldserver, EnumMobSpawn.SPAWNER, new BlockPosition(d3, d4, d5), world.getRandom())) {
+ // Paper start
+ EntityTypes<?> entityType = optional.get();
+ String key = EntityTypes.getName(entityType).getKey();
+
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(key);
+ if (type != null) {
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ MCUtil.toLocation(world, d3, d4, d5),
+ type,
+ org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER
+ );
+ if (!event.callEvent()) {
+ flag = true;
+ if (event.shouldAbortSpawn()) {
+ break;
+ }
+ continue;
+ }
+ }
+ // Paper end
Entity entity = EntityTypes.a(nbttagcompound, world, (entity1) -> {
entity1.setPositionRotation(d3, d4, d5, entity1.yaw, entity1.pitch);
return entity1;
diff --git a/src/main/java/net/minecraft/server/SpawnerCreature.java b/src/main/java/net/minecraft/server/SpawnerCreature.java
index 137ee1b453b80e96c1a8fa3271f6350f9294cafb..0ecdfd45073235b7b01e84f4490f17088c4ee675 100644
--- a/src/main/java/net/minecraft/server/SpawnerCreature.java
+++ b/src/main/java/net/minecraft/server/SpawnerCreature.java
@@ -184,9 +184,16 @@ public final class SpawnerCreature {
j1 = biomesettingsmobs_c.d + worldserver.random.nextInt(1 + biomesettingsmobs_c.e - biomesettingsmobs_c.d);
}
- if (a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2) && spawnercreature_c.test(biomesettingsmobs_c.c, blockposition_mutableblockposition, ichunkaccess)) {
+ // Paper start
+ Boolean doSpawning = a(worldserver, enumcreaturetype, structuremanager, chunkgenerator, biomesettingsmobs_c, blockposition_mutableblockposition, d2);
+ if (doSpawning == null) {
+ return;
+ }
+ if (doSpawning && spawnercreature_c.test(biomesettingsmobs_c.c, blockposition_mutableblockposition, ichunkaccess)) {
+ // Paper end
EntityInsentient entityinsentient = a(worldserver, biomesettingsmobs_c.c);
+
if (entityinsentient == null) {
return;
}
@@ -239,8 +246,24 @@ public final class SpawnerCreature {
}
}
- private static boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeSettingsMobs.c biomesettingsmobs_c, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) {
+ private static Boolean a(WorldServer worldserver, EnumCreatureType enumcreaturetype, StructureManager structuremanager, ChunkGenerator chunkgenerator, BiomeSettingsMobs.c biomesettingsmobs_c, BlockPosition.MutableBlockPosition blockposition_mutableblockposition, double d0) { // Paper
EntityTypes<?> entitytypes = biomesettingsmobs_c.c;
+ // Paper start
+ com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent event;
+ org.bukkit.entity.EntityType type = org.bukkit.entity.EntityType.fromName(EntityTypes.getName(entitytypes).getKey());
+ if (type != null) {
+ event = new com.destroystokyo.paper.event.entity.PreCreatureSpawnEvent(
+ MCUtil.toLocation(worldserver, blockposition_mutableblockposition),
+ type, SpawnReason.NATURAL
+ );
+ if (!event.callEvent()) {
+ if (event.shouldAbortSpawn()) {
+ return null;
+ }
+ return false;
+ }
+ }
+ // Paper end
if (entitytypes.e() == EnumCreatureType.MISC) {
return false;