001package co.aikar.commands;
002
003import java.util.ArrayList;
004import java.util.Collection;
005import java.util.Collections;
006import java.util.List;
007import java.util.Optional;
008import java.util.stream.Collectors;
009
010import com.velocitypowered.api.command.CommandSource;
011import com.velocitypowered.api.proxy.Player;
012import com.velocitypowered.api.proxy.ProxyServer;
013
014import net.kyori.text.TextComponent;
015import net.kyori.text.serializer.legacy.LegacyComponentSerializer;
016
017public class ACFVelocityUtil {
018
019    @SuppressWarnings("deprecation")
020    public static TextComponent color(String message) {
021        return LegacyComponentSerializer.legacy().deserialize(message);
022    }
023
024    public static Player findPlayerSmart(ProxyServer server, CommandIssuer issuer, String search) {
025        CommandSource requester = issuer.getIssuer();
026        String name = ACFUtil.replace(search, ":confirm", "");
027        if (!isValidName(name)) {
028            issuer.sendError(MinecraftMessageKeys.IS_NOT_A_VALID_NAME, "{name}", name);
029            return null;
030        }
031
032        List<Player> matches = new ArrayList<>(matchPlayer(server, name));
033
034        if (matches.size() > 1) {
035            String allMatches = matches.stream().map(Player::getUsername).collect(Collectors.joining(", "));
036            issuer.sendError(MinecraftMessageKeys.MULTIPLE_PLAYERS_MATCH, "{search}", name, "{all}", allMatches);
037            return null;
038        }
039
040        if (matches.isEmpty()) {
041            issuer.sendError(MinecraftMessageKeys.NO_PLAYER_FOUND_SERVER, "{search}", name);
042            return null;
043        }
044
045        return matches.get(0);
046    }
047
048    /*
049     * Original code written by md_5
050     *
051     * Modified to work with Velocity by Crypnotic
052     */
053    private static Collection<Player> matchPlayer(ProxyServer server, final String partialName) {
054        // A better error message might be nice. This just mimics the previous output
055        if (partialName == null) {
056            throw new NullPointerException("partialName");
057        }
058
059        Optional<Player> exactMatch = server.getPlayer(partialName);
060        //noinspection OptionalIsPresent
061        if (exactMatch.isPresent()) {
062            return Collections.singleton(exactMatch.get());
063        }
064
065        return server.getAllPlayers().stream()
066                .filter(player -> player.getUsername().regionMatches(true, 0, partialName, 0, partialName.length()))
067                .collect(Collectors.toList());
068    }
069
070    public static boolean isValidName(String name) {
071        return name != null && !name.isEmpty() && ACFPatterns.VALID_NAME_PATTERN.matcher(name).matches();
072    }
073
074    public static <T> T validate(T object, String message, Object... values) {
075        if (object == null) {
076            throw new NullPointerException(String.format(message, values));
077        }
078        return object;
079    }
080}