9
0
mirror of https://github.com/BX-Team/DivineMC.git synced 2025-12-19 14:59:25 +00:00
Files
DivineMC/patches/server/0050-Paper-PR-Add-Entity-hidden-by-default-flag.patch
2023-03-21 20:54:44 +03:00

161 lines
8.2 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Justin <justin@justinf.dev>
Date: Wed, 24 Aug 2022 05:17:20 -0700
Subject: [PATCH] Paper PR - Add Entity hidden by default flag
Adds a boolean to the server Entity controlling if the entity should be hidden by default.
The TrackedEntity maintains a set of all players that will be able to see the entity even
when it is hidden by default. This set is modified when Player#showEntity and Player#hideEntity
are invoked. Changes are made to the way that TrackedEntity updates players when the entity is
hidden by default - if a player is not present in the above set, the update is abandoned.
This functionality is expanded when a Player is hidden by default. The player will send out
PlayerInfo packets to hide themselves from other Players when hiddenByDefault. There remains a
discrepancy when trying to getHiddenPlayers - players that are hidden by default are currently
not returned from this method, only those hidden with hideEntity or hidePlayer.
Hiding entities by default also respects precedent of keeping entities hidden when other plugins
explicitly hide them from a player. If an entity is hidden by default and by a plugin, the entity
must have the plugin that hid them from a player show them in order to be shown to a player again.
If no plugin had previously hidden the entity before the entity was hidden by default, then any
plugin that attempts to show the entity to a player will succeed in doing so.
diff --git a/src/main/java/net/minecraft/server/level/ChunkMap.java b/src/main/java/net/minecraft/server/level/ChunkMap.java
index 6ae3f09f01e7ad72d46aeb950cca83b0d2a8d88b..07985de694f76e55f8eef2ac7dca6e404980519d 100644
--- a/src/main/java/net/minecraft/server/level/ChunkMap.java
+++ b/src/main/java/net/minecraft/server/level/ChunkMap.java
@@ -1515,6 +1515,7 @@ public class ChunkMap extends ChunkStorage implements ChunkHolder.PlayerProvider
private final int range;
SectionPos lastSectionPos;
public final Set<ServerPlayerConnection> seenBy = new ReferenceOpenHashSet<>(); // Paper - optimise map impl
+ public final Set<ServerPlayerConnection> showToEvenWhenHiddenByDefault = new ReferenceOpenHashSet<>(); // Paper - Entity hiddenByDefault
public TrackedEntity(Entity entity, int i, int j, boolean flag) {
this.serverEntity = new ServerEntity(ChunkMap.this.level, entity, j, flag, this::broadcast, this.seenBy); // CraftBukkit
diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java
index e273fed8e97c98bf5735d3a8c301968990d4cf32..21d980628bcaf80ed8809122766b626713974ed4 100644
--- a/src/main/java/net/minecraft/world/entity/Entity.java
+++ b/src/main/java/net/minecraft/world/entity/Entity.java
@@ -400,6 +400,7 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource {
private UUID originWorld;
public boolean freezeLocked = false; // Paper - Freeze Tick Lock API
public boolean collidingWithWorldBorder; // Paper
+ public boolean hiddenByDefault; // Paper
public void setOrigin(@javax.annotation.Nonnull Location location) {
this.origin = location.toVector();
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
index 57a0dbb23a32123d30c3b3572f4d129be9d97847..6286431870438767e779f37aef1e6d9dd9fbec65 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java
@@ -1442,4 +1442,30 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity {
return !this.getHandle().level.noCollision(this.getHandle(), aabb);
}
// Paper End - Collision API
+
+ // Paper start - Entity hiddenByDefault
+ @Override
+ public void setHiddenByDefault(boolean hiddenByDefault) {
+ this.getHandle().hiddenByDefault = hiddenByDefault;
+
+ // We need to update the players again
+ ChunkMap.TrackedEntity entityTracker = this.getHandle().tracker;
+
+ // Tracker was not initialized yet
+ if (entityTracker == null) {
+ return;
+ }
+
+ // If the entity is already hiddenByDefault, we reset our "show to" set to again hide the entity from all players that may be seeing the entity
+ // We also clear the "show to" set when we stop hiding by default
+ entityTracker.showToEvenWhenHiddenByDefault.clear();
+
+ entityTracker.updatePlayers(this.server.getHandle().getPlayers());
+ }
+
+ @Override
+ public boolean isHiddenByDefault() {
+ return this.getHandle().hiddenByDefault;
+ }
+ // Paper end
}
diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
index 1bada55af5d16437da4d16f9ded55f88a6121eb4..0fbc2971cdf15799c1f0beb1b3670894c41db9c8 100644
--- a/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
+++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java
@@ -1814,6 +1814,7 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
ChunkMap tracker = ((ServerLevel) this.getHandle().level).getChunkSource().chunkMap;
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
if (entry != null) {
+ entry.showToEvenWhenHiddenByDefault.remove(this.getHandle().connection); // Paper - Entity hiddenByDefault
entry.removePlayer(this.getHandle());
}
@@ -1892,9 +1893,15 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
ChunkMap.TrackedEntity entry = tracker.entityMap.get(other.getId());
- if (entry != null && !entry.seenBy.contains(this.getHandle().connection)) {
- entry.updatePlayer(this.getHandle());
+ // Paper start - Entity hiddenByDefault
+ if (entry != null) {
+ entry.showToEvenWhenHiddenByDefault.add(this.getHandle().connection);
+
+ if (!entry.seenBy.contains(this.getHandle().connection)) {
+ entry.updatePlayer(this.getHandle());
+ }
}
+ // Paper end
server.getPluginManager().callEvent(new PlayerShowEntityEvent(this, entity)); // Paper
}
// Paper start
@@ -1970,7 +1977,16 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
@Override
public boolean canSee(org.bukkit.entity.Entity entity) {
- return entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId());
+ // Paper start - Entity hiddenByDefault
+ boolean shownWhenHiddenByDefault = true;
+
+ if (entity.isHiddenByDefault()) {
+ ChunkMap.TrackedEntity tracker = ((CraftEntity) entity).getHandle().tracker;
+ shownWhenHiddenByDefault = tracker == null || tracker.showToEvenWhenHiddenByDefault.contains(this.getHandle().connection);
+ }
+
+ return shownWhenHiddenByDefault && (entity.isVisibleByDefault() ^ this.invertedVisibilityEntities.containsKey(entity.getUniqueId()));
+ // Paper end
}
public boolean canSee(UUID uuid) {
@@ -3143,6 +3159,30 @@ public class CraftPlayer extends CraftHumanEntity implements Player {
}
// Paper end
+ // Paper start - Entity hiddenByDefault
+ @Override
+ public void setHiddenByDefault(boolean hiddenByDefault) {
+ // Update server lists
+ if (hiddenByDefault) {
+ for (CraftPlayer player : this.server.getOnlinePlayers()) {
+ if (player == this || !player.canSee(this)) continue;
+
+ player.getHandle().connection.send(new ClientboundPlayerInfoRemovePacket(List.of(this.getHandle().getUUID())));
+ }
+ } else {
+ for (CraftPlayer player : this.server.getOnlinePlayers()) {
+ if (player == this || player.canSee(this)) continue;
+
+ player.getHandle().connection.send(new ClientboundPlayerInfoUpdatePacket(ClientboundPlayerInfoUpdatePacket.Action.ADD_PLAYER, this.getHandle()));
+ }
+ }
+
+ // Now, process trackers
+ super.setHiddenByDefault(hiddenByDefault);
+ }
+ // Paper end
+
+
public Player.Spigot spigot()
{
return this.spigot;