Skip to content

Commit

Permalink
better API for sending initial join tablist packets
Browse files Browse the repository at this point in the history
  • Loading branch information
Steanky committed Sep 11, 2023
1 parent 32322a5 commit a33d776
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 9 deletions.
13 changes: 10 additions & 3 deletions src/main/java/net/minestom/server/entity/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -293,14 +293,21 @@ public CompletableFuture<Void> UNSAFE_init(@NotNull Instance spawnInstance) {
PlayerTablistShowEvent tablistEvent = new PlayerTablistShowEvent(this, true, spawnInstance);
EventDispatcher.call(tablistEvent);

ServerPacket packet = getAddPlayerToList();
Iterable<Player> recipients = tablistEvent.tablistParticipants();

ServerPacket packet = getAddPlayerToList();
sendPacket(packet);

if (recipients != null) {
for (Player recipient : recipients) {
recipient.sendPacket(packet);
if (recipient != this && tablistEvent.showPlayerPredicate().test(recipient))
if (recipient != this && tablistEvent.showJoiningPlayerToParticipant().test(this, recipient))
recipient.sendPacket(packet);

if (recipient != this && tablistEvent.showParticipantToJoiningPlayer().test(this, recipient))
sendPacket(recipient.getAddPlayerToList());
}
} else {
PacketUtils.broadcastPacket(packet);
}

//Teams
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,21 @@
import org.jetbrains.annotations.Nullable;

import java.util.Objects;
import java.util.function.Predicate;
import java.util.function.BiPredicate;

/**
* Called before tablist packets are sent to new players. Fired when a player first logs in, as well as when they change
* instances.
*/
public class PlayerTablistShowEvent implements PlayerEvent {
private final Player player;
private final boolean firstSpawn;

private final Instance newInstance;

private Iterable<Player> tablistRecipients;
private Predicate<? super Player> showPlayer = (ignored) -> true;
private BiPredicate<? super Player, ? super Player> showParticipantToJoiningPlayer = (ignored, ignored2) -> true;
private BiPredicate<? super Player, ? super Player> showJoiningPlayerToParticipant = (ignored, ignored2) -> true;

public PlayerTablistShowEvent(@NotNull Player player, boolean firstSpawn, @NotNull Instance newInstance) {
this.player = Objects.requireNonNull(player);
Expand All @@ -42,15 +47,43 @@ public void setTablistParticipants(@Nullable Iterable<Player> players) {
this.tablistRecipients = players;
}

/**
* The players who are participating in the tablist event; these are both recipients of tablist packets from the
* joining player, and senders of tablist packets to the joining player. If null, the default vanilla behavior is
* used, which sends tablist packets to all players on the server.
* <p>
* This iterable need not contain {@link PlayerTablistShowEvent#getPlayer()}, as players will always see themselves
* in the tab list.
*
* @return an {@link Iterable} containing all tablist participants
*/
public @Nullable Iterable<Player> tablistParticipants() {
return tablistRecipients;
}

public @NotNull Predicate<? super @NotNull Player> showPlayerPredicate() {
return showPlayer;
/**
* A {@link BiPredicate} that is called in order to determine if the joining player
* {@link PlayerTablistShowEvent#getPlayer()} should see a participant in the tab list, which will be a different
* player. The <i>first</i> parameter of the predicate is the joining player; the second is a different
* participant.
*
* @return a BiPredicate for determining which tablist participants should be shown to the joining player
*/
public @NotNull BiPredicate<? super @NotNull Player, ? super @NotNull Player> showParticipantToJoiningPlayer() {
return showParticipantToJoiningPlayer;
}

public void setShowPlayer(@NotNull Predicate<? super @NotNull Player> showPlayer) {
this.showPlayer = Objects.requireNonNull(showPlayer);
public @NotNull BiPredicate<? super @NotNull Player, ? super @NotNull Player> showJoiningPlayerToParticipant() {
return showJoiningPlayerToParticipant;
}

public void setShowParticipantToJoiningPlayer(@NotNull BiPredicate<? super @NotNull Player, ? super @NotNull Player>
showParticipantToJoiningPlayer) {
this.showParticipantToJoiningPlayer = Objects.requireNonNull(showParticipantToJoiningPlayer);
}

public void setShowJoiningPlayerToParticipant(@NotNull BiPredicate<? super @NotNull Player, ? super @NotNull Player>
showJoiningPlayerToParticipant) {
this.showJoiningPlayerToParticipant = Objects.requireNonNull(showJoiningPlayerToParticipant);
}
}

0 comments on commit a33d776

Please sign in to comment.