177 lines
6.1 KiB
Java
177 lines
6.1 KiB
Java
package com.onarandombox.MultiverseCore.utils;
|
|
|
|
import com.dumptruckman.minecraft.util.Logging;
|
|
import org.bukkit.Bukkit;
|
|
import org.bukkit.command.CommandSender;
|
|
import org.bukkit.entity.Player;
|
|
import org.jetbrains.annotations.NotNull;
|
|
import org.jetbrains.annotations.Nullable;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.List;
|
|
import java.util.UUID;
|
|
import java.util.regex.Pattern;
|
|
import java.util.stream.Collectors;
|
|
|
|
/**
|
|
* Helper class to get {@link Player} from name, UUID or Selectors.
|
|
*/
|
|
public class PlayerFinder {
|
|
|
|
private static final Pattern UUID_REGEX = Pattern.compile("[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[34][0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}");
|
|
private static final Pattern COMMA_SPLIT = Pattern.compile(",");
|
|
|
|
/**
|
|
* Get a {@link Player} based on an identifier of name UUID or selector.
|
|
*
|
|
* @param playerIdentifier An identifier of name UUID or selector.
|
|
* @param sender Target sender for selector.
|
|
* @return The player if found, else null.
|
|
*/
|
|
@Nullable
|
|
public static Player get(@NotNull String playerIdentifier,
|
|
@NotNull CommandSender sender) {
|
|
|
|
Player targetPlayer = getByName(playerIdentifier);
|
|
if (targetPlayer != null) {
|
|
return targetPlayer;
|
|
}
|
|
targetPlayer = getByUuid(playerIdentifier);
|
|
if (targetPlayer != null) {
|
|
return targetPlayer;
|
|
}
|
|
return getBySelector(playerIdentifier, sender);
|
|
}
|
|
|
|
/**
|
|
* Get multiple {@link Player} based on many identifiers of name UUID or selector.
|
|
*
|
|
* @param playerIdentifiers An identifier of multiple names, UUIDs or selectors, separated by comma.
|
|
* @param sender Target sender for selector.
|
|
* @return A list of all the {@link Player} found.
|
|
*/
|
|
@Nullable
|
|
public static List<Player> getMulti(@NotNull String playerIdentifiers,
|
|
@NotNull CommandSender sender) {
|
|
|
|
String[] playerIdentifierArray = COMMA_SPLIT.split(playerIdentifiers);
|
|
if (playerIdentifierArray == null || playerIdentifierArray.length == 0) {
|
|
return null;
|
|
}
|
|
|
|
List<Player> playerResults = new ArrayList<>();
|
|
for (String playerIdentifier : playerIdentifierArray) {
|
|
Player targetPlayer = getByName(playerIdentifier);
|
|
if (targetPlayer != null) {
|
|
playerResults.add(targetPlayer);
|
|
continue;
|
|
}
|
|
targetPlayer = getByUuid(playerIdentifier);
|
|
if (targetPlayer != null) {
|
|
playerResults.add(targetPlayer);
|
|
continue;
|
|
}
|
|
List<Player> targetPlayers = getMultiBySelector(playerIdentifier, sender);
|
|
if (targetPlayers != null) {
|
|
playerResults.addAll(targetPlayers);
|
|
}
|
|
}
|
|
return playerResults;
|
|
}
|
|
|
|
/**
|
|
* Get a {@link Player} based on player name.
|
|
*
|
|
* @param playerName Name of a {@link Player}.
|
|
* @return The player if found, else null.
|
|
*/
|
|
@Nullable
|
|
public static Player getByName(@NotNull String playerName) {
|
|
return Bukkit.getPlayerExact(playerName);
|
|
}
|
|
|
|
/**
|
|
* Get a {@link Player} based on player UUID.
|
|
*
|
|
* @param playerUuid UUID of a player.
|
|
* @return The player if found, else null.
|
|
*/
|
|
@Nullable
|
|
public static Player getByUuid(@NotNull String playerUuid) {
|
|
if (!UUID_REGEX.matcher(playerUuid).matches()) {
|
|
return null;
|
|
}
|
|
UUID uuid;
|
|
try {
|
|
uuid = UUID.fromString(playerUuid);
|
|
} catch (Exception e) {
|
|
return null;
|
|
}
|
|
return getByUuid(uuid);
|
|
}
|
|
|
|
/**
|
|
* Get a {@link Player} based on playerUUID.
|
|
*
|
|
* @param playerUuid UUID of a player.
|
|
* @return The player if found, else null.
|
|
*/
|
|
@Nullable
|
|
public static Player getByUuid(@NotNull UUID playerUuid) {
|
|
return Bukkit.getPlayer(playerUuid);
|
|
}
|
|
|
|
/**
|
|
* Get a {@link Player} based on vanilla selectors.
|
|
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
|
*
|
|
* @param playerSelector A target selector, usually starts with an '@'.
|
|
* @param sender Target sender for selector.
|
|
* @return The player if only one found, else null.
|
|
*/
|
|
@Nullable
|
|
public static Player getBySelector(@NotNull String playerSelector,
|
|
@NotNull CommandSender sender) {
|
|
|
|
List<Player> matchedPlayers = getMultiBySelector(playerSelector, sender);
|
|
if (matchedPlayers == null || matchedPlayers.isEmpty()) {
|
|
Logging.warning("No player found with selector '%s' for %s.", playerSelector, sender.getName());
|
|
return null;
|
|
}
|
|
if (matchedPlayers.size() > 1) {
|
|
Logging.warning("Ambiguous selector result '%s' for %s (more than one player matched) - %s",
|
|
playerSelector, sender.getName(), matchedPlayers.toString());
|
|
return null;
|
|
}
|
|
return matchedPlayers.get(0);
|
|
}
|
|
|
|
/**
|
|
* Get multiple {@link Player} based on selector.
|
|
* https://minecraft.gamepedia.com/Commands#Target_selectors
|
|
*
|
|
* @param playerSelector A target selector, usually starts with an '@'.
|
|
* @param sender Target sender for selector.
|
|
* @return A list of all the {@link Player} found.
|
|
*/
|
|
@Nullable
|
|
public static List<Player> getMultiBySelector(@NotNull String playerSelector,
|
|
@NotNull CommandSender sender) {
|
|
|
|
if (playerSelector.charAt(0) != '@') {
|
|
return null;
|
|
}
|
|
try {
|
|
return Bukkit.selectEntities(sender, playerSelector).stream()
|
|
.filter(e -> e instanceof Player)
|
|
.map(e -> ((Player) e))
|
|
.collect(Collectors.toList());
|
|
} catch (IllegalArgumentException e) {
|
|
Logging.warning("An error occurred while parsing selector '%s' for %s. Is it is the correct format?",
|
|
playerSelector, sender.getName());
|
|
e.printStackTrace();
|
|
return null;
|
|
}
|
|
}
|
|
}
|