# Source code
source: package: co.aikar.commands, class: ACFSpongeUtil

    001package co.aikar.commands;
    002
    003import org.jetbrains.annotations.Nullable;
    004import org.spongepowered.api.Sponge;
    005import org.spongepowered.api.command.CommandSource;
    006import org.spongepowered.api.entity.living.player.Player;
    007
    008import java.util.ArrayList;
    009import java.util.Iterator;
    010import java.util.List;
    011import java.util.stream.Collectors;
    012
    013@SuppressWarnings("WeakerAccess")
    014public class ACFSpongeUtil {
    015    public static Player findPlayerSmart(CommandIssuer issuer, String search) {
    016        CommandSource requester = issuer.getIssuer();
    017        if (search == null) {
    018            return null;
    019        }
    020        String name = ACFUtil.replace(search, ":confirm", "");
    021
    022        List<Player> matches = matchPlayer(name);
    023        List<Player> confirmList = new ArrayList<>();
    024        findMatches(search, requester, matches, confirmList);
    025
    026
    027        if (matches.size() > 1 || confirmList.size() > 1) {
    028            String allMatches = matches.stream().map(Player::getName).collect(Collectors.joining(", "));
    029            issuer.sendError(MinecraftMessageKeys.MULTIPLE_PLAYERS_MATCH,
    030                    "{search}", name, "{all}", allMatches);
    031            return null;
    032        }
    033
    034        if (matches.isEmpty()) {
    035            if (!issuer.getManager().isValidName(name)) {
    036                issuer.sendError(MinecraftMessageKeys.IS_NOT_A_VALID_NAME, "{name}", name);
    037                return null;
    038            }
    039            Player player = ACFUtil.getFirstElement(confirmList);
    040            if (player == null) {
    041                issuer.sendError(MinecraftMessageKeys.NO_PLAYER_FOUND_SERVER, "{search}", name);
    042                return null;
    043            } else {
    044
    045                issuer.sendInfo(MinecraftMessageKeys.PLAYER_IS_VANISHED_CONFIRM, "{vanished}", player.getName());
    046                return null;
    047            }
    048        }
    049
    050        return matches.get(0);
    051    }
    052
    053    private static void findMatches(String search, CommandSource requester, List<Player> matches, List<Player> confirmList) {
    054        // Remove vanished players from smart matching.
    055        Iterator<Player> iter = matches.iterator();
    056        //noinspection Duplicates
    057        while (iter.hasNext()) {
    058            Player player = iter.next();
    059            if (requester instanceof Player && !((Player) requester).canSee(player)) {
    060                if (requester.hasPermission("acf.seevanish")) {
    061                    if (!search.endsWith(":confirm")) {
    062                        confirmList.add(player);
    063                        iter.remove();
    064                    }
    065                } else {
    066                    iter.remove();
    067                }
    068            }
    069        }
    070    }
    071
    072    public static List<Player> matchPlayer(String partialName) {
    073        List<Player> matchedPlayers = new ArrayList<>();
    074
    075        for (Player iterPlayer : Sponge.getServer().getOnlinePlayers()) {
    076            String iterPlayerName = iterPlayer.getName();
    077
    078            if (partialName.equalsIgnoreCase(iterPlayerName)) {
    079                // Exact match
    080                matchedPlayers.clear();
    081                matchedPlayers.add(iterPlayer);
    082                break;
    083            }
    084            if (iterPlayerName.toLowerCase(java.util.Locale.ENGLISH).contains(partialName.toLowerCase(java.util.Locale.ENGLISH))) {
    085                // Partial match
    086                matchedPlayers.add(iterPlayer);
    087            }
    088        }
    089
    090        return matchedPlayers;
    091    }
    092
    093    public static boolean isValidName(@Nullable String name) {
    094        return name != null && !name.isEmpty() && ACFPatterns.VALID_NAME_PATTERN.matcher(name).matches();
    095    }
    096
    097}