Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,11 @@ public void register() {
map(Types.ENTITY_DATA_LIST1_8, RewindTypes.ENTITY_DATA_LIST1_7); // Entity data

handler(getTrackerAndDataHandler(RewindTypes.ENTITY_DATA_LIST1_7, EntityTypes1_8.EntityType.PLAYER));
handler(wrapper -> {
final int entityId = wrapper.get(Types.VAR_INT, 0);
final EntityTracker1_8 tracker = tracker(wrapper.user());
tracker.checkNametagVisibility(entityId);;
});
}
});
protocol.registerClientbound(ClientboundPackets1_8.SET_EQUIPPED_ITEM, new PacketHandlers() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.Protocol1_8To1_7_6_10;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.EntityTracker1_8;
import com.viaversion.viarewind.protocol.v1_8to1_7_6_10.storage.ScoreboardTracker;
import com.viaversion.viaversion.api.protocol.packet.PacketWrapper;
import com.viaversion.viaversion.api.protocol.remapper.PacketHandlers;
Expand Down Expand Up @@ -173,6 +174,7 @@ public void register() {
}

final ScoreboardTracker scoreboard = wrapper.user().get(ScoreboardTracker.class);
final EntityTracker1_8 tracker = wrapper.user().getEntityTracker(Protocol1_8To1_7_6_10.class);

final byte mode = wrapper.passthrough(Types.BYTE);
if (mode != 0 && !scoreboard.teamExists(team)) {
Expand All @@ -190,6 +192,10 @@ public void register() {
if (mode == 0) {
scoreboard.addTeam(team);
} else if (mode == 1) {
// Team removed, nametag visibility might have changed
for (String member : scoreboard.getTeamMembers(team)) {
tracker.checkNametagVisbility(member);
}
scoreboard.removeTeam(team);
}

Expand All @@ -198,7 +204,9 @@ public void register() {
wrapper.passthrough(Types.STRING); // Prefix
wrapper.passthrough(Types.STRING); // Suffix
wrapper.passthrough(Types.BYTE); // Friendly fire
wrapper.read(Types.STRING); // Name tag visibility
final String nameTagVisibility = wrapper.read(Types.STRING);
final String previousVisibility = scoreboard.getTeamNameTagVisibility(team);
scoreboard.setTeamNameTagVisibility(team, nameTagVisibility);
byte color = wrapper.read(Types.BYTE);
if (mode == 2 && scoreboard.getTeamColor(team).get() != color) {
final String sidebar = scoreboard.getColorDependentSidebar().get(color);
Expand All @@ -209,6 +217,13 @@ public void register() {
sidebarPacket.scheduleSend(Protocol1_8To1_7_6_10.class);
}
scoreboard.setTeamColor(team, color);

// Re-evaluate nametag visibility for all team members when visibility changes
if (mode == 2 && !nameTagVisibility.equals(previousVisibility)) {
for (String member : scoreboard.getTeamMembers(team)) {
tracker.checkNametagVisbility(member);
}
}
}
if (mode == 0 || mode == 3 || mode == 4) {
byte color = scoreboard.getTeamColor(team).get();
Expand All @@ -223,6 +238,8 @@ public void register() {
continue;
}
scoreboard.removePlayerFromTeam(entry, team);
// Player left team, nametag visibility may change
tracker.checkNametagVisbility(entry);
if (entry.equals(username)) {
final PacketWrapper sidebarPacket = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
sidebarPacket.write(Types.BYTE, (byte) 1);
Expand All @@ -231,6 +248,8 @@ public void register() {
}
} else {
scoreboard.addPlayerToTeam(entry, team);
// Player joined team, nametag visibility may change
tracker.checkNametagVisbility(entry);
if (entry.equals(username) && scoreboard.getColorDependentSidebar().containsKey(color)) {
final PacketWrapper displayObjective = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_DISPLAY_OBJECTIVE, wrapper.user());
displayObjective.write(Types.BYTE, (byte) 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,18 +37,25 @@
import com.viaversion.viaversion.libs.fastutil.objects.Object2IntOpenHashMap;
import com.viaversion.viaversion.protocols.v1_8to1_9.packet.ClientboundPackets1_8;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.logging.Level;

import com.viaversion.viarewind.api.minecraft.entitydata.EntityDataTypes1_7_6_10;
import com.viaversion.viarewind.api.type.RewindTypes;
import com.viaversion.viarewind.protocol.v1_7_6_10to1_7_2_5.packet.ClientboundPackets1_7_2_5;

public class EntityTracker1_8 extends EntityTrackerBase {

private final Int2ObjectMap<VirtualHologramEntity> holograms = new Int2ObjectArrayMap<>();
private final Int2IntMap vehicles = new Int2IntArrayMap();
private final Int2ObjectMap<UUID> entityIdToUUID = new Int2ObjectArrayMap<>();
private final Object2IntMap<UUID> entityUUIDToId = new Object2IntOpenHashMap<>();
private final Int2IntMap playerNametagHiderEntities = new Int2IntArrayMap();

private final List<EntityData> entityData = new ArrayList<>();

Expand Down Expand Up @@ -77,6 +84,10 @@ public void removeEntity(int entityId) {
holograms.remove(entityId);
}

if (playerNametagHiderEntities.containsKey(entityId)) {
despawnNametagHiderEntity(entityId);
}

if (entityIdToUUID.containsKey(entityId)) {
final UUID playerId = entityIdToUUID.remove(entityId);

Expand All @@ -89,6 +100,7 @@ public void removeEntity(int entityId) {
public void clearEntities() {
super.clearEntities();
vehicles.clear();
playerNametagHiderEntities.clear();
}

@Override
Expand Down Expand Up @@ -155,6 +167,11 @@ public void setPassenger(final int vehicleId, final int passengerId) {
} else {
vehicles.put(vehicleId, passengerId);
}

// Re-evaluate nametag visibility when a player entity's passenger changes
if (vehicleId != -1 && entityIdToUUID.containsKey(vehicleId)) {
checkNametagVisibility(vehicleId);
}
}

protected void attachEntity(final int target) {
Expand Down Expand Up @@ -185,6 +202,83 @@ public void setSpectating(int spectating) {
}
}

public void checkNametagVisibility(final int entityId) {
if (!entityIdToUUID.containsKey(entityId)) return;
final boolean shouldHide = isPlayerNametagHidden(entityId);
final boolean hasServerPassenger = getPassenger(entityId) != -1;
final boolean hasSkull = playerNametagHiderEntities.containsKey(entityId);

if (shouldHide && !hasServerPassenger && !hasSkull) {
spawnNametagHiderEntity(entityId);
} else if ((!shouldHide || hasServerPassenger) && hasSkull) {
despawnNametagHiderEntity(entityId);
}
}

public void checkNametagVisbility(final String username) {
final GameProfileStorage profileStorage = user().get(GameProfileStorage.class);
final GameProfileStorage.GameProfile profile = profileStorage.get(username, false);
if (profile == null) return;

final int entityId = getPlayerEntityId(profile.uuid);
if (entityId == -1) return;

checkNametagVisibility(entityId);
}

private boolean isPlayerNametagHidden(final int entityId) {
final UUID uuid = entityIdToUUID.get(entityId);
if (uuid == null) return false;
final GameProfileStorage profileStorage = user().get(GameProfileStorage.class);
final GameProfileStorage.GameProfile profile = profileStorage.get(uuid);
if (profile == null) return false;
return user().get(ScoreboardTracker.class).isNametagHidden(profile.name);
}

private int getNametagHiderEntityId(final int playerEntityId) {
return Integer.MAX_VALUE - 32000 - playerEntityId;
}

private void spawnNametagHiderEntity(final int playerEntityId) {
final int entityId = getNametagHiderEntityId(playerEntityId);
playerNametagHiderEntities.put(playerEntityId, entityId);

final List<EntityData> mobData = new ArrayList<>();
mobData.add(new EntityData(0, EntityDataTypes1_7_6_10.BYTE, (byte) 0x20));
mobData.add(new EntityData(16, EntityDataTypes1_7_6_10.BYTE, (byte) 0));

final PacketWrapper spawnMob = PacketWrapper.create(ClientboundPackets1_7_2_5.ADD_MOB, user());
spawnMob.write(Types.VAR_INT, entityId);
spawnMob.write(Types.UNSIGNED_BYTE, (short) EntityTypes1_8.EntityType.MAGMA_CUBE.getId());
spawnMob.write(Types.INT, 0); // X
spawnMob.write(Types.INT, 0); // Y
spawnMob.write(Types.INT, 0); // Z
spawnMob.write(Types.BYTE, (byte) 0); // Yaw
spawnMob.write(Types.BYTE, (byte) 0); // Pitch
spawnMob.write(Types.BYTE, (byte) 0); // Head yaw
spawnMob.write(Types.SHORT, (short) 0); // Velocity x
spawnMob.write(Types.SHORT, (short) 0); // Velocity y
spawnMob.write(Types.SHORT, (short) 0); // Velocity z
spawnMob.write(RewindTypes.ENTITY_DATA_LIST1_7, mobData);
spawnMob.scheduleSend(Protocol1_8To1_7_6_10.class);

final PacketWrapper attach = PacketWrapper.create(ClientboundPackets1_7_2_5.SET_ENTITY_LINK, user());
attach.write(Types.INT, entityId);
attach.write(Types.INT, playerEntityId);
attach.write(Types.BOOLEAN, false);
attach.scheduleSend(Protocol1_8To1_7_6_10.class);
}

private void despawnNametagHiderEntity(final int playerEntityId) {
if (!playerNametagHiderEntities.containsKey(playerEntityId)) return;
final int mobId = playerNametagHiderEntities.remove(playerEntityId);

final PacketWrapper despawn = PacketWrapper.create(ClientboundPackets1_7_2_5.REMOVE_ENTITIES, user());
despawn.write(Types.BYTE, (byte) 1);
despawn.write(Types.INT, mobId);
despawn.scheduleSend(Protocol1_8To1_7_6_10.class);
}

public Int2ObjectMap<VirtualHologramEntity> getHolograms() {
return holograms;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public class ScoreboardTracker extends StoredObject {
private final HashMap<String, Byte> teamColors = new HashMap<>();
private final HashSet<String> scoreTeamNames = new HashSet<>();
private final HashMap<Byte, String> colorDependentSidebar = new HashMap<>();
private final HashMap<String, String> teamNameTagVisibilities = new HashMap<>();
private String colorIndependentSidebar;

public ScoreboardTracker(UserConnection user) {
Expand All @@ -63,6 +64,7 @@ public void removeTeam(String team) {
teams.remove(team);
scoreTeams.remove(team);
teamColors.remove(team);
teamNameTagVisibilities.remove(team);
}

public boolean teamExists(String team) {
Expand Down Expand Up @@ -98,6 +100,27 @@ public Optional<String> getTeam(String player) {
return Optional.empty();
}

public void setTeamNameTagVisibility(String team, String visibility) {
teamNameTagVisibilities.put(team, visibility);
}

public String getTeamNameTagVisibility(String team) {
return teamNameTagVisibilities.getOrDefault(team, "always");
}

public boolean isNametagHidden(String username) {
for (Map.Entry<String, List<String>> entry : teams.entrySet()) {
if (entry.getValue().contains(username)) {
return "never".equalsIgnoreCase(teamNameTagVisibilities.getOrDefault(entry.getKey(), "always"));
}
}
return false;
}

public List<String> getTeamMembers(String team) {
return teams.getOrDefault(team, new ArrayList<>());
}

public void addObjective(String name) {
objectives.add(name);
}
Expand Down