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}