From 634b639098c864318deef91fc6abf3fbb72739f5 Mon Sep 17 00:00:00 2001 From: Aikar Date: Tue, 15 Aug 2017 22:29:12 -0400 Subject: [PATCH] Expand World.spawnParticle API and add Builder Adds ability to control who receives it and who is the source/sender (vanish API) the standard API is to send the packet to everyone in the world, which is ineffecient. Adds an option to control the force mode of the particle. This adds a new Builder API which is much friendlier to use. --- .../server/level/ServerLevel.java.patch | 50 +++++++++++-------- .../org/bukkit/craftbukkit/CraftWorld.java | 13 ++++- 2 files changed, 41 insertions(+), 22 deletions(-) diff --git a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch index 55464c27e..f5c9852fc 100644 --- a/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch +++ b/paper-server/patches/sources/net/minecraft/server/level/ServerLevel.java.patch @@ -543,13 +543,13 @@ - return this.addEntity(entity); + // CraftBukkit start + return this.addWithUUID(entity, CreatureSpawnEvent.SpawnReason.DEFAULT); - } - ++ } ++ + public boolean addWithUUID(Entity entity, CreatureSpawnEvent.SpawnReason reason) { + return this.addEntity(entity, reason); + // CraftBukkit end -+ } -+ + } + public void addDuringTeleport(Entity entity) { + // CraftBukkit start + // SPIGOT-6415: Don't call spawn event for entities which travel trough worlds, @@ -733,14 +733,15 @@ case NONE: explosion_effect = Explosion.BlockInteraction.KEEP; break; -@@ -1144,16 +1444,26 @@ +@@ -1143,17 +1443,27 @@ + break; case TRIGGER: explosion_effect = Explosion.BlockInteraction.TRIGGER_BLOCK; - break; ++ break; + // CraftBukkit start - handle custom explosion type + case STANDARD: + explosion_effect = Explosion.BlockInteraction.DESTROY; -+ break; + break; + // CraftBukkit end default: throw new MatchException((String) null, (Throwable) null); @@ -776,7 +777,7 @@ } private Explosion.BlockInteraction getDestroyType(GameRules.Key decayRule) { -@@ -1226,17 +1537,24 @@ +@@ -1226,17 +1537,29 @@ } public int sendParticles(T parameters, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double speed) { @@ -791,12 +792,19 @@ + + // CraftBukkit start - visibility api support + public int sendParticlesSource(ServerPlayer sender, T t0, boolean flag, boolean flag1, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) { ++ // Paper start - Particle API ++ return this.sendParticlesSource(this.players, sender, t0, flag, flag1, d0, d1, d2, i, d3, d4, d5, d6); ++ } ++ public int sendParticlesSource(List receivers, @Nullable ServerPlayer sender, T t0, boolean flag, boolean flag1, double d0, double d1, double d2, int i, double d3, double d4, double d5, double d6) { ++ // Paper end - Particle API + // CraftBukkit end + ClientboundLevelParticlesPacket packetplayoutworldparticles = new ClientboundLevelParticlesPacket(t0, flag, flag1, d0, d1, d2, (float) d3, (float) d4, (float) d5, (float) d6, i); int j = 0; - for (int k = 0; k < this.players.size(); ++k) { - ServerPlayer entityplayer = (ServerPlayer) this.players.get(k); +- for (int k = 0; k < this.players.size(); ++k) { +- ServerPlayer entityplayer = (ServerPlayer) this.players.get(k); ++ for (Player entityhuman : receivers) { // Paper - Particle API ++ ServerPlayer entityplayer = (ServerPlayer) entityhuman; // Paper - Particle API + if (sender != null && !entityplayer.getBukkitEntity().canSee(sender.getBukkitEntity())) continue; // CraftBukkit - if (this.sendParticles(entityplayer, force, x, y, z, packetplayoutworldparticles)) { @@ -804,7 +812,7 @@ ++j; } } -@@ -1292,7 +1610,7 @@ +@@ -1292,7 +1615,7 @@ @Nullable public BlockPos findNearestMapStructure(TagKey structureTag, BlockPos pos, int radius, boolean skipReferencedStructures) { @@ -813,7 +821,7 @@ return null; } else { Optional> optional = this.registryAccess().lookupOrThrow(Registries.STRUCTURE).get(structureTag); -@@ -1334,11 +1652,22 @@ +@@ -1334,11 +1657,22 @@ @Nullable @Override public MapItemSavedData getMapData(MapId id) { @@ -837,7 +845,7 @@ this.getServer().overworld().getDataStorage().set(id.key(), state); } -@@ -1649,6 +1978,11 @@ +@@ -1649,6 +1983,11 @@ @Override public void blockUpdated(BlockPos pos, Block block) { if (!this.isDebug()) { @@ -849,7 +857,7 @@ this.updateNeighborsAt(pos, block); } -@@ -1668,12 +2002,12 @@ +@@ -1668,12 +2007,12 @@ } public boolean isFlat() { @@ -864,7 +872,7 @@ } @Nullable -@@ -1696,7 +2030,7 @@ +@@ -1696,7 +2035,7 @@ private static String getTypeCount(Iterable items, Function classifier) { try { Object2IntOpenHashMap object2intopenhashmap = new Object2IntOpenHashMap(); @@ -873,7 +881,7 @@ while (iterator.hasNext()) { T t0 = iterator.next(); -@@ -1705,7 +2039,7 @@ +@@ -1705,7 +2044,7 @@ object2intopenhashmap.addTo(s, 1); } @@ -882,7 +890,7 @@ String s1 = (String) entry.getKey(); return s1 + ":" + entry.getIntValue(); -@@ -1717,6 +2051,7 @@ +@@ -1717,6 +2056,7 @@ @Override public LevelEntityGetter getEntities() { @@ -890,7 +898,7 @@ return this.entityManager.getEntityGetter(); } -@@ -1802,6 +2137,17 @@ +@@ -1802,6 +2142,17 @@ return this.serverLevelData.getGameRules(); } @@ -908,7 +916,7 @@ @Override public CrashReportCategory fillReportDetails(CrashReport report) { CrashReportCategory crashreportsystemdetails = super.fillReportDetails(report); -@@ -1836,6 +2182,7 @@ +@@ -1836,6 +2187,7 @@ } public void onTrackingStart(Entity entity) { @@ -916,7 +924,7 @@ ServerLevel.this.getChunkSource().addEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.add(entityplayer); -@@ -1864,9 +2211,52 @@ +@@ -1864,9 +2216,52 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::add); @@ -969,7 +977,7 @@ ServerLevel.this.getChunkSource().removeEntity(entity); if (entity instanceof ServerPlayer entityplayer) { ServerLevel.this.players.remove(entityplayer); -@@ -1895,6 +2285,15 @@ +@@ -1895,6 +2290,15 @@ } entity.updateDynamicGameEventListener(DynamicGameEventListener::remove); diff --git a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index cf38f7505..a403507c0 100644 --- a/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/paper-server/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -1989,8 +1989,19 @@ public class CraftWorld extends CraftRegionAccessor implements World { @Override public void spawnParticle(Particle particle, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { + // Paper start - Particle API + this.spawnParticle(particle, null, null, x, y, z, count, offsetX, offsetY, offsetZ, extra, data, force); + } + @Override + public void spawnParticle(Particle particle, List receivers, Player sender, double x, double y, double z, int count, double offsetX, double offsetY, double offsetZ, double extra, T data, boolean force) { + // Paper end - Particle API + data = CraftParticle.convertLegacy(data); + if (data != null) { + Preconditions.checkArgument(particle.getDataType().isInstance(data), "data (%s) should be %s", data.getClass(), particle.getDataType()); + } this.getHandle().sendParticlesSource( - null, // Sender + receivers == null ? this.getHandle().players() : receivers.stream().map(player -> ((CraftPlayer) player).getHandle()).collect(java.util.stream.Collectors.toList()), // Paper - Particle API + sender != null ? ((CraftPlayer) sender).getHandle() : null, // Sender // Paper - Particle API CraftParticle.createParticleParam(particle, data), // Particle false, force, x, y, z, // Position