3737import com .viaversion .viaversion .libs .fastutil .objects .Object2IntOpenHashMap ;
3838import com .viaversion .viaversion .protocols .v1_8to1_9 .packet .ClientboundPackets1_8 ;
3939import java .util .ArrayList ;
40+ import java .util .HashSet ;
4041import java .util .List ;
4142import java .util .Map ;
4243import java .util .Objects ;
44+ import java .util .Set ;
4345import java .util .UUID ;
4446import java .util .logging .Level ;
4547
48+ import com .viaversion .viarewind .api .minecraft .entitydata .EntityDataTypes1_7_6_10 ;
49+ import com .viaversion .viarewind .api .type .RewindTypes ;
50+ import com .viaversion .viarewind .protocol .v1_7_6_10to1_7_2_5 .packet .ClientboundPackets1_7_2_5 ;
51+
4652public class EntityTracker1_8 extends EntityTrackerBase {
4753
4854 private final Int2ObjectMap <VirtualHologramEntity > holograms = new Int2ObjectArrayMap <>();
4955 private final Int2IntMap extraHologramIds = new Int2IntArrayMap ();
5056 private final Int2IntMap vehicles = new Int2IntArrayMap ();
5157 private final Int2ObjectMap <UUID > entityIdToUUID = new Int2ObjectArrayMap <>();
5258 private final Object2IntMap <UUID > entityUUIDToId = new Object2IntOpenHashMap <>();
59+ private final Int2IntMap playerNametagHiderEntities = new Int2IntArrayMap ();
5360
5461 private final List <EntityData > entityData = new ArrayList <>();
5562
@@ -78,6 +85,10 @@ public void removeEntity(int entityId) {
7885 holograms .remove (entityId );
7986 }
8087
88+ if (playerNametagHiderEntities .containsKey (entityId )) {
89+ despawnNametagHiderEntity (entityId );
90+ }
91+
8192 if (entityIdToUUID .containsKey (entityId )) {
8293 final UUID playerId = entityIdToUUID .remove (entityId );
8394
@@ -92,6 +103,7 @@ public void clearEntities() {
92103 holograms .clear ();
93104 extraHologramIds .clear ();
94105 vehicles .clear ();
106+ playerNametagHiderEntities .clear ();
95107 }
96108
97109 @ Override
@@ -158,6 +170,11 @@ public void setPassenger(final int vehicleId, final int passengerId) {
158170 } else {
159171 vehicles .put (vehicleId , passengerId );
160172 }
173+
174+ // Re-evaluate nametag visibility when a player entity's passenger changes
175+ if (vehicleId != -1 && entityIdToUUID .containsKey (vehicleId )) {
176+ checkNametagVisibility (vehicleId );
177+ }
161178 }
162179
163180 protected void attachEntity (final int target ) {
@@ -188,6 +205,93 @@ public void setSpectating(int spectating) {
188205 }
189206 }
190207
208+ public void checkNametagVisibility (final int entityId ) {
209+ if (!entityIdToUUID .containsKey (entityId )) {
210+ return ;
211+ }
212+ final boolean shouldHide = isPlayerNametagHidden (entityId );
213+ final boolean hasServerPassenger = getPassenger (entityId ) != -1 ;
214+ final boolean hasSkull = playerNametagHiderEntities .containsKey (entityId );
215+
216+ if (shouldHide && !hasServerPassenger && !hasSkull ) {
217+ spawnNametagHiderEntity (entityId );
218+ } else if ((!shouldHide || hasServerPassenger ) && hasSkull ) {
219+ despawnNametagHiderEntity (entityId );
220+ }
221+ }
222+
223+ public void checkNametagVisbility (final String username ) {
224+ final GameProfileStorage profileStorage = user ().get (GameProfileStorage .class );
225+ final GameProfileStorage .GameProfile profile = profileStorage .get (username , false );
226+ if (profile == null ) {
227+ return ;
228+ }
229+
230+ final int entityId = getPlayerEntityId (profile .uuid );
231+ if (entityId == -1 ) {
232+ return ;
233+ }
234+
235+ checkNametagVisibility (entityId );
236+ }
237+
238+ private boolean isPlayerNametagHidden (final int entityId ) {
239+ final UUID uuid = entityIdToUUID .get (entityId );
240+ if (uuid == null ) {
241+ return false ;
242+ }
243+ final GameProfileStorage profileStorage = user ().get (GameProfileStorage .class );
244+ final GameProfileStorage .GameProfile profile = profileStorage .get (uuid );
245+ if (profile == null ) {
246+ return false ;
247+ }
248+ return user ().get (ScoreboardTracker .class ).isNametagHidden (profile .name );
249+ }
250+
251+ private int getNametagHiderEntityId (final int playerEntityId ) {
252+ return Integer .MAX_VALUE - 32000 - playerEntityId ;
253+ }
254+
255+ private void spawnNametagHiderEntity (final int playerEntityId ) {
256+ final int entityId = getNametagHiderEntityId (playerEntityId );
257+ playerNametagHiderEntities .put (playerEntityId , entityId );
258+
259+ final List <EntityData > mobData = new ArrayList <>();
260+ mobData .add (new EntityData (0 , EntityDataTypes1_7_6_10 .BYTE , (byte ) 0x20 ));
261+ mobData .add (new EntityData (16 , EntityDataTypes1_7_6_10 .BYTE , (byte ) 0 ));
262+
263+ final PacketWrapper spawnMob = PacketWrapper .create (ClientboundPackets1_7_2_5 .ADD_MOB , user ());
264+ spawnMob .write (Types .VAR_INT , entityId );
265+ spawnMob .write (Types .UNSIGNED_BYTE , (short ) EntityTypes1_8 .EntityType .MAGMA_CUBE .getId ());
266+ spawnMob .write (Types .INT , 0 ); // X
267+ spawnMob .write (Types .INT , 0 ); // Y
268+ spawnMob .write (Types .INT , 0 ); // Z
269+ spawnMob .write (Types .BYTE , (byte ) 0 ); // Yaw
270+ spawnMob .write (Types .BYTE , (byte ) 0 ); // Pitch
271+ spawnMob .write (Types .BYTE , (byte ) 0 ); // Head yaw
272+ spawnMob .write (Types .SHORT , (short ) 0 ); // Velocity x
273+ spawnMob .write (Types .SHORT , (short ) 0 ); // Velocity y
274+ spawnMob .write (Types .SHORT , (short ) 0 ); // Velocity z
275+ spawnMob .write (RewindTypes .ENTITY_DATA_LIST1_7 , mobData );
276+ spawnMob .scheduleSend (Protocol1_8To1_7_6_10 .class );
277+
278+ final PacketWrapper attach = PacketWrapper .create (ClientboundPackets1_7_2_5 .SET_ENTITY_LINK , user ());
279+ attach .write (Types .INT , entityId );
280+ attach .write (Types .INT , playerEntityId );
281+ attach .write (Types .BOOLEAN , false );
282+ attach .scheduleSend (Protocol1_8To1_7_6_10 .class );
283+ }
284+
285+ private void despawnNametagHiderEntity (final int playerEntityId ) {
286+ if (!playerNametagHiderEntities .containsKey (playerEntityId )) return ;
287+ final int mobId = playerNametagHiderEntities .remove (playerEntityId );
288+
289+ final PacketWrapper despawn = PacketWrapper .create (ClientboundPackets1_7_2_5 .REMOVE_ENTITIES , user ());
290+ despawn .write (Types .BYTE , (byte ) 1 );
291+ despawn .write (Types .INT , mobId );
292+ despawn .scheduleSend (Protocol1_8To1_7_6_10 .class );
293+ }
294+
191295 public Int2ObjectMap <VirtualHologramEntity > getHolograms () {
192296 return holograms ;
193297 }
0 commit comments