mirror of https://github.com/Minestom/Minestom.git
Send all Adventure packets grouped where possible
This commit is contained in:
parent
4a0103a795
commit
e02a521494
|
@ -1,6 +1,7 @@
|
|||
package net.minestom.server;
|
||||
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.ServerPacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
|
@ -91,7 +92,7 @@ public interface Viewable {
|
|||
* @return the audience
|
||||
*/
|
||||
default @NotNull Audience getViewersAsAudience() {
|
||||
return Audience.audience(this.getViewersAsAudiences());
|
||||
return PacketGroupingAudience.of(this.getViewers());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -10,10 +10,12 @@ import net.minestom.server.MinecraftServer;
|
|||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.event.player.PlayerDisconnectEvent;
|
||||
import net.minestom.server.network.packet.server.play.BossBarPacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static net.minestom.server.network.packet.server.play.BossBarPacket.Action.*;
|
||||
|
||||
|
@ -50,13 +52,13 @@ public class BossBarManager implements BossBar.Listener {
|
|||
player.getPlayerConnection().sendPacket(holder.createAddPacket());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified player from the boss bar's viewers and despawns the boss bar.
|
||||
*
|
||||
* @param player the intended viewer
|
||||
* @param bar the boss bar to hide
|
||||
*/
|
||||
|
||||
public void removeBossBar(@NotNull Player player, @NotNull BossBar bar) {
|
||||
Holder holder = this.getOrCreateHandler(bar);
|
||||
|
||||
|
@ -65,6 +67,49 @@ public class BossBarManager implements BossBar.Listener {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified players to the boss bar's viewers and spawns the boss bar, registering the
|
||||
* boss bar if needed.
|
||||
*
|
||||
* @param players the players
|
||||
* @param bar the boss bar
|
||||
*/
|
||||
public void addBossBar(@NotNull Collection<Player> players, @NotNull BossBar bar) {
|
||||
Holder holder = this.getOrCreateHandler(bar);
|
||||
Collection<Player> addedPlayers = new ArrayList<>();
|
||||
|
||||
for (Player player : players) {
|
||||
if (holder.players.add(player.getUuid())) {
|
||||
addedPlayers.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (!addedPlayers.isEmpty()) {
|
||||
PacketUtils.sendGroupedPacket(players, holder.createAddPacket());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the specified players from the boss bar's viewers and despawns the boss bar.
|
||||
*
|
||||
* @param players the intended viewers
|
||||
* @param bar the boss bar to hide
|
||||
*/
|
||||
public void removeBossBar(@NotNull Collection<Player> players, @NotNull BossBar bar) {
|
||||
Holder holder = this.getOrCreateHandler(bar);
|
||||
Collection<Player> removedPlayers = new ArrayList<>();
|
||||
|
||||
for (Player player : players) {
|
||||
if (holder.players.remove(player.getUuid())) {
|
||||
removedPlayers.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
if (!removedPlayers.isEmpty()) {
|
||||
PacketUtils.sendGroupedPacket(players, holder.createRemovePacket());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bossBarNameChanged(@NotNull BossBar bar, @NotNull Component oldName, @NotNull Component newName) {
|
||||
Holder holder = this.bars.get(bar);
|
||||
|
@ -100,10 +145,11 @@ public class BossBarManager implements BossBar.Listener {
|
|||
* in the connection manager.
|
||||
*
|
||||
* @param packet the packet
|
||||
* @param players the players
|
||||
* @param uuids the players
|
||||
*/
|
||||
private void updatePlayers(BossBarPacket packet, Set<UUID> players) {
|
||||
Iterator<UUID> iterator = players.iterator();
|
||||
private void updatePlayers(BossBarPacket packet, Set<UUID> uuids) {
|
||||
Iterator<UUID> iterator = uuids.iterator();
|
||||
Collection<Player> players = new ArrayList<>();
|
||||
|
||||
while (iterator.hasNext()) {
|
||||
Player player = MinecraftServer.getConnectionManager().getPlayer(iterator.next());
|
||||
|
@ -111,9 +157,11 @@ public class BossBarManager implements BossBar.Listener {
|
|||
if (player == null) {
|
||||
iterator.remove();
|
||||
} else {
|
||||
player.getPlayerConnection().sendPacket(packet);
|
||||
players.add(player);
|
||||
}
|
||||
}
|
||||
|
||||
PacketUtils.sendGroupedPacket(players, packet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
package net.minestom.server.adventure.audience;
|
||||
|
||||
import net.kyori.adventure.audience.Audience;
|
||||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
import net.kyori.adventure.audience.MessageType;
|
||||
import net.kyori.adventure.bossbar.BossBar;
|
||||
import net.kyori.adventure.identity.Identity;
|
||||
import net.kyori.adventure.sound.Sound;
|
||||
import net.kyori.adventure.sound.SoundStop;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.title.Title;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.adventure.AdventurePacketConvertor;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.ChatMessagePacket;
|
||||
import net.minestom.server.network.packet.server.play.PlayerListHeaderAndFooterPacket;
|
||||
import net.minestom.server.network.packet.server.play.TitlePacket;
|
||||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* An audience implementation that sends grouped packets if possible.
|
||||
*/
|
||||
public interface PacketGroupingAudience extends ForwardingAudience {
|
||||
|
||||
/**
|
||||
* Creates a packet grouping audience that wraps a collection of players.
|
||||
* @param players the players
|
||||
* @return the audience
|
||||
*/
|
||||
static PacketGroupingAudience of(Collection<Player> players) {
|
||||
return new PacketGroupingAudience() {
|
||||
@Override
|
||||
public @NotNull Collection<Player> getPlayers() {
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterable<? extends Audience> audiences() {
|
||||
return players;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an collection of players this audience contains.
|
||||
* @return the connections
|
||||
*/
|
||||
@NotNull Collection<Player> getPlayers();
|
||||
|
||||
@Override
|
||||
default void sendMessage(@NotNull Identity source, @NotNull Component message, @NotNull MessageType type) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new ChatMessagePacket(message, ChatMessagePacket.Position.fromMessageType(type), source.uuid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void sendActionBar(@NotNull Component message) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new TitlePacket(TitlePacket.Action.SET_ACTION_BAR, message));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void sendPlayerListHeaderAndFooter(@NotNull Component header, @NotNull Component footer) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new PlayerListHeaderAndFooterPacket(header, footer));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void showTitle(@NotNull Title title) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new TitlePacket(TitlePacket.Action.SET_TITLE, title.title()));
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new TitlePacket(TitlePacket.Action.SET_SUBTITLE, title.subtitle()));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void clearTitle() {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new TitlePacket(TitlePacket.Action.HIDE));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void resetTitle() {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), new TitlePacket(TitlePacket.Action.RESET));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void showBossBar(@NotNull BossBar bar) {
|
||||
MinecraftServer.getBossBarManager().addBossBar(this.getPlayers(), bar);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void hideBossBar(@NotNull BossBar bar) {
|
||||
MinecraftServer.getBossBarManager().removeBossBar(this.getPlayers(), bar);
|
||||
}
|
||||
|
||||
@Override
|
||||
default void playSound(@NotNull Sound sound, double x, double y, double z) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundPacket(sound, x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
default void stopSound(@NotNull SoundStop stop) {
|
||||
PacketUtils.sendGroupedPacket(this.getPlayers(), AdventurePacketConvertor.createSoundStopPacket(stop));
|
||||
}
|
||||
|
||||
@Override
|
||||
default @NotNull Iterable<? extends Audience> audiences() {
|
||||
return this.getPlayers();
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import net.kyori.adventure.audience.Audience;
|
|||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.UpdateManager;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.data.Data;
|
||||
import net.minestom.server.data.DataContainer;
|
||||
import net.minestom.server.entity.Entity;
|
||||
|
@ -58,7 +59,7 @@ import java.util.function.Consumer;
|
|||
* you need to be sure to signal the {@link UpdateManager} of the changes using
|
||||
* {@link UpdateManager#signalChunkLoad(Instance, int, int)} and {@link UpdateManager#signalChunkUnload(Instance, int, int)}.
|
||||
*/
|
||||
public abstract class Instance implements BlockModifier, EventHandler, DataContainer, ForwardingAudience {
|
||||
public abstract class Instance implements BlockModifier, EventHandler, DataContainer, PacketGroupingAudience {
|
||||
|
||||
protected static final BlockManager BLOCK_MANAGER = MinecraftServer.getBlockManager();
|
||||
protected static final UpdateManager UPDATE_MANAGER = MinecraftServer.getUpdateManager();
|
||||
|
@ -455,6 +456,7 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
|||
*
|
||||
* @return an unmodifiable {@link Set} containing all the players in the instance
|
||||
*/
|
||||
@Override
|
||||
@NotNull
|
||||
public Set<Player> getPlayers() {
|
||||
return Collections.unmodifiableSet(players);
|
||||
|
@ -1105,9 +1107,4 @@ public abstract class Instance implements BlockModifier, EventHandler, DataConta
|
|||
public PFInstanceSpace getInstanceSpace() {
|
||||
return instanceSpace;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterable<? extends Audience> audiences() {
|
||||
return this.getPlayers();
|
||||
}
|
||||
}
|
|
@ -6,6 +6,8 @@ import net.kyori.adventure.audience.ForwardingAudience;
|
|||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.adventure.audience.Audiences;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.entity.fakeplayer.FakePlayer;
|
||||
|
@ -33,11 +35,12 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
|||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Manages the connected clients.
|
||||
*/
|
||||
public final class ConnectionManager implements ForwardingAudience {
|
||||
public final class ConnectionManager implements PacketGroupingAudience {
|
||||
|
||||
private static final long KEEP_ALIVE_DELAY = 10_000;
|
||||
private static final long KEEP_ALIVE_KICK = 30_000;
|
||||
|
@ -145,7 +148,7 @@ public final class ConnectionManager implements ForwardingAudience {
|
|||
* @param jsonMessage the message to send, probably a {@link net.minestom.server.chat.ColoredText} or {@link net.minestom.server.chat.RichMessage}
|
||||
* @param condition the condition to receive the message
|
||||
*
|
||||
* @deprecated Use {@link Audience#sendMessage(Component)} on {@link #audiences(PlayerValidator)}
|
||||
* @deprecated Use {@link Audiences#players(Predicate)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void broadcastMessage(@NotNull JsonMessage jsonMessage, @Nullable PlayerValidator condition) {
|
||||
|
@ -554,30 +557,7 @@ public final class ConnectionManager implements ForwardingAudience {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterable<? extends Audience> audiences() {
|
||||
public @NotNull Collection<Player> getPlayers() {
|
||||
return this.getOnlinePlayers();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the audiences of players who match a given validator.
|
||||
*
|
||||
* @param validator the validator
|
||||
*
|
||||
* @return the audience
|
||||
*/
|
||||
public @NotNull Iterable<? extends Audience> audiences(@Nullable PlayerValidator validator) {
|
||||
if (validator == null) {
|
||||
return this.audiences();
|
||||
}
|
||||
|
||||
List<Player> validatedPlayers = new ArrayList<>();
|
||||
|
||||
for (Player onlinePlayer : this.getOnlinePlayers()) {
|
||||
if (validator.isValid(onlinePlayer)) {
|
||||
validatedPlayers.add(onlinePlayer);
|
||||
}
|
||||
}
|
||||
|
||||
return validatedPlayers;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,16 +4,19 @@ import net.kyori.adventure.audience.Audience;
|
|||
import net.kyori.adventure.audience.ForwardingAudience;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.minestom.server.Viewable;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.entity.Player;
|
||||
import net.minestom.server.network.packet.server.play.DisplayScoreboardPacket;
|
||||
import net.minestom.server.network.packet.server.play.ScoreboardObjectivePacket;
|
||||
import net.minestom.server.network.packet.server.play.UpdateScorePacket;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* This interface represents all scoreboard of Minecraft.
|
||||
*/
|
||||
public interface Scoreboard extends Viewable, ForwardingAudience {
|
||||
public interface Scoreboard extends Viewable, PacketGroupingAudience {
|
||||
|
||||
/**
|
||||
* Creates a creation objective packet.
|
||||
|
@ -101,7 +104,7 @@ public interface Scoreboard extends Viewable, ForwardingAudience {
|
|||
String getObjectiveName();
|
||||
|
||||
@Override
|
||||
@NotNull default Iterable<? extends Audience> audiences() {
|
||||
@NotNull default Collection<Player> getPlayers() {
|
||||
return this.getViewers();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.kyori.adventure.text.Component;
|
|||
import net.kyori.adventure.text.format.NamedTextColor;
|
||||
import net.minestom.server.MinecraftServer;
|
||||
import net.minestom.server.adventure.AdventurePacketConvertor;
|
||||
import net.minestom.server.adventure.audience.PacketGroupingAudience;
|
||||
import net.minestom.server.chat.ChatColor;
|
||||
import net.minestom.server.chat.JsonMessage;
|
||||
import net.minestom.server.entity.LivingEntity;
|
||||
|
@ -18,6 +19,7 @@ import net.minestom.server.network.packet.server.play.TeamsPacket.NameTagVisibil
|
|||
import net.minestom.server.utils.PacketUtils;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
|
@ -25,7 +27,7 @@ import java.util.concurrent.CopyOnWriteArraySet;
|
|||
/**
|
||||
* This object represents a team on a scoreboard that has a common display theme and other properties.
|
||||
*/
|
||||
public class Team implements ForwardingAudience {
|
||||
public class Team implements PacketGroupingAudience {
|
||||
|
||||
private static final ConnectionManager CONNECTION_MANAGER = MinecraftServer.getConnectionManager();
|
||||
|
||||
|
@ -570,7 +572,7 @@ public class Team implements ForwardingAudience {
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NotNull Iterable<? extends Audience> audiences() {
|
||||
public @NotNull Collection<Player> getPlayers() {
|
||||
if (!this.isPlayerMembersUpToDate) {
|
||||
this.playerMembers.clear();
|
||||
|
||||
|
|
|
@ -2,11 +2,13 @@ package net.minestom.server.utils.callback.validator;
|
|||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
/**
|
||||
* Interface used when a value needs to be validated dynamically.
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface Validator<T> {
|
||||
public interface Validator<T> extends Predicate<T> {
|
||||
|
||||
/**
|
||||
* Gets if a value is valid based on a condition.
|
||||
|
@ -16,4 +18,12 @@ public interface Validator<T> {
|
|||
*/
|
||||
boolean isValid(@NotNull T value);
|
||||
|
||||
@Override
|
||||
default boolean test(T t) {
|
||||
if (t == null) {
|
||||
return false;
|
||||
} else {
|
||||
return this.isValid(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue