Mostly javadoc, and also some fixes there and there
This commit is contained in:
@@ -2,7 +2,10 @@ package fr.pandacube.lib.players.standalone;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public interface StandaloneOffPlayer {
|
||||
/**
|
||||
* Represents any player, either offline or online.
|
||||
*/
|
||||
public interface AbstractOffPlayer {
|
||||
|
||||
|
||||
|
||||
@@ -12,20 +15,20 @@ public interface StandaloneOffPlayer {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Return the ID of the minecraft account.
|
||||
*
|
||||
* Returns the {@link UUID} of this player.
|
||||
* @return the id of the player
|
||||
*/
|
||||
UUID getUniqueId();
|
||||
|
||||
/**
|
||||
* @return the last known player name of this player, or null if this player never joined the network.
|
||||
* The last known player name of this player, or null if it is not known.
|
||||
* @return the last known player name of this player, or null if it is not known.
|
||||
*/
|
||||
String getName();
|
||||
|
||||
/**
|
||||
* Indicate if this player is connected to the current node (server or proxy, depending on interface implementation)
|
||||
* @return wether the player is online or not
|
||||
* Indicate if this player is connected to the current node (server or proxy, depending on interface implementation).
|
||||
* @return wether the player is online or not.
|
||||
*/
|
||||
boolean isOnline();
|
||||
|
||||
@@ -42,8 +45,9 @@ public interface StandaloneOffPlayer {
|
||||
/**
|
||||
* Return the online instance of this player, if any exists.
|
||||
* May return itself if the current instance already represent an online player.
|
||||
* @return the online instance for this player.
|
||||
*/
|
||||
StandaloneOnlinePlayer getOnlineInstance();
|
||||
AbstractOnlinePlayer getOnlineInstance();
|
||||
|
||||
|
||||
|
||||
@@ -55,9 +59,9 @@ public interface StandaloneOffPlayer {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns the name of the player (if any), with eventual prefix and suffix depending on permission groups
|
||||
* (and team for bukkit implementation)
|
||||
* @return the display name of the player
|
||||
* Returns the display name of the player (if any), with eventual prefix and suffix depending on permission groups
|
||||
* (and team for bukkit implementation).
|
||||
* @return the display name of the player.
|
||||
*/
|
||||
String getDisplayName();
|
||||
|
@@ -9,7 +9,10 @@ import net.kyori.adventure.text.ComponentLike;
|
||||
import java.util.Locale;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
/**
|
||||
* Represents any online player.
|
||||
*/
|
||||
public interface AbstractOnlinePlayer extends AbstractOffPlayer {
|
||||
|
||||
|
||||
|
||||
@@ -17,15 +20,19 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
/*
|
||||
* General data and state
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @return The current name of this player
|
||||
* @apiNote The implementation is expected to call the environment API
|
||||
* (Bukkit/Bungee) to get the name of the player.
|
||||
* Returns the name of the current server the player is in.
|
||||
* The returned value is used by the 'pandalib-permissions' system.
|
||||
* @return the name of the current server the player is in.
|
||||
*/
|
||||
|
||||
String getServerName();
|
||||
|
||||
|
||||
/**
|
||||
* Returns the name of the current world the player is in.
|
||||
* The returned value is used by the 'pandalib-permissions' system.
|
||||
* @return the name of the current world the player is in.
|
||||
*/
|
||||
String getWorldName();
|
||||
|
||||
|
||||
@@ -40,6 +47,8 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
|
||||
/**
|
||||
* Tells if this online player has the specified permission.
|
||||
* @param permission the permission to test on that player.
|
||||
* @return weither this player has the specified permission or not.
|
||||
* @implSpec Implementation of this method should call the permission system of their environment (paper/bungee),
|
||||
* so this method will work independently of the usage of the 'pandalib-permissions' module.
|
||||
*/
|
||||
@@ -58,15 +67,13 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
*/
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
* the chat is activated.
|
||||
* Display the provided message in the player’s chat, if the chat is activated.
|
||||
* @param message the message to display.
|
||||
*/
|
||||
void sendMessage(Component message);
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
* the chat is activated.
|
||||
* Display the provided message in the player’s chat, if the chat is activated.
|
||||
* @param message the message to display.
|
||||
*/
|
||||
default void sendMessage(ComponentLike message) {
|
||||
@@ -74,8 +81,7 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
* they allows to display CHAT messages
|
||||
* Display the provided message in the player’s chat, if they allows to display CHAT messages.
|
||||
* @param message the message to display.
|
||||
* @param sender the player causing the send of this message. Client side filtering may occur.
|
||||
* May be null if we don’t want client filtering, but still consider the message as CHAT message.
|
||||
@@ -86,8 +92,7 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
void sendMessage(Component message, Identified sender);
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if
|
||||
* they allows to display CHAT messages
|
||||
* Display the provided message in the player’s chat, if they allows to display CHAT messages.
|
||||
* @param message the message to display
|
||||
* @param sender the player causing the send of this message. Client side filtering may occur.
|
||||
* May be null if we don’t want client filtering, but still consider the message as CHAT message.
|
||||
@@ -100,8 +105,7 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the provided message in the player’s chat, if the chat is
|
||||
* activated, prepended with the server prefix.
|
||||
* Display the provided message in the player’s chat, if the chat is activated, prepended with the server prefix.
|
||||
* @param message the message to display
|
||||
*/
|
||||
default void sendPrefixedMessage(ComponentLike message) {
|
||||
@@ -131,9 +135,8 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the server brand field in the debug menu (F3) of the player
|
||||
* (third line in 1.15 debug screen). Supports ChatColor codes but no
|
||||
* line break.
|
||||
* Update the server brand field in the debug menu (F3) of the player (third line in 1.15 debug screen).
|
||||
* Supports legacy section format but no line break.
|
||||
* @param brand the server brand to send to the client.
|
||||
*/
|
||||
void sendServerBrand(String brand);
|
||||
@@ -148,47 +151,57 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
/*
|
||||
* Client options
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Gets the current client options of this player.
|
||||
* @return the current client options of this player.
|
||||
*/
|
||||
ClientOptions getClientOptions();
|
||||
|
||||
|
||||
/**
|
||||
* Interface providing various configuration values of the Minecraft client.
|
||||
*/
|
||||
interface ClientOptions {
|
||||
|
||||
|
||||
/**
|
||||
* The language of the client interface.
|
||||
* @return language of the client interface.
|
||||
*/
|
||||
Locale getLocale();
|
||||
|
||||
|
||||
/**
|
||||
* The client view distance, in chunks.
|
||||
* @return client view distance, in chunks.
|
||||
*/
|
||||
int getViewDistance();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* If the chat displays the text colors.
|
||||
* @return true if the chat displays the text colors, false otherwise.
|
||||
*/
|
||||
boolean hasChatColorEnabled();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to completely hide the chat to the
|
||||
* player. When this is the case, nothing is displayed in the chat box,
|
||||
* and the player can’t send any message or command.
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
* Tells if the client is configured to completely hide the chat to the player. When this is the case, nothing
|
||||
* is displayed in the chat box, and the player can’t send any message or command.
|
||||
* @return true if the chat is fully hidden, false otherwise.
|
||||
*/
|
||||
boolean isChatHidden();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to display the chat normally.
|
||||
* When this is the case, chat messages and system messages are
|
||||
* displayed in the chat box, and the player can send messages and
|
||||
* commands.
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
* Tells if the client is configured to display the chat normally. When this is the case, chat messages and
|
||||
* system messages are displayed in the chat box, and the player can send messages and commands.
|
||||
* @return true if the chat is fully visible, false otherwise.
|
||||
*/
|
||||
boolean isChatFullyVisible();
|
||||
|
||||
/**
|
||||
* Tells if the client is configured to only display system messages
|
||||
* in the chat.
|
||||
* When this is the case, chat messages are hidden but system messages
|
||||
* are visible in the chat box, and the player can only send commands.
|
||||
* @implSpec if the value is unknown, it is assumed that the chat is
|
||||
* fully visible.
|
||||
* Tells if the client is configured to only display system messages in the chat.
|
||||
* When this is the case, chat messages are hidden but system messages are visible in the chat box, and the
|
||||
* player can only send commands.
|
||||
* @return true if the chat is visible but only shows system messages, false otherwise.
|
||||
*/
|
||||
boolean isChatOnlyDisplayingSystemMessages();
|
||||
|
||||
@@ -196,57 +209,85 @@ public interface StandaloneOnlinePlayer extends StandaloneOffPlayer {
|
||||
|
||||
/**
|
||||
* Tells if the client has configured the main hand on the left.
|
||||
* @implSpec if the value is unknown, it is assumed that the main hand
|
||||
* is on the right.
|
||||
* @return true if the player’s character is left handed, false otherwise.
|
||||
*/
|
||||
boolean isLeftHanded();
|
||||
|
||||
/**
|
||||
* Tells if the client has configured the main hand on the right.
|
||||
* @implSpec if the value is unknown, it is assumed that the main hand
|
||||
* is on the right.
|
||||
* @return true if the player’s character is right handed, false otherwise.
|
||||
*/
|
||||
boolean isRightHanded();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the client has enabled the filtering of texts on sign and book titles.
|
||||
* Always false as of MC 1.18.
|
||||
* @return true if the client filters swearing in texts, false otherwise.
|
||||
*/
|
||||
boolean isTextFilteringEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the client allows the server to list their player name in the
|
||||
* multiplayer menu.
|
||||
* Tells if the client allows the server to list their player name in the multiplayer menu.
|
||||
* <b>To respect the player privacy’s configuration, this configuration value must be verified when generating
|
||||
* custom ping response packet (MOTD in multiplayer server’s menu) that includes player names.</b>
|
||||
* @return true if the client allows the server to list their player name in the multiplayer menu, false
|
||||
* otherwise.
|
||||
*/
|
||||
boolean allowsServerListing();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the cape is enabled on the player’s skin.
|
||||
* @return true if the cape is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinCapeEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the jacket is enabled on the player’s skin.
|
||||
* @return true if the jacket is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinJacketEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the left sleeve is enabled on the player’s skin.
|
||||
* @return true if the left sleeve is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinLeftSleeveEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the right sleeve is enabled on the player’s skin.
|
||||
* @return true if the right sleeve is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinRightSleeveEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the left pants is enabled on the player’s skin.
|
||||
* @return true if the left pants is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinLeftPantsEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the right pants is enabled on the player’s skin.
|
||||
* @return true if the right pants is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinRightPantsEnabled();
|
||||
|
||||
|
||||
/**
|
||||
* Tells if the hat is enabled on the player’s skin.
|
||||
* @return true if the hat is enabled on the player’s skin, false otherwise.
|
||||
*/
|
||||
boolean hasSkinHatsEnabled();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the player can send chat messages or receive chat messages from
|
||||
* other players, according to their client configuration.
|
||||
* <br>
|
||||
* Chat messages represent public communication between players. By default,
|
||||
* it only include actual chat message. This method may be used in commands
|
||||
* like /me, /afk or the login/logout broadcasted messages
|
||||
* Tells if the player can send chat messages or receive chat messages from other players, according to their client
|
||||
* configuration.
|
||||
* <p>
|
||||
* Chat messages represent public communication between players. By default, it only include actual chat message.
|
||||
* This method may be used in commands like /me, /afk or the login/logout broadcasted messages.
|
||||
* @return true if the player can send chat messages or receive chat messages from other players, false otherwise.
|
||||
*/
|
||||
default boolean canChat() {
|
||||
return getClientOptions().isChatFullyVisible();
|
@@ -0,0 +1,372 @@
|
||||
package fr.pandacube.lib.players.standalone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
|
||||
import fr.pandacube.lib.chat.ChatStatic;
|
||||
|
||||
/**
|
||||
* Generic implementation of a player manager, handling instances of {@link AbstractOffPlayer} and
|
||||
* {@link AbstractOnlinePlayer}.
|
||||
* Subclasses should handle the addition and removal of {@link AbstractOnlinePlayer} instances according to the
|
||||
* currently online players.
|
||||
* @param <OP> the type of subclass of {@link AbstractOnlinePlayer}
|
||||
* @param <OF> the type of subclass of {@link AbstractOffPlayer}
|
||||
*/
|
||||
public abstract class AbstractPlayerManager<OP extends AbstractOnlinePlayer, OF extends AbstractOffPlayer> {
|
||||
private static AbstractPlayerManager<?, ?> instance;
|
||||
|
||||
/**
|
||||
* Gets the current instance of player manager.
|
||||
* @return the player manager.
|
||||
*/
|
||||
public static synchronized AbstractPlayerManager<?, ?> getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static synchronized void setInstance(AbstractPlayerManager<?, ?> newInstance) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("cannot have multiple instance of PlayerManager");
|
||||
}
|
||||
instance = newInstance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private final Map<UUID, OP> onlinePlayers = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private final LoadingCache<UUID, OF> offlinePlayers = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.build(CacheLoader.from(this::newOffPlayerInstance));
|
||||
|
||||
/**
|
||||
* Creates a new instance of player manager.
|
||||
*/
|
||||
public AbstractPlayerManager() {
|
||||
setInstance(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds the provided player to this player manager.
|
||||
* Usually this is called by a player join event handler.
|
||||
* @param p the player to add.
|
||||
*/
|
||||
protected void addPlayer(OP p) {
|
||||
onlinePlayers.put(p.getUniqueId(), p);
|
||||
offlinePlayers.invalidate(p.getUniqueId());
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the player from this player manager.
|
||||
* Usually this is called by a player quit event handler.
|
||||
* @param p the UUID of the player to remove.
|
||||
* @return the player that has been removed.
|
||||
*/
|
||||
protected OP removePlayer(UUID p) {
|
||||
return onlinePlayers.remove(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the online player that has the provided UUID.
|
||||
* @param p the UUID of the player.
|
||||
* @return the online player instance.
|
||||
*/
|
||||
public OP get(UUID p) {
|
||||
return onlinePlayers.get(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tells if the provided player is online.
|
||||
* @param p the UUID of the player.
|
||||
* @return true if the provided player is online (that is when this player manager contains an online player
|
||||
* instance), false otherwise.
|
||||
*/
|
||||
public boolean isOnline(UUID p) {
|
||||
return onlinePlayers.containsKey(p);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of online player registered in this player manager.
|
||||
* @return the number of online player registered in this player manager.
|
||||
*/
|
||||
public int getPlayerCount() {
|
||||
return onlinePlayers.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the online players is this player manager.
|
||||
* @return all the online players is this player manager.
|
||||
*/
|
||||
public List<OP> getAll() {
|
||||
return new ArrayList<>(onlinePlayers.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an instance of {@link AbstractOffPlayer} corresponding to a player with the provided {@link UUID}.
|
||||
* @param p the UUID of the player.
|
||||
* @return an instance of {@link AbstractOffPlayer}. It can be a new instance, an {@link AbstractOnlinePlayer}
|
||||
* instance if the player is online, or a cached instance of {@link AbstractOffPlayer}.
|
||||
*/
|
||||
public OF getOffline(UUID p) {
|
||||
if (p == null)
|
||||
return null;
|
||||
OP online = get(p);
|
||||
if (online != null) {
|
||||
offlinePlayers.invalidate(p);
|
||||
@SuppressWarnings("unchecked")
|
||||
OF ret = (OF) online;
|
||||
return ret;
|
||||
}
|
||||
// if not online
|
||||
try {
|
||||
return offlinePlayers.get(p); // load and cache new instance if necessary
|
||||
} catch (ExecutionException e) {
|
||||
throw new UncheckedExecutionException(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Create a new instance of the appropriate subclass of {@link AbstractOffPlayer}.
|
||||
* @param p the uuid of the player.
|
||||
* @return the new instance of {@link AbstractOffPlayer}.
|
||||
*/
|
||||
protected abstract OF newOffPlayerInstance(UUID p);
|
||||
|
||||
/**
|
||||
* Abstract method to implement to send a message to the console.
|
||||
* @param message the message to send to the console.
|
||||
*/
|
||||
protected abstract void sendMessageToConsole(Component message);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
* @implSpec subclasses may override this method, for instance to restrict the players being able to see the message
|
||||
* (like /ignored players).
|
||||
*/
|
||||
public void broadcastMessage(ComponentLike message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
Objects.requireNonNull(message, "message cannot be null");
|
||||
|
||||
if (prefix)
|
||||
message = ChatStatic.prefixedAndColored(message.asComponent());
|
||||
|
||||
for (OP op : getAll()) {
|
||||
if (permission != null && !(op.hasPermission(permission))) continue;
|
||||
|
||||
if (sourcePlayer != null)
|
||||
op.sendMessage(message, sourcePlayer); // CHAT message with UUID
|
||||
else
|
||||
op.sendMessage(message); // SYSTEM message
|
||||
}
|
||||
if (console)
|
||||
sendMessageToConsole(message.asComponent());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Message broadcasting
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
*
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
getInstance().broadcastMessage(message, prefix, console, permission, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param permission if not null, the message is only sent to player with this permission.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, String permission) {
|
||||
broadcast(message, prefix, console, permission, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, String, UUID)}.
|
||||
* <p>
|
||||
* This method decides to send the message to the console depending on whether {@code permission}
|
||||
* is null (will send to console) or not (will not send to console). To specify this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param permission if not null, the message is only sent to player with this permission (but not to console).
|
||||
* If null, the message will be sent to all players and to console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, String permission) {
|
||||
broadcast(message, prefix, (permission == null), permission, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param permission if not null, the message is only sent to player with this permission (but not to console).
|
||||
* If null, the message will be sent to all players and to console.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, String permission, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, permission, sourcePlayer);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method doesn’t restrict to a specific permission. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
*
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, UUID sourcePlayer) {
|
||||
getInstance().broadcastMessage(message, prefix, console, null, sourcePlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method doesn’t restrict to a specific permission. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, String)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console) {
|
||||
broadcast(message, prefix, console, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method doesn’t restrict to a specific permission. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, String, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, null, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean)}.
|
||||
* <p>
|
||||
* This method doesn’t restrict to a specific permission. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, String)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix) {
|
||||
broadcast(message, prefix, true, null, null);
|
||||
}
|
||||
|
||||
}
|
@@ -1,216 +0,0 @@
|
||||
package fr.pandacube.lib.players.standalone;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import com.google.common.cache.CacheLoader;
|
||||
import com.google.common.cache.LoadingCache;
|
||||
import com.google.common.util.concurrent.UncheckedExecutionException;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.ComponentLike;
|
||||
|
||||
import fr.pandacube.lib.chat.ChatStatic;
|
||||
|
||||
public abstract class StandalonePlayerManager<OP extends StandaloneOnlinePlayer, OF extends StandaloneOffPlayer> {
|
||||
private static StandalonePlayerManager<?, ?> instance;
|
||||
|
||||
public static synchronized StandalonePlayerManager<?, ?> getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
private static synchronized void setInstance(StandalonePlayerManager<?, ?> newInstance) {
|
||||
if (instance != null) {
|
||||
throw new IllegalStateException("cannot have multiple instance of PlayerManager");
|
||||
}
|
||||
instance = newInstance;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private final Map<UUID, OP> onlinePlayers = Collections.synchronizedMap(new HashMap<>());
|
||||
|
||||
private final LoadingCache<UUID, OF> offlinePlayers = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(10, TimeUnit.MINUTES)
|
||||
.build(CacheLoader.from(this::newOffPlayerInstance));
|
||||
|
||||
|
||||
public StandalonePlayerManager() {
|
||||
setInstance(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected void addPlayer(OP p) {
|
||||
onlinePlayers.put(p.getUniqueId(), p);
|
||||
offlinePlayers.invalidate(p.getUniqueId());
|
||||
}
|
||||
|
||||
protected OP removePlayer(UUID p) {
|
||||
return onlinePlayers.remove(p);
|
||||
}
|
||||
|
||||
public OP get(UUID p) {
|
||||
return onlinePlayers.get(p);
|
||||
}
|
||||
|
||||
public boolean isOnline(UUID p) {
|
||||
return onlinePlayers.containsKey(p);
|
||||
}
|
||||
|
||||
public int getPlayerCount() {
|
||||
return onlinePlayers.size();
|
||||
}
|
||||
|
||||
public List<OP> getAll() {
|
||||
return new ArrayList<>(onlinePlayers.values());
|
||||
}
|
||||
|
||||
public OF getOffline(UUID p) {
|
||||
if (p == null)
|
||||
return null;
|
||||
OP online = get(p);
|
||||
if (online != null) {
|
||||
offlinePlayers.invalidate(p);
|
||||
@SuppressWarnings("unchecked")
|
||||
OF ret = (OF) online;
|
||||
return ret;
|
||||
}
|
||||
// if not online
|
||||
try {
|
||||
return offlinePlayers.get(p); // load and cache new instance if necessary
|
||||
} catch (ExecutionException e) {
|
||||
throw new UncheckedExecutionException(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
protected abstract OF newOffPlayerInstance(UUID p);
|
||||
|
||||
protected abstract void sendMessageToConsole(Component message);
|
||||
|
||||
|
||||
|
||||
public void broadcastMessage(ComponentLike message, boolean prefix, boolean console, String permission, UUID sourcePlayer) {
|
||||
Objects.requireNonNull(message, "message cannot be null");
|
||||
|
||||
if (prefix)
|
||||
message = ChatStatic.prefixedAndColored(message.asComponent());
|
||||
|
||||
for (StandaloneOnlinePlayer op : getAll()) {
|
||||
if (sourcePlayer != null)
|
||||
op.sendMessage(message, sourcePlayer); // CHAT message without UUID
|
||||
else
|
||||
op.sendMessage(message); // SYSTEM message
|
||||
}
|
||||
|
||||
if (console)
|
||||
getInstance().sendMessageToConsole(message.asComponent());
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Message broadcasting
|
||||
*/
|
||||
|
||||
// ComponentLike message
|
||||
// boolean prefix
|
||||
// boolean console = (permission == null)
|
||||
// UUID sourcePlayer = null
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
*
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console, UUID sourcePlayer) {
|
||||
getInstance().broadcastMessage(message, prefix, console, null, sourcePlayer);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Broadcast a message to some or all players, and eventually to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param console if the message must be displayed in the console.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, boolean console) {
|
||||
broadcast(message, prefix, console, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean, UUID)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @param sourcePlayer specifiy the eventual player that is the source of the message.
|
||||
* If null, the message will be sent as a SYSTEM chat message.
|
||||
* If not null, the message will be sent as a CHAT message, and will not be sent
|
||||
* to players ignoring the provided player (if implemented).
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix, UUID sourcePlayer) {
|
||||
broadcast(message, prefix, true, sourcePlayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcast a message to all players, and to the console.
|
||||
* <p>
|
||||
* This method assumes this message is not caused by a specific player. To specify the source player, use
|
||||
* {@link #broadcast(ComponentLike, boolean, UUID)}.
|
||||
* <p>
|
||||
* This method sends the message to the console. To change this behaviour, use
|
||||
* {@link #broadcast(ComponentLike, boolean, boolean)}.
|
||||
*
|
||||
* @param message the message to send.
|
||||
* @param prefix if the server prefix will be prepended to the message.
|
||||
* @throws IllegalArgumentException if message is null.
|
||||
*/
|
||||
public static void broadcast(ComponentLike message, boolean prefix) {
|
||||
broadcast(message, prefix, true, null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
Reference in New Issue
Block a user